From 91f1c7a43009e0bb44d36305b0398268276c9ba5 Mon Sep 17 00:00:00 2001 From: Michael Neumann Date: Sat, 2 Oct 2010 17:39:10 +0200 Subject: [PATCH] Change mptable mapping mechanism during mptable parsing. Apply commit 981bebd11ba5507ab5887bb66ef52935ab350bed for x86_64. --- sys/platform/pc64/x86_64/mp_machdep.c | 108 +++++++++++++++++++------- 1 file changed, 79 insertions(+), 29 deletions(-) diff --git a/sys/platform/pc64/x86_64/mp_machdep.c b/sys/platform/pc64/x86_64/mp_machdep.c index f468740a48..531be44d5c 100644 --- a/sys/platform/pc64/x86_64/mp_machdep.c +++ b/sys/platform/pc64/x86_64/mp_machdep.c @@ -160,6 +160,12 @@ typedef struct BASETABLE_ENTRY { char name[16]; } basetable_entry; +struct mptable_pos { + mpfps_t mp_fps; + mpcth_t mp_cth; + vm_size_t mp_cth_mapsz; +}; + /* * this code MUST be enabled here and in mpboot.s. * it follows the very early stages of AP boot by placing values in CMOS ram. @@ -283,15 +289,16 @@ static u_int boot_address; static u_int base_memory; static int mp_finish; -static mpfps_t mpfps; static long search_for_sig(u_int32_t target, int count); static void mp_enable(u_int boot_addr); static void mptable_hyperthread_fixup(u_int id_mask); -static void mptable_pass1(void); -static int mptable_pass2(void); +static void mptable_pass1(struct mptable_pos *); +static int mptable_pass2(struct mptable_pos *); static void default_mp_table(int type); static void fix_mp_table(void); +static void mptable_map(struct mptable_pos *, vm_paddr_t); +static void mptable_unmap(struct mptable_pos *); #ifdef APIC_IO static void setup_apic_irq_mapping(void); static int apic_int_is_bus_type(int intr, int bus_type); @@ -528,35 +535,30 @@ mp_enable(u_int boot_addr) int apic; u_int ux; #endif /* APIC_IO */ + vm_paddr_t mpfps_paddr; + struct mptable_pos mpt; POSTCODE(MP_ENABLE_POST); - mpfps = (mpfps_t)mp_probe(); - if (mpfps == NULL) + mpfps_paddr = mp_probe(); + if (mpfps_paddr == 0) panic("mp_enable: mp_probe failed\n"); -#if 0 /* JGXXX */ - /* turn on 4MB of V == P addressing so we can get to MP table */ - *(int *)PTD = PG_V | PG_RW | ((uintptr_t)(void *)KPTphys & PG_FRAME); - cpu_invltlb(); -#endif + mptable_map(&mpt, mpfps_paddr); /* * We can safely map physical memory into SMPpt after * mptable_pass1() completes. */ - mptable_pass1(); + mptable_pass1(&mpt); if (cpu_apic_address == 0) panic("mp_enable: no local apic!\n"); /* examine the MP table for needed info, uses physical addresses */ - x = mptable_pass2(); + x = mptable_pass2(&mpt); -#if 0 /* JGXXX */ - *(int *)PTD = 0; - cpu_invltlb(); -#endif /* 0 JGXXX */ + mptable_unmap(&mpt); /* can't process default configs till the CPU APIC is pmapped */ if (x) @@ -743,11 +745,12 @@ static int lookup_bus_type (char *name); * nintrs */ static void -mptable_pass1(void) +mptable_pass1(struct mptable_pos *mpt) { #ifdef APIC_IO int x; #endif + mpfps_t fps; mpcth_t cth; int totalSize; void* position; @@ -757,8 +760,8 @@ mptable_pass1(void) POSTCODE(MPTABLE_PASS1_POST); - if (mpfps == NULL) - panic("mptable_pass1: MP float pointer is not found\n"); + fps = mpt->mp_fps; + KKASSERT(fps != NULL); #ifdef APIC_IO /* clear various tables */ @@ -777,7 +780,7 @@ mptable_pass1(void) id_mask = 0; /* check for use of 'default' configuration */ - if (mpfps->mpfb1 != 0) { + if (fps->mpfb1 != 0) { /* use default addresses */ cpu_apic_address = DEFAULT_APIC_BASE; #ifdef APIC_IO @@ -786,16 +789,16 @@ mptable_pass1(void) /* fill in with defaults */ mp_naps = 2; /* includes BSP */ - mp_nbusses = default_data[mpfps->mpfb1 - 1][0]; + mp_nbusses = default_data[fps->mpfb1 - 1][0]; #if defined(APIC_IO) mp_napics = 1; nintrs = 16; #endif /* APIC_IO */ } else { - if (mpfps->pap == 0) + cth = mpt->mp_cth; + if (cth == NULL) panic("MP Configuration Table Header MISSING!"); - cth = (void *)PHYS_TO_DMAP(mpfps->pap); cpu_apic_address = (vm_offset_t) cth->apic_address; @@ -870,10 +873,11 @@ mptable_pass1(void) * io_apic_ints[N] */ static int -mptable_pass2(void) +mptable_pass2(struct mptable_pos *mpt) { struct PROCENTRY proc; int x; + mpfps_t fps; mpcth_t cth; int totalSize; void* position; @@ -884,6 +888,9 @@ mptable_pass2(void) POSTCODE(MPTABLE_PASS2_POST); + fps = mpt->mp_fps; + KKASSERT(fps != NULL); + /* Initialize fake proc entry for use with HT fixup. */ bzero(&proc, sizeof(proc)); proc.type = 0; @@ -931,16 +938,16 @@ mptable_pass2(void) boot_cpu_id = -1; /* record whether PIC or virtual-wire mode */ - machintr_setvar_simple(MACHINTR_VAR_IMCR_PRESENT, mpfps->mpfb2 & 0x80); + machintr_setvar_simple(MACHINTR_VAR_IMCR_PRESENT, fps->mpfb2 & 0x80); /* check for use of 'default' configuration */ - if (mpfps->mpfb1 != 0) - return mpfps->mpfb1; /* return default configuration type */ + if (fps->mpfb1 != 0) + return fps->mpfb1; /* return default configuration type */ - if (mpfps->pap == 0) + cth = mpt->mp_cth; + if (cth == NULL) panic("MP Configuration Table Header MISSING!"); - cth = (void *)PHYS_TO_DMAP(mpfps->pap); /* walk the table, recording info of interest */ totalSize = cth->base_table_length - sizeof(struct MPCTH); position = (u_char *) cth + sizeof(struct MPCTH); @@ -1004,6 +1011,7 @@ mptable_pass2(void) return 0; } + /* * Check if we should perform a hyperthreading "fix-up" to * enumerate any logical CPU's that aren't already listed @@ -1053,6 +1061,48 @@ mptable_hyperthread_fixup(u_int id_mask) mp_naps *= logical_cpus; } +static void +mptable_map(struct mptable_pos *mpt, vm_paddr_t mpfps_paddr) +{ + mpfps_t fps = NULL; + mpcth_t cth = NULL; + vm_size_t cth_mapsz = 0; + + fps = pmap_mapdev(mpfps_paddr, sizeof(*fps)); + if (fps->pap != 0) { + /* + * Map configuration table header to get + * the base table size + */ + cth = pmap_mapdev(fps->pap, sizeof(*cth)); + cth_mapsz = cth->base_table_length; + pmap_unmapdev((vm_offset_t)cth, sizeof(*cth)); + + /* + * Map the base table + */ + cth = pmap_mapdev(fps->pap, cth_mapsz); + } + + mpt->mp_fps = fps; + mpt->mp_cth = cth; + mpt->mp_cth_mapsz = cth_mapsz; +} + +static void +mptable_unmap(struct mptable_pos *mpt) +{ + if (mpt->mp_cth != NULL) { + pmap_unmapdev((vm_offset_t)mpt->mp_cth, mpt->mp_cth_mapsz); + mpt->mp_cth = NULL; + mpt->mp_cth_mapsz = 0; + } + if (mpt->mp_fps != NULL) { + pmap_unmapdev((vm_offset_t)mpt->mp_fps, sizeof(*mpt->mp_fps)); + mpt->mp_fps = NULL; + } +} + #ifdef APIC_IO void -- 2.41.0