Changeset 894a2c91 in rtems


Ignore:
Timestamp:
Jul 18, 2011, 4:33:30 PM (8 years ago)
Author:
Joel Sherrill <joel.sherrill@…>
Branches:
4.11, master
Children:
9515b955
Parents:
2682dc9
Message:

2011-07-18 Joel Sherrill <joel.sherrill@…>

  • shared/irq/apic.h, shared/smp/smp-imps.c, shared/smp/smp-imps.h: Reformat to be more compliant with RTEMS style.
Location:
c/src/lib/libbsp/i386
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • c/src/lib/libbsp/i386/ChangeLog

    r2682dc9 r894a2c91  
     12011-07-18      Joel Sherrill <joel.sherrill@oarcorp.com>
     2
     3        * shared/irq/apic.h, shared/smp/smp-imps.c, shared/smp/smp-imps.h:
     4        Reformat to be more compliant with RTEMS style.
     5
    162011-07-15      Joel Sherrill <joel.sherrill@oarcorp.com>
    27
  • c/src/lib/libbsp/i386/shared/irq/apic.h

    r2682dc9 r894a2c91  
    5050 * version for AMD Opteron.
    5151 */
    52 #define APIC_BCAST_ID                           0xFF
     52#define APIC_BCAST_ID                           0xFF
    5353
    5454/*
     
    6060 */
    6161/* APIC version register */
    62 #define APIC_VERSION(x)                         ((x) & 0xFF)
    63 #define APIC_MAXREDIR(x)                        (((x) >> 16) & 0xFF)
     62#define APIC_VERSION(x)                         ((x) & 0xFF)
     63#define APIC_MAXREDIR(x)                        (((x) >> 16) & 0xFF)
    6464/* APIC id register */
    65 #define APIC_ID(x)                              ((x) >> 24)
    66 #define APIC_VER_NEW                            0x10
     65#define APIC_ID(x)                              ((x) >> 24)
     66#define APIC_VER_NEW                            0x10
    6767
    68 #define IOAPIC_REGSEL                           0
    69 #define IOAPIC_RW                               0x10
    70 #define         IOAPIC_ID                       0
    71 #define         IOAPIC_VER                      1
    72 #define         IOAPIC_REDIR                    0x10
     68#define IOAPIC_REGSEL                           0
     69#define IOAPIC_RW                               0x10
     70#define         IOAPIC_ID                       0
     71#define         IOAPIC_VER                      1
     72#define         IOAPIC_REDIR                    0x10
    7373
    74 #define LAPIC_ID                                0x20
    75 #define LAPIC_VER                               0x30
    76 #define LAPIC_TPR                               0x80
    77 #define LAPIC_APR                               0x90
    78 #define LAPIC_PPR                               0xA0
    79 #define LAPIC_EOI                               0xB0
    80 #define LAPIC_LDR                               0xD0
    81 #define LAPIC_DFR                               0xE0
    82 #define LAPIC_SPIV                              0xF0
    83 #define         LAPIC_SPIV_ENABLE_APIC          0x100
    84 #define LAPIC_ISR                               0x100
    85 #define LAPIC_TMR                               0x180
    86 #define LAPIC_IRR                               0x200
    87 #define LAPIC_ESR                               0x280
    88 #define LAPIC_ICR                               0x300
    89 #define         LAPIC_ICR_DS_SELF               0x40000
    90 #define         LAPIC_ICR_DS_ALLINC             0x80000
    91 #define         LAPIC_ICR_DS_ALLEX              0xC0000
    92 #define         LAPIC_ICR_TM_LEVEL              0x8000
    93 #define         LAPIC_ICR_LEVELASSERT           0x4000
    94 #define         LAPIC_ICR_STATUS_PEND           0x1000
    95 #define         LAPIC_ICR_DM_LOGICAL            0x800
    96 #define         LAPIC_ICR_DM_LOWPRI             0x100
    97 #define         LAPIC_ICR_DM_SMI                0x200
    98 #define         LAPIC_ICR_DM_NMI                0x400
    99 #define         LAPIC_ICR_DM_INIT               0x500
    100 #define         LAPIC_ICR_DM_SIPI               0x600
    101 #define LAPIC_LVTT                              0x320
    102 #define LAPIC_LVTPC                             0x340
    103 #define LAPIC_LVT0                              0x350
    104 #define LAPIC_LVT1                              0x360
    105 #define LAPIC_LVTE                              0x370
    106 #define LAPIC_TICR                              0x380
    107 #define LAPIC_TCCR                              0x390
    108 #define LAPIC_TDCR                              0x3E0
     74#define LAPIC_ID                                0x20
     75#define LAPIC_VER                               0x30
     76#define LAPIC_TPR                               0x80
     77#define LAPIC_APR                               0x90
     78#define LAPIC_PPR                               0xA0
     79#define LAPIC_EOI                               0xB0
     80#define LAPIC_LDR                               0xD0
     81#define LAPIC_DFR                               0xE0
     82#define LAPIC_SPIV                              0xF0
     83#define         LAPIC_SPIV_ENABLE_APIC          0x100
     84#define LAPIC_ISR                               0x100
     85#define LAPIC_TMR                               0x180
     86#define LAPIC_IRR                               0x200
     87#define LAPIC_ESR                               0x280
     88#define LAPIC_ICR                               0x300
     89#define   LAPIC_ICR_DS_SELF                     0x40000
     90#define   LAPIC_ICR_DS_ALLINC                   0x80000
     91#define   LAPIC_ICR_DS_ALLEX                    0xC0000
     92#define   LAPIC_ICR_TM_LEVEL                    0x8000
     93#define   LAPIC_ICR_LEVELASSERT                 0x4000
     94#define   LAPIC_ICR_STATUS_PEND                 0x1000
     95#define   LAPIC_ICR_DM_LOGICAL                  0x800
     96#define   LAPIC_ICR_DM_LOWPRI                   0x100
     97#define   LAPIC_ICR_DM_SMI                      0x200
     98#define   LAPIC_ICR_DM_NMI                      0x400
     99#define   LAPIC_ICR_DM_INIT                     0x500
     100#define   LAPIC_ICR_DM_SIPI                     0x600
     101#define LAPIC_LVTT                              0x320
     102#define LAPIC_LVTPC                             0x340
     103#define LAPIC_LVT0                              0x350
     104#define LAPIC_LVT1                              0x360
     105#define LAPIC_LVTE                              0x370
     106#define LAPIC_TICR                              0x380
     107#define LAPIC_TCCR                              0x390
     108#define LAPIC_TDCR                              0x3E0
    109109
    110110#endif  /* _APIC_H */
    111 
  • c/src/lib/libbsp/i386/shared/smp/smp-imps.c

    r2682dc9 r894a2c91  
    4242 *           486 CPUs, but is expected to work.
    4343 *   (2) : Presumes "int", "long", and "unsigned" are 32 bits in size, and
    44  *           that 32-bit pointers and memory addressing is used uniformly.
     44 *       that 32-bit pointers and memory addressing is used uniformly.
    4545 */
    4646
    4747#define _SMP_IMPS_C
    48 
    4948
    5049/*
     
    5756
    5857#if 0
    59 #define KERNEL_PRINT(x)         /* some kind of print function */
    60 #define CMOS_WRITE_BYTE(x,y)    /* write unsigned char "y" at CMOS loc "x" */
    61 #define CMOS_READ_BYTE(x)       /* read unsigned char at CMOS loc "x" */
    62 #define PHYS_TO_VIRTUAL(x)      /* convert physical address "x" to virtual */
    63 #define VIRTUAL_TO_PHYS(x)      /* convert virtual address "x" to physical */
    64 #define UDELAY(x)               /* delay roughly at least "x" microsecs */
    65 #define TEST_BOOTED(x)          /* test bootaddr x to see if CPU started */
    66 #define READ_MSR_LO(x)          /* Read MSR low function */
     58#define KERNEL_PRINT(x)       /* some kind of print function */
     59#define CMOS_WRITE_BYTE(x,y)  /* write unsigned char "y" at CMOS loc "x" */
     60#define CMOS_READ_BYTE(x)     /* read unsigned char at CMOS loc "x" */
     61#define PHYS_TO_VIRTUAL(x)    /* convert physical address "x" to virtual */
     62#define VIRTUAL_TO_PHYS(x)    /* convert virtual address "x" to physical */
     63#define UDELAY(x)             /* delay roughly at least "x" microsecs */
     64#define TEST_BOOTED(x)        /* test bootaddr x to see if CPU started */
     65#define READ_MSR_LO(x)        /* Read MSR low function */
    6766#endif
    68 
    6967
    7068/*
     
    8179 *  Defines that are here so as not to be in the global header file.
    8280 */
    83 #define EBDA_SEG_ADDR                   0x40E
    84 #define BIOS_RESET_VECTOR               0x467
    85 #define LAPIC_ADDR_DEFAULT              0xFEE00000uL
    86 #define IOAPIC_ADDR_DEFAULT             0xFEC00000uL
    87 #define CMOS_RESET_CODE                 0xF
    88 #define         CMOS_RESET_JUMP         0xa
    89 #define CMOS_BASE_MEMORY                0x15
    90 
     81#define EBDA_SEG_ADDR       0x40E
     82#define BIOS_RESET_VECTOR   0x467
     83#define LAPIC_ADDR_DEFAULT  0xFEE00000uL
     84#define IOAPIC_ADDR_DEFAULT 0xFEC00000uL
     85#define CMOS_RESET_CODE     0xF
     86#define CMOS_RESET_JUMP     0xa
     87#define CMOS_BASE_MEMORY    0x15
    9188
    9289/*
     
    9491 */
    9592
    96 #define DEF_ENTRIES     23
     93#define DEF_ENTRIES  23
    9794
    9895static int lapic_dummy = 0;
    9996static struct {
    100         imps_processor proc[2];
    101         imps_bus bus[2];
    102         imps_ioapic ioapic;
    103         imps_interrupt intin[16];
    104         imps_interrupt lintin[2];
     97  imps_processor proc[2];
     98  imps_bus bus[2];
     99  imps_ioapic ioapic;
     100  imps_interrupt intin[16];
     101  imps_interrupt lintin[2];
    105102} defconfig = {
    106         { { IMPS_BCT_PROCESSOR, 0, 0, 0, 0, 0},
    107           { IMPS_BCT_PROCESSOR, 1, 0, 0, 0, 0} },
    108         { { IMPS_BCT_BUS, 0, {'E', 'I', 'S', 'A', ' ', ' '}},
    109           { 255, 1, {'P', 'C', 'I', ' ', ' ', ' '}} },
    110         { IMPS_BCT_IOAPIC, 0, 0, IMPS_FLAG_ENABLED, IOAPIC_ADDR_DEFAULT },
    111         { { IMPS_BCT_IO_INTERRUPT, IMPS_INT_EXTINT, 0, 0, 0, 0xFF, 0},
    112           { IMPS_BCT_IO_INTERRUPT, IMPS_INT_INT, 0, 0, 1, 0xFF, 1},
    113           { IMPS_BCT_IO_INTERRUPT, IMPS_INT_INT, 0, 0, 0, 0xFF, 2},
    114           { IMPS_BCT_IO_INTERRUPT, IMPS_INT_INT, 0, 0, 3, 0xFF, 3},
    115           { IMPS_BCT_IO_INTERRUPT, IMPS_INT_INT, 0, 0, 4, 0xFF, 4},
    116           { IMPS_BCT_IO_INTERRUPT, IMPS_INT_INT, 0, 0, 5, 0xFF, 5},
    117           { IMPS_BCT_IO_INTERRUPT, IMPS_INT_INT, 0, 0, 6, 0xFF, 6},
    118           { IMPS_BCT_IO_INTERRUPT, IMPS_INT_INT, 0, 0, 7, 0xFF, 7},
    119           { IMPS_BCT_IO_INTERRUPT, IMPS_INT_INT, 0, 0, 8, 0xFF, 8},
    120           { IMPS_BCT_IO_INTERRUPT, IMPS_INT_INT, 0, 0, 9, 0xFF, 9},
    121           { IMPS_BCT_IO_INTERRUPT, IMPS_INT_INT, 0, 0, 10, 0xFF, 10},
    122           { IMPS_BCT_IO_INTERRUPT, IMPS_INT_INT, 0, 0, 11, 0xFF, 11},
    123           { IMPS_BCT_IO_INTERRUPT, IMPS_INT_INT, 0, 0, 12, 0xFF, 12},
    124           { IMPS_BCT_IO_INTERRUPT, IMPS_INT_INT, 0, 0, 13, 0xFF, 13},
    125           { IMPS_BCT_IO_INTERRUPT, IMPS_INT_INT, 0, 0, 14, 0xFF, 14},
    126           { IMPS_BCT_IO_INTERRUPT, IMPS_INT_INT, 0, 0, 15, 0xFF, 15} },
    127         { { IMPS_BCT_LOCAL_INTERRUPT, IMPS_INT_EXTINT, 0, 0, 15, 0xFF, 0},
    128           { IMPS_BCT_LOCAL_INTERRUPT, IMPS_INT_NMI, 0, 0, 15, 0xFF, 1} }
     103  { { IMPS_BCT_PROCESSOR, 0, 0, 0, 0, 0},
     104    { IMPS_BCT_PROCESSOR, 1, 0, 0, 0, 0} },
     105  { { IMPS_BCT_BUS, 0, {'E', 'I', 'S', 'A', ' ', ' '}},
     106    { 255, 1, {'P', 'C', 'I', ' ', ' ', ' '}} },
     107  { IMPS_BCT_IOAPIC, 0, 0, IMPS_FLAG_ENABLED, IOAPIC_ADDR_DEFAULT },
     108  { { IMPS_BCT_IO_INTERRUPT, IMPS_INT_EXTINT, 0, 0, 0, 0xFF, 0},
     109    { IMPS_BCT_IO_INTERRUPT, IMPS_INT_INT, 0, 0, 1, 0xFF, 1},
     110    { IMPS_BCT_IO_INTERRUPT, IMPS_INT_INT, 0, 0, 0, 0xFF, 2},
     111    { IMPS_BCT_IO_INTERRUPT, IMPS_INT_INT, 0, 0, 3, 0xFF, 3},
     112    { IMPS_BCT_IO_INTERRUPT, IMPS_INT_INT, 0, 0, 4, 0xFF, 4},
     113    { IMPS_BCT_IO_INTERRUPT, IMPS_INT_INT, 0, 0, 5, 0xFF, 5},
     114    { IMPS_BCT_IO_INTERRUPT, IMPS_INT_INT, 0, 0, 6, 0xFF, 6},
     115    { IMPS_BCT_IO_INTERRUPT, IMPS_INT_INT, 0, 0, 7, 0xFF, 7},
     116    { IMPS_BCT_IO_INTERRUPT, IMPS_INT_INT, 0, 0, 8, 0xFF, 8},
     117    { IMPS_BCT_IO_INTERRUPT, IMPS_INT_INT, 0, 0, 9, 0xFF, 9},
     118    { IMPS_BCT_IO_INTERRUPT, IMPS_INT_INT, 0, 0, 10, 0xFF, 10},
     119    { IMPS_BCT_IO_INTERRUPT, IMPS_INT_INT, 0, 0, 11, 0xFF, 11},
     120    { IMPS_BCT_IO_INTERRUPT, IMPS_INT_INT, 0, 0, 12, 0xFF, 12},
     121    { IMPS_BCT_IO_INTERRUPT, IMPS_INT_INT, 0, 0, 13, 0xFF, 13},
     122    { IMPS_BCT_IO_INTERRUPT, IMPS_INT_INT, 0, 0, 14, 0xFF, 14},
     123    { IMPS_BCT_IO_INTERRUPT, IMPS_INT_INT, 0, 0, 15, 0xFF, 15} },
     124  { { IMPS_BCT_LOCAL_INTERRUPT, IMPS_INT_EXTINT, 0, 0, 15, 0xFF, 0},
     125    { IMPS_BCT_LOCAL_INTERRUPT, IMPS_INT_NMI, 0, 0, 15, 0xFF, 1} }
    129126};
    130127
     
    140137unsigned char imps_apic_cpu_map[IMPS_MAX_CPUS];
    141138
    142 
    143139/*
    144140 *  MPS checksum function
     
    146142 *  Function finished.
    147143 */
    148 
    149144static int
    150145get_checksum(unsigned start, int length)
    151146{
    152         unsigned sum = 0;
    153 
    154         while (length-- > 0) {
    155                 sum += *((unsigned char *) (start++));
    156         }
    157 
    158         return (sum&0xFF);
    159 }
    160 
     147  unsigned sum = 0;
     148
     149  while (length-- > 0) {
     150    sum += *((unsigned char *) (start++));
     151  }
     152
     153  return (sum&0xFF);
     154}
    161155
    162156/*
    163157 *  APIC ICR write and status check function.
    164158 */
    165 
    166159static int
    167160send_ipi(unsigned int dst, unsigned int v)
    168161{
    169         int to, send_status;
    170 
    171         IMPS_LAPIC_WRITE(LAPIC_ICR+0x10, (dst << 24));
    172         IMPS_LAPIC_WRITE(LAPIC_ICR, v);
    173 
    174         /* Wait for send to finish */
    175         to = 0;
    176         do {
    177                 UDELAY(100);
    178                 send_status = IMPS_LAPIC_READ(LAPIC_ICR) & LAPIC_ICR_STATUS_PEND;
    179         } while (send_status && (to++ < 1000));
    180 
    181         return (to < 1000);
    182 }
    183 
     162  int to, send_status;
     163
     164  IMPS_LAPIC_WRITE(LAPIC_ICR+0x10, (dst << 24));
     165  IMPS_LAPIC_WRITE(LAPIC_ICR, v);
     166
     167  /* Wait for send to finish */
     168  to = 0;
     169  do {
     170    UDELAY(100);
     171    send_status = IMPS_LAPIC_READ(LAPIC_ICR) & LAPIC_ICR_STATUS_PEND;
     172  } while (send_status && (to++ < 1000));
     173
     174  return (to < 1000);
     175}
    184176
    185177/*
     
    189181 *  that is required.
    190182 */
    191 
    192183static int
    193184boot_cpu(imps_processor *proc)
    194185{
    195         int apicid = proc->apic_id, success = 1, to;
    196         unsigned bootaddr, accept_status;
    197         unsigned bios_reset_vector = PHYS_TO_VIRTUAL(BIOS_RESET_VECTOR);
    198 
    199         /*
    200         * Copy boot code for secondary CPUs here.  Find it in between
    201         * "patch_code_start" and "patch_code_end" symbols.  The other CPUs
    202         * will start there in 16-bit real mode under the 1MB boundary.
    203         * "patch_code_start" should be placed at a 4K-aligned address
    204         * under the 1MB boundary.
    205         */
    206 
    207         extern char patch_code_start[];
    208         extern char patch_code_end[];
    209         bootaddr = (512-64)*1024;
    210         memcpy((char *)bootaddr, patch_code_start, patch_code_end - patch_code_start);
    211 
    212         /*
    213         *  Generic CPU startup sequence starts here.
    214         */
    215 
    216         /* set BIOS reset vector */
    217         CMOS_WRITE_BYTE(CMOS_RESET_CODE, CMOS_RESET_JUMP);
    218         *((volatile unsigned *) bios_reset_vector) = ((bootaddr & 0xFF000) << 12);
    219 
    220         /* clear the APIC error register */
    221         IMPS_LAPIC_WRITE(LAPIC_ESR, 0);
    222         accept_status = IMPS_LAPIC_READ(LAPIC_ESR);
    223 
    224         /* assert INIT IPI */
    225         send_ipi(apicid, LAPIC_ICR_TM_LEVEL | LAPIC_ICR_LEVELASSERT | LAPIC_ICR_DM_INIT);
    226 
    227         UDELAY(10000);
    228 
    229         /* de-assert INIT IPI */
    230         send_ipi(apicid, LAPIC_ICR_TM_LEVEL | LAPIC_ICR_DM_INIT);
    231 
    232         UDELAY(10000);
    233 
    234         /*
    235          *  Send Startup IPIs if not an old pre-integrated APIC.
    236          */
    237 
    238         if (proc->apic_ver >= APIC_VER_NEW) {
    239                 int i;
    240                 for (i = 1; i <= 2; i++) {
    241                         send_ipi(apicid, LAPIC_ICR_DM_SIPI | ((bootaddr >> 12) & 0xFF));
    242                         UDELAY(1000);
    243                 }
    244         }
    245 
    246         /*
    247          *  Check to see if other processor has started.
    248          */
    249         to = 0;
    250         while (!TEST_BOOTED(bootaddr) && to++ < 100)
    251                 UDELAY(10000);
    252         if (to >= 100) {
    253                 KERNEL_PRINT(("CPU Not Responding, DISABLED"));
    254                 success = 0;
    255         } else {
    256                 KERNEL_PRINT(("#%d  Application Processor (AP)", imps_num_cpus));
    257         }
    258 
    259         /*
    260          *  Generic CPU startup sequence ends here, the rest is cleanup.
    261          */
    262 
    263         /* clear the APIC error register */
    264         IMPS_LAPIC_WRITE(LAPIC_ESR, 0);
    265         accept_status = IMPS_LAPIC_READ(LAPIC_ESR);
    266 
    267         /* clean up BIOS reset vector */
    268         CMOS_WRITE_BYTE(CMOS_RESET_CODE, 0);
    269         *((volatile unsigned *) bios_reset_vector) = 0;
    270 
    271         KERNEL_PRINT(("\n"));
    272 
    273         return success;
    274 }
    275 
     186  int apicid = proc->apic_id, success = 1, to;
     187  unsigned bootaddr, accept_status;
     188  unsigned bios_reset_vector = PHYS_TO_VIRTUAL(BIOS_RESET_VECTOR);
     189
     190  /*
     191  * Copy boot code for secondary CPUs here.  Find it in between
     192  * "patch_code_start" and "patch_code_end" symbols.  The other CPUs
     193  * will start there in 16-bit real mode under the 1MB boundary.
     194  * "patch_code_start" should be placed at a 4K-aligned address
     195  * under the 1MB boundary.
     196  */
     197
     198  extern char patch_code_start[];
     199  extern char patch_code_end[];
     200  bootaddr = (512-64)*1024;
     201  memcpy((char *)bootaddr, patch_code_start, patch_code_end - patch_code_start);
     202
     203  /*
     204  *  Generic CPU startup sequence starts here.
     205  */
     206
     207  /* set BIOS reset vector */
     208  CMOS_WRITE_BYTE(CMOS_RESET_CODE, CMOS_RESET_JUMP);
     209  *((volatile unsigned *) bios_reset_vector) = ((bootaddr & 0xFF000) << 12);
     210
     211  /* clear the APIC error register */
     212  IMPS_LAPIC_WRITE(LAPIC_ESR, 0);
     213  accept_status = IMPS_LAPIC_READ(LAPIC_ESR);
     214
     215  /* assert INIT IPI */
     216  send_ipi(
     217    apicid, LAPIC_ICR_TM_LEVEL | LAPIC_ICR_LEVELASSERT | LAPIC_ICR_DM_INIT);
     218
     219  UDELAY(10000);
     220
     221  /* de-assert INIT IPI */
     222  send_ipi(apicid, LAPIC_ICR_TM_LEVEL | LAPIC_ICR_DM_INIT);
     223
     224  UDELAY(10000);
     225
     226  /*
     227   *  Send Startup IPIs if not an old pre-integrated APIC.
     228   */
     229
     230  if (proc->apic_ver >= APIC_VER_NEW) {
     231    int i;
     232    for (i = 1; i <= 2; i++) {
     233      send_ipi(apicid, LAPIC_ICR_DM_SIPI | ((bootaddr >> 12) & 0xFF));
     234      UDELAY(1000);
     235    }
     236  }
     237
     238  /*
     239   *  Check to see if other processor has started.
     240   */
     241  to = 0;
     242  while (!TEST_BOOTED(bootaddr) && to++ < 100)
     243    UDELAY(10000);
     244  if (to >= 100) {
     245    KERNEL_PRINT(("CPU Not Responding, DISABLED"));
     246    success = 0;
     247  } else {
     248    KERNEL_PRINT(("#%d  Application Processor (AP)", imps_num_cpus));
     249  }
     250
     251  /*
     252   *  Generic CPU startup sequence ends here, the rest is cleanup.
     253   */
     254
     255  /* clear the APIC error register */
     256  IMPS_LAPIC_WRITE(LAPIC_ESR, 0);
     257  accept_status = IMPS_LAPIC_READ(LAPIC_ESR);
     258
     259  /* clean up BIOS reset vector */
     260  CMOS_WRITE_BYTE(CMOS_RESET_CODE, 0);
     261  *((volatile unsigned *) bios_reset_vector) = 0;
     262
     263  KERNEL_PRINT(("\n"));
     264
     265  return success;
     266}
    276267
    277268/*
    278269 *  read bios stuff and fill tables
    279270 */
    280 
    281271static void
    282272add_processor(imps_processor *proc)
    283273{
    284         int apicid = proc->apic_id;
    285 
    286         KERNEL_PRINT(("  Processor [APIC id %d ver %d]:  ",
    287                       apicid, proc->apic_ver));
    288         if (!(proc->flags & IMPS_FLAG_ENABLED)) {
    289                 KERNEL_PRINT(("DISABLED\n"));
    290                 return;
    291         }
    292         if (proc->flags & (IMPS_CPUFLAG_BOOT)) {
    293                 KERNEL_PRINT(("#0  BootStrap Processor (BSP)\n"));
    294                 return;
    295         }
    296         if (boot_cpu(proc)) {
    297 
    298                 /*  XXXXX  add OS-specific setup for secondary CPUs here */
    299 
    300                 imps_cpu_apic_map[imps_num_cpus] = apicid;
    301                 imps_apic_cpu_map[apicid] = imps_num_cpus;
    302                 imps_num_cpus++;
    303         }
     274  int apicid = proc->apic_id;
     275
     276  KERNEL_PRINT(("  Processor [APIC id %d ver %d]:  ",
     277          apicid, proc->apic_ver));
     278  if (!(proc->flags & IMPS_FLAG_ENABLED)) {
     279    KERNEL_PRINT(("DISABLED\n"));
     280    return;
     281  }
     282  if (proc->flags & (IMPS_CPUFLAG_BOOT)) {
     283    KERNEL_PRINT(("#0  BootStrap Processor (BSP)\n"));
     284    return;
     285  }
     286  if (boot_cpu(proc)) {
     287
     288    /*  XXXXX  add OS-specific setup for secondary CPUs here */
     289
     290    imps_cpu_apic_map[imps_num_cpus] = apicid;
     291    imps_apic_cpu_map[apicid] = imps_num_cpus;
     292    imps_num_cpus++;
     293  }
    304294}
    305295
     
    308298add_bus(imps_bus *bus)
    309299{
    310         char str[8];
    311 
    312         memcpy(str, bus->bus_type, 6);
    313         str[6] = 0;
    314         KERNEL_PRINT(("  Bus id %d is %s\n", bus->id, str));
    315 
    316         /*  XXXXX  add OS-specific code here */
     300  char str[8];
     301
     302  memcpy(str, bus->bus_type, 6);
     303  str[6] = 0;
     304  KERNEL_PRINT(("  Bus id %d is %s\n", bus->id, str));
     305
     306  /*  XXXXX  add OS-specific code here */
    317307}
    318308
     
    320310add_ioapic(imps_ioapic *ioapic)
    321311{
    322         KERNEL_PRINT(("  I/O APIC id %d ver %d, address: 0x%x  ",
    323                       ioapic->id, ioapic->ver, ioapic->addr));
    324         if (!(ioapic->flags & IMPS_FLAG_ENABLED)) {
    325                 KERNEL_PRINT(("DISABLED\n"));
    326                 return;
    327         }
    328         KERNEL_PRINT(("\n"));
    329 
    330         /*  XXXXX  add OS-specific code here */
    331 }
    332 
     312  KERNEL_PRINT(("  I/O APIC id %d ver %d, address: 0x%x  ",
     313          ioapic->id, ioapic->ver, ioapic->addr));
     314  if (!(ioapic->flags & IMPS_FLAG_ENABLED)) {
     315    KERNEL_PRINT(("DISABLED\n"));
     316    return;
     317  }
     318  KERNEL_PRINT(("\n"));
     319
     320  /*  XXXXX  add OS-specific code here */
     321}
    333322
    334323static void
    335324imps_read_config_table(unsigned start, int count)
    336325{
    337         while (count-- > 0) {
    338                 switch (*((unsigned char *)start)) {
    339                 case IMPS_BCT_PROCESSOR:
    340                         add_processor((imps_processor *)start);
    341                         start += 12;    /* 20 total */
    342                         break;
    343                 case IMPS_BCT_BUS:
    344                         add_bus((imps_bus *)start);
    345                         break;
    346                 case IMPS_BCT_IOAPIC:
    347                         add_ioapic((imps_ioapic *)start);
    348                         break;
    349 #if 0   /*  XXXXX  uncomment this if "add_io_interrupt" is implemented */
    350                 case IMPS_BCT_IO_INTERRUPT:
    351                         add_io_interrupt((imps_interrupt *)start);
    352                         break;
     326  while (count-- > 0) {
     327    switch (*((unsigned char *)start)) {
     328    case IMPS_BCT_PROCESSOR:
     329      add_processor((imps_processor *)start);
     330      start += 12;  /* 20 total */
     331      break;
     332    case IMPS_BCT_BUS:
     333      add_bus((imps_bus *)start);
     334      break;
     335    case IMPS_BCT_IOAPIC:
     336      add_ioapic((imps_ioapic *)start);
     337      break;
     338#if 0  /*  XXXXX  uncomment this if "add_io_interrupt" is implemented */
     339    case IMPS_BCT_IO_INTERRUPT:
     340      add_io_interrupt((imps_interrupt *)start);
     341      break;
    353342#endif
    354 #if 0   /*  XXXXX  uncomment this if "add_local_interrupt" is implemented */
    355                 case IMPS_BCT_LOCAL_INTERRUPT:
    356                         add_local_interupt((imps_interrupt *)start);
    357                         break;
     343#if 0  /*  XXXXX  uncomment this if "add_local_interrupt" is implemented */
     344    case IMPS_BCT_LOCAL_INTERRUPT:
     345      add_local_interupt((imps_interrupt *)start);
     346      break;
    358347#endif
    359                 default:
    360                         break;
    361                 }
    362                 start += 8;
    363         }
    364 }
    365 
     348    default:
     349      break;
     350    }
     351    start += 8;
     352  }
     353}
    366354
    367355static int
    368356imps_bad_bios(imps_fps *fps_ptr)
    369357{
    370         int sum;
    371         imps_cth *local_cth_ptr
    372                 = (imps_cth *) PHYS_TO_VIRTUAL(fps_ptr->cth_ptr);
    373 
    374         if (fps_ptr->feature_info[0] > IMPS_FPS_DEFAULT_MAX) {
    375                 KERNEL_PRINT(("    Invalid MP System Configuration type %d\n",
    376                               fps_ptr->feature_info[0]));
    377                 return 1;
    378         }
    379 
    380         if (fps_ptr->cth_ptr) {
    381                 sum = get_checksum((unsigned)local_cth_ptr,
     358  int sum;
     359  imps_cth *local_cth_ptr
     360    = (imps_cth *) PHYS_TO_VIRTUAL(fps_ptr->cth_ptr);
     361
     362  if (fps_ptr->feature_info[0] > IMPS_FPS_DEFAULT_MAX) {
     363    KERNEL_PRINT(("    Invalid MP System Configuration type %d\n",
     364            fps_ptr->feature_info[0]));
     365    return 1;
     366  }
     367
     368  if (fps_ptr->cth_ptr) {
     369    sum = get_checksum((unsigned)local_cth_ptr,
    382370                                   local_cth_ptr->base_length);
    383                 if (local_cth_ptr->sig != IMPS_CTH_SIGNATURE || sum) {
    384                         KERNEL_PRINT(("    Bad MP Config Table sig 0x%x and/or checksum 0x%x\n", (unsigned)(fps_ptr->cth_ptr), sum));
    385                         return 1;
    386                 }
    387                 if (local_cth_ptr->spec_rev != fps_ptr->spec_rev) {
    388                         KERNEL_PRINT(("    Bad MP Config Table sub-revision # %d\n", local_cth_ptr->spec_rev));
    389                         return 1;
    390                 }
    391                 if (local_cth_ptr->extended_length) {
    392                         sum = (get_checksum(((unsigned)local_cth_ptr)
    393                                             + local_cth_ptr->base_length,
    394                                             local_cth_ptr->extended_length)
    395                                + local_cth_ptr->extended_checksum) & 0xFF;
    396                         if (sum) {
    397                                 KERNEL_PRINT(("    Bad Extended MP Config Table checksum 0x%x\n", sum));
    398                                 return 1;
    399                         }
    400                 }
    401         } else if (!fps_ptr->feature_info[0]) {
    402                 KERNEL_PRINT(("    Missing configuration information\n"));
    403                 return 1;
    404         }
    405 
    406         return 0;
    407 }
    408 
     371    if (local_cth_ptr->sig != IMPS_CTH_SIGNATURE || sum) {
     372      KERNEL_PRINT(
     373        ("    Bad MP Config Table sig 0x%x and/or checksum 0x%x\n",
     374        (unsigned)(fps_ptr->cth_ptr),
     375        sum)
     376      );
     377      return 1;
     378    }
     379    if (local_cth_ptr->spec_rev != fps_ptr->spec_rev) {
     380      KERNEL_PRINT(
     381        ("    Bad MP Config Table sub-revision # %d\n",
     382        local_cth_ptr->spec_rev)
     383      );
     384      return 1;
     385    }
     386    if (local_cth_ptr->extended_length) {
     387      sum = (get_checksum(((unsigned)local_cth_ptr)
     388              + local_cth_ptr->base_length,
     389              local_cth_ptr->extended_length)
     390             + local_cth_ptr->extended_checksum) & 0xFF;
     391      if (sum) {
     392        KERNEL_PRINT(("    Bad Extended MP Config Table checksum 0x%x\n", sum));
     393        return 1;
     394      }
     395    }
     396  } else if (!fps_ptr->feature_info[0]) {
     397    KERNEL_PRINT(("    Missing configuration information\n"));
     398    return 1;
     399  }
     400
     401  return 0;
     402}
    409403
    410404static void
    411405imps_read_bios(imps_fps *fps_ptr)
    412406{
    413         int apicid;
    414         unsigned cth_start, cth_count;
    415         imps_cth *local_cth_ptr
    416                 = (imps_cth *)PHYS_TO_VIRTUAL(fps_ptr->cth_ptr);
    417         char *str_ptr;
    418 
    419         KERNEL_PRINT(("Intel MultiProcessor Spec 1.%d BIOS support detected\n",
    420                       fps_ptr->spec_rev));
    421 
    422         /*
    423          *  Do all checking of errors which would definitely
    424          *  lead to failure of the SMP boot here.
    425          */
    426 
    427         if (imps_bad_bios(fps_ptr)) {
    428                 KERNEL_PRINT(("    Disabling MPS support\n"));
    429                 return;
    430         }
    431 
    432         if (fps_ptr->feature_info[1] & IMPS_FPS_IMCRP_BIT) {
    433                 str_ptr = "IMCR and PIC";
    434         } else {
    435                 str_ptr = "Virtual Wire";
    436         }
    437         if (fps_ptr->cth_ptr) {
    438                 imps_lapic_addr = local_cth_ptr->lapic_addr;
    439         } else {
    440                 imps_lapic_addr = LAPIC_ADDR_DEFAULT;
    441         }
    442         KERNEL_PRINT(("    APIC config: \"%s mode\"    Local APIC address: 0x%x\n",
    443                       str_ptr, imps_lapic_addr));
    444         if (imps_lapic_addr != (READ_MSR_LO(0x1b) & 0xFFFFF000)) {
    445                 KERNEL_PRINT(("Inconsistent Local APIC address, Disabling SMP support\n"));
    446                 return;
    447         }
    448         imps_lapic_addr = PHYS_TO_VIRTUAL(imps_lapic_addr);
    449 
    450         /*
    451          *  Setup primary CPU.
    452          */
    453         apicid = IMPS_LAPIC_READ(LAPIC_SPIV);
    454         IMPS_LAPIC_WRITE(LAPIC_SPIV, apicid|LAPIC_SPIV_ENABLE_APIC);
    455         apicid = APIC_ID(IMPS_LAPIC_READ(LAPIC_ID));
    456         imps_cpu_apic_map[0] = apicid;
    457         imps_apic_cpu_map[apicid] = 0;
    458 
    459         if (fps_ptr->cth_ptr) {
    460                 char str1[16], str2[16];
    461                 memcpy(str1, local_cth_ptr->oem_id, 8);
    462                 str1[8] = 0;
    463                 memcpy(str2, local_cth_ptr->prod_id, 12);
    464                 str2[12] = 0;
    465                 KERNEL_PRINT(("  OEM id: %s  Product id: %s\n", str1, str2));
    466                 cth_start = ((unsigned) local_cth_ptr) + sizeof(imps_cth);
    467                 cth_count = local_cth_ptr->entry_count;
    468         } else {
    469                 *((volatile unsigned *) IOAPIC_ADDR_DEFAULT) =  IOAPIC_ID;
    470                 defconfig.ioapic.id
    471                         = APIC_ID(*((volatile unsigned *)
    472                                     (IOAPIC_ADDR_DEFAULT+IOAPIC_RW)));
    473                 *((volatile unsigned *) IOAPIC_ADDR_DEFAULT) =  IOAPIC_VER;
    474                 defconfig.ioapic.ver
    475                         = APIC_VERSION(*((volatile unsigned *)
    476                                          (IOAPIC_ADDR_DEFAULT+IOAPIC_RW)));
    477                 defconfig.proc[apicid].flags
    478                   = IMPS_FLAG_ENABLED|IMPS_CPUFLAG_BOOT;
    479                 defconfig.proc[!apicid].flags = IMPS_FLAG_ENABLED;
    480                 imps_num_cpus = 2;
    481                 if (fps_ptr->feature_info[0] == 1
    482                  || fps_ptr->feature_info[0] == 5) {
    483                         memcpy(defconfig.bus[0].bus_type, "ISA   ", 6);
    484                 }
    485                 if (fps_ptr->feature_info[0] == 4
    486                  || fps_ptr->feature_info[0] == 7) {
    487                         memcpy(defconfig.bus[0].bus_type, "MCA   ", 6);
    488                 }
    489                 if (fps_ptr->feature_info[0] > 4) {
    490                         defconfig.proc[0].apic_ver = 0x10;
    491                         defconfig.proc[1].apic_ver = 0x10;
    492                         defconfig.bus[1].type = IMPS_BCT_BUS;
    493                 }
    494                 if (fps_ptr->feature_info[0] == 2) {
    495                         defconfig.intin[2].type = 255;
    496                         defconfig.intin[13].type = 255;
    497                 }
    498                 if (fps_ptr->feature_info[0] == 7) {
    499                         defconfig.intin[0].type = 255;
    500                 }
    501                 cth_start = (unsigned) &defconfig;
    502                 cth_count = DEF_ENTRIES;
    503         }
    504         imps_read_config_table(cth_start, cth_count);
    505 
    506         /* %%%%% ESB read extended entries here */
    507 
    508         imps_enabled = 1;
    509 }
    510 
     407  int apicid;
     408  unsigned cth_start, cth_count;
     409  imps_cth *local_cth_ptr
     410    = (imps_cth *)PHYS_TO_VIRTUAL(fps_ptr->cth_ptr);
     411  char *str_ptr;
     412
     413  KERNEL_PRINT(("Intel MultiProcessor Spec 1.%d BIOS support detected\n",
     414          fps_ptr->spec_rev));
     415
     416  /*
     417   *  Do all checking of errors which would definitely
     418   *  lead to failure of the SMP boot here.
     419   */
     420  if (imps_bad_bios(fps_ptr)) {
     421    KERNEL_PRINT(("    Disabling MPS support\n"));
     422    return;
     423  }
     424
     425  if (fps_ptr->feature_info[1] & IMPS_FPS_IMCRP_BIT) {
     426    str_ptr = "IMCR and PIC";
     427  } else {
     428    str_ptr = "Virtual Wire";
     429  }
     430  if (fps_ptr->cth_ptr) {
     431    imps_lapic_addr = local_cth_ptr->lapic_addr;
     432  } else {
     433    imps_lapic_addr = LAPIC_ADDR_DEFAULT;
     434  }
     435  KERNEL_PRINT(("    APIC config: \"%s mode\"    Local APIC address: 0x%x\n",
     436          str_ptr, imps_lapic_addr));
     437  if (imps_lapic_addr != (READ_MSR_LO(0x1b) & 0xFFFFF000)) {
     438    KERNEL_PRINT(("Inconsistent Local APIC address, Disabling SMP support\n"));
     439    return;
     440  }
     441  imps_lapic_addr = PHYS_TO_VIRTUAL(imps_lapic_addr);
     442
     443  /*
     444   *  Setup primary CPU.
     445   */
     446  apicid = IMPS_LAPIC_READ(LAPIC_SPIV);
     447  IMPS_LAPIC_WRITE(LAPIC_SPIV, apicid|LAPIC_SPIV_ENABLE_APIC);
     448  apicid = APIC_ID(IMPS_LAPIC_READ(LAPIC_ID));
     449  imps_cpu_apic_map[0] = apicid;
     450  imps_apic_cpu_map[apicid] = 0;
     451
     452  if (fps_ptr->cth_ptr) {
     453    char str1[16], str2[16];
     454    memcpy(str1, local_cth_ptr->oem_id, 8);
     455    str1[8] = 0;
     456    memcpy(str2, local_cth_ptr->prod_id, 12);
     457    str2[12] = 0;
     458    KERNEL_PRINT(("  OEM id: %s  Product id: %s\n", str1, str2));
     459    cth_start = ((unsigned) local_cth_ptr) + sizeof(imps_cth);
     460    cth_count = local_cth_ptr->entry_count;
     461  } else {
     462    *((volatile unsigned *) IOAPIC_ADDR_DEFAULT) =  IOAPIC_ID;
     463    defconfig.ioapic.id
     464      = APIC_ID(*((volatile unsigned *)
     465            (IOAPIC_ADDR_DEFAULT+IOAPIC_RW)));
     466    *((volatile unsigned *) IOAPIC_ADDR_DEFAULT) =  IOAPIC_VER;
     467    defconfig.ioapic.ver
     468      = APIC_VERSION(*((volatile unsigned *)
     469           (IOAPIC_ADDR_DEFAULT+IOAPIC_RW)));
     470    defconfig.proc[apicid].flags
     471      = IMPS_FLAG_ENABLED|IMPS_CPUFLAG_BOOT;
     472    defconfig.proc[!apicid].flags = IMPS_FLAG_ENABLED;
     473    imps_num_cpus = 2;
     474    if (fps_ptr->feature_info[0] == 1
     475     || fps_ptr->feature_info[0] == 5) {
     476      memcpy(defconfig.bus[0].bus_type, "ISA   ", 6);
     477    }
     478    if (fps_ptr->feature_info[0] == 4
     479     || fps_ptr->feature_info[0] == 7) {
     480      memcpy(defconfig.bus[0].bus_type, "MCA   ", 6);
     481    }
     482    if (fps_ptr->feature_info[0] > 4) {
     483      defconfig.proc[0].apic_ver = 0x10;
     484      defconfig.proc[1].apic_ver = 0x10;
     485      defconfig.bus[1].type = IMPS_BCT_BUS;
     486    }
     487    if (fps_ptr->feature_info[0] == 2) {
     488      defconfig.intin[2].type = 255;
     489      defconfig.intin[13].type = 255;
     490    }
     491    if (fps_ptr->feature_info[0] == 7) {
     492      defconfig.intin[0].type = 255;
     493    }
     494    cth_start = (unsigned) &defconfig;
     495    cth_count = DEF_ENTRIES;
     496  }
     497  imps_read_config_table(cth_start, cth_count);
     498
     499  /* %%%%% ESB read extended entries here */
     500
     501  imps_enabled = 1;
     502}
    511503
    512504/*
     
    524516 *  Function finished.
    525517 */
    526 
    527518static int
    528519imps_scan(unsigned start, unsigned length)
    529520{
    530         IMPS_DEBUG_PRINT(("Scanning from 0x%x for %d bytes\n",
    531                           start, length));
    532 
    533         while (length > 0) {
    534                 imps_fps *fps_ptr = (imps_fps *) PHYS_TO_VIRTUAL(start);
    535 
    536                 if (fps_ptr->sig == IMPS_FPS_SIGNATURE
    537                 && fps_ptr->length == 1
    538                 && (fps_ptr->spec_rev == 1 || fps_ptr->spec_rev == 4)
    539                 && !get_checksum(start, 16)) {
    540                         IMPS_DEBUG_PRINT(("Found MP Floating Structure Pointer at %x\n", start));
    541                         imps_read_bios(fps_ptr);
    542                         return 1;
    543                 }
    544 
    545                 length -= 16;
    546                 start += 16;
    547         }
    548 
    549         return 0;
     521  IMPS_DEBUG_PRINT(("Scanning from 0x%x for %d bytes\n",
     522        start, length));
     523
     524  while (length > 0) {
     525    imps_fps *fps_ptr = (imps_fps *) PHYS_TO_VIRTUAL(start);
     526
     527    if (fps_ptr->sig == IMPS_FPS_SIGNATURE
     528    && fps_ptr->length == 1
     529    && (fps_ptr->spec_rev == 1 || fps_ptr->spec_rev == 4)
     530    && !get_checksum(start, 16)) {
     531      IMPS_DEBUG_PRINT(("Found MP Floating Structure Pointer at %x\n", start));
     532      imps_read_bios(fps_ptr);
     533      return 1;
     534    }
     535
     536    length -= 16;
     537    start += 16;
     538  }
     539
     540  return 0;
    550541}
    551542
     
    557548imps_force(int ncpus)
    558549{
    559         int apicid, i;
    560         imps_processor p;
    561 
    562         KERNEL_PRINT(("Intel MultiProcessor \"Force\" Support\n"));
    563 
    564         imps_lapic_addr = (READ_MSR_LO(0x1b) & 0xFFFFF000);
    565         imps_lapic_addr = PHYS_TO_VIRTUAL(imps_lapic_addr);
    566 
    567         /*
    568          *  Setup primary CPU.
    569          */
    570         apicid = IMPS_LAPIC_READ(LAPIC_SPIV);
    571         IMPS_LAPIC_WRITE(LAPIC_SPIV, apicid|LAPIC_SPIV_ENABLE_APIC);
    572         apicid = APIC_ID(IMPS_LAPIC_READ(LAPIC_ID));
    573         imps_cpu_apic_map[0] = apicid;
    574         imps_apic_cpu_map[apicid] = 0;
    575 
    576         p.type = 0;
    577         p.apic_ver = 0x10;
    578         p.signature = p.features = 0;
    579 
    580         for (i = 0; i < ncpus; i++) {
    581                 if (apicid == i) {
    582                         p.flags = IMPS_FLAG_ENABLED | IMPS_CPUFLAG_BOOT;
    583                 } else {
    584                         p.flags = IMPS_FLAG_ENABLED;
    585                 }
    586                 p.apic_id = i;
    587                 add_processor(&p);
    588         }
    589 
    590         return imps_num_cpus;
    591 }
    592 
     550  int apicid, i;
     551  imps_processor p;
     552
     553  KERNEL_PRINT(("Intel MultiProcessor \"Force\" Support\n"));
     554
     555  imps_lapic_addr = (READ_MSR_LO(0x1b) & 0xFFFFF000);
     556  imps_lapic_addr = PHYS_TO_VIRTUAL(imps_lapic_addr);
     557
     558  /*
     559   *  Setup primary CPU.
     560   */
     561  apicid = IMPS_LAPIC_READ(LAPIC_SPIV);
     562  IMPS_LAPIC_WRITE(LAPIC_SPIV, apicid|LAPIC_SPIV_ENABLE_APIC);
     563  apicid = APIC_ID(IMPS_LAPIC_READ(LAPIC_ID));
     564  imps_cpu_apic_map[0] = apicid;
     565  imps_apic_cpu_map[apicid] = 0;
     566
     567  p.type = 0;
     568  p.apic_ver = 0x10;
     569  p.signature = p.features = 0;
     570
     571  for (i = 0; i < ncpus; i++) {
     572    if (apicid == i) {
     573      p.flags = IMPS_FLAG_ENABLED | IMPS_CPUFLAG_BOOT;
     574    } else {
     575      p.flags = IMPS_FLAG_ENABLED;
     576    }
     577    p.apic_id = i;
     578    add_processor(&p);
     579  }
     580
     581  return imps_num_cpus;
     582}
    593583
    594584/*
     
    603593 *
    604594 *   (1) : A non-linear virtual to physical memory mapping is probably OK,
    605  *           as (I think) the structures all fall within page boundaries,
    606  *           but a linear mapping is recommended.  Currently assumes that
    607  *           the mapping will remain identical over time (which should be
    608  *           OK since it only accesses memory which shouldn't be munged
    609  *           by the OS anyway).
     595 *       as (I think) the structures all fall within page boundaries,
     596 *       but a linear mapping is recommended.  Currently assumes that
     597 *       the mapping will remain identical over time (which should be
     598 *       OK since it only accesses memory which shouldn't be munged
     599 *       by the OS anyway).
    610600 *   (2) : The OS only consumes memory which the BIOS says is OK to use,
    611  *           and not any of the BIOS standard areas (the areas 0x400 to
    612  *           0x600, the EBDA, 0xE0000 to 0xFFFFF, and unreported physical
    613  *           RAM).  Sometimes a small amount of physical RAM is not
    614  *           reported by the BIOS, to be used to store MPS and other
    615  *           information.
     601 *       and not any of the BIOS standard areas (the areas 0x400 to
     602 *       0x600, the EBDA, 0xE0000 to 0xFFFFF, and unreported physical
     603 *       RAM).  Sometimes a small amount of physical RAM is not
     604 *       reported by the BIOS, to be used to store MPS and other
     605 *       information.
    616606 *   (3) : It must be possible to read the CMOS.
    617607 *   (4) : There must be between 512K and 640K of lower memory (this is a
    618  *           sanity check).
     608 *       sanity check).
    619609 *
    620610 *  Function finished.
    621611 */
    622 
    623612int
    624613imps_probe(void)
    625614{
    626         /*
    627         *  Determine possible address of the EBDA
    628         */
    629         unsigned ebda_addr = *((unsigned short *)
    630                                PHYS_TO_VIRTUAL(EBDA_SEG_ADDR)) << 4;
    631 
    632         /*
    633         *  Determine amount of installed lower memory (not *available*
    634         *  lower memory).
    635         *
    636         *  NOTE:  This should work reliably as long as we verify the
    637         *         machine is at least a system that could possibly have
    638         *         MPS compatibility to begin with.
    639         */
    640         unsigned mem_lower = ((CMOS_READ_BYTE(CMOS_BASE_MEMORY+1) << 8)
    641                               | CMOS_READ_BYTE(CMOS_BASE_MEMORY))       << 10;
     615  /*
     616  *  Determine possible address of the EBDA
     617  */
     618  unsigned ebda_addr = *((unsigned short *)
     619             PHYS_TO_VIRTUAL(EBDA_SEG_ADDR)) << 4;
     620
     621  /*
     622  *  Determine amount of installed lower memory (not *available*
     623  *  lower memory).
     624  *
     625  *  NOTE:  This should work reliably as long as we verify the
     626  *         machine is at least a system that could possibly have
     627  *         MPS compatibility to begin with.
     628  */
     629  unsigned mem_lower = ((CMOS_READ_BYTE(CMOS_BASE_MEMORY+1) << 8)
     630            | CMOS_READ_BYTE(CMOS_BASE_MEMORY))       << 10;
    642631
    643632#ifdef IMPS_DEBUG
    644         imps_enabled = 0;
    645         imps_num_cpus = 1;
     633  imps_enabled = 0;
     634  imps_num_cpus = 1;
    646635#endif
    647636
    648         /*
    649         *  Sanity check : if this isn't reasonable, it is almost impossibly
    650         *    unlikely to be an MPS compatible machine, so return failure.
    651         */
    652         if (mem_lower < 512*1024 || mem_lower > 640*1024) {
    653                 return 0;
    654         }
    655 
    656         if (ebda_addr > mem_lower - 1024
    657         || ebda_addr + *((unsigned char *) PHYS_TO_VIRTUAL(ebda_addr))
     637  /*
     638  *  Sanity check : if this isn't reasonable, it is almost impossibly
     639  *    unlikely to be an MPS compatible machine, so return failure.
     640  */
     641  if (mem_lower < 512*1024 || mem_lower > 640*1024) {
     642    return 0;
     643  }
     644
     645  if (ebda_addr > mem_lower - 1024
     646  || ebda_addr + *((unsigned char *) PHYS_TO_VIRTUAL(ebda_addr))
    658647         * 1024 > mem_lower) {
    659                 ebda_addr = 0;
    660         }
    661 
    662         if (((ebda_addr && imps_scan(ebda_addr, 1024))
    663         || (!ebda_addr && imps_scan(mem_lower - 1024, 1024))
    664         || imps_scan(0xF0000, 0x10000)) && imps_enabled) {
    665                 return imps_num_cpus;
    666         }
    667 
    668         /*
    669         *  If no BIOS info on MPS hardware is found, then return failure.
    670         */
    671 
    672         return 0;
    673 }
    674 
     648    ebda_addr = 0;
     649  }
     650
     651  if (((ebda_addr && imps_scan(ebda_addr, 1024))
     652  || (!ebda_addr && imps_scan(mem_lower - 1024, 1024))
     653  || imps_scan(0xF0000, 0x10000)) && imps_enabled) {
     654    return imps_num_cpus;
     655  }
     656
     657  /*
     658  *  If no BIOS info on MPS hardware is found, then return failure.
     659  */
     660
     661  return 0;
     662}
     663
  • c/src/lib/libbsp/i386/shared/smp/smp-imps.h

    r2682dc9 r894a2c91  
    4343/* make sure "apic.h" is included */
    4444#ifndef _APIC_H
    45 #error          Must include "apic.h" before "smp-imps.h"
     45#error          Must include "apic.h" before "smp-imps.h"
    4646#endif  /* !_APIC_H */
    4747
     
    5050 */
    5151
    52 #define IMPS_READ(x)    (*((volatile unsigned *) (x)))
    53 #define IMPS_WRITE(x,y) (*((volatile unsigned *) (x)) = (y))
     52#define IMPS_READ(x)    (*((volatile unsigned *) (x)))
     53#define IMPS_WRITE(x,y) (*((volatile unsigned *) (x)) = (y))
    5454
    5555#ifdef IMPS_DEBUG
     
    5959#endif /* !IMPS_DEBUG */
    6060
    61 #define IMPS_MAX_CPUS                   APIC_BCAST_ID
     61#define IMPS_MAX_CPUS                   APIC_BCAST_ID
    6262
    6363/*
     
    6565 *  Floating Pointer Structure.
    6666 */
    67 #define IMPS_FPS_SIGNATURE      ('_' | ('M'<<8) | ('P'<<16) | ('_'<<24))
    68 #define IMPS_FPS_IMCRP_BIT      0x80
    69 #define IMPS_FPS_DEFAULT_MAX    7
     67#define IMPS_FPS_SIGNATURE      ('_' | ('M'<<8) | ('P'<<16) | ('_'<<24))
     68#define IMPS_FPS_IMCRP_BIT      0x80
     69#define IMPS_FPS_DEFAULT_MAX    7
    7070
    7171/*
     
    7373 *  Configuration Table Header.
    7474 */
    75 #define IMPS_CTH_SIGNATURE      ('P' | ('C'<<8) | ('M'<<16) | ('P'<<24))
     75#define IMPS_CTH_SIGNATURE      ('P' | ('C'<<8) | ('M'<<16) | ('P'<<24))
    7676
    7777/*
    7878 *  These are the "type" values for Base MP Configuration Table entries.
    7979 */
    80 #define         IMPS_FLAG_ENABLED       1
    81 #define IMPS_BCT_PROCESSOR              0
    82 #define         IMPS_CPUFLAG_BOOT       2
    83 #define IMPS_BCT_BUS                    1
    84 #define IMPS_BCT_IOAPIC                 2
    85 #define IMPS_BCT_IO_INTERRUPT           3
    86 #define IMPS_BCT_LOCAL_INTERRUPT        4
    87 #define         IMPS_INT_INT            0
    88 #define         IMPS_INT_NMI            1
    89 #define         IMPS_INT_SMI            2
    90 #define         IMPS_INT_EXTINT         3
     80#define         IMPS_FLAG_ENABLED       1
     81#define IMPS_BCT_PROCESSOR              0
     82#define         IMPS_CPUFLAG_BOOT       2
     83#define IMPS_BCT_BUS                    1
     84#define IMPS_BCT_IOAPIC                 2
     85#define IMPS_BCT_IO_INTERRUPT           3
     86#define IMPS_BCT_LOCAL_INTERRUPT        4
     87#define         IMPS_INT_INT            0
     88#define         IMPS_INT_NMI            1
     89#define         IMPS_INT_SMI            2
     90#define         IMPS_INT_EXTINT         3
    9191
    9292
     
    9595 */
    9696
    97 typedef struct imps_fps imps_fps;       /* MP floating pointer structure */
    98 typedef struct imps_cth imps_cth;       /* MP configuration table header */
     97typedef struct imps_fps imps_fps;       /* MP floating pointer structure */
     98typedef struct imps_cth imps_cth;       /* MP configuration table header */
    9999typedef struct imps_processor imps_processor;
    100100typedef struct imps_bus imps_bus;
     
    115115struct imps_fps
    116116{
    117         unsigned sig;
    118         imps_cth *cth_ptr;
    119         unsigned char length;
    120         unsigned char spec_rev;
    121         unsigned char checksum;
    122         unsigned char feature_info[5];
     117  unsigned sig;
     118  imps_cth *cth_ptr;
     119  unsigned char length;
     120  unsigned char spec_rev;
     121  unsigned char checksum;
     122  unsigned char feature_info[5];
    123123};
    124124
     
    131131struct imps_cth
    132132{
    133         unsigned sig;
    134         unsigned short base_length;
    135         unsigned char spec_rev;
    136         unsigned char checksum;
    137         char oem_id[8];
    138         char prod_id[12];
    139         unsigned oem_table_ptr;
    140         unsigned short oem_table_size;
    141         unsigned short entry_count;
    142         unsigned lapic_addr;
    143         unsigned short extended_length;
    144         unsigned char extended_checksum;
    145         char reserved[1];
     133  unsigned sig;
     134  unsigned short base_length;
     135  unsigned char spec_rev;
     136  unsigned char checksum;
     137  char oem_id[8];
     138  char prod_id[12];
     139  unsigned oem_table_ptr;
     140  unsigned short oem_table_size;
     141  unsigned short entry_count;
     142  unsigned lapic_addr;
     143  unsigned short extended_length;
     144  unsigned char extended_checksum;
     145        char reserved[1];
    146146};
    147147
     
    154154struct imps_processor
    155155{
    156         unsigned char type;                     /* must be 0 */
    157         unsigned char apic_id;
    158         unsigned char apic_ver;
    159         unsigned char flags;
    160         unsigned signature;
    161         unsigned features;
    162         char reserved[8];
     156  unsigned char type;                     /* must be 0 */
     157  unsigned char apic_id;
     158  unsigned char apic_ver;
     159  unsigned char flags;
     160  unsigned signature;
     161  unsigned features;
     162  char reserved[8];
    163163};
    164164
    165165struct imps_bus
    166166{
    167         unsigned char type;                     /* must be 1 */
    168         unsigned char id;
    169         char bus_type[6];
     167  unsigned char type;                     /* must be 1 */
     168  unsigned char id;
     169  char bus_type[6];
    170170};
    171171
    172172struct imps_ioapic
    173173{
    174         unsigned char type;                     /* must be 2 */
    175         unsigned char id;
    176         unsigned char ver;
    177         unsigned char flags;
    178         unsigned addr;
     174  unsigned char type;                     /* must be 2 */
     175  unsigned char id;
     176  unsigned char ver;
     177  unsigned char flags;
     178  unsigned addr;
    179179};
    180180
    181181struct imps_interrupt
    182182{
    183         unsigned char type;                     /* must be 3 or 4 */
    184         unsigned char int_type;
    185         unsigned short flags;
    186         unsigned char source_bus_id;
    187         unsigned char source_bus_irq;
    188         unsigned char dest_apic_id;
    189         unsigned char dest_apic_intin;
    190 };
    191 
     183  unsigned char type;                     /* must be 3 or 4 */
     184  unsigned char int_type;
     185  unsigned short flags;
     186  unsigned char source_bus_id;
     187  unsigned char source_bus_irq;
     188  unsigned char dest_apic_id;
     189  unsigned char dest_apic_intin;
     190};
    192191
    193192/*
     
    216215extern unsigned char imps_cpu_apic_map[IMPS_MAX_CPUS];
    217216extern unsigned char imps_apic_cpu_map[IMPS_MAX_CPUS];
    218 
    219217
    220218/*
     
    230228 *  and is valid, else 0.
    231229 */
    232 
    233230int imps_probe(void);
    234231
     
    237234 *  to start, and it will assume a certain number and try it.
    238235 */
    239 
    240236int imps_force(int ncpus);
    241237
     
    244240 *  Defines that use variables
    245241 */
    246 
    247242#define IMPS_LAPIC_READ(x)  (*((volatile unsigned *) (imps_lapic_addr+(x))))
    248243#define IMPS_LAPIC_WRITE(x, y)   \
Note: See TracChangeset for help on using the changeset viewer.