Changeset f701b236 in mainline for arch/ia32/src/smp/apic.c


Ignore:
Timestamp:
2005-11-24T00:46:43Z (19 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
9149135
Parents:
8418c7d
Message:

More SMP cleanup.
Suddenly, keyboard started to work on SMP under Simics.
Still not functional on Bochs (will consult Bochs people).
Doxygen style comments for apic.c.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • arch/ia32/src/smp/apic.c

    r8418c7d rf701b236  
    6363__u32 apic_id_mask = 0;
    6464
    65 int apic_poll_errors(void);
     65static int apic_poll_errors(void);
     66
     67static char *delmod_str[] = {
     68        "Fixed",
     69        "Lowest Priority",
     70        "SMI",
     71        "Reserved",
     72        "NMI",
     73        "INIT",
     74        "STARTUP",
     75        "ExtInt"
     76};
     77
     78static char *destmod_str[] = {
     79        "Physical",
     80        "Logical"
     81};
     82
     83static char *trigmod_str[] = {
     84        "Edge",
     85        "Level"
     86};
     87
     88static char *mask_str[] = {
     89        "Unmasked",
     90        "Masked"
     91};
     92
     93static char *delivs_str[] = {
     94        "Idle",
     95        "Send Pending"
     96};
     97
     98static char *tm_mode_str[] = {
     99        "One-shot",
     100        "Periodic"
     101};
     102
     103static char *intpol_str[] = {
     104        "Polarity High",
     105        "Polarity Low"
     106};
    66107
    67108/** Initialize APIC on BSP. */
     
    115156}
    116157
     158/** APIC spurious interrupt handler.
     159 *
     160 * @param n Interrupt vector.
     161 * @param stack Interrupted stack.
     162 */
    117163void apic_spurious(__u8 n, __native stack[])
    118164{
     
    120166}
    121167
     168/** Poll for APIC errors.
     169 *
     170 * Examine Error Status Register and report all errors found.
     171 *
     172 * @return 0 on error, 1 on success.
     173 */
    122174int apic_poll_errors(void)
    123175{
    124         __u32 esr;
    125        
    126         esr = l_apic[ESR] & ~ESRClear;
    127        
    128         if ((esr>>0) & 1)
     176        esr_t esr;
     177       
     178        esr.value = l_apic[ESR];
     179       
     180        if (esr.send_checksum_error)
    129181                printf("Send CS Error\n");
    130         if ((esr>>1) & 1)
     182        if (esr.receive_checksum_error)
    131183                printf("Receive CS Error\n");
    132         if ((esr>>2) & 1)
     184        if (esr.send_accept_error)
    133185                printf("Send Accept Error\n");
    134         if ((esr>>3) & 1)
     186        if (esr.receive_accept_error)
    135187                printf("Receive Accept Error\n");
    136         if ((esr>>5) & 1)
     188        if (esr.send_illegal_vector)
    137189                printf("Send Illegal Vector\n");
    138         if ((esr>>6) & 1)
     190        if (esr.received_illegal_vector)
    139191                printf("Received Illegal Vector\n");
    140         if ((esr>>7) & 1)
     192        if (esr.illegal_register_address)
    141193                printf("Illegal Register Address\n");
    142194
    143         return !esr;
    144 }
    145 
    146 /*
    147  * Send all CPUs excluding CPU IPI vector.
     195        return !esr.err_bitmap;
     196}
     197
     198/** Send all CPUs excluding CPU IPI vector.
     199 *
     200 * @param vector Interrupt vector to be sent.
     201 *
     202 * @return 0 on failure, 1 on success.
    148203 */
    149204int l_apic_broadcast_custom_ipi(__u8 vector)
     
    168223}
    169224
    170 /*
    171  * Universal Start-up Algorithm for bringing up the AP processors.
     225/** Universal Start-up Algorithm for bringing up the AP processors.
     226 *
     227 * @param apicid APIC ID of the processor to be brought up.
     228 *
     229 * @return 0 on failure, 1 on success.
    172230 */
    173231int l_apic_send_init_ipi(__u8 apicid)
     
    239297}
    240298
     299/** Initialize Local APIC. */
    241300void l_apic_init(void)
    242301{
     
    244303        lvt_lint_t lint;
    245304        svr_t svr;
     305        icr_t icr;
     306        tdcr_t tdcr;
    246307        lvt_tm_t tm;
    247         icr_t icr;
    248308        __u32 t1, t2;
    249309
     
    283343        l_apic[ICRlo] = icr.lo;
    284344       
    285         /*
    286          * Program the timer for periodic mode and respective vector.
    287          */
    288 
    289         l_apic[TDCR] &= TDCRClear;
    290         l_apic[TDCR] |= 0xb;
    291 
     345        /* Timer Divide Configuration Register initialization. */
     346        tdcr.value = l_apic[TDCR];
     347        tdcr.div_value = DIVIDE_1;
     348        l_apic[TDCR] = tdcr.value;
     349
     350        /* Program local timer. */
    292351        tm.value = l_apic[LVT_Tm];
    293352        tm.vector = VECTOR_CLK;
     
    296355        l_apic[LVT_Tm] = tm.value;
    297356
     357        /* Measure and configure the timer to generate timer interrupt each ms. */
    298358        t1 = l_apic[CCRT];
    299359        l_apic[ICRT] = 0xffffffff;
     
    310370}
    311371
     372/** Local APIC End of Interrupt. */
    312373void l_apic_eoi(void)
    313374{
     
    315376}
    316377
     378/** Dump content of Local APIC registers. */
    317379void l_apic_debug(void)
    318380{
    319381#ifdef LAPIC_VERBOSE
    320         int i, lint;
    321 
     382        lvt_tm_t tm;
     383        lvt_lint_t lint;
     384        lvt_error_t error;     
     385       
    322386        printf("LVT on cpu%d, LAPIC ID: %d\n", CPU->id, l_apic_id());
    323387
    324         printf("LVT_Tm: ");
    325         if (l_apic[LVT_Tm] & (1<<17)) printf("periodic"); else printf("one-shot"); putchar(',');       
    326         if (l_apic[LVT_Tm] & (1<<16)) printf("masked"); else printf("not masked"); putchar(',');
    327         if (l_apic[LVT_Tm] & (1<<12)) printf("send pending"); else printf("idle"); putchar(',');
    328         printf("%B\n", l_apic[LVT_Tm] & 0xff);
    329        
    330         for (i=0; i<2; i++) {
    331                 lint = i ? LVT_LINT1 : LVT_LINT0;
    332                 printf("LVT_LINT%d: ", i);
    333                 if (l_apic[lint] & (1<<16)) printf("masked"); else printf("not masked"); putchar(',');
    334                 if (l_apic[lint] & (1<<15)) printf("level"); else printf("edge"); putchar(',');
    335                 printf("%d", l_apic[lint] & (1<<14)); putchar(',');
    336                 printf("%d", l_apic[lint] & (1<<13)); putchar(',');
    337                 if (l_apic[lint] & (1<<12)) printf("send pending"); else printf("idle"); putchar(',');
    338        
    339                 switch ((l_apic[lint]>>8)&7) {
    340                     case 0: printf("fixed"); break;
    341                     case 4: printf("NMI"); break;
    342                     case 7: printf("ExtINT"); break;
    343                 }
    344                 putchar(',');
    345                 printf("%B\n", l_apic[lint] & 0xff);   
    346         }
    347 
    348         printf("LVT_Err: ");
    349         if (l_apic[LVT_Err] & (1<<16)) printf("masked"); else printf("not masked"); putchar(',');
    350         if (l_apic[LVT_Err] & (1<<12)) printf("send pending"); else printf("idle"); putchar(',');
    351         printf("%B\n", l_apic[LVT_Err] & 0xff);
    352 
    353         /*
    354          * This register is supported only on P6 and higher.
    355          */
    356         if (CPU->arch.family > 5) {
    357                 printf("LVT_PCINT: ");
    358                 if (l_apic[LVT_PCINT] & (1<<16)) printf("masked"); else printf("not masked"); putchar(',');
    359                 if (l_apic[LVT_PCINT] & (1<<12)) printf("send pending"); else printf("idle"); putchar(',');
    360                 switch ((l_apic[LVT_PCINT] >> 8)&7) {
    361                     case 0: printf("fixed"); break;
    362                     case 4: printf("NMI"); break;
    363                     case 7: printf("ExtINT"); break;
    364                 }
    365                 putchar(',');
    366                 printf("%B\n", l_apic[LVT_PCINT] & 0xff);
    367         }
     388        tm.value = l_apic[LVT_Tm];
     389        printf("LVT Tm: vector=%B, %s, %s, %s\n", tm.vector, delivs_str[tm.delivs], mask_str[tm.masked], tm_mode_str[tm.mode]);
     390        lint.value = l_apic[LVT_LINT0];
     391        printf("LVT LINT0: vector=%B, %s, %s, %s, irr=%d, %s, %s\n", tm.vector, delmod_str[lint.delmod], delivs_str[lint.delivs], intpol_str[lint.intpol], lint.irr, trigmod_str[lint.trigger_mode], mask_str[lint.masked]);
     392        lint.value = l_apic[LVT_LINT1];
     393        printf("LVT LINT1: vector=%B, %s, %s, %s, irr=%d, %s, %s\n", tm.vector, delmod_str[lint.delmod], delivs_str[lint.delivs], intpol_str[lint.intpol], lint.irr, trigmod_str[lint.trigger_mode], mask_str[lint.masked]);   
     394        error.value = l_apic[LVT_Err];
     395        printf("LVT Err: vector=%B, %s, %s\n", error.vector, delivs_str[error.delivs], mask_str[error.masked]);
    368396#endif
    369397}
    370398
     399/** Local APIC Timer Interrupt.
     400 *
     401 * @param n Interrupt vector number.
     402 * @param stack Interrupted stack.
     403 */
    371404void l_apic_timer_interrupt(__u8 n, __native stack[])
    372405{
     
    375408}
    376409
     410/** Get Local APIC ID.
     411 *
     412 * @return Local APIC ID.
     413 */
    377414__u8 l_apic_id(void)
    378415{
    379         return (l_apic[L_APIC_ID] >> L_APIC_IDShift)&L_APIC_IDMask;
    380 }
    381 
     416        lapic_id_t lapic_id;
     417       
     418        lapic_id.value = l_apic[L_APIC_ID];
     419        return lapic_id.apic_id;
     420}
     421
     422/** Read from IO APIC register.
     423 *
     424 * @param address IO APIC register address.
     425 *
     426 * @return Content of the addressed IO APIC register.
     427 */
    382428__u32 io_apic_read(__u8 address)
    383429{
    384         __u32 tmp;
    385        
    386         tmp = io_apic[IOREGSEL] & ~0xf;
    387         io_apic[IOREGSEL] = tmp | address;
     430        io_regsel_t regsel;
     431       
     432        regsel.value = io_apic[IOREGSEL];
     433        regsel.reg_addr = address;
     434        io_apic[IOREGSEL] = regsel.value;
    388435        return io_apic[IOWIN];
    389436}
    390437
     438/** Write to IO APIC register.
     439 *
     440 * @param address IO APIC register address.
     441 * @param Content to be written to the addressed IO APIC register.
     442 */
    391443void io_apic_write(__u8 address, __u32 x)
    392444{
    393         __u32 tmp;
    394 
    395         tmp = io_apic[IOREGSEL] & ~0xf;
    396         io_apic[IOREGSEL] = tmp | address;
     445        io_regsel_t regsel;
     446       
     447        regsel.value = io_apic[IOREGSEL];
     448        regsel.reg_addr = address;
     449        io_apic[IOREGSEL] = regsel.value;
    397450        io_apic[IOWIN] = x;
    398451}
    399452
    400 void io_apic_change_ioredtbl(int signal, int dest, __u8 v, int flags)
     453/** Change some attributes of one item in I/O Redirection Table.
     454 *
     455 * @param pin IO APIC pin number.
     456 * @param dest Interrupt destination address.
     457 * @param v Interrupt vector to trigger.
     458 * @param flags Flags.
     459 */
     460void io_apic_change_ioredtbl(int pin, int dest, __u8 v, int flags)
    401461{
    402462        io_redirection_reg_t reg;
    403         int dlvr = 0;
     463        int dlvr = DELMOD_FIXED;
    404464       
    405465        if (flags & LOPRI)
     
    407467
    408468       
    409         reg.lo = io_apic_read(IOREDTBL + signal*2);
    410         reg.hi = io_apic_read(IOREDTBL + signal*2 + 1);
     469        reg.lo = io_apic_read(IOREDTBL + pin*2);
     470        reg.hi = io_apic_read(IOREDTBL + pin*2 + 1);
    411471       
    412472        reg.dest =  dest;
     
    417477        reg.intvec = v;
    418478
    419         io_apic_write(IOREDTBL + signal*2, reg.lo);
    420         io_apic_write(IOREDTBL + signal*2 + 1, reg.hi);
    421 }
    422 
     479        io_apic_write(IOREDTBL + pin*2, reg.lo);
     480        io_apic_write(IOREDTBL + pin*2 + 1, reg.hi);
     481}
     482
     483/** Mask IRQs in IO APIC.
     484 *
     485 * @param irqmask Bitmask of IRQs to be masked (0 = do not mask, 1 = mask).
     486 */
    423487void io_apic_disable_irqs(__u16 irqmask)
    424488{
     
    443507}
    444508
     509/** Unmask IRQs in IO APIC.
     510 *
     511 * @param irqmask Bitmask of IRQs to be unmasked (0 = do not unmask, 1 = unmask).
     512 */
    445513void io_apic_enable_irqs(__u16 irqmask)
    446514{
Note: See TracChangeset for help on using the changeset viewer.