summaryrefslogtreecommitdiff
path: root/sys/arch/amd64/amd64/pmap.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/arch/amd64/amd64/pmap.c')
-rw-r--r--sys/arch/amd64/amd64/pmap.c93
1 files changed, 59 insertions, 34 deletions
diff --git a/sys/arch/amd64/amd64/pmap.c b/sys/arch/amd64/amd64/pmap.c
index aac10a10054..15e60b4da0a 100644
--- a/sys/arch/amd64/amd64/pmap.c
+++ b/sys/arch/amd64/amd64/pmap.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pmap.c,v 1.23 2007/05/25 16:22:11 art Exp $ */
+/* $OpenBSD: pmap.c,v 1.24 2007/05/27 08:58:31 art Exp $ */
/* $NetBSD: pmap.c,v 1.3 2003/05/08 18:13:13 thorpej Exp $ */
/*
@@ -237,11 +237,6 @@ long nbpd[] = NBPD_INITIALIZER;
pd_entry_t *normal_pdes[] = PDES_INITIALIZER;
pd_entry_t *alternate_pdes[] = APDES_INITIALIZER;
-/*
- * Direct map.
- */
-paddr_t DMPDpa;
-
/* int nkpde = NKPTP; */
struct simplelock pmaps_lock;
@@ -575,8 +570,6 @@ pmap_bootstrap(vaddr_t kva_start, paddr_t max_pa)
{
vaddr_t kva, kva_end;
struct pmap *kpm;
- pt_entry_t *tmppte;
- vaddr_t tmpva;
int i;
unsigned long p1i;
pt_entry_t pg_nx = (cpu_feature & CPUID_NXE? PG_NX : 0);
@@ -658,58 +651,83 @@ pmap_bootstrap(vaddr_t kva_start, paddr_t max_pa)
}
/*
- * Temporary mapping for setting up the direct map.
+ * Map the direct map. The first 4GB were mapped in locore, here
+ * we map the rest if it exists. We actually use the direct map
+ * here to set up the page tables, we're assuming that we're still
+ * operating in the lower 4GB of memory.
*/
- tmpva = (KERNBASE + NKL2_KIMG_ENTRIES * NBPD_L2);
- virtual_avail += PAGE_SIZE;
- tmppte = PTE_BASE + pl1_i(tmpva);
+ ndmpdp = (max_pa + NBPD_L3 - 1) >> L3_SHIFT;
+ if (ndmpdp < NDML2_ENTRIES)
+ ndmpdp = NDML2_ENTRIES; /* At least 4GB */
+
+printf("ndmpdp: %ld\n", ndmpdp);
+
+ dmpdp = kpm->pm_pdir[PDIR_SLOT_DIRECT] & PG_FRAME;
+
+ dmpd = avail_start; avail_start += ndmpdp * PAGE_SIZE;
+
+ for (i = NDML2_ENTRIES; i < NPDPG * ndmpdp; i++) {
+ paddr_t pdp;
+ vaddr_t va;
+
+ pdp = (paddr_t)&(((pd_entry_t *)dmpd)[i]);
+ va = PMAP_DIRECT_MAP(pdp);
+
+ *((pd_entry_t *)va) = ((paddr_t)i << L2_SHIFT);
+ *((pd_entry_t *)va) |= PG_RW | PG_V | PG_PS | PG_G | PG_U |
+ PG_M;
+ }
+
+ for (i = NDML2_ENTRIES; i < ndmpdp; i++) {
+ paddr_t pdp;
+ vaddr_t va;
+
+ pdp = (paddr_t)&(((pd_entry_t *)dmpdp)[i]);
+ va = PMAP_DIRECT_MAP(pdp);
+
+ *((pd_entry_t *)va) = dmpd + (i << PAGE_SHIFT);
+ *((pd_entry_t *)va) |= PG_RW | PG_V | PG_U | PG_M;
+ }
+
+ kpm->pm_pdir[PDIR_SLOT_DIRECT] = dmpdp | PG_V | PG_KW | PG_U |
+ PG_M;
/*
- * Map the direct map. We steal pages for the page tables from
- * avail_start, then we create temporary mappings using the
- * early_zerop. Scary, slow, but we only do it once.
+ * Now do the same thing, but for the direct uncached map.
*/
ndmpdp = (max_pa + NBPD_L3 - 1) >> L3_SHIFT;
- if (ndmpdp < 4)
- ndmpdp = 4; /* At least 4GB */
+ if (ndmpdp < NDML2_ENTRIES)
+ ndmpdp = NDML2_ENTRIES; /* At least 4GB */
dmpdp = avail_start; avail_start += PAGE_SIZE;
dmpd = avail_start; avail_start += ndmpdp * PAGE_SIZE;
for (i = 0; i < NPDPG * ndmpdp; i++) {
paddr_t pdp;
- paddr_t off;
vaddr_t va;
pdp = (paddr_t)&(((pd_entry_t *)dmpd)[i]);
- off = pdp - trunc_page(pdp);
- *tmppte = (trunc_page(pdp) & PG_FRAME) | PG_V | PG_RW;
- pmap_update_pg(tmpva);
+ va = PMAP_DIRECT_MAP(pdp);
- va = tmpva + off;
*((pd_entry_t *)va) = (paddr_t)i << L2_SHIFT;
- *((pd_entry_t *)va) |= PG_RW | PG_V | PG_PS | PG_G;
+ *((pd_entry_t *)va) |= PG_RW | PG_V | PG_PS | PG_G | PG_N |
+ PG_U | PG_M;
}
for (i = 0; i < ndmpdp; i++) {
paddr_t pdp;
- paddr_t off;
vaddr_t va;
pdp = (paddr_t)&(((pd_entry_t *)dmpdp)[i]);
- off = pdp - trunc_page(pdp);
- *tmppte = (trunc_page(pdp) & PG_FRAME) | PG_V | PG_RW;
- pmap_update_pg(tmpva);
+ va = PMAP_DIRECT_MAP(pdp);
- va = tmpva + off;
*((pd_entry_t *)va) = dmpd + (i << PAGE_SHIFT);
- *((pd_entry_t *)va) |= PG_RW | PG_V | PG_U;
+ *((pd_entry_t *)va) |= PG_RW | PG_V | PG_U | PG_M;
}
- *tmppte = 0;
-
- DMPDpa = dmpdp;
- kpm->pm_pdir[PDIR_SLOT_DIRECT] = DMPDpa | PG_V | PG_KW | PG_U;
+ kpm->pm_pdir[PDIR_SLOT_DIRECT_NC] = dmpdp | PG_V | PG_KW | PG_U |
+ PG_M;
+
tlbflush();
msgbuf_vaddr = virtual_avail;
@@ -1073,7 +1091,8 @@ pmap_pdp_ctor(void *arg, void *object, int flags)
memset(&pdir[PDIR_SLOT_KERN + npde], 0,
(NTOPLEVEL_PDES - (PDIR_SLOT_KERN + npde)) * sizeof(pd_entry_t));
- pdir[PDIR_SLOT_DIRECT] = DMPDpa | PG_V | PG_KW | PG_U;
+ pdir[PDIR_SLOT_DIRECT] = pmap_kernel()->pm_pdir[PDIR_SLOT_DIRECT];
+ pdir[PDIR_SLOT_DIRECT_NC] = pmap_kernel()->pm_pdir[PDIR_SLOT_DIRECT_NC];
#if VM_MIN_KERNEL_ADDRESS != KERNBASE
pdir[pl4_pi(KERNBASE)] = PDP_BASE[pl4_pi(KERNBASE)];
@@ -1388,6 +1407,12 @@ pmap_extract(struct pmap *pmap, vaddr_t va, paddr_t *pap)
return (TRUE);
}
+ if (pmap == pmap_kernel() && va >= PMAP_DIRECT_BASE_NC &&
+ va < PMAP_DIRECT_END_NC) {
+ *pap = va - PMAP_DIRECT_BASE_NC;
+ return (TRUE);
+ }
+
pmap_map_ptes(pmap, &ptes, &pdes);
if (pmap_pdes_valid(va, pdes, &pde) == FALSE) {
return FALSE;