diff options
author | peter <peter@FreeBSD.org> | 2003-10-01 23:46:08 +0000 |
---|---|---|
committer | peter <peter@FreeBSD.org> | 2003-10-01 23:46:08 +0000 |
commit | b9ef48a8b5c980a888e2e6f3efba09e0c9389355 (patch) | |
tree | 9ca10d85c8583c95f38339ea38e76aae2a4108f5 /sys/amd64 | |
parent | 39516d17c039978395669a1aa1ccaa94be3a2567 (diff) | |
download | FreeBSD-src-b9ef48a8b5c980a888e2e6f3efba09e0c9389355.zip FreeBSD-src-b9ef48a8b5c980a888e2e6f3efba09e0c9389355.tar.gz |
Commit Bosko's patch to clean up the PSE/PG_G initialization to and
avoid problems with some Pentium 4 cpus and some older PPro/Pentium2
cpus. There are several problems, some documented in Intel errata.
This patch:
1) moves the kernel to the second page in the PSE case. There is an
errata that says that you Must Not point a 4MB page at physical
address zero on older cpus. We avoided bugs here due to sheer luck.
2) sets up PSE page tables right from the start in locore, rather than
trying to switch from 4K to 4M (or 2M) pages part way through the boot
sequence at the same time that we're messing with PG_G.
For some reason, the pmap work over the last 18 months seems to tickle
the problems, and the PAE infrastructure changes disturb the cpu
bugs even more.
A couple of people have reported a problem with APM bios calls during
boot. I'll work with people to get this resolved.
Obtained from: bmilekic
Diffstat (limited to 'sys/amd64')
-rw-r--r-- | sys/amd64/amd64/bios.c | 24 | ||||
-rw-r--r-- | sys/amd64/amd64/mp_machdep.c | 10 | ||||
-rw-r--r-- | sys/amd64/amd64/mpboot.S | 16 | ||||
-rw-r--r-- | sys/amd64/amd64/mptable.c | 10 | ||||
-rw-r--r-- | sys/amd64/include/mptable.h | 10 |
5 files changed, 34 insertions, 36 deletions
diff --git a/sys/amd64/amd64/bios.c b/sys/amd64/amd64/bios.c index 69f6ded..da862ba 100644 --- a/sys/amd64/amd64/bios.c +++ b/sys/amd64/amd64/bios.c @@ -396,18 +396,16 @@ bios16(struct bios_args *args, char *fmt, ...) */ 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 @@ bios16(struct bios_args *args, char *fmt, ...) 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); } diff --git a/sys/amd64/amd64/mp_machdep.c b/sys/amd64/amd64/mp_machdep.c index a050d3c..fe150ff 100644 --- a/sys/amd64/amd64/mp_machdep.c +++ b/sys/amd64/amd64/mp_machdep.c @@ -536,8 +536,6 @@ init_secondary(void) cr0 = rcr0(); cr0 &= ~(CR0_CD | CR0_NW | CR0_EM); load_cr0(cr0); - - pmap_set_opt(); } @@ -926,7 +924,6 @@ mptable_pass2(void) int type; int apic, bus, cpu, intr; int i, j; - int pgeflag; POSTCODE(MPTABLE_PASS2_POST); @@ -935,8 +932,6 @@ mptable_pass2(void) 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 @@ mptable_pass2(void) /* 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 @@ start_all_aps(u_int boot_addr) 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 @@ start_ap(int logical_cpu, u_int boot_addr) /* 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; diff --git a/sys/amd64/amd64/mpboot.S b/sys/amd64/amd64/mpboot.S index e245007..d77b877 100644 --- a/sys/amd64/amd64/mpboot.S +++ b/sys/amd64/amd64/mpboot.S @@ -86,6 +86,22 @@ NON_GPROF_ENTRY(MPentry) 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! */ diff --git a/sys/amd64/amd64/mptable.c b/sys/amd64/amd64/mptable.c index a050d3c..fe150ff 100644 --- a/sys/amd64/amd64/mptable.c +++ b/sys/amd64/amd64/mptable.c @@ -536,8 +536,6 @@ init_secondary(void) cr0 = rcr0(); cr0 &= ~(CR0_CD | CR0_NW | CR0_EM); load_cr0(cr0); - - pmap_set_opt(); } @@ -926,7 +924,6 @@ mptable_pass2(void) int type; int apic, bus, cpu, intr; int i, j; - int pgeflag; POSTCODE(MPTABLE_PASS2_POST); @@ -935,8 +932,6 @@ mptable_pass2(void) 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 @@ mptable_pass2(void) /* 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 @@ start_all_aps(u_int boot_addr) 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 @@ start_ap(int logical_cpu, u_int boot_addr) /* 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; diff --git a/sys/amd64/include/mptable.h b/sys/amd64/include/mptable.h index a050d3c..fe150ff 100644 --- a/sys/amd64/include/mptable.h +++ b/sys/amd64/include/mptable.h @@ -536,8 +536,6 @@ init_secondary(void) cr0 = rcr0(); cr0 &= ~(CR0_CD | CR0_NW | CR0_EM); load_cr0(cr0); - - pmap_set_opt(); } @@ -926,7 +924,6 @@ mptable_pass2(void) int type; int apic, bus, cpu, intr; int i, j; - int pgeflag; POSTCODE(MPTABLE_PASS2_POST); @@ -935,8 +932,6 @@ mptable_pass2(void) 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 @@ mptable_pass2(void) /* 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 @@ start_all_aps(u_int boot_addr) 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 @@ start_ap(int logical_cpu, u_int boot_addr) /* 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; |