From: Sepherosa Ziehau Date: Fri, 12 Jun 2009 10:15:38 +0000 (+0800) Subject: Change mptable mapping mechanism during mptable parsing. X-Git-Tag: v2.3.2~184^2~2 X-Git-Url: https://gitweb.dragonflybsd.org/dragonfly.git/commitdiff_plain/981bebd11ba5507ab5887bb66ef52935ab350bed Change mptable mapping mechanism during mptable parsing. - Don't setup PTD for P=V, instead, pmap_mapdev() is used to mapping MP float pointer struct and MP base configuration table. - Get rid of 'mpfps' global variable --- diff --git a/sys/platform/pc32/i386/mp_machdep.c b/sys/platform/pc32/i386/mp_machdep.c index 77cf090ba9..6b196a486b 100644 --- a/sys/platform/pc32/i386/mp_machdep.c +++ b/sys/platform/pc32/i386/mp_machdep.c @@ -87,7 +87,7 @@ /* MP Floating Pointer Structure */ typedef struct MPFPS { char signature[4]; - void *pap; + u_int32_t pap; u_char length; u_char spec_rev; u_char checksum; @@ -158,6 +158,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 int 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); @@ -489,31 +496,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"); - /* 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(); + 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); - *(int *)PTD = 0; - cpu_invltlb(); + mptable_unmap(&mpt); /* local apic is mapped on last page */ SMPpt[NPTEPG - 1] = (pt_entry_t)(PG_V | PG_RW | PG_N | @@ -704,11 +710,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; @@ -718,8 +725,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 */ @@ -738,7 +745,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 @@ -747,14 +754,15 @@ 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 ((cth = mpfps->pap) == 0) + cth = mpt->mp_cth; + if (cth == NULL) panic("MP Configuration Table Header MISSING!"); cpu_apic_address = (vm_offset_t) cth->apic_address; @@ -830,10 +838,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; @@ -844,6 +853,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; @@ -891,13 +903,14 @@ 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 ((cth = mpfps->pap) == 0) + cth = mpt->mp_cth; + if (cth == NULL) panic("MP Configuration Table Header MISSING!"); /* walk the table, recording info of interest */ @@ -1012,6 +1025,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