? arch/i386/conf/GENERIC_PAE Index: arch/i386/i386/locore.S =================================================================== RCS file: /cvsroot/src/sys/arch/i386/i386/locore.S,v retrieving revision 1.78.4.3 diff -u -p -r1.78.4.3 locore.S --- arch/i386/i386/locore.S 4 Apr 2009 17:39:09 -0000 1.78.4.3 +++ arch/i386/i386/locore.S 14 Dec 2009 01:14:53 -0000 @@ -209,7 +209,11 @@ __KERNEL_RCSID(0, "$NetBSD: locore.S,v 1 .globl _C_LABEL(esym) .globl _C_LABEL(eblob) .globl _C_LABEL(atdevbase) - .globl _C_LABEL(proc0uarea),_C_LABEL(PDPpaddr) + .globl _C_LABEL(proc0uarea), +#ifdef PAE + .globl _C_LABEL(PDPtable) +#endif + .globl _C_LABEL(PDPpaddr) .globl _C_LABEL(gdt) .globl _C_LABEL(idt) .globl _C_LABEL(lapic_tpr) @@ -241,6 +245,14 @@ _C_LABEL(cpu): .long 0 # are we 80486, _C_LABEL(cpuid_level): .long 0 _C_LABEL(atdevbase): .long 0 # location of start of iomem in virtual _C_LABEL(proc0uarea): .long 0 +#ifdef PAE + .align 32 +_C_LABEL(PDPtable): # PAE page directory pointer scratchpad + .long 0; .long 0 + .long 0; .long 0 + .long 0; .long 0 + .long 0; .long 0 +#endif _C_LABEL(PDPpaddr): .long 0 # paddr of PDP, for libkvm _C_LABEL(tablesize): .long 0 @@ -497,7 +509,11 @@ try586: /* Use the `cpuid' instruction. */ #define PROC0_PDIR_OFF 0 +#ifdef PAE +#define PROC0_STK_OFF (PROC0_PDIR_OFF + (PAGE_SIZE * 4)) +#else #define PROC0_STK_OFF (PROC0_PDIR_OFF + PAGE_SIZE) +#endif #define PROC0_PTP1_OFF (PROC0_STK_OFF + UPAGES * PAGE_SIZE) /* @@ -507,12 +523,20 @@ try586: /* Use the `cpuid' instruction. * ecx = number of pages to map */ +#ifdef PAE +#define fillkpt \ +1: movl %eax,(%ebx) ; /* store phys addr */ \ + movl $0,4(%ebx) ; /* store upper phys addr */ \ + addl $8,%ebx ; /* next pte/pde */ \ + addl $PAGE_SIZE,%eax ; /* next phys page */ \ + loop 1b ; +#else #define fillkpt \ 1: movl %eax,(%ebx) ; /* store phys addr */ \ addl $4,%ebx ; /* next pte/pde */ \ addl $PAGE_SIZE,%eax ; /* next phys page */ \ - loop 1b ; \ - + loop 1b ; +#endif /* Find end of kernel image. */ movl $RELOC(end),%edi @@ -546,9 +570,14 @@ try586: /* Use the `cpuid' instruction. incl %eax /* one more ptp for VAs stolen by bootstrap */ 1: movl %eax,RELOC(nkptp)+1*4 - /* tablesize = (1 + UPAGES + nkptp) << PGSHIFT; */ + /* tablesize = (PDpages + UPAGES + nkptp) << PGSHIFT; */ +#ifdef PAE + addl $(4+UPAGES),%eax + shll $(PGSHIFT+1),%eax /* table is 2x larger in PAE mode */ +#else addl $(1+UPAGES),%eax shll $PGSHIFT,%eax +#endif movl %eax,RELOC(tablesize) /* ensure that nkptp covers bootstrap tables */ @@ -586,7 +615,11 @@ try586: /* Use the `cpuid' instruction. */ movl $_RELOC(KERNTEXTOFF),%eax movl %eax,%ecx +#ifndef PAE shrl $(PGSHIFT-2),%ecx /* ((n >> PGSHIFT) << 2) for # pdes */ +#else + shrl $(PGSHIFT-3),%ecx /* ptes are twice as large with PAE */ +#endif addl %ecx,%ebx /* Map the kernel text read-only. */ @@ -620,29 +653,70 @@ try586: /* Use the `cpuid' instruction. fillkpt /* Set up top level entries for actual kernel mapping */ - leal (PROC0_PDIR_OFF + L2_SLOT_KERNBASE*4)(%esi),%ebx +#ifdef PAE + leal (PROC0_PDIR_OFF + (L2_SLOT_KERNBASE*8))(%esi),%ebx +#else + leal (PROC0_PDIR_OFF + (L2_SLOT_KERNBASE*4))(%esi),%ebx +#endif leal (PROC0_PTP1_OFF)(%esi),%eax orl $(PG_V|PG_KW), %eax movl RELOC(nkptp)+1*4,%ecx fillkpt /* Install a PDE recursively mapping page directory as a page table! */ +#ifdef PAE + leal (PROC0_PDIR_OFF + PDIR_SLOT_PTE*8)(%esi),%ebx + leal (PROC0_PDIR_OFF)(%esi),%eax + orl $(PG_V|PG_KW),%eax + movl $4,%ecx + fillkpt +#else leal (PROC0_PDIR_OFF + PDIR_SLOT_PTE*4)(%esi),%ebx leal (PROC0_PDIR_OFF)(%esi),%eax orl $(PG_V|PG_KW),%eax movl %eax,(%ebx) +#endif +#ifdef PAE + /* + * In PAE mode, we need a 4 entries for the PDPTable pointing at + * the PDs we just created. For simplicity, these live in the kernel + * data segment + */ + leal RELOC(PDPtable),%ebx + movl %ebx,RELOC(PDPpaddr) + leal (PROC0_PDIR_OFF)(%esi),%eax + orl $(PG_V),%eax + movl $4,%ecx + fillkpt + + leal (PROC0_PDIR_OFF)(%esi),%eax + addl (3*PAGE_SIZE),%eax + addl $KERNBASE,%eax + movl %eax,RELOC(pmap_kl2pd) /* kernel l2 page directory */ + /* XXX - is this needed, or */ + /* is it a XENism? */ +#else /* Save phys. addr of PDP, for libkvm. */ movl %esi,RELOC(PDPpaddr) +#endif /* * Startup checklist: * 1. Load %cr3 with pointer to PDIR. */ +#ifdef PAE + leal RELOC(PDPtable),%eax + movl %eax,%cr3 /* Load PDPTR */ + movl %cr4,%eax + or $CR4_PAE,%eax + movl %eax,%cr4 /* Enable PAE mode */ +#else movl %esi,%eax # phys address of ptd in proc 0 movl %eax,%cr3 # load ptd addr into mmu - +#endif + /* * 2. Enable paging and the rest of it. */ @@ -696,9 +770,15 @@ begin: movl _C_LABEL(tablesize),%eax addl %esi,%eax # skip past stack and page tables +#ifdef PAE + pushl $0 /* paddr_t is 64 bits with PAE */ +#endif pushl %eax call _C_LABEL(init386) # wire 386 chip for unix operation addl $4+NGDT*8,%esp # pop temporary gdt +#ifdef PAE + addl $4,%esp +#endif #ifdef SAFARI_FIFO_HACK movb $5,%al Index: arch/i386/i386/machdep.c =================================================================== RCS file: /cvsroot/src/sys/arch/i386/i386/machdep.c,v retrieving revision 1.644.4.11 diff -u -p -r1.644.4.11 machdep.c --- arch/i386/i386/machdep.c 3 Oct 2009 23:49:50 -0000 1.644.4.11 +++ arch/i386/i386/machdep.c 14 Dec 2009 01:14:53 -0000 @@ -330,7 +331,7 @@ int biosmem_implicit; * boot loader. Only be used by native_loader(). */ struct bootinfo_source { uint32_t bs_naddrs; - paddr_t bs_addrs[1]; /* Actually longer. */ + void *bs_addrs[1]; /* Actually longer. */ }; /* Only called by locore.h; no need to be in a header file. */ @@ -396,8 +397,8 @@ native_loader(int bl_boothowto, int bl_b bc = (struct btinfo_common *)(bl_bootinfo->bs_addrs[i]); - if ((paddr_t)(data + bc->len) > - (paddr_t)(&bidest->bi_data[0] + BOOTINFO_MAXSIZE)) + if (((vaddr_t)data + bc->len) > + (vaddr_t)(&bidest->bi_data[0] + BOOTINFO_MAXSIZE)) break; memcpy(data, bc, bc->len); @@ -487,7 +488,7 @@ cpu_startup() wrmsr(MSR_DEBUGCTLMSR, 0x1); #endif - format_bytes(pbuf, sizeof(pbuf), ptoa(physmem)); + format_bytes(pbuf, sizeof(pbuf), ptoa((uint64_t)physmem)); printf("total memory = %s\n", pbuf); #if NCARDBUS > 0 @@ -509,7 +510,7 @@ cpu_startup() mb_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr, nmbclusters * mclbytes, VM_MAP_INTRSAFE, false, NULL); - format_bytes(pbuf, sizeof(pbuf), ptoa(uvmexp.free)); + format_bytes(pbuf, sizeof(pbuf), ptoa((uint64_t)uvmexp.free)); printf("avail memory = %s\n", pbuf); /* Safe for i/o port / memory space allocation to use malloc now. */ @@ -1159,6 +1160,7 @@ add_mem_cluster(uint64_t seg_start, uint uint64_t new_physmem; int i; +#ifndef PAE if (seg_end > 0x100000000ULL) { printf("WARNING: skipping large " "memory map entry: " @@ -1175,6 +1177,7 @@ add_mem_cluster(uint64_t seg_start, uint */ if (seg_end == 0x100000000ULL) seg_end -= PAGE_SIZE; +#endif if (seg_end <= seg_start) return; @@ -1196,8 +1199,19 @@ add_mem_cluster(uint64_t seg_start, uint * the addresses are page rounded just to make * sure we get them all. */ +#ifdef PAE + if (seg_start > 0xFFFFFFFF && seg_end > 0xFFFFFFFF) { + /* In PAE mode we want to report this segment, but we can't + * allocate it from the iomem extent, seeing how iomem is only + * as large as a u_long, only covering the lower 4Gb of the + * physical address space. In this case it doesn't (shouldn't) + * matter, we don't need to reserve this because its impossible + * to allocate it from iomem anyway */ + ; + } else +#endif if (extent_alloc_region(iomem_ex, seg_start, - seg_end - seg_start, EX_NOWAIT)) { + seg_end - seg_start, EX_NOWAIT)) { /* XXX What should we do? */ printf("WARNING: CAN'T ALLOCATE " "MEMORY SEGMENT " @@ -1320,7 +1334,9 @@ init386_msgbuf(void) vps = NULL; for (x = 0; x < vm_nphysseg; ++x) { vps = &vm_physmem[x]; - if (ptoa(vps->avail_end) == avail_end) { + /* shifting vps->avail_end can drop higher bits, instead + * shift avail_end down */ + if (vps->avail_end == atop(avail_end)) { break; } } @@ -1512,6 +1534,9 @@ init386(paddr_t first_avail) * Page 3: ACPI wakeup code * Page 4: Temporary page table for 0MB-4MB * Page 5: Temporary page directory + * + * PAE: Only the lower 2MB is mapped. Additionally, the end 4 entries + * of the temporary page directory are re-used as the PTP table */ avail_start = 6 * PAGE_SIZE; #else /* !XEN */ @@ -1984,7 +2008,7 @@ init386(paddr_t first_avail) "have %lu bytes, want %lu bytes\n" "running in degraded mode\n" "press a key to confirm\n\n", - ptoa(physmem), 2*1024*1024UL); + (vaddr_t)ptoa(physmem), 2*1024*1024UL); cngetc(); } } Index: arch/i386/i386/mptramp.S =================================================================== RCS file: /cvsroot/src/sys/arch/i386/i386/mptramp.S,v retrieving revision 1.18 diff -u -p -r1.18 mptramp.S --- arch/i386/i386/mptramp.S 26 Aug 2008 13:07:48 -0000 1.18 +++ arch/i386/i386/mptramp.S 14 Dec 2009 01:14:53 -0000 @@ -160,6 +160,12 @@ _TRMP_LABEL(mp_startup) movl %eax,%cr4 1: +#ifdef PAE + movl %cr4,%eax + orl $CR4_PAE,%eax + movl %eax,%cr4 +#endif + movl RELOC(mp_pdirpa),%ecx HALTT(0x5,%ecx) Index: arch/i386/i386/multiboot.c =================================================================== RCS file: /cvsroot/src/sys/arch/i386/i386/multiboot.c,v retrieving revision 1.17 diff -u -p -r1.17 multiboot.c --- arch/i386/i386/multiboot.c 11 Oct 2008 11:06:19 -0000 1.17 +++ arch/i386/i386/multiboot.c 14 Dec 2009 01:14:54 -0000 @@ -279,8 +279,8 @@ copy_syms(struct multiboot_info *mi) Elf32_Shdr *symtabp, *strtabp; struct multiboot_symbols *ms; size_t symsize, strsize; - paddr_t symaddr, straddr; - paddr_t symstart, strstart; + vaddr_t symaddr, straddr; + vaddr_t symstart, strstart; /* @@ -336,27 +336,27 @@ copy_syms(struct multiboot_info *mi) * that if the tables start before the kernel's end address, * they will not grow over this address. */ - if ((paddr_t)symtabp < (paddr_t)&end - KERNBASE && - (paddr_t)strtabp < (paddr_t)&end - KERNBASE) { + if ((vaddr_t)symtabp < (vaddr_t)&end - KERNBASE && + (vaddr_t)strtabp < (vaddr_t)&end - KERNBASE) { symstart = (paddr_t)((vaddr_t)&end - KERNBASE); strstart = symstart + symsize; memcpy((void *)symstart, (void *)symaddr, symsize); memcpy((void *)strstart, (void *)straddr, strsize); - } else if ((paddr_t)symtabp > (paddr_t)&end - KERNBASE && - (paddr_t)strtabp < (paddr_t)&end - KERNBASE) { + } else if ((vaddr_t)symtabp > (vaddr_t)&end - KERNBASE && + (vaddr_t)strtabp < (vaddr_t)&end - KERNBASE) { symstart = (paddr_t)((vaddr_t)&end - KERNBASE); strstart = symstart + symsize; memcpy((void *)symstart, (void *)symaddr, symsize); memcpy((void *)strstart, (void *)straddr, strsize); - } else if ((paddr_t)symtabp < (paddr_t)&end - KERNBASE && - (paddr_t)strtabp > (paddr_t)&end - KERNBASE) { + } else if ((vaddr_t)symtabp < (vaddr_t)&end - KERNBASE && + (vaddr_t)strtabp > (vaddr_t)&end - KERNBASE) { strstart = (paddr_t)((vaddr_t)&end - KERNBASE); symstart = strstart + strsize; memcpy((void *)strstart, (void *)straddr, strsize); memcpy((void *)symstart, (void *)symaddr, symsize); } else { /* symtabp and strtabp are both over end */ - if ((paddr_t)symtabp < (paddr_t)strtabp) { + if ((vaddr_t)symtabp < (vaddr_t)strtabp) { symstart = (paddr_t)((vaddr_t)&end - KERNBASE); strstart = symstart + symsize; memcpy((void *)symstart, (void *)symaddr, symsize); Index: arch/i386/include/pmap.h =================================================================== RCS file: /cvsroot/src/sys/arch/i386/include/pmap.h,v retrieving revision 1.103 diff -u -p -r1.103 pmap.h --- arch/i386/include/pmap.h 26 Oct 2008 06:57:30 -0000 1.103 +++ arch/i386/include/pmap.h 14 Dec 2009 01:14:59 -0000 @@ -220,7 +220,11 @@ #define L2_SLOT_PTE (KERNBASE/NBPD_L2-4) /* 1532: for recursive PDP map */ #define L2_SLOT_KERN (KERNBASE/NBPD_L2) /* 1536: start of kernel space */ #define L2_SLOT_KERNBASE L2_SLOT_KERN +#ifndef XEN +#define L2_SLOT_APTE 2044 /* native APTE */ +#else #define L2_SLOT_APTE 1960 /* 1964-2047 reserved by Xen */ +#endif #else /* PAE */ #define L2_SLOT_PTE (KERNBASE/NBPD_L2-1) /* 767: for recursive PDP map */ #define L2_SLOT_KERN (KERNBASE/NBPD_L2) /* 768: start of kernel space */ @@ -255,17 +259,17 @@ #define AL2_BASE ((pd_entry_t *)((char *)AL1_BASE + L2_SLOT_PTE * NBPD_L1)) #define PDP_PDE (L2_BASE + PDIR_SLOT_PTE) -#ifdef PAE +#if defined(XEN) && defined(PAE) /* - * when PAE is in use we can't write APDP_PDE though the recursive mapping, + * when PAE+XEN is in use we can't write APDP_PDE though the recursive mapping, * because it points to the shadow PD. Use the kernel PD instead, which is * static */ #define APDP_PDE (&pmap_kl2pd[l2tol2(PDIR_SLOT_APTE)]) #define APDP_PDE_SHADOW (L2_BASE + PDIR_SLOT_APTE) -#else /* PAE */ +#else /* XEN && PAE */ #define APDP_PDE (L2_BASE + PDIR_SLOT_APTE) -#endif /* PAE */ +#endif /* XEN && PAE */ #define PDP_BASE L2_BASE #define APDP_BASE AL2_BASE @@ -295,6 +299,11 @@ #define PDES_INITIALIZER { L2_BASE } #define APDES_INITIALIZER { AL2_BASE } +/* + * jmorse - it looks impossible to recursively map the PDPT in PAE mode, so + * instead stick fingers in our ears and pretend the 3rd level does not exist. + * It's constantly mapped to the PDEs, so should never need to be inspected + */ #define PTP_LEVELS 2 /* @@ -321,6 +330,15 @@ #define pmap_pa2pte(a) (a) #define pmap_pte2pa(a) ((a) & PG_FRAME) #define pmap_pte_set(p, n) do { *(p) = (n); } while (0) +#ifdef PAE +#define pmap_pte_cas(p, o, n) atomic_cas_64((p), (o), (n)) +#define pmap_pte_testset(p, n) \ + atomic_swap_64((volatile uint64_t *)p, n) +#define pmap_pte_setbits(p, b) \ + atomic_or_64((volatile uint64_t *)p, b) +#define pmap_pte_clearbits(p, b) \ + atomic_and_64((volatile uint64_t *)p, ~(b)) +#else /*PAE*/ #define pmap_pte_cas(p, o, n) atomic_cas_32((p), (o), (n)) #define pmap_pte_testset(p, n) \ atomic_swap_ulong((volatile unsigned long *)p, n) @@ -328,8 +346,9 @@ atomic_or_ulong((volatile unsigned long *)p, b) #define pmap_pte_clearbits(p, b) \ atomic_and_ulong((volatile unsigned long *)p, ~(b)) +#endif /*PAE*/ #define pmap_pte_flush() /* nothing */ -#else +#else /*XEN*/ static __inline pt_entry_t pmap_pa2pte(paddr_t pa) { @@ -402,7 +421,7 @@ pmap_pte_flush(void) splx(s); } -#endif +#endif /*XEN*/ #ifdef PAE /* addresses of static pages used for PAE pmap: */ Index: arch/i386/pci/elan520.c =================================================================== RCS file: /cvsroot/src/sys/arch/i386/pci/elan520.c,v retrieving revision 1.35 diff -u -p -r1.35 elan520.c --- arch/i386/pci/elan520.c 31 May 2008 22:37:00 -0000 1.35 +++ arch/i386/pci/elan520.c 14 Dec 2009 01:15:00 -0000 @@ -703,8 +703,8 @@ elansc_protect_text(device_t self, struc par = bus_space_read_4(memt, memh, MMCR_PAR(pidx)); aprint_debug_dev(self, - "protect kernel text at physical addresses %p - %p\n", - (void *)region0.start, (void *)region0.end); + "protect kernel text at physical addresses %jx - %jx\n", + (uintmax_t)region0.start, (uintmax_t)region0.end); nregion = region_paddr_to_par(®ion0, regions, sfkb); if (nregion == 0) { @@ -720,8 +720,8 @@ elansc_protect_text(device_t self, struc end_pa = regions[0].end; aprint_debug_dev(self, - "actually protect kernel text at physical addresses %p - %p\n", - (void *)start_pa, (void *)end_pa); + "actually protect kernel text at physical addresses %jx - %jx\n", + (uintmax_t)start_pa, (uintmax_t)end_pa); aprint_verbose_dev(self, "%" PRIu32 " bytes of kernel text are unprotected\n", unprotsize); @@ -744,8 +744,8 @@ elansc_protect_text(device_t self, struc for (i = 1; i < nregion; i++) { xnregion = region_paddr_to_par(®ions[i], xregions, fkb); if (xnregion == 0) { - aprint_verbose_dev(self, "skip region %p - %p\n", - (void *)regions[i].start, (void *)regions[i].end); + aprint_verbose_dev(self, "skip region %jx - %jx\n", + (uintmax_t)regions[i].start, (uintmax_t)regions[i].end); continue; } if ((pidx = elansc_alloc_par(memt, memh)) == -1) { @@ -757,8 +757,8 @@ elansc_protect_text(device_t self, struc sc->sc_textpar[tidx++] = pidx; aprint_debug_dev(self, - "protect add'l kernel text at physical addresses %p - %p\n", - (void *)xregions[0].start, (void *)xregions[0].end); + "protect add'l kernel text at physical addresses %jx - %jx\n", + (uintmax_t)xregions[0].start, (uintmax_t)xregions[0].end); for (j = 1; j < xnregion; j++) unprotsize += xregions[j].end - xregions[j].start; Index: arch/x86/include/pmap.h =================================================================== RCS file: /cvsroot/src/sys/arch/x86/include/pmap.h,v retrieving revision 1.20.4.1 diff -u -p -r1.20.4.1 pmap.h --- arch/x86/include/pmap.h 4 Apr 2009 17:39:09 -0000 1.20.4.1 +++ arch/x86/include/pmap.h 14 Dec 2009 01:18:36 -0000 @@ -148,10 +148,16 @@ struct pmap { LIST_ENTRY(pmap) pm_list; /* list (lck by pm_list lock) */ pd_entry_t *pm_pdir; /* VA of PD (lck by object lock) */ #ifdef PAE +#ifndef XEN + paddr_t *pm_pdirpa; + paddr_t pm_l3dirpa; + struct pglist l3pg; +#else /*XEN*/ paddr_t pm_pdirpa[PDP_SIZE]; -#else +#endif /*XEN*/ +#else /*PAE*/ paddr_t pm_pdirpa; /* PA of PD (read-only after create) */ -#endif +#endif /*PAE*/ struct vm_page *pm_ptphint[PTP_LEVELS-1]; /* pointer to a PTP in our pmap */ struct pmap_statistics pm_stats; /* pmap stats (lck by object lock) */ Index: arch/x86/x86/acpi_machdep.c =================================================================== RCS file: /cvsroot/src/sys/arch/x86/x86/acpi_machdep.c,v retrieving revision 1.22 diff -u -p -r1.22 acpi_machdep.c --- arch/x86/x86/acpi_machdep.c 3 Jul 2008 14:02:25 -0000 1.22 +++ arch/x86/x86/acpi_machdep.c 14 Dec 2009 01:18:38 -0000 @@ -206,7 +206,7 @@ acpi_md_OsUnmapMemory(void *LogicalAddre { (void) _x86_memio_unmap(X86_BUS_SPACE_MEM, - (bus_space_handle_t) LogicalAddress, Length, NULL); + (bus_space_handle_t)(vaddr_t) LogicalAddress, Length, NULL); } ACPI_STATUS Index: arch/x86/x86/bus_dma.c =================================================================== RCS file: /cvsroot/src/sys/arch/x86/x86/bus_dma.c,v retrieving revision 1.45 diff -u -p -r1.45 bus_dma.c --- arch/x86/x86/bus_dma.c 28 Jun 2008 17:23:01 -0000 1.45 +++ arch/x86/x86/bus_dma.c 14 Dec 2009 01:18:38 -0000 @@ -182,7 +182,7 @@ _bus_dmamem_alloc_range(bus_dma_tag_t t, #ifdef DIAGNOSTIC if (curaddr < low || curaddr >= high) { printf("vm_page_alloc_memory returned non-sensical" - " address 0x%lx\n", curaddr); + " address 0x%jx\n", (uintmax_t)curaddr); panic("_bus_dmamem_alloc_range"); } #endif Index: arch/x86/x86/cpu.c =================================================================== RCS file: /cvsroot/src/sys/arch/x86/x86/cpu.c,v retrieving revision 1.57.4.3 diff -u -p -r1.57.4.3 cpu.c --- arch/x86/x86/cpu.c 2 Feb 2009 20:10:16 -0000 1.57.4.3 +++ arch/x86/x86/cpu.c 14 Dec 2009 01:18:38 -0000 @@ -712,8 +710,13 @@ cpu_hatch(void *v) KASSERT((ci->ci_flags & CPUF_RUNNING) == 0); +#ifdef PAE + lcr3(pmap_kernel()->pm_l3dirpa); + curlwp->l_addr->u_pcb.pcb_cr3 = pmap_kernel()->pm_l3dirpa; +#else lcr3(pmap_kernel()->pm_pdirpa); curlwp->l_addr->u_pcb.pcb_cr3 = pmap_kernel()->pm_pdirpa; +#endif lcr0(ci->ci_data.cpu_idlelwp->l_addr->u_pcb.pcb_cr0); cpu_init_idt(); gdt_init_cpu(ci); @@ -809,7 +812,11 @@ tss_init(struct i386tss *tss, void *stac tss->tss_fs = GSEL(GCPU_SEL, SEL_KPL); tss->tss_gs = tss->__tss_es = tss->__tss_ds = tss->__tss_ss = GSEL(GDATA_SEL, SEL_KPL); +#ifdef PAE + tss->tss_cr3 = pmap_kernel()->pm_l3dirpa; +#else tss->tss_cr3 = pmap_kernel()->pm_pdirpa; +#endif tss->tss_esp = (int)((char *)stack + USPACE - 16); tss->tss_ldt = GSEL(GLDT_SEL, SEL_KPL); tss->__tss_eflags = PSL_MBO | PSL_NT; /* XXX not needed? */ Index: arch/x86/x86/pmap.c =================================================================== RCS file: /cvsroot/src/sys/arch/x86/x86/pmap.c,v retrieving revision 1.74.4.1 diff -u -p -r1.74.4.1 pmap.c --- arch/x86/x86/pmap.c 4 Apr 2009 17:39:09 -0000 1.74.4.1 +++ arch/x86/x86/pmap.c 14 Dec 2009 01:18:41 -0000 @@ -517,6 +519,11 @@ static struct pool_cache pmap_cache; static struct pool_cache pmap_pv_cache; +/* On i386 PAE, kernel pmaps l3 PDPs exist elsewhere */ +#if defined(PAE) && !defined(XEN) && defined(i386) +extern paddr_t PDPtable[4]; +#endif + /* * MULTIPROCESSOR: special VA's/ PTE's are actually allocated inside a * maxcpus*NPTECL array of PTE's, to avoid cache line thrashing @@ -874,6 +881,14 @@ pmap_map_ptes(struct pmap *pmap, struct if (!pmap_valid_entry(opde) || pmap_pte2pa(opde) != pmap_pdirpa(pmap, 0)) { pmap_pte_set(APDP_PDE, npde); +#ifdef PAE + npde = pmap_pa2pte(pmap_pdirpa(pmap, 512)) | PG_RW | PG_V; + pmap_pte_set(APDP_PDE+1,npde); + npde = pmap_pa2pte(pmap_pdirpa(pmap, 1024)) | PG_RW | PG_V; + pmap_pte_set(APDP_PDE+2,npde); + npde = pmap_pa2pte(pmap_pdirpa(pmap, 1536)) | PG_RW | PG_V; + pmap_pte_set(APDP_PDE+3,npde); +#endif pmap_pte_flush(); if (pmap_valid_entry(opde)) pmap_apte_flush(ourpmap); @@ -924,6 +940,11 @@ pmap_unmap_ptes(struct pmap *pmap, struc #endif #if defined(MULTIPROCESSOR) pmap_pte_set(APDP_PDE, 0); +#if defined(PAE) && !defined(XEN) + pmap_pte_set(APDP_PDE+1, 0); + pmap_pte_set(APDP_PDE+2, 0); + pmap_pte_set(APDP_PDE+2, 0); +#endif pmap_pte_flush(); pmap_apte_flush(pmap2); #endif @@ -1244,13 +1263,18 @@ pmap_bootstrap(vaddr_t kva_start) } memset(&kpm->pm_list, 0, sizeof(kpm->pm_list)); /* pm_list not used */ kpm->pm_pdir = (pd_entry_t *)(lwp0.l_addr->u_pcb.pcb_cr3 + KERNBASE); -#ifdef PAE +#if defined(PAE) && defined(XEN) for (i = 0; i < PDP_SIZE; i++) kpm->pm_pdirpa[i] = - (paddr_t)lwp0.l_addr->u_pcb.pcb_cr3 + PAGE_SIZE * i; + (paddr_t)lwp0.l_addr->u_pcb.pcb_cr3 + PAGE_SIZE * i; +#elif defined(PAE) && !defined(XEN) + kpm->pm_pdirpa = &PDPtable[0]; + kpm->pm_l3dirpa = rcr3(); + lwp0.l_addr->u_pcb.pcb_cr3 = kpm->pm_l3dirpa; #else kpm->pm_pdirpa = (paddr_t) lwp0.l_addr->u_pcb.pcb_cr3; #endif + kpm->pm_stats.wired_count = kpm->pm_stats.resident_count = x86_btop(kva_start - VM_MIN_KERNEL_ADDRESS); @@ -1363,6 +1390,7 @@ pmap_bootstrap(vaddr_t kva_start) * recycle some of this waste by putting the idle stacks here * as well; we could waste less space if we knew the largest * CPU ID beforehand. + * Note: In PAE mode, we only have 4 ptes per cache line anyway */ csrcp = (char *) virtual_avail; csrc_pte = pte; @@ -2145,6 +2178,10 @@ pmap_create(void) { struct pmap *pmap; int i; +#if defined(PAE) && !defined(XEN) && defined(i386) + struct vm_page *pg; + int ret; +#endif pmap = pool_cache_get(&pmap_cache, PR_WAITOK); @@ -2154,7 +2191,13 @@ pmap_create(void) pmap->pm_ptphint[i] = NULL; } pmap->pm_stats.wired_count = 0; - pmap->pm_stats.resident_count = 1; /* count the PDP allocd below */ + +#ifdef PAE + pmap->pm_stats.resident_count = 4; /* count PDPs allocd below */ +#else + pmap->pm_stats.resident_count = 1; /* count PDP allocd below */ +#endif + #if !defined(__x86_64__) pmap->pm_hiexec = 0; #endif /* !defined(__x86_64__) */ @@ -2168,6 +2211,30 @@ pmap_create(void) pmap->pm_ldt_sel = GSYSSEL(GLDT_SEL, SEL_KPL); /* allocate PDP */ + +#if defined(PAE) && !defined(XEN) && defined(i386) + /* Allocate page for l3 PDPs and map before entering pmaps_lock - + * mapping memory, we might end up in pmap_growkernel */ + + /* Allocate a page in lower 4Gb */ + ret = uvm_pglistalloc(PAGE_SIZE, 0, 0x100000000ULL, 32, 0, + &pmap->l3pg, 1, 1); /* waiting is acceptable */ + pg = TAILQ_FIRST(&pmap->l3pg); + if (ret || !pg) + panic("pmap_create: failed to allocate l3pdp: %d\n", ret); + + pmap->pm_l3dirpa = pg->phys_addr; + + /* And some vma - NB, uvm manual says this can sleep indefinately */ + pmap->pm_pdirpa = (void *)uvm_km_alloc(kernel_map, PAGE_SIZE, 0, + UVM_KMF_VAONLY | UVM_KMF_WAITVA); + if (!pmap->pm_pdirpa) + panic("pmap_create: failed to allocate vma for l3pdp\n"); + + pmap_kenter_pa((vaddr_t)pmap->pm_pdirpa, pg->phys_addr, + VM_PROT_READ | VM_PROT_WRITE); +#endif + try_again: pmap->pm_pdir = pool_cache_get(&pmap_pdp_cache, PR_WAITOK); @@ -2183,9 +2250,14 @@ pmap_create(void) for (i = 0; i < PDP_SIZE; i++) pmap->pm_pdirpa[i] = pmap_pte2pa(pmap->pm_pdir[PDIR_SLOT_PTE + i]); -#else + +#ifndef XEN + for (i = 0; i < PDP_SIZE; i++) + pmap->pm_pdirpa[i] |= PG_V; +#endif /*XEN*/ +#else /*PAE*/ pmap->pm_pdirpa = pmap_pte2pa(pmap->pm_pdir[PDIR_SLOT_PTE]); -#endif +#endif /*PAE*/ LIST_INSERT_HEAD(&pmaps, pmap, pm_list); @@ -2293,8 +2365,17 @@ pmap_destroy(struct pmap *pmap) } #endif +#if defined(PAE) && !defined(XEN) && defined(i386) + /* We also need to kill resources allocated for the l3 pdp */ + pmap_kremove((vaddr_t)pmap->pm_pdirpa, PAGE_SIZE); + uvm_km_free(kernel_map, (vaddr_t)pmap->pm_pdirpa, PAGE_SIZE, + UVM_KMF_VAONLY); + uvm_pglistfree(&pmap->l3pg); +#endif + for (i = 0; i < PTP_LEVELS - 1; i++) mutex_destroy(&pmap->pm_obj[i].vmobjlock); + pool_cache_put(&pmap_cache, pmap); } @@ -2523,11 +2604,13 @@ pmap_reactivate(struct pmap *pmap) KASSERT(kpreempt_disabled()); #if defined(XEN) && defined(__x86_64__) KASSERT(pmap->pm_pdirpa == xen_current_user_pgd); -#elif defined(PAE) +#elif defined(XEN) && defined(PAE) KASSERT(pmap_pdirpa(pmap, 0) == pmap_pte2pa(pmap_l3pd[0])); #elif !defined(XEN) || (defined(XEN) && defined(XEN3)) +#ifndef PAE /* See other jmorse comments, need an i386 pae assert */ KASSERT(pmap->pm_pdirpa == pmap_pte2pa(rcr3())); #endif +#endif /* * if we still have a lazy reference to this pmap, @@ -2628,11 +2711,13 @@ pmap_load(void) #if defined(XEN) && defined(__x86_64__) KASSERT(oldpmap->pm_pdirpa == xen_current_user_pgd || oldpmap == pmap_kernel()); -#elif defined(PAE) +#elif defined(XEN) && defined(PAE) KASSERT(pmap_pdirpa(oldpmap, 0) == pmap_pte2pa(pmap_l3pd[0])); #elif !defined(XEN) || (defined(XEN) && defined(XEN3)) +#ifndef PAE /* jmorse - still need a PAE assert */ KASSERT(oldpmap->pm_pdirpa == pmap_pte2pa(rcr3())); #endif +#endif KASSERT((pmap->pm_cpus & cpumask) == 0); KASSERT((pmap->pm_kernel_cpus & cpumask) == 0); @@ -2652,8 +2737,10 @@ pmap_load(void) * update tss. now that we have registered for invalidations * from other CPUs, we're good to load the page tables. */ -#ifdef PAE +#if defined(XEN) && defined(PAE) pcb->pcb_cr3 = pmap_l3paddr; +#elif defined(PAE) && defined(i386) + pcb->pcb_cr3 = pmap->pm_l3dirpa; #else pcb->pcb_cr3 = pmap->pm_pdirpa; #endif @@ -2706,7 +2793,7 @@ pmap_load(void) #endif #endif /* XEN */ lldt(pmap->pm_ldt_sel); -#ifdef PAE +#if defined(XEN) && defined(PAE) { paddr_t l3_pd = xpmap_ptom_masked(pmap_l3paddr); int i; @@ -2720,9 +2807,10 @@ pmap_load(void) xpq_flush_queue(); splx(s); } -#else /* PAE */ + lcr3(pmap_l3paddr); +#else /* XEN && PAE */ lcr3(pcb->pcb_cr3); -#endif /* PAE */ +#endif /* XEN && PAE */ #endif /* XEN && x86_64 */ ci->ci_want_pmapload = 0; @@ -2791,11 +2879,13 @@ pmap_deactivate(struct lwp *l) #if defined(XEN) && defined(__x86_64__) KASSERT(pmap->pm_pdirpa == xen_current_user_pgd); -#elif defined(PAE) +#elif defined(XEN) && defined(PAE) KASSERT(pmap_pdirpa(pmap, 0) == pmap_pte2pa(pmap_l3pd[0])); #elif !defined(XEN) || (defined(XEN) && defined(XEN3)) +#ifndef PAE /* jmorse - again, generate assertion... */ KASSERT(pmap->pm_pdirpa == pmap_pte2pa(rcr3())); #endif +#endif KASSERT(ci->ci_pmap == pmap); /* @@ -2845,7 +2935,11 @@ pmap_extract(struct pmap *pmap, vaddr_t pd_entry_t * const *pdes; struct pmap *pmap2; struct cpu_info *ci; +#if defined(PAE) && defined(i386) && !defined(XEN) + paddr_t pa; +#else vaddr_t pa; +#endif lwp_t *l; bool hard, rv; @@ -4755,7 +4850,10 @@ pmap_init_tmp_pgtbl(paddr_t pg) }; static vaddr_t x86_tmp_pml_vaddr[] = { 0, 0, 0, 0 }; - pd_entry_t *tmp_pml, *kernel_pml; + pd_entry_t *tmp_pml; +#ifndef PAE + pd_entry_t *kernel_pml; +#endif int level; @@ -4775,6 +4873,7 @@ pmap_init_tmp_pgtbl(paddr_t pg) maps_loaded = true; } +#ifndef PAE /* Zero levels 1-3 */ for (level = 0; level < PTP_LEVELS - 1; ++level) { tmp_pml = (void *)x86_tmp_pml_vaddr[level]; @@ -4796,9 +4895,33 @@ pmap_init_tmp_pgtbl(paddr_t pg) tmp_pml[pl_i(pg, level + 1)] = (x86_tmp_pml_paddr[level - 1] & PG_FRAME) | PG_RW | PG_V; } +#else + /* + * For i386 PAE, we can re-use the kernel PDPTable to map 1Gb->4Gb, + * then build the page directory and table for the specific mapping. + * First the PDPTable + */ + + memset((void*)x86_tmp_pml_vaddr[0], 0, PAGE_SIZE); + memset((void*)x86_tmp_pml_vaddr[1], 0, PAGE_SIZE); + + tmp_pml = (void *)x86_tmp_pml_vaddr[1]; + tmp_pml[508] = x86_tmp_pml_paddr[1] | PG_V; + tmp_pml[509] = pmap_pdirpa(pmap_kernel(),512) | PG_V; + tmp_pml[510] = pmap_pdirpa(pmap_kernel(),1024) | PG_V; + tmp_pml[511] = pmap_pdirpa(pmap_kernel(),1536) | PG_V; + + /* Map the level 1 page table in */ + tmp_pml[0] = x86_tmp_pml_paddr[0] | PG_RW | PG_V; +#endif tmp_pml = (void *)x86_tmp_pml_vaddr[0]; tmp_pml[pl_i(pg, 1)] = (pg & PG_FRAME) | PG_RW | PG_V; +#ifndef PAE return x86_tmp_pml_paddr[PTP_LEVELS - 1]; +#else + tmp_pml = (void *)x86_tmp_pml_vaddr[1]; + return vtophys((vaddr_t)&tmp_pml[508]); +#endif } Index: dev/isa/i82365_isasubr.c =================================================================== RCS file: /cvsroot/src/sys/dev/isa/i82365_isasubr.c,v retrieving revision 1.40 diff -u -p -r1.40 i82365_isasubr.c --- dev/isa/i82365_isasubr.c 8 Apr 2008 20:08:49 -0000 1.40 +++ dev/isa/i82365_isasubr.c 14 Dec 2009 01:20:57 -0000 @@ -442,7 +442,7 @@ void pcic_isa_bus_width_probe (sc, iot, DPRINTF(("%s: bus_space_alloc range 0x%04lx-0x%04lx (probed)\n", device_xname(&sc->dev), (long) sc->iobase, - (long) sc->iobase + sc->iosize)); + (long) (sc->iobase + sc->iosize))); if (pcic_isa_alloc_iobase && pcic_isa_alloc_iosize) { sc->iobase = pcic_isa_alloc_iobase; @@ -450,7 +450,7 @@ void pcic_isa_bus_width_probe (sc, iot, DPRINTF(("%s: bus_space_alloc range 0x%04lx-0x%04lx " "(config override)\n", device_xname(&sc->dev), (long) sc->iobase, - (long) sc->iobase + sc->iosize)); + (long) (sc->iobase + sc->iosize))); } } Index: dev/isapnp/i82365_isapnp.c =================================================================== RCS file: /cvsroot/src/sys/dev/isapnp/i82365_isapnp.c,v retrieving revision 1.26 diff -u -p -r1.26 i82365_isapnp.c --- dev/isapnp/i82365_isapnp.c 26 Jun 2008 12:33:17 -0000 1.26 +++ dev/isapnp/i82365_isapnp.c 14 Dec 2009 01:21:04 -0000 @@ -155,7 +155,7 @@ pcic_isapnp_attach(struct device *parent printf(": can't alloc mem space\n"); return; } - printf(": using iomem 0x%lx iosiz 0x%x", maddr, msize); + printf(": using iomem 0x%jx iosiz 0x%x", (uintmax_t)maddr, msize); sc->membase = maddr; sc->subregionmask = (1 << (msize / PCIC_MEM_PAGESIZE)) - 1; Index: uvm/uvm_map.c =================================================================== RCS file: /cvsroot/src/sys/uvm/uvm_map.c,v retrieving revision 1.263.4.3 diff -u -p -r1.263.4.3 uvm_map.c --- uvm/uvm_map.c 19 Apr 2009 15:43:14 -0000 1.263.4.3 +++ uvm/uvm_map.c 14 Dec 2009 01:27:11 -0000 @@ -5027,8 +5027,8 @@ uvm_page_printit(struct vm_page *pg, boo (*pr)("PAGE %p:\n", pg); bitmask_snprintf(pg->flags, page_flagbits, pgbuf, sizeof(pgbuf)); bitmask_snprintf(pg->pqflags, page_pqflagbits, pqbuf, sizeof(pqbuf)); - (*pr)(" flags=%s, pqflags=%s, wire_count=%d, pa=0x%lx\n", - pgbuf, pqbuf, pg->wire_count, (long)VM_PAGE_TO_PHYS(pg)); + (*pr)(" flags=%s, pqflags=%s, wire_count=%d, pa=0x%jx\n", + pgbuf, pqbuf, pg->wire_count, (uintmax_t)VM_PAGE_TO_PHYS(pg)); (*pr)(" uobject=%p, uanon=%p, offset=0x%llx loan_count=%d\n", pg->uobject, pg->uanon, (long long)pg->offset, pg->loan_count); #if defined(UVM_PAGE_TRKOWN) Index: uvm/uvm_page.c =================================================================== RCS file: /cvsroot/src/sys/uvm/uvm_page.c,v retrieving revision 1.140.6.3 diff -u -p -r1.140.6.3 uvm_page.c --- uvm/uvm_page.c 2 Mar 2009 20:51:35 -0000 1.140.6.3 +++ uvm/uvm_page.c 14 Dec 2009 01:27:11 -0000 @@ -332,7 +332,8 @@ uvm_page_init_buckets(struct pgfreelist void uvm_page_init(vaddr_t *kvm_startp, vaddr_t *kvm_endp) { - vsize_t freepages, pagecount, bucketcount, n; +/* XXXjmorse vsize -> psize... */ + psize_t freepages, pagecount, bucketcount, n; struct pgflbucket *bucketarray, *cpuarray; struct vm_page *pagearray; int lcv; Index: uvm/uvm_param.h =================================================================== RCS file: /cvsroot/src/sys/uvm/uvm_param.h,v retrieving revision 1.21 diff -u -p -r1.21 uvm_param.h --- uvm/uvm_param.h 4 Aug 2006 22:42:36 -0000 1.21 +++ uvm/uvm_param.h 14 Dec 2009 01:27:12 -0000 @@ -196,7 +196,14 @@ */ #ifdef _KERNEL #define atop(x) (((paddr_t)(x)) >> PAGE_SHIFT) + +#if defined(PAE) && defined(i386) && !defined(XEN) +/* uvm shouldn't treat paddrs as vaddrs, i386 PAE drops bits here. However, + * protect with some MD ifdefs for now, casts might be here for a reason */ +#define ptoa(x) ((x) << PAGE_SHIFT) +#else #define ptoa(x) ((vaddr_t)((vaddr_t)(x) << PAGE_SHIFT)) +#endif /* * Round off or truncate to the nearest page. These will work Index: arch/i386/conf/GENERIC_PAE =================================================================== --- arch/i386/conf/GENERIC_PAE 12 Dec 2009 14:59:42 -0000 +++ arch/i386/conf/GENERIC_PAE 12 Dec 2009 14:59:42 -0000 @@ -0,0 +0,3 @@ +include "arch/i386/conf/GENERIC" + +options PAE