--- //depot/vendor/freebsd/src/sys/conf/ldscript.i386 2003/01/05 23:40:18 +++ //depot/user/bmilekic/intelsux/src/sys/conf/ldscript.i386 2003/08/01 10:19:29 @@ -6,7 +6,7 @@ SECTIONS { /* Read-only sections, merged into text segment: */ - . = kernbase + 0x00100000 + SIZEOF_HEADERS; + . = kernbase + kernload + SIZEOF_HEADERS; .interp : { *(.interp) } .hash : { *(.hash) } .dynsym : { *(.dynsym) } --- //depot/vendor/freebsd/src/sys/i386/bios/apm.c 2003/07/02 09:10:37 +++ //depot/user/bmilekic/intelsux/src/sys/i386/bios/apm.c 2003/08/21 13:24:41 @@ -121,7 +121,7 @@ static int apm_suspend_delay = 1; static int apm_standby_delay = 1; static int apm_swab_batt_minutes = 0; -static int apm_debug = 0; +static int apm_debug = 1; #define APM_DPRINT(args...) do { \ if (apm_debug) { \ @@ -189,9 +189,12 @@ if (sc->connectmode == APM_PROT32CONNECT) { set_bios_selectors(&sc->bios.seg, BIOSCODE_FLAG | BIOSDATA_FLAG); + APM_DPRINT("Calling bios32 code...\n"); errno = bios32(&sc->bios.r, sc->bios.entry, GSEL(GBIOSCODE32_SEL, SEL_KPL)); + APM_DPRINT("Returned from bios32 code... errno = %d\n", errno); } else { + APM_DPRINT("Calling bios16 code...\n"); errno = bios16(&sc->bios, NULL); } #endif @@ -1176,9 +1179,13 @@ * 1.02 driver resulted in a 1.02 connection. */ drv_version = apm_version > 0x102 ? 0x102 : apm_version; - for (; drv_version > 0x100; drv_version--) - if (apm_driver_version(drv_version) == 0) + for (; drv_version > 0x100; drv_version--) { + APM_DPRINT("Calling bios to check if version is: %x\n", drv_version); + if (apm_driver_version(drv_version) == 0) { + APM_DPRINT("Found version: %x\n", drv_version); break; + } + } sc->minorversion = ((drv_version & 0x00f0) >> 4) * 10 + ((drv_version & 0x000f) >> 0); sc->majorversion = ((drv_version & 0xf000) >> 12) * 10 + --- //depot/vendor/freebsd/src/sys/i386/conf/GENERIC 2003/09/19 13:05:25 +++ //depot/user/bmilekic/intelsux/src/sys/i386/conf/GENERIC 2003/10/01 12:10:34 @@ -155,7 +155,7 @@ device npx # Power management support (see NOTES for more options) -#device apm +device apm # Add suspend/resume support for the i8254. device pmtimer --- //depot/vendor/freebsd/src/sys/i386/i386/bios.c 2003/08/25 02:50:41 +++ //depot/user/bmilekic/intelsux/src/sys/i386/i386/bios.c 2003/10/01 12:10:34 @@ -396,18 +396,16 @@ */ pte = (pt_entry_t *)malloc(PAGE_SIZE, M_TEMP, M_WAITOK); ptd = (pd_entry_t *)((u_int)IdlePTD + KERNBASE); + *pte = (vm86pa - PAGE_SIZE) | PG_RW | PG_V; *ptd = vtophys(pte) | PG_RW | PG_V; } else { /* * this is a user-level page table */ pte = PTmap; + *pte = (vm86pa - PAGE_SIZE) | PG_RW | PG_V; } - /* - * install pointer to page 0. we don't need to flush the tlb, - * since there should not be a previous mapping for page 0. - */ - *pte = (vm86pa - PAGE_SIZE) | PG_RW | PG_V; + pmap_invalidate_all(kernel_pmap); /* XXX insurance for now */ stack_top = stack; va_start(ap, fmt); @@ -457,19 +455,21 @@ bioscall_vector.vec16.segment = GSEL(GBIOSCODE16_SEL, SEL_KPL); i = bios16_call(&args->r, stack_top); - + if (pte == PTmap) { *pte = 0; /* remove entry */ + /* + * XXX only needs to be invlpg(0) but that doesn't work on the 386 + */ + pmap_invalidate_all(kernel_pmap); } else { *ptd = 0; /* remove page table */ + /* + * XXX only needs to be invlpg(0) but that doesn't work on the 386 + */ + pmap_invalidate_all(kernel_pmap); free(pte, M_TEMP); /* ... and free it */ } - - /* - * XXX only needs to be invlpg(0) but that doesn't work on the 386 - */ - pmap_invalidate_all(kernel_pmap); - return (i); } --- //depot/vendor/freebsd/src/sys/i386/i386/genassym.c 2003/09/30 01:15:28 +++ //depot/user/bmilekic/intelsux/src/sys/i386/i386/genassym.c 2003/10/01 12:10:34 @@ -110,13 +110,16 @@ ASSYM(NPGPTD, NPGPTD); ASSYM(PDESIZE, sizeof(pd_entry_t)); ASSYM(PTESIZE, sizeof(pt_entry_t)); +ASSYM(PDESHIFT, PDESHIFT); ASSYM(PTESHIFT, PTESHIFT); ASSYM(PAGE_SHIFT, PAGE_SHIFT); ASSYM(PAGE_MASK, PAGE_MASK); ASSYM(PDRSHIFT, PDRSHIFT); +ASSYM(PDRMASK, PDRMASK); ASSYM(USRSTACK, USRSTACK); ASSYM(VM_MAXUSER_ADDRESS, VM_MAXUSER_ADDRESS); ASSYM(KERNBASE, KERNBASE); +ASSYM(KERNLOAD, KERNLOAD); ASSYM(MCLBYTES, MCLBYTES); ASSYM(PCB_CR3, offsetof(struct pcb, pcb_cr3)); ASSYM(PCB_EDI, offsetof(struct pcb, pcb_edi)); --- //depot/vendor/freebsd/src/sys/i386/i386/locore.s 2003/07/29 15:00:47 +++ //depot/user/bmilekic/intelsux/src/sys/i386/i386/locore.s 2003/08/08 09:26:56 @@ -87,10 +87,12 @@ #endif /* SMP */ /* - * Compiled KERNBASE location + * Compiled KERNBASE location and the kernel load address */ .globl kernbase .set kernbase,KERNBASE + .globl kernload + .set kernload,KERNLOAD /* * Globals @@ -731,9 +733,9 @@ je no_kernend movl %edi,%esi no_kernend: - - addl $PAGE_MASK,%esi - andl $~PAGE_MASK,%esi + + addl $PDRMASK,%esi /* Play conservative for now, and */ + andl $~PDRMASK,%esi /* ... wrap to next 4M. */ movl %esi,R(KERNend) /* save end of kernel */ movl %esi,R(physfree) /* next free page is at end of kernel */ @@ -783,16 +785,46 @@ movl %esi, R(SMPpt) /* relocated to KVM space */ #endif /* SMP */ -/* Map read-only from zero to the end of the kernel text section */ +/* Map read-only from zero to the beginning of the kernel text section */ xorl %eax, %eax xorl %edx,%edx - movl $R(etext),%ecx + movl $R(btext),%ecx addl $PAGE_MASK,%ecx shrl $PAGE_SHIFT,%ecx fillkptphys(%edx) -/* Map read-write, data, bss and symbols */ - movl $R(etext),%eax +/* + * Enable PSE and PGE. + */ +#ifndef DISABLE_PSE + testl $CPUID_PSE, R(cpu_feature) + jz 1f + movl $PG_PS, R(pseflag) + movl %cr4, %eax + orl $CR4_PSE, %eax + movl %eax, %cr4 +1: +#endif +#ifndef DISABLE_PG_G + testl $CPUID_PGE, R(cpu_feature) + jz 2f + movl $PG_G, R(pgeflag) + movl %cr4, %eax + orl $CR4_PGE, %eax + movl %eax, %cr4 +2: +#endif + +/* + * Write page tables for the kernel starting at btext and + * until the end. Make sure to map read+write. We do this even + * if we've enabled PSE above, we'll just switch the corresponding kernel + * PDEs before we turn on paging. + * + * XXX: We waste some pages here in the PSE case! DON'T BLINDLY REMOVE + * THIS! SMP needs the page table to be there to map the kernel P==V. + */ + movl $R(btext),%eax addl $PAGE_MASK, %eax andl $~PAGE_MASK, %eax movl $PG_RW,%edx @@ -881,12 +913,33 @@ movl $NKPT, %ecx fillkpt(R(IdlePTD), $PG_RW) -/* install pde's for pt's */ +/* + * For the non-PSE case, install PDEs for PTs covering the kernel. + * For the PSE case, do the same, but clobber the ones corresponding + * to the kernel (from btext to KERNend) with 4M ('PS') PDEs immediately + * after. + */ movl R(KPTphys), %eax movl $KPTDI, %ebx movl $NKPT, %ecx fillkpt(R(IdlePTD), $PG_RW) + cmpl $0,R(pseflag) + je done_pde + movl R(KERNend), %ecx + movl $KERNLOAD, %eax + subl %eax, %ecx + shrl $PDRSHIFT, %ecx + movl $(KPTDI+(KERNLOAD/(1 << PDRSHIFT))), %ebx + shll $PDESHIFT, %ebx + addl R(IdlePTD), %ebx + orl $(PG_V|PG_RW|PG_PS), %eax +1: movl %eax, (%ebx) + addl $(1 << PDRSHIFT), %eax + addl $PDESIZE, %ebx + loop 1b + +done_pde: /* install a pde recursively mapping page directory as a page table */ movl R(IdlePTD), %eax movl $PTDPTDI, %ebx --- //depot/vendor/freebsd/src/sys/i386/i386/machdep.c 2003/09/29 21:55:33 +++ //depot/user/bmilekic/intelsux/src/sys/i386/i386/machdep.c 2003/10/01 12:10:34 @@ -1798,7 +1798,7 @@ /* * block out kernel memory as not available. */ - if (pa >= 0x100000 && pa < first) + if (pa >= KERNLOAD && pa < first) continue; page_bad = FALSE; --- //depot/vendor/freebsd/src/sys/i386/i386/mp_machdep.c 2003/09/09 18:38:09 +++ //depot/user/bmilekic/intelsux/src/sys/i386/i386/mp_machdep.c 2003/10/01 12:10:34 @@ -536,8 +536,6 @@ cr0 = rcr0(); cr0 &= ~(CR0_CD | CR0_NW | CR0_EM); load_cr0(cr0); - - pmap_set_opt(); } @@ -926,7 +924,6 @@ int type; int apic, bus, cpu, intr; int i, j; - int pgeflag; POSTCODE(MPTABLE_PASS2_POST); @@ -935,8 +932,6 @@ proc.type = 0; proc.cpu_flags = PROCENTRY_FLAG_EN; - pgeflag = 0; /* XXX - Not used under SMP yet. */ - MALLOC(io_apic_versions, u_int32_t *, sizeof(u_int32_t) * mp_napics, M_DEVBUF, M_WAITOK); MALLOC(ioapic, volatile ioapic_t **, sizeof(ioapic_t *) * mp_napics, @@ -961,7 +956,7 @@ /* use this slot if available */ if (((vm_offset_t)SMPpt[NPTEPG-2-j] & PG_FRAME) == 0) { SMPpt[NPTEPG-2-j] = (pt_entry_t)(PG_V | PG_RW | - pgeflag | (io_apic_address[i] & PG_FRAME)); + (io_apic_address[i] & PG_FRAME)); ioapic[i] = (ioapic_t *)((u_int)SMP_prvspace + (NPTEPG-2-j) * PAGE_SIZE + (io_apic_address[i] & PAGE_MASK)); @@ -2177,7 +2172,6 @@ for (x = 0; x < NKPT; x++) PTD[x] = 0; - pmap_set_opt(); /* number of APs actually started */ return mp_ncpus - 1; @@ -2285,7 +2279,7 @@ /* setup common fields for subsequent IPIs */ icr_lo = lapic.icr_lo & APIC_ICRLO_RESV_MASK; icr_lo |= APIC_DESTMODE_PHY; - + /* do an INIT IPI: assert RESET */ lapic.icr_lo = icr_lo | APIC_DEST_DESTFLD | APIC_TRIGMOD_EDGE | APIC_LEVEL_ASSERT | APIC_DELMODE_INIT; --- //depot/vendor/freebsd/src/sys/i386/i386/mpboot.s 2003/03/29 21:25:29 +++ //depot/user/bmilekic/intelsux/src/sys/i386/i386/mpboot.s 2003/08/12 08:23:16 @@ -86,6 +86,22 @@ movl R(IdlePTD), %eax movl %eax,%cr3 #endif +#ifndef DISABLE_PSE + cmpl $0, R(pseflag) + je 1f + movl %cr4, %eax + orl $CR4_PSE, %eax + movl %eax, %cr4 +1: +#endif +#ifndef DISABLE_PG_G + cmpl $0, R(pgeflag) + je 2f + movl %cr4, %eax + orl $CR4_PGE, %eax + movl %eax, %cr4 +2: +#endif movl %cr0,%eax orl $CR0_PE|CR0_PG,%eax /* enable paging */ movl %eax,%cr0 /* let the games begin! */ --- //depot/vendor/freebsd/src/sys/i386/i386/pmap.c 2003/09/30 23:00:48 +++ //depot/user/bmilekic/intelsux/src/sys/i386/i386/pmap.c 2003/10/01 12:10:34 @@ -195,8 +195,8 @@ vm_offset_t virtual_avail; /* VA of first avail page (after kernel bss) */ vm_offset_t virtual_end; /* VA of last avail page (end of kernel AS) */ static boolean_t pmap_initialized = FALSE; /* Has pmap_init completed? */ -static int pgeflag; /* PG_G or-in */ -static int pseflag; /* PG_PS or-in */ +int pgeflag = 0; /* PG_G or-in */ +int pseflag = 0; /* PG_PS or-in */ static int nkpt; vm_offset_t kernel_vm_end; @@ -260,8 +260,6 @@ static void *pmap_pdpt_allocf(uma_zone_t zone, int bytes, u_int8_t *flags, int wait); #endif -static pd_entry_t pdir4mb; - CTASSERT(1 << PDESHIFT == sizeof(pd_entry_t)); CTASSERT(1 << PTESHIFT == sizeof(pt_entry_t)); @@ -285,7 +283,7 @@ #endif #ifndef DISABLE_PSE if (cpu_feature & CPUID_PSE) - newaddr = (addr + (NBPDR - 1)) & ~(NBPDR - 1); + newaddr = (addr + PDRMASK) & ~PDRMASK; #endif return newaddr; } @@ -397,11 +395,6 @@ for (i = 0; i < NKPT; i++) PTD[i] = 0; - pgeflag = 0; -#ifndef DISABLE_PG_G - if (cpu_feature & CPUID_PGE) - pgeflag = PG_G; -#endif #ifdef I686_CPU_not /* Problem seems to have gone away */ /* Deal with un-resolved Pentium4 issues */ if (cpu_class == CPUCLASS_686 && @@ -411,21 +404,7 @@ pgeflag = 0; } #endif - -/* - * Initialize the 4MB page size flag - */ - pseflag = 0; -/* - * The 4MB page version of the initial - * kernel page mapping. - */ - pdir4mb = 0; -#ifndef DISABLE_PSE - if (cpu_feature & CPUID_PSE) - pseflag = PG_PS; -#endif #ifdef I686_CPU_not /* Problem seems to have gone away */ /* Deal with un-resolved Pentium4 issues */ if (cpu_class == CPUCLASS_686 && @@ -435,26 +414,10 @@ pseflag = 0; } #endif -#ifndef DISABLE_PSE - if (pseflag) { - pd_entry_t ptditmp; - /* - * Note that we have enabled PSE mode - */ - ptditmp = *(PTmap + i386_btop(KERNBASE)); - ptditmp &= ~(NBPDR - 1); - ptditmp |= PG_V | PG_RW | PG_PS | PG_U | pgeflag; - pdir4mb = ptditmp; - } -#endif -#ifndef SMP - /* - * Turn on PGE/PSE. SMP does this later on since the - * 4K page tables are required for AP boot (for now). - * XXX fixme. - */ - pmap_set_opt(); -#endif + + /* Turn on PG_G on kernel page(s) */ + pmap_set_pg(); + #ifdef SMP if (cpu_apic_address == 0) panic("pmap_bootstrap: no local apic! (non-SMP hardware?)"); @@ -467,55 +430,41 @@ } /* - * Enable 4MB page mode for MP startup. Turn on PG_G support. - * BSP will run this after all the AP's have started up. + * Set PG_G on kernel pages. Only the BSP calls this when SMP is turned on. */ void -pmap_set_opt(void) +pmap_set_pg(void) { + pd_entry_t pdir; pt_entry_t *pte; vm_offset_t va, endva; + int i; + + if (pgeflag == 0) + return; - if (pgeflag && (cpu_feature & CPUID_PGE)) { - load_cr4(rcr4() | CR4_PGE); - invltlb(); /* Insurance */ - } -#ifndef DISABLE_PSE - if (pseflag && (cpu_feature & CPUID_PSE)) { - load_cr4(rcr4() | CR4_PSE); - invltlb(); /* Insurance */ - } -#endif - if (PCPU_GET(cpuid) == 0) { -#ifndef DISABLE_PSE - if (pdir4mb) { - kernel_pmap->pm_pdir[KPTDI] = PTD[KPTDI] = pdir4mb; - invltlb(); /* Insurance */ + i = KERNLOAD/NBPDR; + endva = KERNBASE + KERNend; + + if (pseflag) { + va = KERNBASE + KERNLOAD; + while (va < endva) { + pdir = kernel_pmap->pm_pdir[KPTDI+i]; + pdir |= pgeflag; + kernel_pmap->pm_pdir[KPTDI+i] = PTD[KPTDI+i] = pdir; + invltlb(); /* Play it safe, invltlb() every time */ + i++; + va += NBPDR; } -#endif - if (pgeflag) { - /* Turn on PG_G for text, data, bss pages. */ - va = (vm_offset_t)btext; -#ifndef DISABLE_PSE - if (pseflag && (cpu_feature & CPUID_PSE)) { - if (va < KERNBASE + (1 << PDRSHIFT)) - va = KERNBASE + (1 << PDRSHIFT); - } -#endif - endva = KERNBASE + KERNend; - while (va < endva) { - pte = vtopte(va); - if (*pte) - *pte |= pgeflag; - va += PAGE_SIZE; - } - invltlb(); /* Insurance */ + } else { + va = (vm_offset_t)btext; + while (va < endva) { + pte = vtopte(va); + if (*pte) + *pte |= pgeflag; + invltlb(); /* Play it safe, invltlb() every time */ + va += PAGE_SIZE; } - /* - * We do not need to broadcast the invltlb here, because - * each AP does it the moment it is released from the boot - * lock. See ap_init(). - */ } } @@ -3156,7 +3105,7 @@ return addr; } - addr = (addr + (NBPDR - 1)) & ~(NBPDR - 1); + addr = (addr + PDRMASK) & ~PDRMASK; return addr; } --- //depot/vendor/freebsd/src/sys/i386/include/pmap.h 2003/09/24 19:55:33 +++ //depot/user/bmilekic/intelsux/src/sys/i386/include/pmap.h 2003/10/01 12:10:34 @@ -330,6 +330,8 @@ extern vm_offset_t clean_eva; extern vm_offset_t clean_sva; extern vm_paddr_t phys_avail[]; +extern int pseflag; +extern int pgeflag; extern char *ptvmmap; /* poor name! */ extern vm_offset_t virtual_avail; extern vm_offset_t virtual_end; @@ -340,7 +342,7 @@ void *pmap_mapdev(vm_paddr_t, vm_size_t); void pmap_unmapdev(vm_offset_t, vm_size_t); pt_entry_t *pmap_pte_quick(pmap_t, vm_offset_t) __pure2; -void pmap_set_opt(void); +void pmap_set_pg(void); void pmap_invalidate_page(pmap_t, vm_offset_t); void pmap_invalidate_range(pmap_t, vm_offset_t, vm_offset_t); void pmap_invalidate_all(pmap_t); --- //depot/vendor/freebsd/src/sys/i386/include/vmparam.h 2003/04/30 17:11:31 +++ //depot/user/bmilekic/intelsux/src/sys/i386/include/vmparam.h 2003/08/01 10:19:29 @@ -84,6 +84,13 @@ /* + * Kernel physical load address. + */ +#ifndef KERNLOAD +#define KERNLOAD 0x400000 +#endif + +/* * Virtual addresses of things. Derived from the page directory and * page table indexes from pmap.h for precision. * Because of the page that is both a PD and PT, it looks a little