Change mptable mapping mechanism during mptable parsing.
authorMichael Neumann <mneumann@ntecs.de>
Sat, 2 Oct 2010 15:39:10 +0000 (17:39 +0200)
committerMichael Neumann <mneumann@ntecs.de>
Sat, 2 Oct 2010 15:39:10 +0000 (17:39 +0200)
Apply commit 981bebd11ba5507ab5887bb66ef52935ab350bed for x86_64.

sys/platform/pc64/x86_64/mp_machdep.c

index f468740..531be44 100644 (file)
@@ -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