diff options
author | Tom Cosgrove <tom@cvs.openbsd.org> | 2007-02-20 21:15:02 +0000 |
---|---|---|
committer | Tom Cosgrove <tom@cvs.openbsd.org> | 2007-02-20 21:15:02 +0000 |
commit | b5de0662c0ae590547e7ddf1190bad604e2d2d32 (patch) | |
tree | 24d8349b344e6d332fcbcfcb1db55cf1ca3417ee /sys | |
parent | d084ccaa91178ec96027c48218e22002215bedba (diff) |
Revert PAE pmap for now, until the strange bug is found. This stops
the freezes many of us are seeing (especially on amd64 machines running
OpenBSD/i386).
Much testing by nick@ (as always - thanks!), hugh@, ian@, kettenis@
and Sam Smith (s (at) msmith (dot) net).
Requested by, input from, and ok deraadt@ ok art@, kettenis@, miod@
Diffstat (limited to 'sys')
25 files changed, 670 insertions, 984 deletions
diff --git a/sys/arch/i386/conf/files.i386 b/sys/arch/i386/conf/files.i386 index e0c62190346..35aee08457f 100644 --- a/sys/arch/i386/conf/files.i386 +++ b/sys/arch/i386/conf/files.i386 @@ -1,4 +1,4 @@ -# $OpenBSD: files.i386,v 1.153 2007/02/17 17:38:37 tom Exp $ +# $OpenBSD: files.i386,v 1.154 2007/02/20 21:15:01 tom Exp $ # # new style config file for i386 architecture # @@ -33,7 +33,6 @@ file arch/i386/i386/k6_mem.c mtrr file arch/i386/i386/microtime.s file arch/i386/i386/p4tcc.c !small_kernel & i686_cpu file arch/i386/i386/pmap.c -file arch/i386/i386/pmapae.c !small_kernel file arch/i386/i386/powernow.c !small_kernel & i586_cpu file arch/i386/i386/powernow-k7.c !small_kernel & i686_cpu file arch/i386/i386/powernow-k8.c !small_kernel & i686_cpu diff --git a/sys/arch/i386/i386/autoconf.c b/sys/arch/i386/i386/autoconf.c index 59b314022b5..0721333c06e 100644 --- a/sys/arch/i386/i386/autoconf.c +++ b/sys/arch/i386/i386/autoconf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: autoconf.c,v 1.69 2006/11/29 22:40:13 miod Exp $ */ +/* $OpenBSD: autoconf.c,v 1.70 2007/02/20 21:15:01 tom Exp $ */ /* $NetBSD: autoconf.c,v 1.20 1996/05/03 19:41:56 christos Exp $ */ /*- @@ -124,9 +124,6 @@ cpu_configure(void) kvm86_init(); #endif -#ifndef SMALL_KERNEL - pmap_bootstrap_pae(); -#endif if (config_rootfound("mainbus", NULL) == NULL) panic("cpu_configure: mainbus not configured"); diff --git a/sys/arch/i386/i386/cpu.c b/sys/arch/i386/i386/cpu.c index 9f601ebcd5f..aab0c99c860 100644 --- a/sys/arch/i386/i386/cpu.c +++ b/sys/arch/i386/i386/cpu.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cpu.c,v 1.20 2006/06/10 17:50:30 gwk Exp $ */ +/* $OpenBSD: cpu.c,v 1.21 2007/02/20 21:15:01 tom Exp $ */ /* $NetBSD: cpu.c,v 1.1.2.7 2000/06/26 02:04:05 sommerfeld Exp $ */ /*- @@ -248,7 +248,8 @@ cpu_attach(struct device *parent, struct device *self, void *aux) pcb->pcb_tss.tss_esp = kstack + USPACE - 16 - sizeof (struct trapframe); pcb->pcb_pmap = pmap_kernel(); - pcb->pcb_cr3 = pcb->pcb_pmap->pm_pdirpa; + pcb->pcb_cr3 = vtophys((vaddr_t)pcb->pcb_pmap->pm_pdir); + /* pcb->pcb_cr3 = pcb->pcb_pmap->pm_pdir - KERNBASE; XXX ??? */ cpu_default_ldt(ci); /* Use the `global' ldt until one alloc'd */ #endif @@ -409,7 +410,7 @@ cpu_boot_secondary(struct cpu_info *ci) printf("%s: starting", ci->ci_dev.dv_xname); /* XXX move elsewhere, not per CPU. */ - mp_pdirpa = kpm->pm_pdirpa; + mp_pdirpa = vtophys((vaddr_t)kpm->pm_pdir); pcb = ci->ci_idle_pcb; diff --git a/sys/arch/i386/i386/db_memrw.c b/sys/arch/i386/i386/db_memrw.c index f490f1e02e1..6ff8a7eb835 100644 --- a/sys/arch/i386/i386/db_memrw.c +++ b/sys/arch/i386/i386/db_memrw.c @@ -1,4 +1,4 @@ -/* $OpenBSD: db_memrw.c,v 1.11 2006/05/11 13:21:11 mickey Exp $ */ +/* $OpenBSD: db_memrw.c,v 1.12 2007/02/20 21:15:01 tom Exp $ */ /* $NetBSD: db_memrw.c,v 1.6 1999/04/12 20:38:19 pk Exp $ */ /* @@ -63,19 +63,28 @@ db_read_bytes(vaddr_t addr, size_t size, char *data) void db_write_bytes(vaddr_t addr, size_t size, char *data) { - extern char etext; - u_int32_t bits, bits1; - vaddr_t addr1 = 0; char *dst; + pt_entry_t *ptep0 = 0; + pt_entry_t oldmap0 = { 0 }; + vaddr_t addr1; + pt_entry_t *ptep1 = 0; + pt_entry_t oldmap1 = { 0 }; + extern char etext; + if (addr >= VM_MIN_KERNEL_ADDRESS && addr < (vaddr_t)&etext) { - bits = pmap_pte_setbits(addr, PG_RW, 0) & PG_RW; + ptep0 = kvtopte(addr); + oldmap0 = *ptep0; + *(int *)ptep0 |= /* INTEL_PTE_WRITE */ PG_RW; addr1 = trunc_page(addr + size - 1); - if (trunc_page(addr) != addr1) + if (trunc_page(addr) != addr1) { /* data crosses a page boundary */ - bits1 = pmap_pte_setbits(addr1, PG_RW, 0) & PG_RW; + ptep1 = kvtopte(addr1); + oldmap1 = *ptep1; + *(int *)ptep1 |= /* INTEL_PTE_WRITE */ PG_RW; + } tlbflush(); } @@ -84,10 +93,10 @@ db_write_bytes(vaddr_t addr, size_t size, char *data) while (size-- > 0) *dst++ = *data++; - if (addr1) { - pmap_pte_setbits(addr, 0, bits ^ PG_RW); - if (trunc_page(addr) != addr1) - pmap_pte_setbits(addr1, 0, bits1 ^ PG_RW); + if (ptep0) { + *ptep0 = oldmap0; + if (ptep1) + *ptep1 = oldmap1; tlbflush(); } } diff --git a/sys/arch/i386/i386/genassym.cf b/sys/arch/i386/i386/genassym.cf index cb328569a85..b47fb186d00 100644 --- a/sys/arch/i386/i386/genassym.cf +++ b/sys/arch/i386/i386/genassym.cf @@ -1,4 +1,4 @@ -# $OpenBSD: genassym.cf,v 1.24 2006/04/27 15:37:50 mickey Exp $ +# $OpenBSD: genassym.cf,v 1.25 2007/02/20 21:15:01 tom Exp $ # # Copyright (c) 1982, 1990 The Regents of the University of California. # All rights reserved. @@ -80,6 +80,7 @@ export PDSLOT_KERN export PDSLOT_PTE export PDSLOT_APTE export NKPTP_MIN +export NKPTP_MAX # values for virtual memory export VM_MAXUSER_ADDRESS diff --git a/sys/arch/i386/i386/kgdb_machdep.c b/sys/arch/i386/i386/kgdb_machdep.c index 85706ba7866..5d74f8123c7 100644 --- a/sys/arch/i386/i386/kgdb_machdep.c +++ b/sys/arch/i386/i386/kgdb_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kgdb_machdep.c,v 1.7 2006/09/19 11:06:33 jsg Exp $ */ +/* $OpenBSD: kgdb_machdep.c,v 1.8 2007/02/20 21:15:01 tom Exp $ */ /* $NetBSD: kgdb_machdep.c,v 1.6 1998/08/13 21:36:03 thorpej Exp $ */ /*- @@ -95,13 +95,15 @@ int kgdb_acc(vaddr_t va, size_t len) { vaddr_t last_va; + pt_entry_t *pte; last_va = va + len; va &= ~PGOFSET; last_va &= ~PGOFSET; do { - if ((pmap_pte_bits(va) & PG_V) == 0) + pte = kvtopte(va); + if ((*pte & PG_V) == 0) return (0); va += NBPG; } while (va < last_va); diff --git a/sys/arch/i386/i386/kvm86.c b/sys/arch/i386/i386/kvm86.c index 2ccea3bcd8b..4a42bc44b99 100644 --- a/sys/arch/i386/i386/kvm86.c +++ b/sys/arch/i386/i386/kvm86.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kvm86.c,v 1.2 2006/11/27 16:00:19 gwk Exp $ */ +/* $OpenBSD: kvm86.c,v 1.3 2007/02/20 21:15:01 tom Exp $ */ /* $NetBSD: kvm86.c,v 1.10 2005/12/26 19:23:59 perry Exp $ */ /* * Copyright (c) 2002 @@ -48,9 +48,6 @@ extern void kvm86_ret(struct trapframe *, int); #define PGTABLE_SIZE ((1024 + 64) * 1024 / PAGE_SIZE) -/* XXX: not here */ -typedef u_int32_t pt_entry_t; - struct kvm86_data { pt_entry_t pgtbl[PGTABLE_SIZE]; diff --git a/sys/arch/i386/i386/lapic.c b/sys/arch/i386/i386/lapic.c index 7ca7fc9ef0a..bd74f8d5f10 100644 --- a/sys/arch/i386/i386/lapic.c +++ b/sys/arch/i386/i386/lapic.c @@ -1,4 +1,4 @@ -/* $OpenBSD: lapic.c,v 1.12 2007/02/19 11:59:00 tom Exp $ */ +/* $OpenBSD: lapic.c,v 1.13 2007/02/20 21:15:01 tom Exp $ */ /* $NetBSD: lapic.c,v 1.1.2.8 2000/02/23 06:10:50 sommerfeld Exp $ */ /*- @@ -78,8 +78,9 @@ void lapic_map(lapic_base) paddr_t lapic_base; { - vaddr_t va = (vaddr_t)&local_apic; int s; + pt_entry_t *pte; + vaddr_t va = (vaddr_t)&local_apic; disable_intr(); s = lapic_tpr; @@ -93,7 +94,8 @@ lapic_map(lapic_base) * might have changed the value of cpu_number().. */ - pmap_pte_set(va, lapic_base, PG_RW | PG_V | PG_N); + pte = kvtopte(va); + *pte = lapic_base | PG_RW | PG_V | PG_N; invlpg(va); #ifdef MULTIPROCESSOR diff --git a/sys/arch/i386/i386/locore.s b/sys/arch/i386/i386/locore.s index 020ae8e0b45..fd5d7bc1ddc 100644 --- a/sys/arch/i386/i386/locore.s +++ b/sys/arch/i386/i386/locore.s @@ -1,4 +1,4 @@ -/* $OpenBSD: locore.s,v 1.105 2006/12/08 21:35:05 dim Exp $ */ +/* $OpenBSD: locore.s,v 1.106 2007/02/20 21:15:01 tom Exp $ */ /* $NetBSD: locore.s,v 1.145 1996/05/03 19:41:19 christos Exp $ */ /*- @@ -201,7 +201,6 @@ .globl _C_LABEL(cpu_cache_ecx), _C_LABEL(cpu_cache_edx) .globl _C_LABEL(cold), _C_LABEL(cnvmem), _C_LABEL(extmem) .globl _C_LABEL(esym) - .globl _C_LABEL(nkptp_max) .globl _C_LABEL(boothowto), _C_LABEL(bootdev), _C_LABEL(atdevbase) .globl _C_LABEL(proc0paddr), _C_LABEL(PTDpaddr), _C_LABEL(PTDsize) .globl _C_LABEL(gdt) @@ -535,9 +534,9 @@ try586: /* Use the `cpuid' instruction. */ * 0 1 2 3 */ #define PROC0PDIR ((0) * NBPG) -#define PROC0STACK ((4) * NBPG) -#define SYSMAP ((4+UPAGES) * NBPG) -#define TABLESIZE ((4+UPAGES) * NBPG) /* + _C_LABEL(nkpde) * NBPG */ +#define PROC0STACK ((1) * NBPG) +#define SYSMAP ((1+UPAGES) * NBPG) +#define TABLESIZE ((1+UPAGES) * NBPG) /* + _C_LABEL(nkpde) * NBPG */ /* Find end of kernel image. */ movl $RELOC(_C_LABEL(end)),%edi @@ -565,9 +564,9 @@ try586: /* Use the `cpuid' instruction. */ jge 1f movl $NKPTP_MIN,%ecx # set at min jmp 2f -1: cmpl RELOC(_C_LABEL(nkptp_max)),%ecx # larger than max? +1: cmpl $NKPTP_MAX,%ecx # larger than max? jle 2f - movl RELOC(_C_LABEL(nkptp_max)),%ecx + movl $NKPTP_MAX,%ecx 2: movl %ecx,RELOC(_C_LABEL(nkpde)) # and store it back /* Clear memory for bootstrap tables. */ @@ -652,8 +651,6 @@ try586: /* Use the `cpuid' instruction. */ /* Install a PDE recursively mapping page directory as a page table! */ leal (PROC0PDIR+PG_V|PG_KW)(%esi),%eax # pte for ptd movl %eax,(PROC0PDIR+PDSLOT_PTE*4)(%esi) # recursive PD slot - addl $NBPG, %eax # pte for ptd[1] - movl %eax,(PROC0PDIR+(PDSLOT_PTE+1)*4)(%esi) # recursive PD slot /* Save phys. addr of PTD, for libkvm. */ movl %esi,RELOC(_C_LABEL(PTDpaddr)) @@ -2305,42 +2302,6 @@ ENTRY(i686_pagezero) ret #endif -#ifndef SMALL_KERNEL -/* - * int cpu_paenable(void *); - */ -ENTRY(cpu_paenable) - movl $-1, %eax - testl $CPUID_PAE, _C_LABEL(cpu_feature) - jz 1f - - pushl %esi - pushl %edi - movl 12(%esp), %esi - movl %cr3, %edi - orl $0xfe0, %edi /* PDPT will be in the last four slots! */ - movl %edi, %cr3 - addl $KERNBASE, %edi /* and make it back virtual again */ - movl $8, %ecx - cld - rep - movsl - movl %cr4, %eax - orl $CR4_PAE, %eax - movl %eax, %cr4 /* BANG!!! */ - movl 12(%esp), %eax - subl $KERNBASE, %eax - movl %eax, %cr3 /* reload real PDPT */ - movl $4*NBPG, %eax - movl %eax, _C_LABEL(PTDsize) - - xorl %eax, %eax - popl %edi - popl %esi -1: - ret -#endif /* !SMALL_KERNEL */ - #if NLAPIC > 0 #include <i386/i386/apicvec.s> #endif diff --git a/sys/arch/i386/i386/machdep.c b/sys/arch/i386/i386/machdep.c index 60f984e5f38..74af9afb577 100644 --- a/sys/arch/i386/i386/machdep.c +++ b/sys/arch/i386/i386/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.377 2007/02/17 23:59:03 marco Exp $ */ +/* $OpenBSD: machdep.c,v 1.378 2007/02/20 21:15:01 tom Exp $ */ /* $NetBSD: machdep.c,v 1.214 1996/11/10 03:16:17 thorpej Exp $ */ /*- @@ -218,9 +218,6 @@ int bufcachepercent = BUFCACHEPERCENT; extern int boothowto; int physmem; -#ifndef SMALL_KERNEL -int pae_copy; -#endif struct dumpmem { paddr_t start; @@ -246,7 +243,7 @@ int i386_has_sse2; int i386_has_xcrypt; bootarg_t *bootargp; -paddr_t avail_end, avail_end2; +paddr_t avail_end; struct vm_map *exec_map = NULL; struct vm_map *phys_map = NULL; @@ -328,12 +325,6 @@ int allowaperture = 0; #endif #endif -#ifdef I686_PAE -int cpu_pae = 1; -#else -int cpu_pae = 0; -#endif - void winchip_cpu_setup(struct cpu_info *); void amd_family5_setperf_setup(struct cpu_info *); void amd_family5_setup(struct cpu_info *); @@ -2849,6 +2840,7 @@ fix_f00f(void) struct region_descriptor region; vaddr_t va; void *p; + pt_entry_t *pte; /* Allocate two new pages */ va = uvm_km_zalloc(kernel_map, NBPG*2); @@ -2863,7 +2855,8 @@ fix_f00f(void) GCODE_SEL); /* Map first page RO */ - pmap_pte_setbits(va, 0, PG_RW); + pte = PTE_BASE + atop(va); + *pte &= ~PG_RW; /* Reload idtr */ setregion(®ion, idt, sizeof(idt_region) - 1); @@ -3018,11 +3011,11 @@ init386(paddr_t first_avail) if (bootargc > NBPG) panic("too many boot args"); - if (extent_alloc_region(iomem_ex, (u_long)bootargv, bootargc, + if (extent_alloc_region(iomem_ex, (paddr_t)bootargv, bootargc, EX_NOWAIT)) panic("cannot reserve /boot args memory"); - pmap_enter(pmap_kernel(), (vaddr_t)bootargp, (u_long)bootargv, + pmap_enter(pmap_kernel(), (vaddr_t)bootargp, (paddr_t)bootargv, VM_PROT_READ|VM_PROT_WRITE, VM_PROT_READ|VM_PROT_WRITE|PMAP_WIRED); @@ -3035,6 +3028,15 @@ init386(paddr_t first_avail) if (bios_memmap == NULL) panic("no BIOS memory map supplied"); #endif + +#if defined(MULTIPROCESSOR) + /* install the page after boot args as PT page for first 4M */ + pmap_enter(pmap_kernel(), (u_long)vtopte(0), + round_page((vaddr_t)(bootargv + bootargc)), + VM_PROT_READ|VM_PROT_WRITE, + VM_PROT_READ|VM_PROT_WRITE|PMAP_WIRED); + memset(vtopte(0), 0, NBPG); /* make sure it is clean before using */ +#endif /* * account all the memory passed in the map from /boot @@ -3048,12 +3050,27 @@ init386(paddr_t first_avail) for(i = 0, im = bios_memmap; im->type != BIOS_MAP_END; im++) if (im->type == BIOS_MAP_FREE) { paddr_t a, e; +#ifdef DEBUG + printf(" %llx-%llx", im->addr, im->addr + im->size); +#endif + + if (im->addr >= 0x100000000ULL) { +#ifdef DEBUG + printf("-H"); +#endif + continue; + } a = round_page(im->addr); - e = trunc_page(im->addr + im->size); + if (im->addr + im->size <= 0xfffff000ULL) + e = trunc_page(im->addr + im->size); + else { #ifdef DEBUG - printf(" %llx-%llx", a, e); + printf("-T"); #endif + e = 0xfffff000; + } + /* skip first eight pages */ if (a < 8 * NBPG) a = 8 * NBPG; @@ -3073,16 +3090,7 @@ init386(paddr_t first_avail) continue; } - if (a >= 0x100000000ULL) { -#ifdef DEBUG - printf("-H"); -#endif - if (!cpu_pae) - continue; - } - - if (e <= 0x100000000ULL && - extent_alloc_region(iomem_ex, a, e - a, EX_NOWAIT)) + if (extent_alloc_region(iomem_ex, a, e - a, EX_NOWAIT)) /* XXX What should we do? */ printf("\nWARNING: CAN'T ALLOCATE RAM (%x-%x)" " FROM IOMEM EXTENT MAP!\n", a, e); @@ -3091,15 +3099,11 @@ init386(paddr_t first_avail) dumpmem[i].start = atop(a); dumpmem[i].end = atop(e); i++; - avail_end2 = MAX(avail_end2, e); - if (avail_end2 < 0x100000000ULL) - avail_end = avail_end2; + avail_end = max(avail_end, e); } ndumpmem = i; avail_end -= round_page(MSGBUFSIZE); - if (avail_end2 < 0x100000000ULL) - avail_end2 = avail_end; #ifdef DEBUG printf(": %lx\n", avail_end); @@ -3130,34 +3134,30 @@ init386(paddr_t first_avail) e = dumpmem[i].end; if (a < atop(first_avail) && e > atop(first_avail)) a = atop(first_avail); - if (a < atop(avail_end) && e > atop(avail_end)) + if (e > atop(avail_end)) e = atop(avail_end); if (a < e) { if (a < atop(16 * 1024 * 1024)) { lim = MIN(atop(16 * 1024 * 1024), e); #ifdef DEBUG - printf(" %llx-%llx (<16M)", a, lim); +- printf(" %x-%x (<16M)", a, lim); #endif uvm_page_physload(a, lim, a, lim, VM_FREELIST_FIRST16); if (e > lim) { #ifdef DEBUG - printf(" %llx-%llx", lim, e); +- printf(" %x-%x", lim, e); #endif uvm_page_physload(lim, e, lim, e, VM_FREELIST_DEFAULT); } } else { #ifdef DEBUG - printf(" %llx-%llx", a, e); +- printf(" %x-%x", a, e); #endif - if (a >= atop(0x100000000ULL)) - uvm_page_physload(a, e, a, a - 1, - VM_FREELIST_ABOVE4G); - else - uvm_page_physload(a, e, a, e, - VM_FREELIST_DEFAULT); + uvm_page_physload(a, e, a, e, + VM_FREELIST_DEFAULT); } } } @@ -3566,8 +3566,8 @@ bus_mem_add_mapping(bus_addr_t bpa, bus_size_t size, int cacheable, bus_space_handle_t *bshp) { u_long pa, endpa; - u_int32_t bits; vaddr_t va; + pt_entry_t *pte; bus_size_t map_size; #ifdef MULTIPROCESSOR u_int32_t cpumask = 0; @@ -3599,12 +3599,13 @@ bus_mem_add_mapping(bus_addr_t bpa, bus_size_t size, int cacheable, * on those machines. */ if (cpu_class != CPUCLASS_386) { + pte = kvtopte(va); if (cacheable) - bits = pmap_pte_setbits(va, 0, PG_N); + *pte &= ~PG_N; else - bits = pmap_pte_setbits(va, PG_N, 0); + *pte |= PG_N; #ifdef MULTIPROCESSOR - pmap_tlb_shootdown(pmap_kernel(), va, bits, + pmap_tlb_shootdown(pmap_kernel(), va, *pte, &cpumask); #else pmap_update_pg(va); @@ -3624,7 +3625,7 @@ bus_space_unmap(bus_space_tag_t t, bus_space_handle_t bsh, bus_size_t size) { struct extent *ex; u_long va, endva; - paddr_t bpa; + bus_addr_t bpa; /* * Find the correct extent and bus physical address. @@ -3634,7 +3635,7 @@ bus_space_unmap(bus_space_tag_t t, bus_space_handle_t bsh, bus_size_t size) bpa = bsh; } else if (t == I386_BUS_SPACE_MEM) { ex = iomem_ex; - bpa = (u_long)ISA_PHYSADDR(bsh); + bpa = (bus_addr_t)ISA_PHYSADDR(bsh); if (IOM_BEGIN <= bpa && bpa <= IOM_END) goto ok; @@ -3670,7 +3671,7 @@ _bus_space_unmap(bus_space_tag_t t, bus_space_handle_t bsh, bus_size_t size, bus_addr_t *adrp) { u_long va, endva; - paddr_t bpa; + bus_addr_t bpa; /* * Find the correct bus physical address. @@ -3678,7 +3679,7 @@ _bus_space_unmap(bus_space_tag_t t, bus_space_handle_t bsh, bus_size_t size, if (t == I386_BUS_SPACE_IO) { bpa = bsh; } else if (t == I386_BUS_SPACE_MEM) { - bpa = (u_long)ISA_PHYSADDR(bsh); + bpa = (bus_addr_t)ISA_PHYSADDR(bsh); if (IOM_BEGIN <= bpa && bpa <= IOM_END) goto ok; @@ -3732,7 +3733,6 @@ _bus_dmamap_create(bus_dma_tag_t t, bus_size_t size, int nsegments, struct i386_bus_dmamap *map; void *mapstore; size_t mapsize; - int npages; /* * Allocate and initialize the DMA map. The end of the map @@ -3748,17 +3748,6 @@ _bus_dmamap_create(bus_dma_tag_t t, bus_size_t size, int nsegments, */ mapsize = sizeof(struct i386_bus_dmamap) + (sizeof(bus_dma_segment_t) * (nsegments - 1)); - npages = 0; -#ifndef SMALL_KERNEL - if (avail_end2 > avail_end && - (flags & (BUS_DMA_64BIT|BUS_DMA_24BIT)) == 0) { - /* this many pages plus one in case we get split */ - npages = round_page(size) / PAGE_SIZE + 1; - if (npages < nsegments) /* looks stupid, but possible */ - npages = nsegments; - mapsize += sizeof(struct vm_page *) * npages; - } -#endif /* !SMALL_KERNEL */ if ((mapstore = malloc(mapsize, M_DEVBUF, (flags & BUS_DMA_NOWAIT) ? M_NOWAIT : M_WAITOK)) == NULL) return (ENOMEM); @@ -3769,55 +3758,10 @@ _bus_dmamap_create(bus_dma_tag_t t, bus_size_t size, int nsegments, map->_dm_segcnt = nsegments; map->_dm_maxsegsz = maxsegsz; map->_dm_boundary = boundary; - map->_dm_pages = npages? (void *)&map->dm_segs[nsegments] : NULL; - map->_dm_npages = npages; map->_dm_flags = flags & ~(BUS_DMA_WAITOK|BUS_DMA_NOWAIT); map->dm_mapsize = 0; /* no valid mappings */ map->dm_nsegs = 0; -#ifndef SMALL_KERNEL - if (npages) { - struct pglist mlist; - vaddr_t va; - int error; - - size = npages << PGSHIFT; - va = uvm_km_valloc(kernel_map, size); - if (va == 0) { - map->_dm_npages = 0; - free(map, M_DEVBUF); - return (ENOMEM); - } - - TAILQ_INIT(&mlist); - /* if not a 64bit map -- allocate some bouncy-bouncy */ - error = uvm_pglistalloc(size, - round_page(ISA_DMA_BOUNCE_THRESHOLD), 0xfffff000, - PAGE_SIZE, boundary, &mlist, nsegments, - (flags & BUS_DMA_NOWAIT) == 0); - if (error) { - map->_dm_npages = 0; - uvm_km_free(kernel_map, (vaddr_t)va, size); - free(map, M_DEVBUF); - return (ENOMEM); - } else { - struct vm_page **pg = map->_dm_pages; - - npages--; - *pg = TAILQ_FIRST(&mlist); - pmap_kenter_pa(va, VM_PAGE_TO_PHYS(*pg), - VM_PROT_READ | VM_PROT_WRITE | PMAP_WIRED); - for (pg++, va += PAGE_SIZE; npages--; - pg++, va += PAGE_SIZE) { - *pg = TAILQ_NEXT(pg[-1], pageq); - pmap_kenter_pa(va, VM_PAGE_TO_PHYS(*pg), - VM_PROT_READ | VM_PROT_WRITE | PMAP_WIRED); - } - } - map->_dm_pgva = va; - } -#endif /* !SMALL_KERNEL */ - *dmamp = map; return (0); } @@ -3841,7 +3785,7 @@ int _bus_dmamap_load(bus_dma_tag_t t, bus_dmamap_t map, void *buf, bus_size_t buflen, struct proc *p, int flags) { - paddr_t lastaddr; + bus_addr_t lastaddr; int seg, error; /* @@ -4009,7 +3953,6 @@ _bus_dmamap_unload(bus_dma_tag_t t, bus_dmamap_t map) */ map->dm_mapsize = 0; map->dm_nsegs = 0; - map->_dm_nused = 0; } /* @@ -4017,43 +3960,10 @@ _bus_dmamap_unload(bus_dma_tag_t t, bus_dmamap_t map) * by bus-specific DMA map synchronization functions. */ void -_bus_dmamap_sync(bus_dma_tag_t t, bus_dmamap_t map, bus_addr_t offset, +_bus_dmamap_sync(bus_dma_tag_t t, bus_dmamap_t map, bus_addr_t addr, bus_size_t size, int op) { -#ifndef SMALL_KERNEL - bus_dma_segment_t *sg; - int i, off = offset; - bus_size_t l; - - /* scan the segment list performing necessary copies */ - if (!(map->_dm_flags & BUS_DMA_64BIT) && map->_dm_nused) { - for (i = map->_dm_segcnt, sg = map->dm_segs; - size && i--; sg++) { - if (off >= sg->ds_len) { - off -= sg->ds_len; - continue; - } - - l = sg->ds_len - off; - if (l > size) - l = size; - size -= l; - if (sg->ds_addr2) { - if (op & BUS_DMASYNC_POSTREAD) { - bcopy((void *)(sg->ds_va2 + off), - (void *)(sg->ds_va + off), l); - pae_copy++; - } - if (op & BUS_DMASYNC_PREWRITE) { - bcopy((void *)(sg->ds_va + off), - (void *)(sg->ds_va2 + off), l); - pae_copy++; - } - } - off = 0; - } - } -#endif /* !SMALL_KERNEL */ + /* Nothing to do here. */ } /* @@ -4197,8 +4107,8 @@ _bus_dmamap_load_buffer(bus_dma_tag_t t, bus_dmamap_t map, void *buf, int first) { bus_size_t sgsize; - paddr_t curaddr, lastaddr, oaddr, baddr, bmask; - vaddr_t pgva, vaddr = (vaddr_t)buf; + bus_addr_t curaddr, lastaddr, baddr, bmask; + vaddr_t vaddr = (vaddr_t)buf; int seg; pmap_t pmap; @@ -4214,24 +4124,7 @@ _bus_dmamap_load_buffer(bus_dma_tag_t t, bus_dmamap_t map, void *buf, /* * Get the physical address for this segment. */ - pmap_extract(pmap, vaddr, &curaddr); - oaddr = 0; - pgva = 0; -#ifndef SMALL_KERNEL - if (!(map->_dm_flags & BUS_DMA_64BIT) && - curaddr >= 0x100000000ULL) { - struct vm_page *pg; - int page, off; - - if (map->_dm_nused + 1 >= map->_dm_npages) - return (ENOMEM); - off = vaddr & PAGE_MASK; - pg = map->_dm_pages[page = map->_dm_nused++]; - oaddr = curaddr; - curaddr = VM_PAGE_TO_PHYS(pg) + off; - pgva = map->_dm_pgva + (page << PGSHIFT) + off; - } -#endif /* !SMALL_KERNEL */ + pmap_extract(pmap, vaddr, (paddr_t *)&curaddr); /* * Compute the segment size, and adjust counts. @@ -4255,10 +4148,7 @@ _bus_dmamap_load_buffer(bus_dma_tag_t t, bus_dmamap_t map, void *buf, */ if (first) { map->dm_segs[seg].ds_addr = curaddr; - map->dm_segs[seg].ds_addr2 = oaddr; map->dm_segs[seg].ds_len = sgsize; - map->dm_segs[seg].ds_va = vaddr; - map->dm_segs[seg].ds_va2 = pgva; first = 0; } else { if (curaddr == lastaddr && @@ -4272,10 +4162,7 @@ _bus_dmamap_load_buffer(bus_dma_tag_t t, bus_dmamap_t map, void *buf, if (++seg >= map->_dm_segcnt) break; map->dm_segs[seg].ds_addr = curaddr; - map->dm_segs[seg].ds_addr2 = oaddr; map->dm_segs[seg].ds_len = sgsize; - map->dm_segs[seg].ds_va = vaddr; - map->dm_segs[seg].ds_va2 = pgva; } } @@ -4311,19 +4198,6 @@ _bus_dmamem_alloc_range(bus_dma_tag_t t, bus_size_t size, bus_size_t alignment, /* Always round the size. */ size = round_page(size); - if (flags & BUS_DMA_64BIT) { - if (high > 0x100000000ULL && low < 0x100000000ULL) - low = 0x100000000ULL; - } else if (high > 0x100000000ULL) { - if (low >= 0x100000000ULL) { -#ifdef DIAGNOSTIC - printf("_bus_dmamem_alloc_range: " - "32bit request in above 4GB space\n"); -#endif - return (EINVAL); - } else - high = 0x100000000ULL; - } TAILQ_INIT(&mlist); /* diff --git a/sys/arch/i386/i386/mpbios.c b/sys/arch/i386/i386/mpbios.c index 415e5c0145c..5157a990767 100644 --- a/sys/arch/i386/i386/mpbios.c +++ b/sys/arch/i386/i386/mpbios.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mpbios.c,v 1.20 2007/01/23 21:17:18 kettenis Exp $ */ +/* $OpenBSD: mpbios.c,v 1.21 2007/02/20 21:15:01 tom Exp $ */ /* $NetBSD: mpbios.c,v 1.2 2002/10/01 12:56:57 fvdl Exp $ */ /*- @@ -1024,7 +1024,7 @@ mpbios_ioapic(const u_int8_t *ent, struct device *self) aaa.aaa_name = "ioapic"; aaa.apic_id = entry->apic_id; aaa.apic_version = entry->apic_version; - aaa.apic_address = (u_long)entry->apic_address; + aaa.apic_address = (paddr_t)entry->apic_address; aaa.apic_vecbase = -1; aaa.flags = (mp_fps->mpfb2 & 0x80) ? IOAPIC_PICMODE : IOAPIC_VWIRE; diff --git a/sys/arch/i386/i386/mptramp.s b/sys/arch/i386/i386/mptramp.s index 7ec527bd359..b68ec50ed12 100644 --- a/sys/arch/i386/i386/mptramp.s +++ b/sys/arch/i386/i386/mptramp.s @@ -1,4 +1,4 @@ -/* $OpenBSD: mptramp.s,v 1.7 2006/10/16 15:51:26 tom Exp $ */ +/* $OpenBSD: mptramp.s,v 1.8 2007/02/20 21:15:01 tom Exp $ */ /*- * Copyright (c) 2000 The NetBSD Foundation, Inc. @@ -165,20 +165,10 @@ _TRMP_LABEL(mp_startup) /* Load base of page directory and enable mapping. */ movl %ecx,%cr3 # load ptd addr into mmu -#ifndef SMALL_KERNEL - movl $_C_LABEL(pmap_pte_set_pae),%eax - cmpl RELOC(_C_LABEL(pmap_pte_set_p)),%eax - jne nopae - - movl %cr4,%eax - orl $CR4_PAE,%eax - movl %eax, %cr4 -nopae: -#endif - movl %cr0,%eax # get control word - # enable paging & NPX emulation - orl $(CR0_PE|CR0_PG|CR0_NE|CR0_TS|CR0_EM|CR0_MP|CR0_WP),%eax - movl %eax,%cr0 # and let's page NOW! + movl %cr0,%eax # get control word + # enable paging & NPX emulation + orl $(CR0_PE|CR0_PG|CR0_NE|CR0_TS|CR0_EM|CR0_MP|CR0_WP),%eax + movl %eax,%cr0 # and let's page NOW! #ifdef MPDEBUG leal _C_LABEL(cpu_trace),%edi diff --git a/sys/arch/i386/i386/pmap.c b/sys/arch/i386/i386/pmap.c index 0871e629546..6b30caaa9e3 100644 --- a/sys/arch/i386/i386/pmap.c +++ b/sys/arch/i386/i386/pmap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pmap.c,v 1.96 2007/02/03 16:48:23 miod Exp $ */ +/* $OpenBSD: pmap.c,v 1.97 2007/02/20 21:15:01 tom Exp $ */ /* $NetBSD: pmap.c,v 1.91 2000/06/02 17:46:37 thorpej Exp $ */ /* @@ -81,6 +81,15 @@ #include <stand/boot/bootarg.h> /* + * general info: + * + * - for an explanation of how the i386 MMU hardware works see + * the comments in <machine/pte.h>. + * + * - for an explanation of the general memory structure used by + * this pmap (including the recursive mapping), see the comments + * in <machine/pmap.h>. + * * this file contains the code for the "pmap module." the module's * job is to manage the hardware's virtual to physical address mappings. * note that there are two levels of mapping in the VM system: @@ -118,181 +127,6 @@ * its pv_entrys. */ /* - * i386 MMU hardware structure: - * - * the i386 MMU is a two-level MMU which maps 4GB of virtual memory. - * the pagesize is 4K (4096 [0x1000] bytes), although newer pentium - * processors can support a 4MB pagesize as well. - * - * the first level table (segment table?) is called a "page directory" - * and it contains 1024 page directory entries (PDEs). each PDE is - * 4 bytes (an int), so a PD fits in a single 4K page. this page is - * the page directory page (PDP). each PDE in a PDP maps 4MB of space - * (1024 * 4MB = 4GB). a PDE contains the physical address of the - * second level table: the page table. or, if 4MB pages are being used, - * then the PDE contains the PA of the 4MB page being mapped. - * - * a page table consists of 1024 page table entries (PTEs). each PTE is - * 4 bytes (an int), so a page table also fits in a single 4K page. a - * 4K page being used as a page table is called a page table page (PTP). - * each PTE in a PTP maps one 4K page (1024 * 4K = 4MB). a PTE contains - * the physical address of the page it maps and some flag bits (described - * below). - * - * the processor has a special register, "cr3", which points to the - * the PDP which is currently controlling the mappings of the virtual - * address space. - * - * the following picture shows the translation process for a 4K page: - * - * %cr3 register [PA of PDP] - * | - * | - * | bits <31-22> of VA bits <21-12> of VA bits <11-0> - * | index the PDP (0 - 1023) index the PTP are the page offset - * | | | | - * | v | | - * +--->+----------+ | | - * | PD Page | PA of v | - * | |---PTP-------->+------------+ | - * | 1024 PDE | | page table |--PTE--+ | - * | entries | | (aka PTP) | | | - * +----------+ | 1024 PTE | | | - * | entries | | | - * +------------+ | | - * | | - * bits <31-12> bits <11-0> - * p h y s i c a l a d d r - * - * the i386 caches PTEs in a TLB. it is important to flush out old - * TLB mappings when making a change to a mappings. writing to the - * %cr3 will flush the entire TLB. newer processors also have an - * instruction that will invalidate the mapping of a single page (which - * is useful if you are changing a single mappings because it preserves - * all the cached TLB entries). - * - * as shows, bits 31-12 of the PTE contain PA of the page being mapped. - * the rest of the PTE is defined as follows: - * bit# name use - * 11 n/a available for OS use, hardware ignores it - * 10 n/a available for OS use, hardware ignores it - * 9 n/a available for OS use, hardware ignores it - * 8 G global bit (see discussion below) - * 7 PS page size [for PDEs] (0=4k, 1=4M <if supported>) - * 6 D dirty (modified) page - * 5 A accessed (referenced) page - * 4 PCD cache disable - * 3 PWT prevent write through (cache) - * 2 U/S user/supervisor bit (0=supervisor only, 1=both u&s) - * 1 R/W read/write bit (0=read only, 1=read-write) - * 0 P present (valid) - * - * notes: - * - on the i386 the R/W bit is ignored if processor is in supervisor - * state (bug!) - * - PS is only supported on newer processors - * - PTEs with the G bit are global in the sense that they are not - * flushed from the TLB when %cr3 is written (to flush, use the - * "flush single page" instruction). this is only supported on - * newer processors. this bit can be used to keep the kernel's - * TLB entries around while context switching. since the kernel - * is mapped into all processes at the same place it does not make - * sense to flush these entries when switching from one process' - * pmap to another. - */ -/* - * A pmap describes a process' 4GB virtual address space. This - * virtual address space can be broken up into 1024 4MB regions which - * are described by PDEs in the PDP. The PDEs are defined as follows: - * - * Ranges are inclusive -> exclusive, just like vm_map_entry start/end. - * The following assumes that KERNBASE is 0xd0000000. - * - * PDE#s VA range Usage - * 0->831 0x0 -> 0xcfc00000 user address space, note that the - * max user address is 0xcfbfe000 - * the final two pages in the last 4MB - * used to be reserved for the UAREA - * but now are no longer used. - * 831 0xcfc00000-> recursive mapping of PDP (used for - * 0xd0000000 linear mapping of PTPs). - * 832->1023 0xd0000000-> kernel address space (constant - * 0xffc00000 across all pmaps/processes). - * 1023 0xffc00000-> "alternate" recursive PDP mapping - * <end> (for other pmaps). - * - * - * Note: A recursive PDP mapping provides a way to map all the PTEs for - * a 4GB address space into a linear chunk of virtual memory. In other - * words, the PTE for page 0 is the first int mapped into the 4MB recursive - * area. The PTE for page 1 is the second int. The very last int in the - * 4MB range is the PTE that maps VA 0xffffe000 (the last page in a 4GB - * address). - * - * All pmaps' PDs must have the same values in slots 832->1023 so that - * the kernel is always mapped in every process. These values are loaded - * into the PD at pmap creation time. - * - * At any one time only one pmap can be active on a processor. This is - * the pmap whose PDP is pointed to by processor register %cr3. This pmap - * will have all its PTEs mapped into memory at the recursive mapping - * point (slot #831 as show above). When the pmap code wants to find the - * PTE for a virtual address, all it has to do is the following: - * - * Address of PTE = (831 * 4MB) + (VA / NBPG) * sizeof(pt_entry_t) - * = 0xcfc00000 + (VA / 4096) * 4 - * - * What happens if the pmap layer is asked to perform an operation - * on a pmap that is not the one which is currently active? In that - * case we take the PA of the PDP of non-active pmap and put it in - * slot 1023 of the active pmap. This causes the non-active pmap's - * PTEs to get mapped in the final 4MB of the 4GB address space - * (e.g. starting at 0xffc00000). - * - * The following figure shows the effects of the recursive PDP mapping: - * - * PDP (%cr3) - * +----+ - * | 0| -> PTP#0 that maps VA 0x0 -> 0x400000 - * | | - * | | - * | 831| -> points back to PDP (%cr3) mapping VA 0xcfc00000 -> 0xd0000000 - * | 832| -> first kernel PTP (maps 0xd0000000 -> 0xe0400000) - * | | - * |1023| -> points to alternate pmap's PDP (maps 0xffc00000 -> end) - * +----+ - * - * Note that the PDE#831 VA (0xcfc00000) is defined as "PTE_BASE". - * Note that the PDE#1023 VA (0xffc00000) is defined as "APTE_BASE". - * - * Starting at VA 0xcfc00000 the current active PDP (%cr3) acts as a - * PTP: - * - * PTP#831 == PDP(%cr3) => maps VA 0xcfc00000 -> 0xd0000000 - * +----+ - * | 0| -> maps the contents of PTP#0 at VA 0xcfc00000->0xcfc01000 - * | | - * | | - * | 831| -> maps the contents of PTP#831 (the PDP) at VA 0xcff3f000 - * | 832| -> maps the contents of first kernel PTP - * | | - * |1023| - * +----+ - * - * Note that mapping of the PDP at PTP#831's VA (0xcff3f000) is - * defined as "PDP_BASE".... within that mapping there are two - * defines: - * "PDP_PDE" (0xcff3fcfc) is the VA of the PDE in the PDP - * which points back to itself. - * "APDP_PDE" (0xcff3fffc) is the VA of the PDE in the PDP which - * establishes the recursive mapping of the alternate pmap. - * To set the alternate PDP, one just has to put the correct - * PA info in *APDP_PDE. - * - * Note that in the APTE_BASE space, the APDP appears at VA - * "APDP_BASE" (0xfffff000). - */ -/* * memory allocation * * - there are three data structures that we must dynamically allocate: @@ -384,79 +218,6 @@ struct simplelock pmaps_lock; #define PMAP_HEAD_TO_MAP_LOCK() /* null */ #define PMAP_HEAD_TO_MAP_UNLOCK() /* null */ -#define PG_FRAME 0xfffff000 /* page frame mask */ -#define PG_LGFRAME 0xffc00000 /* large (4M) page frame mask */ - -/* - * The following defines give the virtual addresses of various MMU - * data structures: - * PTE_BASE and APTE_BASE: the base VA of the linear PTE mappings - * PTD_BASE and APTD_BASE: the base VA of the recursive mapping of the PTD - * PDP_PDE and APDP_PDE: the VA of the PDE that points back to the PDP/APDP - */ -#define PTE_BASE ((pt_entry_t *) (PDSLOT_PTE * NBPD) ) -#define APTE_BASE ((pt_entry_t *) (PDSLOT_APTE * NBPD) ) -#define PDP_BASE ((pd_entry_t *)(((char *)PTE_BASE) + (PDSLOT_PTE * NBPG))) -#define APDP_BASE ((pd_entry_t *)(((char *)APTE_BASE) + (PDSLOT_APTE * NBPG))) -#define PDP_PDE (PDP_BASE + PDSLOT_PTE) -#define APDP_PDE (PDP_BASE + PDSLOT_APTE) - -#define PDOFSET (NBPD-1) /* mask for non-PD part of VA */ -#define PTES_PER_PTP (NBPD / NBPG) /* # of PTEs in a PTP */ - -/* - * various address macros - * - * vtopte: return a pointer to the PTE mapping a VA - * - */ -#define vtopte(VA) (PTE_BASE + atop((vaddr_t)VA)) - -/* - * Mach derived conversion macros - */ -#define i386_round_pdr(x) ((((unsigned)(x)) + PDOFSET) & ~PDOFSET) - -/* - * pdei/ptei: generate index into PDP/PTP from a VA - */ -#define PD_MASK 0xffc00000 /* page directory address bits */ -#define PT_MASK 0x003ff000 /* page table address bits */ -#define pdei(VA) (((VA) & PD_MASK) >> PDSHIFT) -#define ptei(VA) (((VA) & PT_MASK) >> PGSHIFT) - -/* - * PTP macros: - * A PTP's index is the PD index of the PDE that points to it. - * A PTP's offset is the byte-offset in the PTE space that this PTP is at. - * A PTP's VA is the first VA mapped by that PTP. - * - * Note that NBPG == number of bytes in a PTP (4096 bytes == 1024 entries) - * NBPD == number of bytes a PTP can map (4MB) - */ - -#define ptp_i2o(I) ((I) * NBPG) /* index => offset */ -#define ptp_o2i(O) ((O) / NBPG) /* offset => index */ -#define ptp_i2v(I) ((I) * NBPD) /* index => VA */ -#define ptp_v2i(V) ((V) / NBPD) /* VA => index (same as pdei) */ - -/* - * Access PD and PT - */ -#define PDE(pm,i) (((pd_entry_t *)(pm)->pm_pdir)[(i)]) - -/* - * here we define the data types for PDEs and PTEs - */ -typedef u_int32_t pd_entry_t; /* PDE */ -typedef u_int32_t pt_entry_t; /* PTE */ - -/* - * Number of PTE's per cache line. 4 byte pte, 32-byte cache line - * Used to avoid false sharing of cache lines. - */ -#define NPTECL 8 - /* * TLB Shootdown: * @@ -476,13 +237,13 @@ struct pmap_tlb_shootdown_job { TAILQ_ENTRY(pmap_tlb_shootdown_job) pj_list; vaddr_t pj_va; /* virtual address */ pmap_t pj_pmap; /* the pmap which maps the address */ - u_int32_t pj_pte; /* the PTE bits */ + pt_entry_t pj_pte; /* the PTE bits */ struct pmap_tlb_shootdown_job *pj_nextfree; }; struct pmap_tlb_shootdown_q { TAILQ_HEAD(, pmap_tlb_shootdown_job) pq_head; - u_int32_t pq_pte; /* aggregate PTE bits */ + int pq_pte; /* aggregate PTE bits */ int pq_count; /* number of pending requests */ struct mutex pq_mutex; /* mutex on queue */ int pq_flushg; /* pending flush global */ @@ -504,8 +265,7 @@ struct pmap_tlb_shootdown_job *pj_page, *pj_free; * global data structures */ -struct pmap kernel_pmap_store /* the kernel's pmap (proc0) */ - __attribute__((aligned(32))); +struct pmap kernel_pmap_store; /* the kernel's pmap (proc0) */ /* * nkpde is the number of kernel PTPs allocated for the kernel at @@ -515,7 +275,6 @@ struct pmap kernel_pmap_store /* the kernel's pmap (proc0) */ */ int nkpde = NKPTP; -int nkptp_max = 1024 - (KERNBASE/NBPD) - 1; /* largest value (-1 for APTP space) */ #ifdef NKPDE #error "obsolete NKPDE: use NKPTP" #endif @@ -541,8 +300,8 @@ paddr_t hole_end; /* PA of end of "hole" */ * other data structures */ -u_int32_t protection_codes[8]; /* maps MI prot to i386 prot code */ -boolean_t pmap_initialized = FALSE; /* pmap_init done yet? */ +static pt_entry_t protection_codes[8]; /* maps MI prot to i386 prot code */ +static boolean_t pmap_initialized = FALSE; /* pmap_init done yet? */ /* * the following two vaddr_t's are used during system startup @@ -551,10 +310,8 @@ boolean_t pmap_initialized = FALSE; /* pmap_init done yet? */ * VM space is turned over to the kernel_map vm_map. */ -vaddr_t virtual_avail; /* VA of first free KVA */ -vaddr_t virtual_end; /* VA of last free KVA */ - -vaddr_t vm_max_address = (PDSLOT_PTE << PDSHIFT) + (PDSLOT_PTE << PGSHIFT); +static vaddr_t virtual_avail; /* VA of first free KVA */ +static vaddr_t virtual_end; /* VA of last free KVA */ /* * pv_page management structures: locked by pvalloc_lock @@ -575,8 +332,8 @@ static vaddr_t pv_cachedva; /* cached VA for later use */ * linked list of all non-kernel pmaps */ -struct pmap_head pmaps; -struct pmap *pmaps_hand = NULL; /* used by pmap_steal_ptp */ +static struct pmap_head pmaps; +static struct pmap *pmaps_hand = NULL; /* used by pmap_steal_ptp */ /* * pool that pmap structures are allocated from @@ -603,7 +360,7 @@ struct pool pmap_pmap_pool; */ static pt_entry_t *csrc_pte, *cdst_pte, *zero_pte, *ptp_pte; -caddr_t pmap_csrcp, pmap_cdstp, pmap_zerop, pmap_ptpp; +static caddr_t csrcp, cdstp, zerop, ptpp; caddr_t vmmap; /* XXX: used by mem.c... it should really uvm_map_reserve it */ #if defined(I586_CPU) @@ -617,27 +374,46 @@ extern vaddr_t pentium_idt_vaddr; */ struct pv_entry *pmap_add_pvpage(struct pv_page *, boolean_t); +struct vm_page *pmap_alloc_ptp(struct pmap *, int, boolean_t); +struct pv_entry *pmap_alloc_pv(struct pmap *, int); /* see codes below */ #define ALLOCPV_NEED 0 /* need PV now */ #define ALLOCPV_TRY 1 /* just try to allocate, don't steal */ #define ALLOCPV_NONEED 2 /* don't need PV, just growing cache */ struct pv_entry *pmap_alloc_pvpage(struct pmap *, int); -struct vm_page *pmap_alloc_ptp_86(struct pmap *, int, boolean_t); -struct vm_page *pmap_get_ptp_86(struct pmap *, int, boolean_t); -struct vm_page *pmap_steal_ptp_86(struct uvm_object *, vaddr_t); -pt_entry_t *pmap_map_ptes_86(struct pmap *); -void pmap_unmap_ptes_86(struct pmap *); -boolean_t pmap_remove_pte_86(struct pmap *, struct vm_page *, - pt_entry_t *, vaddr_t, int32_t *); -void pmap_remove_ptes_86(struct pmap *, struct vm_page *, vaddr_t, - vaddr_t, vaddr_t, int32_t *); -vaddr_t pmap_tmpmap_pa_86(paddr_t); -pt_entry_t *pmap_tmpmap_pvepte_86(struct pv_entry *); -void pmap_tmpunmap_pa_86(void); -void pmap_tmpunmap_pvepte_86(struct pv_entry *); -boolean_t pmap_try_steal_pv_86(struct pv_head *, - struct pv_entry *, struct pv_entry *); - -void pmap_release(pmap_t); +void pmap_enter_pv(struct pv_head *, + struct pv_entry *, struct pmap *, + vaddr_t, struct vm_page *); +void pmap_free_pv(struct pmap *, struct pv_entry *); +void pmap_free_pvs(struct pmap *, struct pv_entry *); +void pmap_free_pv_doit(struct pv_entry *); +void pmap_free_pvpage(void); +struct vm_page *pmap_get_ptp(struct pmap *, int, boolean_t); +boolean_t pmap_is_curpmap(struct pmap *); +boolean_t pmap_is_active(struct pmap *, int); +pt_entry_t *pmap_map_ptes(struct pmap *); +struct pv_entry *pmap_remove_pv(struct pv_head *, struct pmap *, + vaddr_t); +boolean_t pmap_remove_pte(struct pmap *, struct vm_page *, pt_entry_t *, + vaddr_t, int32_t *); +void pmap_remove_ptes(struct pmap *, struct vm_page *, vaddr_t, + vaddr_t, vaddr_t, int32_t *); +struct vm_page *pmap_steal_ptp(struct uvm_object *, vaddr_t); +vaddr_t pmap_tmpmap_pa(paddr_t); +pt_entry_t *pmap_tmpmap_pvepte(struct pv_entry *); +void pmap_tmpunmap_pa(void); +void pmap_tmpunmap_pvepte(struct pv_entry *); +void pmap_apte_flush(struct pmap *); +boolean_t pmap_try_steal_pv(struct pv_head *, + struct pv_entry *, + struct pv_entry *); +void pmap_unmap_ptes(struct pmap *); +void pmap_exec_account(struct pmap *, vaddr_t, pt_entry_t, + pt_entry_t); + +void pmap_pinit(pmap_t); +void pmap_release(pmap_t); + +void pmap_zero_phys(paddr_t); void setcslimit(struct pmap *, struct trapframe *, struct pcb *, vaddr_t); @@ -677,13 +453,13 @@ pmap_is_active(pmap, cpu_id) */ vaddr_t -pmap_tmpmap_pa_86(paddr_t pa) +pmap_tmpmap_pa(paddr_t pa) { #ifdef MULTIPROCESSOR int id = cpu_number(); #endif pt_entry_t *ptpte = PTESLEW(ptp_pte, id); - caddr_t ptpva = VASLEW(pmap_ptpp, id); + caddr_t ptpva = VASLEW(ptpp, id); #if defined(DIAGNOSTIC) if (*ptpte) panic("pmap_tmpmap_pa: ptp_pte in use?"); @@ -697,13 +473,13 @@ pmap_tmpmap_pa_86(paddr_t pa) */ void -pmap_tmpunmap_pa_86() +pmap_tmpunmap_pa() { #ifdef MULTIPROCESSOR int id = cpu_number(); #endif pt_entry_t *ptpte = PTESLEW(ptp_pte, id); - caddr_t ptpva = VASLEW(pmap_ptpp, id); + caddr_t ptpva = VASLEW(ptpp, id); #if defined(DIAGNOSTIC) if (!pmap_valid_entry(*ptpte)) panic("pmap_tmpunmap_pa: our pte invalid?"); @@ -724,7 +500,7 @@ pmap_tmpunmap_pa_86() */ pt_entry_t * -pmap_tmpmap_pvepte_86(struct pv_entry *pve) +pmap_tmpmap_pvepte(struct pv_entry *pve) { #ifdef DIAGNOSTIC if (pve->pv_pmap == pmap_kernel()) @@ -735,7 +511,7 @@ pmap_tmpmap_pvepte_86(struct pv_entry *pve) if (pmap_is_curpmap(pve->pv_pmap)) return(vtopte(pve->pv_va)); - return(((pt_entry_t *)pmap_tmpmap_pa_86(VM_PAGE_TO_PHYS(pve->pv_ptp))) + return(((pt_entry_t *)pmap_tmpmap_pa(VM_PAGE_TO_PHYS(pve->pv_ptp))) + ptei((unsigned)pve->pv_va)); } @@ -744,13 +520,13 @@ pmap_tmpmap_pvepte_86(struct pv_entry *pve) */ void -pmap_tmpunmap_pvepte_86(struct pv_entry *pve) +pmap_tmpunmap_pvepte(struct pv_entry *pve) { /* was it current pmap? if so, return */ if (pmap_is_curpmap(pve->pv_pmap)) return; - pmap_tmpunmap_pa_86(); + pmap_tmpunmap_pa(); } void @@ -793,7 +569,7 @@ pmap_apte_flush(struct pmap *pmap) */ pt_entry_t * -pmap_map_ptes_86(struct pmap *pmap) +pmap_map_ptes(struct pmap *pmap) { pd_entry_t opde; @@ -832,7 +608,7 @@ pmap_map_ptes_86(struct pmap *pmap) */ void -pmap_unmap_ptes_86(struct pmap *pmap) +pmap_unmap_ptes(struct pmap *pmap) { if (pmap == pmap_kernel()) return; @@ -851,7 +627,7 @@ pmap_unmap_ptes_86(struct pmap *pmap) void pmap_exec_account(struct pmap *pm, vaddr_t va, - u_int32_t opte, u_int32_t npte) + pt_entry_t opte, pt_entry_t npte) { if (curproc == NULL || curproc->p_vmspace == NULL || pm != vm_map_pmap(&curproc->p_vmspace->vm_map)) @@ -925,48 +701,6 @@ pmap_exec_fixup(struct vm_map *map, struct trapframe *tf, struct pcb *pcb) return (1); } -u_int32_t -pmap_pte_set_86(vaddr_t va, paddr_t pa, u_int32_t bits) -{ - pt_entry_t pte, *ptep = vtopte(va); - - pte = i386_atomic_testset_ul(ptep, pa | bits); /* zap! */ - return (pte & ~PG_FRAME); -} - -u_int32_t -pmap_pte_setbits_86(vaddr_t va, u_int32_t set, u_int32_t clr) -{ - pt_entry_t *ptep = vtopte(va); - pt_entry_t pte = *ptep; - - *ptep = (pte | set) & ~clr; - return (pte & ~PG_FRAME); - -} - -u_int32_t -pmap_pte_bits_86(vaddr_t va) -{ - pt_entry_t *ptep = vtopte(va); - - return (*ptep & ~PG_FRAME); -} - -paddr_t -pmap_pte_paddr_86(vaddr_t va) -{ - pt_entry_t *ptep = vtopte(va); - - return (*ptep & PG_FRAME); -} - -paddr_t -vtophys(vaddr_t va) -{ - return ((*vtopte(va) & PG_FRAME) | (va & ~PG_FRAME)); -} - void setcslimit(struct pmap *pm, struct trapframe *tf, struct pcb *pcb, vaddr_t limit) @@ -1021,15 +755,16 @@ setcslimit(struct pmap *pm, struct trapframe *tf, struct pcb *pcb, void pmap_kenter_pa(vaddr_t va, paddr_t pa, vm_prot_t prot) { - u_int32_t bits; + pt_entry_t *pte, opte, npte; - bits = pmap_pte_set(va, pa, ((prot & VM_PROT_WRITE)? PG_RW : PG_RO) | - PG_V | pmap_pg_g); - if (pmap_valid_entry(bits)) { + pte = vtopte(va); + npte = pa | ((prot & VM_PROT_WRITE)? PG_RW : PG_RO) | PG_V | pmap_pg_g; + opte = i386_atomic_testset_ul(pte, npte); /* zap! */ + if (pmap_valid_entry(opte)) { #ifdef MULTIPROCESSOR int32_t cpumask = 0; - pmap_tlb_shootdown(pmap_kernel(), va, bits, &cpumask); + pmap_tlb_shootdown(pmap_kernel(), va, opte, &cpumask); pmap_tlb_shootnow(cpumask); #else /* Don't bother deferring in the single CPU case. */ @@ -1050,21 +785,25 @@ pmap_kenter_pa(vaddr_t va, paddr_t pa, vm_prot_t prot) void pmap_kremove(vaddr_t va, vsize_t len) { - u_int32_t bits; + pt_entry_t *pte, opte; #ifdef MULTIPROCESSOR int32_t cpumask = 0; #endif len >>= PAGE_SHIFT; for ( /* null */ ; len ; len--, va += PAGE_SIZE) { - bits = pmap_pte_set(va, 0, 0); + if (va < VM_MIN_KERNEL_ADDRESS) + pte = vtopte(va); + else + pte = kvtopte(va); + opte = i386_atomic_testset_ul(pte, 0); /* zap! */ #ifdef DIAGNOSTIC - if (bits & PG_PVLIST) + if (opte & PG_PVLIST) panic("pmap_kremove: PG_PVLIST mapping for 0x%lx", va); #endif - if ((bits & (PG_V | PG_U)) == (PG_V | PG_U)) + if ((opte & (PG_V | PG_U)) == (PG_V | PG_U)) #ifdef MULTIPROCESSOR - pmap_tlb_shootdown(pmap_kernel(), va, bits, &cpumask); + pmap_tlb_shootdown(pmap_kernel(), va, opte, &cpumask); #else pmap_update_pg(va); #endif @@ -1165,8 +904,8 @@ pmap_bootstrap(vaddr_t kva_start) kpm->pm_obj.uo_npages = 0; kpm->pm_obj.uo_refs = 1; bzero(&kpm->pm_list, sizeof(kpm->pm_list)); /* pm_list not used */ - kpm->pm_pdir = (vaddr_t)(proc0.p_addr->u_pcb.pcb_cr3 + KERNBASE); - kpm->pm_pdirpa = proc0.p_addr->u_pcb.pcb_cr3; + kpm->pm_pdir = (pd_entry_t *)(proc0.p_addr->u_pcb.pcb_cr3 + KERNBASE); + kpm->pm_pdirpa = (u_int32_t) proc0.p_addr->u_pcb.pcb_cr3; kpm->pm_stats.wired_count = kpm->pm_stats.resident_count = atop(kva_start - VM_MIN_KERNEL_ADDRESS); @@ -1209,27 +948,27 @@ pmap_bootstrap(vaddr_t kva_start) * as well; we could waste less space if we knew the largest * CPU ID beforehand. */ - pmap_csrcp = (caddr_t) virtual_avail; csrc_pte = pte; + csrcp = (caddr_t) virtual_avail; csrc_pte = pte; - pmap_cdstp = (caddr_t) virtual_avail+PAGE_SIZE; cdst_pte = pte+1; + cdstp = (caddr_t) virtual_avail+PAGE_SIZE; cdst_pte = pte+1; - pmap_zerop = (caddr_t) virtual_avail+PAGE_SIZE*2; zero_pte = pte+2; + zerop = (caddr_t) virtual_avail+PAGE_SIZE*2; zero_pte = pte+2; - pmap_ptpp = (caddr_t) virtual_avail+PAGE_SIZE*3; ptp_pte = pte+3; + ptpp = (caddr_t) virtual_avail+PAGE_SIZE*3; ptp_pte = pte+3; virtual_avail += PAGE_SIZE * I386_MAXPROCS * NPTECL; pte += I386_MAXPROCS * NPTECL; #else - pmap_csrcp = (caddr_t) virtual_avail; csrc_pte = pte; /* allocate */ + csrcp = (caddr_t) virtual_avail; csrc_pte = pte; /* allocate */ virtual_avail += PAGE_SIZE; pte++; /* advance */ - pmap_cdstp = (caddr_t) virtual_avail; cdst_pte = pte; + cdstp = (caddr_t) virtual_avail; cdst_pte = pte; virtual_avail += PAGE_SIZE; pte++; - pmap_zerop = (caddr_t) virtual_avail; zero_pte = pte; + zerop = (caddr_t) virtual_avail; zero_pte = pte; virtual_avail += PAGE_SIZE; pte++; - pmap_ptpp = (caddr_t) virtual_avail; ptp_pte = pte; + ptpp = (caddr_t) virtual_avail; ptp_pte = pte; virtual_avail += PAGE_SIZE; pte++; #endif @@ -1263,7 +1002,7 @@ pmap_bootstrap(vaddr_t kva_start) * initialize the pmap pool. */ - pool_init(&pmap_pmap_pool, sizeof(struct pmap), 32, 0, 0, "pmappl", + pool_init(&pmap_pmap_pool, sizeof(struct pmap), 0, 0, 0, "pmappl", &pool_allocator_nointr); /* @@ -1277,14 +1016,6 @@ pmap_bootstrap(vaddr_t kva_start) mtx_init(&pmap_tlb_shootdown_q[i].pq_mutex, IPL_IPI); } -#if defined(MULTIPROCESSOR) - /* install the page after boot args as PT page for first 4M */ - pmap_enter(pmap_kernel(), (u_long)vtopte(0), - round_page((vaddr_t)(bootargv + bootargc)), - VM_PROT_READ|VM_PROT_WRITE, VM_PROT_READ|VM_PROT_WRITE|PMAP_WIRED); - memset(vtopte(0), 0, NBPG); /* make sure it is clean before using */ -#endif - /* * ensure the TLB is sync'd with reality by flushing it... */ @@ -1588,7 +1319,7 @@ steal_one: */ boolean_t -pmap_try_steal_pv_86(struct pv_head *pvh, struct pv_entry *cpv, +pmap_try_steal_pv(struct pv_head *pvh, struct pv_entry *cpv, struct pv_entry *prevpv) { pt_entry_t *ptep, opte; @@ -1609,7 +1340,7 @@ pmap_try_steal_pv_86(struct pv_head *pvh, struct pv_entry *cpv, * mapping from the pmap. */ - ptep = pmap_tmpmap_pvepte_86(cpv); + ptep = pmap_tmpmap_pvepte(cpv); if (*ptep & PG_W) { ptep = NULL; /* wired page, avoid stealing this one */ } else { @@ -1622,7 +1353,7 @@ pmap_try_steal_pv_86(struct pv_head *pvh, struct pv_entry *cpv, if (pmap_is_curpmap(cpv->pv_pmap)) pmap_update_pg(cpv->pv_va); #endif - pmap_tmpunmap_pvepte_86(cpv); + pmap_tmpunmap_pvepte(cpv); } if (ptep == NULL) { simple_unlock(&cpv->pv_pmap->pm_obj.vmobjlock); @@ -1904,7 +1635,7 @@ pmap_remove_pv(struct pv_head *pvh, struct pmap *pmap, vaddr_t va) */ struct vm_page * -pmap_alloc_ptp_86(struct pmap *pmap, int pde_index, boolean_t just_try) +pmap_alloc_ptp(struct pmap *pmap, int pde_index, boolean_t just_try) { struct vm_page *ptp; @@ -1913,7 +1644,7 @@ pmap_alloc_ptp_86(struct pmap *pmap, int pde_index, boolean_t just_try) if (ptp == NULL) { if (just_try) return(NULL); - ptp = pmap_steal_ptp_86(&pmap->pm_obj, ptp_i2o(pde_index)); + ptp = pmap_steal_ptp(&pmap->pm_obj, ptp_i2o(pde_index)); if (ptp == NULL) { return (NULL); } @@ -1924,8 +1655,8 @@ pmap_alloc_ptp_86(struct pmap *pmap, int pde_index, boolean_t just_try) /* got one! */ ptp->flags &= ~PG_BUSY; /* never busy */ ptp->wire_count = 1; /* no mappings yet */ - PDE(pmap, pde_index) = - (pd_entry_t) (VM_PAGE_TO_PHYS(ptp) | PG_u | PG_RW | PG_V); + pmap->pm_pdir[pde_index] = + (pd_entry_t) (VM_PAGE_TO_PHYS(ptp) | PG_u | PG_RW | PG_V); pmap->pm_stats.resident_count++; /* count PTP as resident */ pmap->pm_ptphint = ptp; return(ptp); @@ -1943,7 +1674,7 @@ pmap_alloc_ptp_86(struct pmap *pmap, int pde_index, boolean_t just_try) */ struct vm_page * -pmap_steal_ptp_86(struct uvm_object *obj, vaddr_t offset) +pmap_steal_ptp(struct uvm_object *obj, vaddr_t offset) { struct vm_page *ptp = NULL; struct pmap *firstpmap; @@ -1977,21 +1708,21 @@ pmap_steal_ptp_86(struct uvm_object *obj, vaddr_t offset) idx = ptp_o2i(ptp->offset); #ifdef DIAGNOSTIC if (VM_PAGE_TO_PHYS(ptp) != - (PDE(pmaps_hand, idx) & PG_FRAME)) + (pmaps_hand->pm_pdir[idx] & PG_FRAME)) panic("pmap_steal_ptp: PTP mismatch!"); #endif ptes = (pt_entry_t *) - pmap_tmpmap_pa_86(VM_PAGE_TO_PHYS(ptp)); + pmap_tmpmap_pa(VM_PAGE_TO_PHYS(ptp)); for (lcv = 0 ; lcv < PTES_PER_PTP ; lcv++) if ((ptes[lcv] & (PG_V|PG_W)) == (PG_V|PG_W)) break; if (lcv == PTES_PER_PTP) - pmap_remove_ptes_86(pmaps_hand, ptp, + pmap_remove_ptes(pmaps_hand, ptp, (vaddr_t)ptes, ptp_i2v(idx), ptp_i2v(idx+1), &cpumask); - pmap_tmpunmap_pa_86(); + pmap_tmpunmap_pa(); if (lcv != PTES_PER_PTP) /* wired, try next PTP */ @@ -2001,7 +1732,7 @@ pmap_steal_ptp_86(struct uvm_object *obj, vaddr_t offset) * got it!!! */ - PDE(pmaps_hand, idx) = 0; /* zap! */ + pmaps_hand->pm_pdir[idx] = 0; /* zap! */ pmaps_hand->pm_stats.resident_count--; #ifdef MULTIPROCESSOR pmap_apte_flush(pmaps_hand); @@ -2045,15 +1776,15 @@ pmap_steal_ptp_86(struct uvm_object *obj, vaddr_t offset) */ struct vm_page * -pmap_get_ptp_86(struct pmap *pmap, int pde_index, boolean_t just_try) +pmap_get_ptp(struct pmap *pmap, int pde_index, boolean_t just_try) { struct vm_page *ptp; - if (pmap_valid_entry(PDE(pmap, pde_index))) { + if (pmap_valid_entry(pmap->pm_pdir[pde_index])) { /* valid... check hint (saves us a PA->PG lookup) */ if (pmap->pm_ptphint && - (PDE(pmap, pde_index) & PG_FRAME) == + (pmap->pm_pdir[pde_index] & PG_FRAME) == VM_PAGE_TO_PHYS(pmap->pm_ptphint)) return(pmap->pm_ptphint); @@ -2067,7 +1798,7 @@ pmap_get_ptp_86(struct pmap *pmap, int pde_index, boolean_t just_try) } /* allocate a new PTP (updates ptphint) */ - return(pmap_alloc_ptp_86(pmap, pde_index, just_try)); + return(pmap_alloc_ptp(pmap, pde_index, just_try)); } /* @@ -2087,7 +1818,17 @@ pmap_create(void) struct pmap *pmap; pmap = pool_get(&pmap_pmap_pool, PR_WAITOK); + pmap_pinit(pmap); + return(pmap); +} +/* + * pmap_pinit: given a zero'd pmap structure, init it. + */ + +void +pmap_pinit(struct pmap *pmap) +{ /* init uvm_object */ simple_lock_init(&pmap->pm_obj.vmobjlock); pmap->pm_obj.pgops = NULL; /* currently not a mappable object */ @@ -2100,37 +1841,26 @@ pmap_create(void) pmap->pm_hiexec = 0; pmap->pm_flags = 0; - /* init the LDT */ - pmap->pm_ldt = NULL; - pmap->pm_ldt_len = 0; - pmap->pm_ldt_sel = GSEL(GLDT_SEL, SEL_KPL); - setsegment(&pmap->pm_codeseg, 0, atop(I386_MAX_EXE_ADDR) - 1, SDT_MEMERA, SEL_UPL, 1, 1); - pmap_pinit_pd(pmap); - return(pmap); -} - -/* - * pmap_pinit: given a zero'd pmap structure, init it. - */ - -void -pmap_pinit_pd_86(struct pmap *pmap) -{ /* allocate PDP */ - pmap->pm_pdir = uvm_km_alloc(kernel_map, NBPG); + pmap->pm_pdir = (pd_entry_t *) uvm_km_alloc(kernel_map, NBPG); if (pmap->pm_pdir == NULL) panic("pmap_pinit: kernel_map out of virtual space!"); - pmap_extract(pmap_kernel(), (vaddr_t)pmap->pm_pdir, &pmap->pm_pdirpa); - pmap->pm_pdirsize = NBPG; + (void) pmap_extract(pmap_kernel(), (vaddr_t)pmap->pm_pdir, + (paddr_t *)&pmap->pm_pdirpa); /* init PDP */ /* zero init area */ - bzero((void *)pmap->pm_pdir, PDSLOT_PTE * sizeof(pd_entry_t)); + bzero(pmap->pm_pdir, PDSLOT_PTE * sizeof(pd_entry_t)); /* put in recursive PDE to map the PTEs */ - PDE(pmap, PDSLOT_PTE) = pmap->pm_pdirpa | PG_V | PG_KW; + pmap->pm_pdir[PDSLOT_PTE] = pmap->pm_pdirpa | PG_V | PG_KW; + + /* init the LDT */ + pmap->pm_ldt = NULL; + pmap->pm_ldt_len = 0; + pmap->pm_ldt_sel = GSEL(GLDT_SEL, SEL_KPL); /* * we need to lock pmaps_lock to prevent nkpde from changing on @@ -2140,10 +1870,10 @@ pmap_pinit_pd_86(struct pmap *pmap) */ simple_lock(&pmaps_lock); /* put in kernel VM PDEs */ - bcopy(&PDP_BASE[PDSLOT_KERN], &PDE(pmap, PDSLOT_KERN), + bcopy(&PDP_BASE[PDSLOT_KERN], &pmap->pm_pdir[PDSLOT_KERN], nkpde * sizeof(pd_entry_t)); /* zero the rest */ - bzero(&PDE(pmap, PDSLOT_KERN + nkpde), + bzero(&pmap->pm_pdir[PDSLOT_KERN + nkpde], NBPG - ((PDSLOT_KERN + nkpde) * sizeof(pd_entry_t))); LIST_INSERT_HEAD(&pmaps, pmap, pm_list); simple_unlock(&pmaps_lock); @@ -2221,7 +1951,7 @@ pmap_release(struct pmap *pmap) * MULTIPROCESSOR -- no need to flush out of other processors' * APTE space because we do that in pmap_unmap_ptes(). */ - uvm_km_free(kernel_map, pmap->pm_pdir, pmap->pm_pdirsize); + uvm_km_free(kernel_map, (vaddr_t)pmap->pm_pdir, NBPG); #ifdef USER_LDT if (pmap->pm_flags & PMF_USER_LDT) { @@ -2402,15 +2132,15 @@ pmap_deactivate(struct proc *p) */ boolean_t -pmap_extract_86(struct pmap *pmap, vaddr_t va, paddr_t *pap) +pmap_extract(struct pmap *pmap, vaddr_t va, paddr_t *pap) { paddr_t retval; pt_entry_t *ptes; - if (PDE(pmap, pdei(va))) { - ptes = pmap_map_ptes_86(pmap); + if (pmap->pm_pdir[pdei(va)]) { + ptes = pmap_map_ptes(pmap); retval = (paddr_t)(ptes[atop(va)] & PG_FRAME); - pmap_unmap_ptes_86(pmap); + pmap_unmap_ptes(pmap); if (pap != NULL) *pap = retval | (va & ~PG_FRAME); return (TRUE); @@ -2446,13 +2176,13 @@ pmap_zero_page(struct vm_page *pg) * initialized. */ void -pmap_zero_phys_86(paddr_t pa) +pmap_zero_phys(paddr_t pa) { #ifdef MULTIPROCESSOR int id = cpu_number(); #endif pt_entry_t *zpte = PTESLEW(zero_pte, id); - caddr_t zerova = VASLEW(pmap_zerop, id); + caddr_t zerova = VASLEW(zerop, id); #ifdef DIAGNOSTIC if (*zpte) @@ -2470,13 +2200,13 @@ pmap_zero_phys_86(paddr_t pa) */ boolean_t -pmap_zero_page_uncached_86(paddr_t pa) +pmap_zero_page_uncached(paddr_t pa) { #ifdef MULTIPROCESSOR int id = cpu_number(); #endif pt_entry_t *zpte = PTESLEW(zero_pte, id); - caddr_t zerova = VASLEW(pmap_zerop, id); + caddr_t zerova = VASLEW(zerop, id); #ifdef DIAGNOSTIC if (*zpte) @@ -2497,7 +2227,7 @@ pmap_zero_page_uncached_86(paddr_t pa) */ void -pmap_copy_page_86(struct vm_page *srcpg, struct vm_page *dstpg) +pmap_copy_page(struct vm_page *srcpg, struct vm_page *dstpg) { paddr_t srcpa = VM_PAGE_TO_PHYS(srcpg); paddr_t dstpa = VM_PAGE_TO_PHYS(dstpg); @@ -2506,8 +2236,8 @@ pmap_copy_page_86(struct vm_page *srcpg, struct vm_page *dstpg) #endif pt_entry_t *spte = PTESLEW(csrc_pte,id); pt_entry_t *dpte = PTESLEW(cdst_pte,id); - caddr_t csrcva = VASLEW(pmap_csrcp, id); - caddr_t cdstva = VASLEW(pmap_cdstp, id); + caddr_t csrcva = VASLEW(csrcp, id); + caddr_t cdstva = VASLEW(cdstp, id); #ifdef DIAGNOSTIC if (*spte || *dpte) @@ -2541,7 +2271,7 @@ pmap_copy_page_86(struct vm_page *srcpg, struct vm_page *dstpg) */ void -pmap_remove_ptes_86(struct pmap *pmap, struct vm_page *ptp, vaddr_t ptpva, +pmap_remove_ptes(struct pmap *pmap, struct vm_page *ptp, vaddr_t ptpva, vaddr_t startva, vaddr_t endva, int32_t *cpumaskp) { struct pv_entry *pv_tofree = NULL; /* list of pv_entrys to free */ @@ -2600,7 +2330,7 @@ pmap_remove_ptes_86(struct pmap *pmap, struct vm_page *ptp, vaddr_t ptpva, #ifdef DIAGNOSTIC if (bank == -1) panic("pmap_remove_ptes: unmanaged page marked " - "PG_PVLIST, va = 0x%lx, pa = 0x%llx", + "PG_PVLIST, va = 0x%lx, pa = 0x%lx", startva, (u_long)(opte & PG_FRAME)); #endif @@ -2634,7 +2364,7 @@ pmap_remove_ptes_86(struct pmap *pmap, struct vm_page *ptp, vaddr_t ptpva, */ boolean_t -pmap_remove_pte_86(struct pmap *pmap, struct vm_page *ptp, pt_entry_t *pte, +pmap_remove_pte(struct pmap *pmap, struct vm_page *ptp, pt_entry_t *pte, vaddr_t va, int32_t *cpumaskp) { pt_entry_t opte; @@ -2681,7 +2411,7 @@ pmap_remove_pte_86(struct pmap *pmap, struct vm_page *ptp, pt_entry_t *pte, #ifdef DIAGNOSTIC if (bank == -1) panic("pmap_remove_pte: unmanaged page marked " - "PG_PVLIST, va = 0x%lx, pa = 0x%llx", va, + "PG_PVLIST, va = 0x%lx, pa = 0x%lx", va, (u_long)(opte & PG_FRAME)); #endif @@ -2703,7 +2433,7 @@ pmap_remove_pte_86(struct pmap *pmap, struct vm_page *ptp, pt_entry_t *pte, */ void -pmap_remove_86(struct pmap *pmap, vaddr_t sva, vaddr_t eva) +pmap_remove(struct pmap *pmap, vaddr_t sva, vaddr_t eva) { pt_entry_t *ptes, opte; boolean_t result; @@ -2717,7 +2447,7 @@ pmap_remove_86(struct pmap *pmap, vaddr_t sva, vaddr_t eva) */ PMAP_MAP_TO_HEAD_LOCK(); - ptes = pmap_map_ptes_86(pmap); /* locks pmap */ + ptes = pmap_map_ptes(pmap); /* locks pmap */ /* * removing one page? take shortcut function. @@ -2725,10 +2455,10 @@ pmap_remove_86(struct pmap *pmap, vaddr_t sva, vaddr_t eva) if (sva + PAGE_SIZE == eva) { - if (pmap_valid_entry(PDE(pmap, pdei(sva)))) { + if (pmap_valid_entry(pmap->pm_pdir[pdei(sva)])) { /* PA of the PTP */ - ptppa = PDE(pmap, pdei(sva)) & PG_FRAME; + ptppa = pmap->pm_pdir[pdei(sva)] & PG_FRAME; /* get PTP if non-kernel mapping */ @@ -2751,7 +2481,7 @@ pmap_remove_86(struct pmap *pmap, vaddr_t sva, vaddr_t eva) } /* do it! */ - result = pmap_remove_pte_86(pmap, ptp, + result = pmap_remove_pte(pmap, ptp, &ptes[atop(sva)], sva, &cpumask); /* @@ -2762,7 +2492,7 @@ pmap_remove_86(struct pmap *pmap, vaddr_t sva, vaddr_t eva) if (result && ptp && ptp->wire_count <= 1) { /* zap! */ opte = i386_atomic_testset_ul( - &PDE(pmap, pdei(sva)), 0); + &pmap->pm_pdir[pdei(sva)], 0); #ifdef MULTIPROCESSOR /* * XXXthorpej Redundant shootdown can happen @@ -2793,7 +2523,7 @@ pmap_remove_86(struct pmap *pmap, vaddr_t sva, vaddr_t eva) } } pmap_tlb_shootnow(cpumask); - pmap_unmap_ptes_86(pmap); /* unlock pmap */ + pmap_unmap_ptes(pmap); /* unlock pmap */ PMAP_MAP_TO_HEAD_UNLOCK(); return; } @@ -2823,12 +2553,12 @@ pmap_remove_86(struct pmap *pmap, vaddr_t sva, vaddr_t eva) /* XXXCDC: ugly hack to avoid freeing PDP here */ continue; - if (!pmap_valid_entry(PDE(pmap, pdei(sva)))) + if (!pmap_valid_entry(pmap->pm_pdir[pdei(sva)])) /* valid block? */ continue; /* PA of the PTP */ - ptppa = PDE(pmap, pdei(sva)) & PG_FRAME; + ptppa = (pmap->pm_pdir[pdei(sva)] & PG_FRAME); /* get PTP if non-kernel mapping */ if (pmap == pmap_kernel()) { @@ -2847,14 +2577,14 @@ pmap_remove_86(struct pmap *pmap, vaddr_t sva, vaddr_t eva) #endif } } - pmap_remove_ptes_86(pmap, ptp, (vaddr_t)&ptes[atop(sva)], + pmap_remove_ptes(pmap, ptp, (vaddr_t)&ptes[atop(sva)], sva, blkendva, &cpumask); /* if PTP is no longer being used, free it! */ if (ptp && ptp->wire_count <= 1) { /* zap! */ opte = i386_atomic_testset_ul( - &PDE(pmap, pdei(sva)), 0); + &pmap->pm_pdir[pdei(sva)], 0); #if defined(MULTIPROCESSOR) /* * XXXthorpej Redundant shootdown can happen here @@ -2883,7 +2613,7 @@ pmap_remove_86(struct pmap *pmap, vaddr_t sva, vaddr_t eva) } pmap_tlb_shootnow(cpumask); - pmap_unmap_ptes_86(pmap); + pmap_unmap_ptes(pmap); PMAP_MAP_TO_HEAD_UNLOCK(); } @@ -2895,7 +2625,7 @@ pmap_remove_86(struct pmap *pmap, vaddr_t sva, vaddr_t eva) */ void -pmap_page_remove_86(struct vm_page *pg) +pmap_page_remove(struct vm_page *pg) { int bank, off; struct pv_head *pvh; @@ -2922,19 +2652,19 @@ pmap_page_remove_86(struct vm_page *pg) simple_lock(&pvh->pvh_lock); for (pve = pvh->pvh_list ; pve != NULL ; pve = pve->pv_next) { - ptes = pmap_map_ptes_86(pve->pv_pmap); /* locks pmap */ + ptes = pmap_map_ptes(pve->pv_pmap); /* locks pmap */ #ifdef DIAGNOSTIC if (pve->pv_va >= uvm.pager_sva && pve->pv_va < uvm.pager_eva) printf("pmap_page_remove: found pager VA on pv_list\n"); - if (pve->pv_ptp && (PDE(pve->pv_pmap, - pdei(pve->pv_va)) & PG_FRAME) != - VM_PAGE_TO_PHYS(pve->pv_ptp)) { + if (pve->pv_ptp && (pve->pv_pmap->pm_pdir[pdei(pve->pv_va)] & + PG_FRAME) + != VM_PAGE_TO_PHYS(pve->pv_ptp)) { printf("pmap_page_remove: pg=%p: va=%lx, pv_ptp=%p\n", pg, pve->pv_va, pve->pv_ptp); printf("pmap_page_remove: PTP's phys addr: " "actual=%x, recorded=%lx\n", - (PDE(pve->pv_pmap, pdei(pve->pv_va)) & + (pve->pv_pmap->pm_pdir[pdei(pve->pv_va)] & PG_FRAME), VM_PAGE_TO_PHYS(pve->pv_ptp)); panic("pmap_page_remove: mapped managed page has " "invalid pv_ptp field"); @@ -2970,7 +2700,8 @@ pmap_page_remove_86(struct vm_page *pg) /* zap! */ opte = i386_atomic_testset_ul( - &PDE(pve->pv_pmap, pdei(pve->pv_va)), 0); + &pve->pv_pmap->pm_pdir[pdei(pve->pv_va)], + 0); pmap_tlb_shootdown(curpcb->pcb_pmap, ((vaddr_t)ptes) + pve->pv_ptp->offset, opte, &cpumask); @@ -2992,7 +2723,7 @@ pmap_page_remove_86(struct vm_page *pg) uvm_pagefree(pve->pv_ptp); } } - pmap_unmap_ptes_86(pve->pv_pmap); /* unlocks pmap */ + pmap_unmap_ptes(pve->pv_pmap); /* unlocks pmap */ } pmap_free_pvs(NULL, pvh->pvh_list); pvh->pvh_list = NULL; @@ -3015,7 +2746,7 @@ pmap_page_remove_86(struct vm_page *pg) */ boolean_t -pmap_test_attrs_86(struct vm_page *pg, int testbits) +pmap_test_attrs(struct vm_page *pg, int testbits) { int bank, off; char *myattrs; @@ -3052,9 +2783,9 @@ pmap_test_attrs_86(struct vm_page *pg, int testbits) for (pve = pvh->pvh_list; pve != NULL && (*myattrs & testbits) == 0; pve = pve->pv_next) { - ptes = pmap_map_ptes_86(pve->pv_pmap); + ptes = pmap_map_ptes(pve->pv_pmap); pte = ptes[atop(pve->pv_va)]; - pmap_unmap_ptes_86(pve->pv_pmap); + pmap_unmap_ptes(pve->pv_pmap); *myattrs |= pte; } @@ -3076,7 +2807,7 @@ pmap_test_attrs_86(struct vm_page *pg, int testbits) */ boolean_t -pmap_change_attrs_86(struct vm_page *pg, int setbits, int clearbits) +pmap_change_attrs(struct vm_page *pg, int setbits, int clearbits) { u_int32_t result; int bank, off; @@ -3104,12 +2835,12 @@ pmap_change_attrs_86(struct vm_page *pg, int setbits, int clearbits) for (pve = pvh->pvh_list; pve != NULL; pve = pve->pv_next) { #ifdef DIAGNOSTIC - if (!pmap_valid_entry(PDE(pve->pv_pmap, pdei(pve->pv_va)))) + if (!pmap_valid_entry(pve->pv_pmap->pm_pdir[pdei(pve->pv_va)])) panic("pmap_change_attrs: mapping without PTP " "detected"); #endif - ptes = pmap_map_ptes_86(pve->pv_pmap); /* locks pmap */ + ptes = pmap_map_ptes(pve->pv_pmap); /* locks pmap */ npte = ptes[atop(pve->pv_va)]; result |= (npte & clearbits); npte = (npte | setbits) & ~clearbits; @@ -3119,7 +2850,7 @@ pmap_change_attrs_86(struct vm_page *pg, int setbits, int clearbits) pmap_tlb_shootdown(pve->pv_pmap, atop(pve->pv_va), opte, &cpumask); } - pmap_unmap_ptes_86(pve->pv_pmap); /* unlocks pmap */ + pmap_unmap_ptes(pve->pv_pmap); /* unlocks pmap */ } simple_unlock(&pvh->pvh_lock); @@ -3155,7 +2886,7 @@ pmap_change_attrs_86(struct vm_page *pg, int setbits, int clearbits) */ void -pmap_write_protect_86(struct pmap *pmap, vaddr_t sva, vaddr_t eva, +pmap_write_protect(struct pmap *pmap, vaddr_t sva, vaddr_t eva, vm_prot_t prot) { pt_entry_t *ptes, *spte, *epte, npte; @@ -3163,7 +2894,7 @@ pmap_write_protect_86(struct pmap *pmap, vaddr_t sva, vaddr_t eva, u_int32_t md_prot; int32_t cpumask = 0; - ptes = pmap_map_ptes_86(pmap); /* locks pmap */ + ptes = pmap_map_ptes(pmap); /* locks pmap */ /* should be ok, but just in case ... */ sva &= PG_FRAME; @@ -3189,7 +2920,7 @@ pmap_write_protect_86(struct pmap *pmap, vaddr_t sva, vaddr_t eva, continue; /* empty block? */ - if (!pmap_valid_entry(PDE(pmap, pdei(sva)))) + if (!pmap_valid_entry(pmap->pm_pdir[pdei(sva)])) continue; md_prot = protection_codes[prot]; @@ -3218,7 +2949,7 @@ pmap_write_protect_86(struct pmap *pmap, vaddr_t sva, vaddr_t eva, } pmap_tlb_shootnow(cpumask); - pmap_unmap_ptes_86(pmap); /* unlocks pmap */ + pmap_unmap_ptes(pmap); /* unlocks pmap */ } /* @@ -3232,12 +2963,12 @@ pmap_write_protect_86(struct pmap *pmap, vaddr_t sva, vaddr_t eva, */ void -pmap_unwire_86(struct pmap *pmap, vaddr_t va) +pmap_unwire(struct pmap *pmap, vaddr_t va) { pt_entry_t *ptes; - if (pmap_valid_entry(PDE(pmap, pdei(va)))) { - ptes = pmap_map_ptes_86(pmap); /* locks pmap */ + if (pmap_valid_entry(pmap->pm_pdir[pdei(va)])) { + ptes = pmap_map_ptes(pmap); /* locks pmap */ #ifdef DIAGNOSTIC if (!pmap_valid_entry(ptes[atop(va)])) @@ -3253,7 +2984,7 @@ pmap_unwire_86(struct pmap *pmap, vaddr_t va) "didn't change!\n", pmap, va); } #endif - pmap_unmap_ptes_86(pmap); /* unlocks map */ + pmap_unmap_ptes(pmap); /* unlocks map */ } #ifdef DIAGNOSTIC else { @@ -3299,7 +3030,7 @@ pmap_collect(struct pmap *pmap) */ int -pmap_enter_86(struct pmap *pmap, vaddr_t va, paddr_t pa, +pmap_enter(struct pmap *pmap, vaddr_t va, paddr_t pa, vm_prot_t prot, int flags) { pt_entry_t *ptes, opte, npte; @@ -3319,7 +3050,7 @@ pmap_enter_86(struct pmap *pmap, vaddr_t va, paddr_t pa, /* sanity check: kernel PTPs should already have been pre-allocated */ if (va >= VM_MIN_KERNEL_ADDRESS && - !pmap_valid_entry(PDE(pmap, pdei(va)))) + !pmap_valid_entry(pmap->pm_pdir[pdei(va)])) panic("pmap_enter: missing kernel PTP!"); #endif @@ -3330,11 +3061,11 @@ pmap_enter_86(struct pmap *pmap, vaddr_t va, paddr_t pa, * map in ptes and get a pointer to our PTP (unless we are the kernel) */ - ptes = pmap_map_ptes_86(pmap); /* locks pmap */ + ptes = pmap_map_ptes(pmap); /* locks pmap */ if (pmap == pmap_kernel()) { ptp = NULL; } else { - ptp = pmap_get_ptp_86(pmap, pdei(va), FALSE); + ptp = pmap_get_ptp(pmap, pdei(va), FALSE); if (ptp == NULL) { if (flags & PMAP_CANFAIL) { error = ENOMEM; @@ -3376,7 +3107,7 @@ pmap_enter_86(struct pmap *pmap, vaddr_t va, paddr_t pa, if (bank == -1) panic("pmap_enter: same pa PG_PVLIST " "mapping with unmanaged page " - "pa = 0x%llx (0x%lx)", pa, + "pa = 0x%lx (0x%lx)", pa, atop(pa)); #endif pvh = &vm_physmem[bank].pmseg.pvhead[off]; @@ -3404,7 +3135,7 @@ pmap_enter_86(struct pmap *pmap, vaddr_t va, paddr_t pa, if (bank == -1) panic("pmap_enter: PG_PVLIST mapping with " "unmanaged page " - "pa = 0x%llx (0x%lx)", pa, atop(pa)); + "pa = 0x%lx (0x%lx)", pa, atop(pa)); #endif pvh = &vm_physmem[bank].pmseg.pvhead[off]; simple_lock(&pvh->pvh_lock); @@ -3490,7 +3221,7 @@ enter_now: error = 0; out: - pmap_unmap_ptes_86(pmap); + pmap_unmap_ptes(pmap); PMAP_MAP_TO_HEAD_UNLOCK(); return error; @@ -3504,7 +3235,7 @@ out: */ vaddr_t -pmap_growkernel_86(vaddr_t maxkvaddr) +pmap_growkernel(vaddr_t maxkvaddr) { struct pmap *kpm = pmap_kernel(), *pm; int needed_kpde; /* needed number of kernel PTPs */ @@ -3535,9 +3266,10 @@ pmap_growkernel_86(vaddr_t maxkvaddr) if (uvm_page_physget(&ptaddr) == FALSE) panic("pmap_growkernel: out of memory"); - pmap_zero_phys_86(ptaddr); + pmap_zero_phys(ptaddr); - PDE(kpm, PDSLOT_KERN + nkpde) = ptaddr | PG_RW | PG_V; + kpm->pm_pdir[PDSLOT_KERN + nkpde] = + ptaddr | PG_RW | PG_V; /* count PTP as resident */ kpm->pm_stats.resident_count++; @@ -3550,18 +3282,18 @@ pmap_growkernel_86(vaddr_t maxkvaddr) * INVOKED WHILE pmap_init() IS RUNNING! */ - if (pmap_alloc_ptp_86(kpm, PDSLOT_KERN+nkpde, FALSE) == NULL) { + if (pmap_alloc_ptp(kpm, PDSLOT_KERN+nkpde, FALSE) == NULL) { panic("pmap_growkernel: alloc ptp failed"); } /* PG_u not for kernel */ - PDE(kpm, PDSLOT_KERN + nkpde) &= ~PG_u; + kpm->pm_pdir[PDSLOT_KERN + nkpde] &= ~PG_u; /* distribute new kernel PTP to all active pmaps */ simple_lock(&pmaps_lock); LIST_FOREACH(pm, &pmaps, pm_list) { - PDE(pm, PDSLOT_KERN + nkpde) = - PDE(kpm, PDSLOT_KERN + nkpde); + pm->pm_pdir[PDSLOT_KERN + nkpde] = + kpm->pm_pdir[PDSLOT_KERN + nkpde]; } simple_unlock(&pmaps_lock); } @@ -3574,7 +3306,7 @@ out: } #ifdef DEBUG -void pmap_dump_86(struct pmap *, vaddr_t, vaddr_t); +void pmap_dump(struct pmap *, vaddr_t, vaddr_t); /* * pmap_dump: dump all the mappings from a pmap @@ -3583,7 +3315,7 @@ void pmap_dump_86(struct pmap *, vaddr_t, vaddr_t); */ void -pmap_dump_86(struct pmap *pmap, vaddr_t sva, vaddr_t eva) +pmap_dump(struct pmap *pmap, vaddr_t sva, vaddr_t eva) { pt_entry_t *ptes, *pte; vaddr_t blkendva; @@ -3601,7 +3333,7 @@ pmap_dump_86(struct pmap *pmap, vaddr_t sva, vaddr_t eva) */ PMAP_MAP_TO_HEAD_LOCK(); - ptes = pmap_map_ptes_86(pmap); /* locks pmap */ + ptes = pmap_map_ptes(pmap); /* locks pmap */ /* * dumping a range of pages: we dump in PTP sized blocks (4MB) @@ -3615,7 +3347,7 @@ pmap_dump_86(struct pmap *pmap, vaddr_t sva, vaddr_t eva) blkendva = eva; /* valid block? */ - if (!pmap_valid_entry(PDE(pmap, pdei(sva)))) + if (!pmap_valid_entry(pmap->pm_pdir[pdei(sva)])) continue; pte = &ptes[atop(sva)]; @@ -3626,7 +3358,7 @@ pmap_dump_86(struct pmap *pmap, vaddr_t sva, vaddr_t eva) sva, *pte, *pte & PG_FRAME); } } - pmap_unmap_ptes_86(pmap); + pmap_unmap_ptes(pmap); PMAP_MAP_TO_HEAD_UNLOCK(); } #endif @@ -3692,7 +3424,7 @@ pmap_tlb_shootnow(int32_t cpumask) * Cause the TLB entry for pmap/va to be shot down. */ void -pmap_tlb_shootdown(pmap_t pmap, vaddr_t va, u_int32_t pte, int32_t *cpumaskp) +pmap_tlb_shootdown(pmap_t pmap, vaddr_t va, pt_entry_t pte, int32_t *cpumaskp) { struct cpu_info *ci, *self; struct pmap_tlb_shootdown_q *pq; @@ -3912,31 +3644,3 @@ pmap_tlb_shootdown_job_put(struct pmap_tlb_shootdown_q *pq, pq->pq_count--; } - -#ifndef SMALL_KERNEL -u_int32_t (*pmap_pte_set_p)(vaddr_t, paddr_t, u_int32_t) = - pmap_pte_set_86; -u_int32_t (*pmap_pte_setbits_p)(vaddr_t, u_int32_t, u_int32_t) = - pmap_pte_setbits_86; -u_int32_t (*pmap_pte_bits_p)(vaddr_t) = pmap_pte_bits_86; -paddr_t (*pmap_pte_paddr_p)(vaddr_t) = pmap_pte_paddr_86; -boolean_t (*pmap_change_attrs_p)(struct vm_page *, int, int) = - pmap_change_attrs_86; -int (*pmap_enter_p)(pmap_t, vaddr_t, paddr_t, vm_prot_t, int) = - pmap_enter_86; -boolean_t (*pmap_extract_p)(pmap_t, vaddr_t, paddr_t *) = pmap_extract_86; -vaddr_t (*pmap_growkernel_p)(vaddr_t) = pmap_growkernel_86; -void (*pmap_page_remove_p)(struct vm_page *) = pmap_page_remove_86; -void (*pmap_remove_p)(struct pmap *, vaddr_t, vaddr_t) = pmap_remove_86; -boolean_t (*pmap_test_attrs_p)(struct vm_page *, int) = pmap_test_attrs_86; -void (*pmap_unwire_p)(struct pmap *, vaddr_t) = pmap_unwire_86; -void (*pmap_write_protect_p)(struct pmap *, vaddr_t, vaddr_t, vm_prot_t) = - pmap_write_protect_86; -void (*pmap_pinit_pd_p)(pmap_t) = pmap_pinit_pd_86; -void (*pmap_zero_phys_p)(paddr_t) = pmap_zero_phys_86; -boolean_t (*pmap_zero_page_uncached_p)(paddr_t) = pmap_zero_page_uncached_86; -void (*pmap_copy_page_p)(struct vm_page *, struct vm_page *) = - pmap_copy_page_86; -boolean_t (*pmap_try_steal_pv_p)(struct pv_head *, struct pv_entry *, - struct pv_entry *) = pmap_try_steal_pv_86; -#endif /* !SMALL_KERNEL */ diff --git a/sys/arch/i386/i386/vm_machdep.c b/sys/arch/i386/i386/vm_machdep.c index c62f3682c9d..7bc934d292f 100644 --- a/sys/arch/i386/i386/vm_machdep.c +++ b/sys/arch/i386/i386/vm_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vm_machdep.c,v 1.47 2006/11/29 12:26:13 miod Exp $ */ +/* $OpenBSD: vm_machdep.c,v 1.48 2007/02/20 21:15:01 tom Exp $ */ /* $NetBSD: vm_machdep.c,v 1.61 1996/05/03 19:42:35 christos Exp $ */ /*- @@ -217,7 +217,8 @@ cpu_coredump(struct proc *p, struct vnode *vp, struct ucred *cred, void pagemove(caddr_t from, caddr_t to, size_t size) { - u_int32_t ofpte, otpte; + pt_entry_t *fpte, *tpte; + pt_entry_t ofpte, otpte; #ifdef MULTIPROCESSOR u_int32_t cpumask = 0; #endif @@ -226,12 +227,13 @@ pagemove(caddr_t from, caddr_t to, size_t size) if ((size & PAGE_MASK) != 0) panic("pagemove"); #endif + fpte = kvtopte((vaddr_t)from); + tpte = kvtopte((vaddr_t)to); while (size > 0) { - ofpte = pmap_pte_bits((vaddr_t)from); - otpte = pmap_pte_bits((vaddr_t)to); - pmap_pte_set((vaddr_t)to, - pmap_pte_paddr((vaddr_t)from), ofpte); - pmap_pte_set((vaddr_t)from, 0, 0); + ofpte = *fpte; + otpte = *tpte; + *tpte++ = *fpte; + *fpte++ = 0; #if defined(I386_CPU) && !defined(MULTIPROCESSOR) if (cpu_class != CPUCLASS_386) #endif diff --git a/sys/arch/i386/include/_types.h b/sys/arch/i386/include/_types.h index f731aefd89f..cef2a372f29 100644 --- a/sys/arch/i386/include/_types.h +++ b/sys/arch/i386/include/_types.h @@ -1,4 +1,4 @@ -/* $OpenBSD: _types.h,v 1.3 2006/04/27 15:37:53 mickey Exp $ */ +/* $OpenBSD: _types.h,v 1.4 2007/02/20 21:15:01 tom Exp $ */ /*- * Copyright (c) 1990, 1993 @@ -86,9 +86,9 @@ typedef __int32_t __register_t; /* VM system types */ typedef unsigned long __vaddr_t; +typedef unsigned long __paddr_t; typedef unsigned long __vsize_t; -typedef unsigned long long __paddr_t; -typedef unsigned long long __psize_t; +typedef unsigned long __psize_t; /* Standard system types */ typedef int __clock_t; diff --git a/sys/arch/i386/include/bus.h b/sys/arch/i386/include/bus.h index 9900c76d4f0..5c5caf3e6c7 100644 --- a/sys/arch/i386/include/bus.h +++ b/sys/arch/i386/include/bus.h @@ -1,4 +1,4 @@ -/* $OpenBSD: bus.h,v 1.39 2006/04/27 15:37:53 mickey Exp $ */ +/* $OpenBSD: bus.h,v 1.40 2007/02/20 21:15:01 tom Exp $ */ /* $NetBSD: bus.h,v 1.6 1996/11/10 03:19:25 thorpej Exp $ */ /*- @@ -741,7 +741,7 @@ void bus_space_free(bus_space_tag_t t, bus_space_handle_t bsh, #define BUS_DMA_COHERENT 0x004 /* hint: map memory DMA coherent */ #define BUS_DMA_BUS1 0x010 /* placeholders for bus functions... */ #define BUS_DMA_BUS2 0x020 -#define BUS_DMA_64BIT 0x040 /* large memory high segment is ok */ +#define BUS_DMA_BUS3 0x040 #define BUS_DMA_24BIT 0x080 /* isadma map */ #define BUS_DMA_STREAMING 0x100 /* hint: sequential, unidirectional */ #define BUS_DMA_READ 0x200 /* mapping is device -> memory only */ @@ -771,10 +771,7 @@ typedef struct i386_bus_dmamap *bus_dmamap_t; */ struct i386_bus_dma_segment { bus_addr_t ds_addr; /* DMA address */ - paddr_t ds_addr2; /* replacement store */ bus_size_t ds_len; /* length of transfer */ - vaddr_t ds_va; /* mapped loaded data */ - vaddr_t ds_va2; /* mapped replacement data */ }; typedef struct i386_bus_dma_segment bus_dma_segment_t; @@ -866,11 +863,6 @@ struct i386_bus_dmamap { void *_dm_cookie; /* cookie for bus-specific functions */ - struct vm_page **_dm_pages; /* replacement pages */ - vaddr_t _dm_pgva; /* those above -- mapped */ - int _dm_npages; /* number of pages allocated */ - int _dm_nused; /* number of pages replaced */ - /* * PUBLIC MEMBERS: these are used by machine-independent code. */ diff --git a/sys/arch/i386/include/cpu.h b/sys/arch/i386/include/cpu.h index b9ac96eca8a..153e6f2c608 100644 --- a/sys/arch/i386/include/cpu.h +++ b/sys/arch/i386/include/cpu.h @@ -1,4 +1,4 @@ -/* $OpenBSD: cpu.h,v 1.86 2006/12/24 20:30:35 miod Exp $ */ +/* $OpenBSD: cpu.h,v 1.87 2007/02/20 21:15:01 tom Exp $ */ /* $NetBSD: cpu.h,v 1.35 1996/05/05 19:29:26 christos Exp $ */ /*- @@ -420,10 +420,6 @@ int kvtop(caddr_t); void vm86_gpfault(struct proc *, int); #endif /* VM86 */ -#ifndef SMALL_KERNEL -int cpu_paenable(void *); -#endif /* !SMALL_KERNEL */ - #ifdef GENERIC /* swapgeneric.c */ void setconf(void); diff --git a/sys/arch/i386/include/loadfile_machdep.h b/sys/arch/i386/include/loadfile_machdep.h index 5903231fc58..4990ae48bbd 100644 --- a/sys/arch/i386/include/loadfile_machdep.h +++ b/sys/arch/i386/include/loadfile_machdep.h @@ -1,4 +1,4 @@ -/* $OpenBSD: loadfile_machdep.h,v 1.2 2006/04/27 15:37:53 mickey Exp $ */ +/* $OpenBSD: loadfile_machdep.h,v 1.3 2007/02/20 21:15:01 tom Exp $ */ /* $NetBSD: loadfile_machdep.h,v 1.1 1999/04/29 03:17:12 tsubai Exp $ */ /*- @@ -43,7 +43,7 @@ #define LOAD_KERNEL (LOAD_ALL & ~LOAD_TEXTA) #define COUNT_KERNEL (COUNT_ALL & ~COUNT_TEXTA) -#define LOADADDR(a) (((u_long)(a) + (u_long)offset)&0xfffffff) +#define LOADADDR(a) ((((u_long)(a)) + offset)&0xfffffff) #define ALIGNENTRY(a) ((u_long)(a)) #define READ(f, b, c) read((f), (void *)LOADADDR(b), (c)) #define BCOPY(s, d, c) memcpy((void *)LOADADDR(d), (void *)(s), (c)) diff --git a/sys/arch/i386/include/param.h b/sys/arch/i386/include/param.h index cc288c2239b..161973c6f36 100644 --- a/sys/arch/i386/include/param.h +++ b/sys/arch/i386/include/param.h @@ -1,4 +1,4 @@ -/* $OpenBSD: param.h,v 1.38 2006/11/30 21:20:41 dim Exp $ */ +/* $OpenBSD: param.h,v 1.39 2007/02/20 21:15:01 tom Exp $ */ /* $NetBSD: param.h,v 1.29 1996/03/04 05:04:26 cgd Exp $ */ /*- @@ -75,6 +75,8 @@ #define PAGE_SIZE (1 << PAGE_SHIFT) #define PAGE_MASK (PAGE_SIZE - 1) +#define NPTEPG (NBPG/(sizeof (pt_entry_t))) + /* * Start of kernel virtual space. Remember to alter the memory and * page table layout description in pmap.h when changing this. @@ -129,3 +131,9 @@ /* bytes to disk blocks */ #define dbtob(x) ((x) << DEV_BSHIFT) #define btodb(x) ((x) >> DEV_BSHIFT) + +/* + * Mach derived conversion macros + */ +#define i386_round_pdr(x) ((((unsigned)(x)) + PDOFSET) & ~PDOFSET) +#define i386_trunc_pdr(x) ((unsigned)(x) & ~PDOFSET) diff --git a/sys/arch/i386/include/pmap.h b/sys/arch/i386/include/pmap.h index b1e1c2ec4b8..405edfe6ada 100644 --- a/sys/arch/i386/include/pmap.h +++ b/sys/arch/i386/include/pmap.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pmap.h,v 1.42 2006/04/27 15:37:53 mickey Exp $ */ +/* $OpenBSD: pmap.h,v 1.43 2007/02/20 21:15:01 tom Exp $ */ /* $NetBSD: pmap.h,v 1.44 2000/04/24 17:18:18 thorpej Exp $ */ /* @@ -47,11 +47,123 @@ #include <uvm/uvm_object.h> /* - * The following defines identify the slots used as described in pmap.c . + * See pte.h for a description of i386 MMU terminology and hardware + * interface. + * + * A pmap describes a process' 4GB virtual address space. This + * virtual address space can be broken up into 1024 4MB regions which + * are described by PDEs in the PDP. The PDEs are defined as follows: + * + * Ranges are inclusive -> exclusive, just like vm_map_entry start/end. + * The following assumes that KERNBASE is 0xd0000000. + * + * PDE#s VA range Usage + * 0->831 0x0 -> 0xcfc00000 user address space, note that the + * max user address is 0xcfbfe000 + * the final two pages in the last 4MB + * used to be reserved for the UAREA + * but now are no longer used. + * 831 0xcfc00000-> recursive mapping of PDP (used for + * 0xd0000000 linear mapping of PTPs). + * 832->1023 0xd0000000-> kernel address space (constant + * 0xffc00000 across all pmaps/processes). + * 1023 0xffc00000-> "alternate" recursive PDP mapping + * <end> (for other pmaps). + * + * + * Note: A recursive PDP mapping provides a way to map all the PTEs for + * a 4GB address space into a linear chunk of virtual memory. In other + * words, the PTE for page 0 is the first int mapped into the 4MB recursive + * area. The PTE for page 1 is the second int. The very last int in the + * 4MB range is the PTE that maps VA 0xffffe000 (the last page in a 4GB + * address). + * + * All pmaps' PDs must have the same values in slots 832->1023 so that + * the kernel is always mapped in every process. These values are loaded + * into the PD at pmap creation time. + * + * At any one time only one pmap can be active on a processor. This is + * the pmap whose PDP is pointed to by processor register %cr3. This pmap + * will have all its PTEs mapped into memory at the recursive mapping + * point (slot #831 as show above). When the pmap code wants to find the + * PTE for a virtual address, all it has to do is the following: + * + * Address of PTE = (831 * 4MB) + (VA / NBPG) * sizeof(pt_entry_t) + * = 0xcfc00000 + (VA / 4096) * 4 + * + * What happens if the pmap layer is asked to perform an operation + * on a pmap that is not the one which is currently active? In that + * case we take the PA of the PDP of non-active pmap and put it in + * slot 1023 of the active pmap. This causes the non-active pmap's + * PTEs to get mapped in the final 4MB of the 4GB address space + * (e.g. starting at 0xffc00000). + * + * The following figure shows the effects of the recursive PDP mapping: + * + * PDP (%cr3) + * +----+ + * | 0| -> PTP#0 that maps VA 0x0 -> 0x400000 + * | | + * | | + * | 831| -> points back to PDP (%cr3) mapping VA 0xcfc00000 -> 0xd0000000 + * | 832| -> first kernel PTP (maps 0xd0000000 -> 0xe0400000) + * | | + * |1023| -> points to alternate pmap's PDP (maps 0xffc00000 -> end) + * +----+ + * + * Note that the PDE#831 VA (0xcfc00000) is defined as "PTE_BASE". + * Note that the PDE#1023 VA (0xffc00000) is defined as "APTE_BASE". + * + * Starting at VA 0xcfc00000 the current active PDP (%cr3) acts as a + * PTP: + * + * PTP#831 == PDP(%cr3) => maps VA 0xcfc00000 -> 0xd0000000 + * +----+ + * | 0| -> maps the contents of PTP#0 at VA 0xcfc00000->0xcfc01000 + * | | + * | | + * | 831| -> maps the contents of PTP#831 (the PDP) at VA 0xcff3f000 + * | 832| -> maps the contents of first kernel PTP + * | | + * |1023| + * +----+ + * + * Note that mapping of the PDP at PTP#831's VA (0xcff3f000) is + * defined as "PDP_BASE".... within that mapping there are two + * defines: + * "PDP_PDE" (0xcff3fcfc) is the VA of the PDE in the PDP + * which points back to itself. + * "APDP_PDE" (0xcff3fffc) is the VA of the PDE in the PDP which + * establishes the recursive mapping of the alternate pmap. + * To set the alternate PDP, one just has to put the correct + * PA info in *APDP_PDE. + * + * Note that in the APTE_BASE space, the APDP appears at VA + * "APDP_BASE" (0xfffff000). */ -#define PDSLOT_PTE ((KERNBASE/NBPD)-2) /* 830: for recursive PDP map */ -#define PDSLOT_KERN (KERNBASE/NBPD) /* 832: start of kernel space */ -#define PDSLOT_APTE ((unsigned)1022) /* 1022: alternative recursive slot */ + +/* + * The following defines identify the slots used as described above. + */ + +#define PDSLOT_PTE ((KERNBASE/NBPD)-1) /* 831: for recursive PDP map */ +#define PDSLOT_KERN (KERNBASE/NBPD) /* 832: start of kernel space */ +#define PDSLOT_APTE ((unsigned)1023) /* 1023: alternative recursive slot */ + +/* + * The following defines give the virtual addresses of various MMU + * data structures: + * PTE_BASE and APTE_BASE: the base VA of the linear PTE mappings + * PTD_BASE and APTD_BASE: the base VA of the recursive mapping of the PTD + * PDP_PDE and APDP_PDE: the VA of the PDE that points back to the PDP/APDP + */ + +#define PTE_BASE ((pt_entry_t *) (PDSLOT_PTE * NBPD) ) +#define APTE_BASE ((pt_entry_t *) (PDSLOT_APTE * NBPD) ) +#define PDP_BASE ((pd_entry_t *)(((char *)PTE_BASE) + (PDSLOT_PTE * NBPG))) +#define APDP_BASE ((pd_entry_t *)(((char *)APTE_BASE) + (PDSLOT_APTE * NBPG))) +#define PDP_PDE (PDP_BASE + PDSLOT_PTE) +#define APDP_PDE (PDP_BASE + PDSLOT_APTE) /* * The following define determines how many PTPs should be set up for the @@ -59,10 +171,55 @@ * get the VM system running. Once the VM system is running, the * pmap module can add more PTPs to the kernel area on demand. */ + #ifndef NKPTP -#define NKPTP 8 /* 16/32MB to start */ +#define NKPTP 4 /* 16MB to start */ #endif #define NKPTP_MIN 4 /* smallest value we allow */ +#define NKPTP_MAX (1024 - (KERNBASE/NBPD) - 1) + /* largest value (-1 for APTP space) */ + +/* + * various address macros + * + * vtopte: return a pointer to the PTE mapping a VA + * kvtopte: same as above (takes a KVA, but doesn't matter with this pmap) + * ptetov: given a pointer to a PTE, return the VA that it maps + * vtophys: translate a VA to the PA mapped to it + * + * plus alternative versions of the above + */ + +#define vtopte(VA) (PTE_BASE + atop(VA)) +#define kvtopte(VA) vtopte(VA) +#define ptetov(PT) (ptoa(PT - PTE_BASE)) +#define vtophys(VA) ((*vtopte(VA) & PG_FRAME) | \ + ((unsigned)(VA) & ~PG_FRAME)) +#define avtopte(VA) (APTE_BASE + atop(VA)) +#define ptetoav(PT) (ptoa(PT - APTE_BASE)) +#define avtophys(VA) ((*avtopte(VA) & PG_FRAME) | \ + ((unsigned)(VA) & ~PG_FRAME)) + +/* + * pdei/ptei: generate index into PDP/PTP from a VA + */ +#define pdei(VA) (((VA) & PD_MASK) >> PDSHIFT) +#define ptei(VA) (((VA) & PT_MASK) >> PGSHIFT) + +/* + * PTP macros: + * A PTP's index is the PD index of the PDE that points to it. + * A PTP's offset is the byte-offset in the PTE space that this PTP is at. + * A PTP's VA is the first VA mapped by that PTP. + * + * Note that NBPG == number of bytes in a PTP (4096 bytes == 1024 entries) + * NBPD == number of bytes a PTP can map (4MB) + */ + +#define ptp_i2o(I) ((I) * NBPG) /* index => offset */ +#define ptp_o2i(O) ((O) / NBPG) /* offset => index */ +#define ptp_i2v(I) ((I) * NBPD) /* index => VA */ +#define ptp_v2i(V) ((V) / NBPD) /* VA => index (same as pdei) */ /* * PG_AVAIL usage: we make use of the ignored bits of the PTE @@ -72,6 +229,12 @@ #define PG_PVLIST PG_AVAIL2 /* mapping has entry on pvlist */ #define PG_X PG_AVAIL3 /* executable mapping */ +/* + * Number of PTE's per cache line. 4 byte pte, 32-byte cache line + * Used to avoid false sharing of cache lines. + */ +#define NPTECL 8 + #ifdef _KERNEL /* * pmap data structures: see pmap.c for details of locking. @@ -94,15 +257,13 @@ LIST_HEAD(pmap_head, pmap); /* struct pmap_head: head of a pmap list */ */ struct pmap { - paddr_t pm_pdidx[4]; /* PDIEs for PAE mode */ - paddr_t pm_pdirpa; /* PA of PD (read-only after create) */ - vaddr_t pm_pdir; /* VA of PD (lck by object lock) */ - int pm_pdirsize; /* PD size (4k vs 16k on pae */ struct uvm_object pm_obj; /* object (lck by object lock) */ #define pm_lock pm_obj.vmobjlock LIST_ENTRY(pmap) pm_list; /* list (lck by pm_list lock) */ + pd_entry_t *pm_pdir; /* VA of PD (lck by object lock) */ + paddr_t pm_pdirpa; /* PA of PD (read-only after create) */ struct vm_page *pm_ptphint; /* pointer to a PTP in our pmap */ - struct pmap_statistics pm_stats;/* pmap stats (lck by object lock) */ + struct pmap_statistics pm_stats; /* pmap stats (lck by object lock) */ vaddr_t pm_hiexec; /* highest executable mapping */ int pm_flags; /* see below */ @@ -172,185 +333,67 @@ struct pv_page { /* * global kernel variables */ -extern char PTD[]; + +extern pd_entry_t PTD[]; + +/* PTDpaddr: is the physical address of the kernel's PDP */ +extern u_int32_t PTDpaddr; + extern struct pmap kernel_pmap_store; /* kernel pmap */ -extern int nkptp_max; +extern int nkpde; /* current # of PDEs for kernel */ +extern int pmap_pg_g; /* do we support PG_G? */ /* - * Our dual-pmap design requires to play a pointer-and-seek. - * Although being nice folks we are handle single-pmap kernels special. + * Macros */ -#define PMAP_EXCLUDE_DECLS /* tells uvm_pmap.h *not* to include decls */ -/* - * Dumb macros - */ #define pmap_kernel() (&kernel_pmap_store) #define pmap_resident_count(pmap) ((pmap)->pm_stats.resident_count) #define pmap_update(pm) /* nada */ -#define pmap_clear_modify(pg) pmap_change_attrs(pg, 0, PG_M) -#define pmap_clear_reference(pg) pmap_change_attrs(pg, 0, PG_U) -#define pmap_copy(DP,SP,D,L,S) /* nicht */ -#define pmap_is_modified(pg) pmap_test_attrs(pg, PG_M) -#define pmap_is_referenced(pg) pmap_test_attrs(pg, PG_U) -#define pmap_phys_address(ppn) ptoa(ppn) -#define pmap_valid_entry(E) ((E) & PG_V) /* is PDE or PTE valid? */ +#define pmap_clear_modify(pg) pmap_change_attrs(pg, 0, PG_M) +#define pmap_clear_reference(pg) pmap_change_attrs(pg, 0, PG_U) +#define pmap_copy(DP,SP,D,L,S) +#define pmap_is_modified(pg) pmap_test_attrs(pg, PG_M) +#define pmap_is_referenced(pg) pmap_test_attrs(pg, PG_U) +#define pmap_phys_address(ppn) ptoa(ppn) +#define pmap_valid_entry(E) ((E) & PG_V) /* is PDE or PTE valid? */ + +#define pmap_proc_iflush(p,va,len) /* nothing */ +#define pmap_unuse_final(p) /* nothing */ -#define pmap_proc_iflush(p,va,len) /* nothing */ -#define pmap_unuse_final(p) /* 4anaEB u nycToTa */ /* * Prototypes */ + void pmap_bootstrap(vaddr_t); -void pmap_bootstrap_pae(void); -void pmap_virtual_space(vaddr_t *, vaddr_t *); -void pmap_init(void); -struct pmap * pmap_create(void); -void pmap_destroy(struct pmap *); -void pmap_reference(struct pmap *); -void pmap_fork(struct pmap *, struct pmap *); -void pmap_collect(struct pmap *); -void pmap_activate(struct proc *); -void pmap_deactivate(struct proc *); -void pmap_kenter_pa(vaddr_t, paddr_t, vm_prot_t); -void pmap_kremove(vaddr_t, vsize_t); -void pmap_zero_page(struct vm_page *); -void pmap_copy_page(struct vm_page *, struct vm_page *); - -struct pv_entry*pmap_alloc_pv(struct pmap *, int); -void pmap_enter_pv(struct pv_head *, struct pv_entry *, - struct pmap *, vaddr_t, struct vm_page *); -void pmap_free_pv(struct pmap *, struct pv_entry *); -void pmap_free_pvs(struct pmap *, struct pv_entry *); -void pmap_free_pv_doit(struct pv_entry *); -void pmap_free_pvpage(void); +boolean_t pmap_change_attrs(struct vm_page *, int, int); static void pmap_page_protect(struct vm_page *, vm_prot_t); -static void pmap_protect(struct pmap *, vaddr_t, vaddr_t, vm_prot_t); +void pmap_page_remove(struct vm_page *); +static void pmap_protect(struct pmap *, vaddr_t, + vaddr_t, vm_prot_t); +void pmap_remove(struct pmap *, vaddr_t, vaddr_t); +boolean_t pmap_test_attrs(struct vm_page *, int); static void pmap_update_pg(vaddr_t); -static void pmap_update_2pg(vaddr_t, vaddr_t); +static void pmap_update_2pg(vaddr_t,vaddr_t); +void pmap_write_protect(struct pmap *, vaddr_t, + vaddr_t, vm_prot_t); int pmap_exec_fixup(struct vm_map *, struct trapframe *, struct pcb *); -void pmap_exec_account(struct pmap *, vaddr_t, u_int32_t, - u_int32_t); vaddr_t reserve_dumppages(vaddr_t); /* XXX: not a pmap fn */ -paddr_t vtophys(vaddr_t va); -void pmap_tlb_shootdown(pmap_t, vaddr_t, u_int32_t, int32_t *); +void pmap_tlb_shootdown(pmap_t, vaddr_t, pt_entry_t, int32_t *); void pmap_tlb_shootnow(int32_t); void pmap_do_tlb_shootdown(struct cpu_info *); -boolean_t pmap_is_curpmap(struct pmap *); -boolean_t pmap_is_active(struct pmap *, int); -void pmap_apte_flush(struct pmap *); -struct pv_entry *pmap_remove_pv(struct pv_head *, struct pmap *, vaddr_t); - -#ifdef SMALL_KERNEL -#define pmap_pte_set_86 pmap_pte_set -#define pmap_pte_setbits_86 pmap_pte_setbits -#define pmap_pte_bits_86 pmap_pte_bits -#define pmap_pte_paddr_86 pmap_pte_paddr -#define pmap_change_attrs_86 pmap_change_attrs -#define pmap_enter_86 pmap_enter -#define pmap_extract_86 pmap_extract -#define pmap_growkernel_86 pmap_growkernel -#define pmap_page_remove_86 pmap_page_remove -#define pmap_remove_86 pmap_remove -#define pmap_test_attrs_86 pmap_test_attrs -#define pmap_unwire_86 pmap_unwire -#define pmap_write_protect_86 pmap_write_protect -#define pmap_pinit_pd_86 pmap_pinit_pd -#define pmap_zero_phys_86 pmap_zero_phys -#define pmap_zero_page_uncached_86 pmap_zero_page_uncached -#define pmap_copy_page_86 pmap_copy_page -#define pmap_try_steal_pv_86 pmap_try_steal_pv -#else -extern u_int32_t (*pmap_pte_set_p)(vaddr_t, paddr_t, u_int32_t); -extern u_int32_t (*pmap_pte_setbits_p)(vaddr_t, u_int32_t, u_int32_t); -extern u_int32_t (*pmap_pte_bits_p)(vaddr_t); -extern paddr_t (*pmap_pte_paddr_p)(vaddr_t); -extern boolean_t (*pmap_change_attrs_p)(struct vm_page *, int, int); -extern int (*pmap_enter_p)(pmap_t, vaddr_t, paddr_t, vm_prot_t, int); -extern boolean_t (*pmap_extract_p)(pmap_t, vaddr_t, paddr_t *); -extern vaddr_t (*pmap_growkernel_p)(vaddr_t); -extern void (*pmap_page_remove_p)(struct vm_page *); -extern void (*pmap_remove_p)(struct pmap *, vaddr_t, vaddr_t); -extern boolean_t (*pmap_test_attrs_p)(struct vm_page *, int); -extern void (*pmap_unwire_p)(struct pmap *, vaddr_t); -extern void (*pmap_write_protect_p)(struct pmap*, vaddr_t, vaddr_t, vm_prot_t); -extern void (*pmap_pinit_pd_p)(pmap_t); -extern void (*pmap_zero_phys_p)(paddr_t); -extern boolean_t (*pmap_zero_page_uncached_p)(paddr_t); -extern void (*pmap_copy_page_p)(struct vm_page *, struct vm_page *); -extern boolean_t (*pmap_try_steal_pv_p)(struct pv_head *pvh, - struct pv_entry *cpv, struct pv_entry *prevpv); - -u_int32_t pmap_pte_set_pae(vaddr_t, paddr_t, u_int32_t); -u_int32_t pmap_pte_setbits_pae(vaddr_t, u_int32_t, u_int32_t); -u_int32_t pmap_pte_bits_pae(vaddr_t); -paddr_t pmap_pte_paddr_pae(vaddr_t); -boolean_t pmap_try_steal_pv_pae(struct pv_head *pvh, struct pv_entry *cpv, - struct pv_entry *prevpv); -boolean_t pmap_change_attrs_pae(struct vm_page *, int, int); -int pmap_enter_pae(pmap_t, vaddr_t, paddr_t, vm_prot_t, int); -boolean_t pmap_extract_pae(pmap_t, vaddr_t, paddr_t *); -vaddr_t pmap_growkernel_pae(vaddr_t); -void pmap_page_remove_pae(struct vm_page *); -void pmap_remove_pae(struct pmap *, vaddr_t, vaddr_t); -boolean_t pmap_test_attrs_pae(struct vm_page *, int); -void pmap_unwire_pae(struct pmap *, vaddr_t); -void pmap_write_protect_pae(struct pmap *, vaddr_t, vaddr_t, vm_prot_t); -void pmap_pinit_pd_pae(pmap_t); -void pmap_zero_phys_pae(paddr_t); -boolean_t pmap_zero_page_uncached_pae(paddr_t); -void pmap_copy_page_pae(struct vm_page *, struct vm_page *); - -#define pmap_pte_set (*pmap_pte_set_p) -#define pmap_pte_setbits (*pmap_pte_setbits_p) -#define pmap_pte_bits (*pmap_pte_bits_p) -#define pmap_pte_paddr (*pmap_pte_paddr_p) -#define pmap_change_attrs (*pmap_change_attrs_p) -#define pmap_enter (*pmap_enter_p) -#define pmap_extract (*pmap_extract_p) -#define pmap_growkernel (*pmap_growkernel_p) -#define pmap_page_remove (*pmap_page_remove_p) -#define pmap_remove (*pmap_remove_p) -#define pmap_test_attrs (*pmap_test_attrs_p) -#define pmap_unwire (*pmap_unwire_p) -#define pmap_write_protect (*pmap_write_protect_p) -#define pmap_pinit_pd (*pmap_pinit_pd_p) -#define pmap_zero_phys (*pmap_zero_phys_p) -#define pmap_zero_page_uncached (*pmap_zero_page_uncached_p) -#define pmap_copy_page (*pmap_copy_page_p) -#define pmap_try_steal_pv (*pmap_try_steal_pv_p) -#endif - -u_int32_t pmap_pte_set_86(vaddr_t, paddr_t, u_int32_t); -u_int32_t pmap_pte_setbits_86(vaddr_t, u_int32_t, u_int32_t); -u_int32_t pmap_pte_bits_86(vaddr_t); -paddr_t pmap_pte_paddr_86(vaddr_t); -boolean_t pmap_try_steal_pv_86(struct pv_head *pvh, struct pv_entry *cpv, - struct pv_entry *prevpv); -boolean_t pmap_change_attrs_86(struct vm_page *, int, int); -int pmap_enter_86(pmap_t, vaddr_t, paddr_t, vm_prot_t, int); -boolean_t pmap_extract_86(pmap_t, vaddr_t, paddr_t *); -vaddr_t pmap_growkernel_86(vaddr_t); -void pmap_page_remove_86(struct vm_page *); -void pmap_remove_86(struct pmap *, vaddr_t, vaddr_t); -boolean_t pmap_test_attrs_86(struct vm_page *, int); -void pmap_unwire_86(struct pmap *, vaddr_t); -void pmap_write_protect_86(struct pmap *, vaddr_t, vaddr_t, vm_prot_t); -void pmap_pinit_pd_86(pmap_t); -void pmap_zero_phys_86(paddr_t); -boolean_t pmap_zero_page_uncached_86(paddr_t); -void pmap_copy_page_86(struct vm_page *, struct vm_page *); #define PMAP_GROWKERNEL /* turn on pmap_growkernel interface */ /* * Do idle page zero'ing uncached to avoid polluting the cache. */ +boolean_t pmap_zero_page_uncached(paddr_t); #define PMAP_PAGEIDLEZERO(pg) pmap_zero_page_uncached(VM_PAGE_TO_PHYS(pg)) /* diff --git a/sys/arch/i386/include/pte.h b/sys/arch/i386/include/pte.h index 73a3bc3e7b0..a3b3542824d 100644 --- a/sys/arch/i386/include/pte.h +++ b/sys/arch/i386/include/pte.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pte.h,v 1.8 2006/04/27 15:37:53 mickey Exp $ */ +/* $OpenBSD: pte.h,v 1.9 2007/02/20 21:15:01 tom Exp $ */ /* $NetBSD: pte.h,v 1.11 1998/02/06 21:58:05 thorpej Exp $ */ /* @@ -45,11 +45,114 @@ #define _I386_PTE_H_ /* + * i386 MMU hardware structure: + * + * the i386 MMU is a two-level MMU which maps 4GB of virtual memory. + * the pagesize is 4K (4096 [0x1000] bytes), although newer pentium + * processors can support a 4MB pagesize as well. + * + * the first level table (segment table?) is called a "page directory" + * and it contains 1024 page directory entries (PDEs). each PDE is + * 4 bytes (an int), so a PD fits in a single 4K page. this page is + * the page directory page (PDP). each PDE in a PDP maps 4MB of space + * (1024 * 4MB = 4GB). a PDE contains the physical address of the + * second level table: the page table. or, if 4MB pages are being used, + * then the PDE contains the PA of the 4MB page being mapped. + * + * a page table consists of 1024 page table entries (PTEs). each PTE is + * 4 bytes (an int), so a page table also fits in a single 4K page. a + * 4K page being used as a page table is called a page table page (PTP). + * each PTE in a PTP maps one 4K page (1024 * 4K = 4MB). a PTE contains + * the physical address of the page it maps and some flag bits (described + * below). + * + * the processor has a special register, "cr3", which points to the + * the PDP which is currently controlling the mappings of the virtual + * address space. + * + * the following picture shows the translation process for a 4K page: + * + * %cr3 register [PA of PDP] + * | + * | + * | bits <31-22> of VA bits <21-12> of VA bits <11-0> + * | index the PDP (0 - 1023) index the PTP are the page offset + * | | | | + * | v | | + * +--->+----------+ | | + * | PD Page | PA of v | + * | |---PTP-------->+------------+ | + * | 1024 PDE | | page table |--PTE--+ | + * | entries | | (aka PTP) | | | + * +----------+ | 1024 PTE | | | + * | entries | | | + * +------------+ | | + * | | + * bits <31-12> bits <11-0> + * p h y s i c a l a d d r + * + * the i386 caches PTEs in a TLB. it is important to flush out old + * TLB mappings when making a change to a mappings. writing to the + * %cr3 will flush the entire TLB. newer processors also have an + * instruction that will invalidate the mapping of a single page (which + * is useful if you are changing a single mappings because it preserves + * all the cached TLB entries). + * + * as shows, bits 31-12 of the PTE contain PA of the page being mapped. + * the rest of the PTE is defined as follows: + * bit# name use + * 11 n/a available for OS use, hardware ignores it + * 10 n/a available for OS use, hardware ignores it + * 9 n/a available for OS use, hardware ignores it + * 8 G global bit (see discussion below) + * 7 PS page size [for PDEs] (0=4k, 1=4M <if supported>) + * 6 D dirty (modified) page + * 5 A accessed (referenced) page + * 4 PCD cache disable + * 3 PWT prevent write through (cache) + * 2 U/S user/supervisor bit (0=supervisor only, 1=both u&s) + * 1 R/W read/write bit (0=read only, 1=read-write) + * 0 P present (valid) + * + * notes: + * - on the i386 the R/W bit is ignored if processor is in supervisor + * state (bug!) + * - PS is only supported on newer processors + * - PTEs with the G bit are global in the sense that they are not + * flushed from the TLB when %cr3 is written (to flush, use the + * "flush single page" instruction). this is only supported on + * newer processors. this bit can be used to keep the kernel's + * TLB entries around while context switching. since the kernel + * is mapped into all processes at the same place it does not make + * sense to flush these entries when switching from one process' + * pmap to another. + */ + +#if !defined(_LOCORE) + +/* + * here we define the data types for PDEs and PTEs + */ + +typedef u_int32_t pd_entry_t; /* PDE */ +typedef u_int32_t pt_entry_t; /* PTE */ + +#endif + +/* * now we define various for playing with virtual addresses */ #define PDSHIFT 22 /* offset of PD index in VA */ #define NBPD (1 << PDSHIFT) /* # bytes mapped by PD (4MB) */ +#define PDOFSET (NBPD-1) /* mask for non-PD part of VA */ +#if 0 /* not used? */ +#define NPTEPD (NBPD / NBPG) /* # of PTEs in a PD */ +#else +#define PTES_PER_PTP (NBPD / NBPG) /* # of PTEs in a PTP */ +#endif +#define PD_MASK 0xffc00000 /* page directory address bits */ +#define PT_MASK 0x003ff000 /* page table address bits */ /* * here we define the bits of the PDE/PTE, as described above: @@ -70,6 +173,8 @@ #define PG_AVAIL1 0x00000200 /* ignored by hardware */ #define PG_AVAIL2 0x00000400 /* ignored by hardware */ #define PG_AVAIL3 0x00000800 /* ignored by hardware */ +#define PG_FRAME 0xfffff000 /* page frame mask */ +#define PG_LGFRAME 0xffc00000 /* large (4M) page frame mask */ /* * various short-hand protection codes diff --git a/sys/arch/i386/include/vmparam.h b/sys/arch/i386/include/vmparam.h index 6174c378725..8d7dd4e1cf6 100644 --- a/sys/arch/i386/include/vmparam.h +++ b/sys/arch/i386/include/vmparam.h @@ -1,4 +1,4 @@ -/* $OpenBSD: vmparam.h,v 1.35 2006/04/27 15:37:53 mickey Exp $ */ +/* $OpenBSD: vmparam.h,v 1.36 2007/02/20 21:15:01 tom Exp $ */ /* $NetBSD: vmparam.h,v 1.15 1994/10/27 04:16:34 cgd Exp $ */ /*- @@ -91,23 +91,22 @@ /* user/kernel map constants */ #define VM_MIN_ADDRESS ((vaddr_t)0) -#define VM_MAXUSER_ADDRESS ((vaddr_t)0xcf800000) -#define VM_MAX_ADDRESS (vm_max_address) -extern vaddr_t vm_max_address; +#define VM_MAXUSER_ADDRESS ((vaddr_t)((PDSLOT_PTE<<PDSHIFT) - USPACE)) +#define VM_MAX_ADDRESS ((vaddr_t)((PDSLOT_PTE<<PDSHIFT) + \ + (PDSLOT_PTE<<PGSHIFT))) #define VM_MIN_KERNEL_ADDRESS ((vaddr_t)KERNBASE) -#define VM_MAX_KERNEL_ADDRESS ((vaddr_t)0xff800000) +#define VM_MAX_KERNEL_ADDRESS ((vaddr_t)(PDSLOT_APTE<<PDSHIFT)) /* virtual sizes (bytes) for various kernel submaps */ #define VM_PHYS_SIZE (USRIOSIZE*PAGE_SIZE) -#define VM_PHYSSEG_MAX 8 /* actually we could have this many segments */ +#define VM_PHYSSEG_MAX 5 /* actually we could have this many segments */ #define VM_PHYSSEG_STRAT VM_PSTRAT_BSEARCH #define VM_PHYSSEG_NOADD /* can't add RAM after vm_mem_init */ -#define VM_NFREELIST 3 +#define VM_NFREELIST 2 #define VM_FREELIST_DEFAULT 0 #define VM_FREELIST_FIRST16 1 -#define VM_FREELIST_ABOVE4G 2 /* * pmap specific data stored in the vm_physmem[] array diff --git a/sys/arch/i386/pci/pci_addr_fixup.c b/sys/arch/i386/pci/pci_addr_fixup.c index 6f12fe5618a..294454e7a1a 100644 --- a/sys/arch/i386/pci/pci_addr_fixup.c +++ b/sys/arch/i386/pci/pci_addr_fixup.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pci_addr_fixup.c,v 1.20 2006/09/19 11:06:34 jsg Exp $ */ +/* $OpenBSD: pci_addr_fixup.c,v 1.21 2007/02/20 21:15:01 tom Exp $ */ /* $NetBSD: pci_addr_fixup.c,v 1.7 2000/08/03 20:10:45 nathanw Exp $ */ /*- @@ -45,22 +45,24 @@ #include <i386/pci/pcibiosvar.h> typedef int (*pciaddr_resource_manage_func_t)(struct pcibios_softc *, pci_chipset_tag_t, pcitag_t, int, - struct extent *, int, u_long *, bus_size_t); + struct extent *, int, bus_addr_t *, bus_size_t); void pciaddr_resource_manage(struct pcibios_softc *, pci_chipset_tag_t, pcitag_t, pciaddr_resource_manage_func_t); void pciaddr_resource_reserve(struct pcibios_softc *, pci_chipset_tag_t, pcitag_t); void pciaddr_resource_reserve_disabled(struct pcibios_softc *, pci_chipset_tag_t, pcitag_t); -int pciaddr_do_resource_reserve(struct pcibios_softc *, pci_chipset_tag_t, - pcitag_t, int, struct extent *, int, u_long *, bus_size_t); +int pciaddr_do_resource_reserve(struct pcibios_softc *, + pci_chipset_tag_t, pcitag_t, int, struct extent *, int, + bus_addr_t *, bus_size_t); int pciaddr_do_resource_reserve_disabled(struct pcibios_softc *, pci_chipset_tag_t, pcitag_t, int, struct extent *, int, u_long *, bus_size_t); void pciaddr_resource_allocate(struct pcibios_softc *, pci_chipset_tag_t, pcitag_t); -int pciaddr_do_resource_allocate(struct pcibios_softc *, pci_chipset_tag_t, - pcitag_t, int, struct extent *, int, u_long *, bus_size_t); +int pciaddr_do_resource_allocate(struct pcibios_softc *, + pci_chipset_tag_t, pcitag_t, int, struct extent *, int, bus_addr_t *, + bus_size_t); bus_addr_t pciaddr_ioaddr(u_int32_t); void pciaddr_print_devid(pci_chipset_tag_t, pcitag_t); @@ -181,7 +183,7 @@ pciaddr_resource_manage(struct pcibios_softc *sc, pci_chipset_tag_t pc, { struct extent *ex; pcireg_t val, mask; - u_long addr; + bus_addr_t addr; bus_size_t size; int error, mapreg, type, reg_start, reg_end, width; @@ -260,7 +262,7 @@ pciaddr_resource_manage(struct pcibios_softc *sc, pci_chipset_tag_t pc, int pciaddr_do_resource_allocate(struct pcibios_softc *sc, pci_chipset_tag_t pc, - pcitag_t tag, int mapreg, struct extent *ex, int type, u_long *addr, + pcitag_t tag, int mapreg, struct extent *ex, int type, bus_addr_t *addr, bus_size_t size) { bus_addr_t start; @@ -306,7 +308,7 @@ pciaddr_do_resource_allocate(struct pcibios_softc *sc, pci_chipset_tag_t pc, int pciaddr_do_resource_reserve(struct pcibios_softc *sc, pci_chipset_tag_t pc, - pcitag_t tag, int mapreg, struct extent *ex, int type, u_long *addr, + pcitag_t tag, int mapreg, struct extent *ex, int type, bus_addr_t *addr, bus_size_t size) { pcireg_t val; diff --git a/sys/arch/i386/pci/pci_machdep.c b/sys/arch/i386/pci/pci_machdep.c index 397f3661a41..6353b135729 100644 --- a/sys/arch/i386/pci/pci_machdep.c +++ b/sys/arch/i386/pci/pci_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pci_machdep.c,v 1.37 2006/12/20 18:59:50 kettenis Exp $ */ +/* $OpenBSD: pci_machdep.c,v 1.38 2007/02/20 21:15:01 tom Exp $ */ /* $NetBSD: pci_machdep.c,v 1.28 1997/06/06 23:29:17 thorpej Exp $ */ /*- @@ -113,7 +113,9 @@ extern bios_pciinfo_t *bios_pciinfo; #endif #include "pcibios.h" +#if NPCIBIOS > 0 #include <i386/pci/pcibiosvar.h> +#endif int pci_mode = -1; diff --git a/sys/arch/i386/pci/pcibios.c b/sys/arch/i386/pci/pcibios.c index d58c361e319..44f11ec98a5 100644 --- a/sys/arch/i386/pci/pcibios.c +++ b/sys/arch/i386/pci/pcibios.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pcibios.c,v 1.35 2006/11/29 22:40:13 miod Exp $ */ +/* $OpenBSD: pcibios.c,v 1.36 2007/02/20 21:15:01 tom Exp $ */ /* $NetBSD: pcibios.c,v 1.5 2000/08/01 05:23:59 uch Exp $ */ /* @@ -266,7 +266,7 @@ pcibios_pir_init(struct pcibios_softc *sc) for (i = 0; i < pirh->tablesize; i++) cksum += p[i]; - printf("%s: PCI IRQ Routing Table rev %d.%d @ 0x%llx/%d " + printf("%s: PCI IRQ Routing Table rev %d.%d @ 0x%lx/%d " "(%d entries)\n", sc->sc_dev.dv_xname, pirh->version >> 8, pirh->version & 0xff, pa, pirh->tablesize, (pirh->tablesize - sizeof(*pirh)) / 16); |