Change mptable mapping mechanism during mptable parsing.
authorSepherosa Ziehau <sephe@dragonflybsd.org>
Fri, 12 Jun 2009 10:15:38 +0000 (18:15 +0800)
committerSepherosa Ziehau <sephe@dragonflybsd.org>
Fri, 12 Jun 2009 11:07:55 +0000 (19:07 +0800)
- 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

sys/platform/pc32/i386/mp_machdep.c

index 77cf090..6b196a4 100644 (file)
@@ -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