Changeset f701b236 in mainline


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.

Location:
arch/ia32
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • arch/ia32/include/smp/apic.h

    r8418c7d rf701b236  
    7171#define POLARITY_HIGH   0x0
    7272#define POLARITY_LOW    0x1
     73
     74/** Divide Values. (Bit 2 is always 0) */
     75#define DIVIDE_2        0x0
     76#define DIVIDE_4        0x1
     77#define DIVIDE_8        0x2
     78#define DIVIDE_16       0x3
     79#define DIVIDE_32       0x8
     80#define DIVIDE_64       0x9
     81#define DIVIDE_128      0xa
     82#define DIVIDE_1        0xb
     83
     84/** Timer Modes. */
     85#define TIMER_ONESHOT   0x0
     86#define TIMER_PERIODIC  0x1
    7387
    7488#define SEND_PENDING    (1<<12)
     
    106120#define EOI             (0x0b0/sizeof(__u32))
    107121
    108 /* Error Status Register */
     122/** Error Status Register. */
    109123#define ESR             (0x280/sizeof(__u32))
    110 #define ESRClear        ((0xffffff<<8)|(1<<4))
     124union esr {
     125        __u32 value;
     126        __u8 err_bitmap;
     127        struct {
     128                unsigned send_checksum_error : 1;
     129                unsigned receive_checksum_error : 1;
     130                unsigned send_accept_error : 1;
     131                unsigned receive_accept_error : 1;
     132                unsigned : 1;
     133                unsigned send_illegal_vector : 1;
     134                unsigned received_illegal_vector : 1;
     135                unsigned illegal_register_address : 1;
     136                unsigned : 24;
     137        } __attribute__ ((packed));
     138};
     139typedef union esr esr_t;
    111140
    112141/* Task Priority Register */
     
    127156typedef union svr svr_t;
    128157
    129 /* Time Divide Configuration Register */
     158/** Time Divide Configuration Register. */
    130159#define TDCR            (0x3e0/sizeof(__u32))
    131 #define TDCRClear       (~0xb)
     160union tdcr {
     161        __u32 value;
     162        struct {
     163                unsigned div_value : 4;         /**< Divide Value, bit 2 is always 0. */
     164                unsigned : 28;                  /**< Reserved. */
     165        } __attribute__ ((packed));
     166};
     167typedef union tdcr tdcr_t;
    132168
    133169/* Initial Count Register for Timer */
     
    136172/* Current Count Register for Timer */
    137173#define CCRT            (0x390/sizeof(__u32))
    138 
    139 /** Timer Modes. */
    140 #define TIMER_ONESHOT   0x0
    141 #define TIMER_PERIODIC  0x1
    142174
    143175/** LVT Timer register. */
     
    191223typedef union lvt_error lvt_error_t;
    192224
    193 
    194 #define LVT_PCINT       (0x340/sizeof(__u32))
    195 
    196 /* Local APIC ID Register */
     225/** Local APIC ID Register. */
    197226#define L_APIC_ID       (0x020/sizeof(__u32))
    198 #define L_APIC_IDClear  (~(0xf<<24))
    199 #define L_APIC_IDShift  24
    200 #define L_APIC_IDMask   0xf
     227union lapic_id {
     228        __u32 value;
     229        struct {
     230                unsigned : 24;          /**< Reserved. */
     231                __u8 apic_id;           /**< Local APIC ID. */
     232        } __attribute__ ((packed));
     233};
     234typedef union lapic_id lapic_id_t;
    201235
    202236/* Local APIC Version Register */
     
    215249#define IOAPICARB       0x02
    216250#define IOREDTBL        0x10
     251
     252/** I/O Register Select Register. */
     253union io_regsel {
     254        __u32 value;
     255        struct {
     256                __u8 reg_addr;          /**< APIC Register Address. */
     257                unsigned : 24;          /**< Reserved. */
     258        } __attribute__ ((packed));
     259};
     260typedef union io_regsel io_regsel_t;
    217261
    218262/** I/O Redirection Register. */
     
    262306extern __u32 io_apic_read(__u8 address);
    263307extern void io_apic_write(__u8 address , __u32 x);
    264 extern void io_apic_change_ioredtbl(int signal, int dest, __u8 v, int flags);
     308extern void io_apic_change_ioredtbl(int pin, int dest, __u8 v, int flags);
    265309extern void io_apic_disable_irqs(__u16 irqmask);
    266310extern void io_apic_enable_irqs(__u16 irqmask);
  • arch/ia32/src/drivers/i8254.c

    r8418c7d rf701b236  
    6161{
    6262        outb(CLK_PORT4, 0x36);
    63         trap_virtual_disable_irqs(1<<IRQ_CLK);
     63        pic_disable_irqs(1<<IRQ_CLK);
    6464        outb(CLK_PORT1, (CLK_CONST/HZ) & 0xf);
    6565        outb(CLK_PORT1, (CLK_CONST/HZ) >> 8);
    66         trap_virtual_enable_irqs(1<<IRQ_CLK);
     66        pic_enable_irqs(1<<IRQ_CLK);
    6767        trap_register(VECTOR_CLK, i8254_interrupt);
    6868}
  • arch/ia32/src/ia32.c

    r8418c7d rf701b236  
    9595{
    9696        i8254_calibrate_delay_loop();
    97         i8254_normal_operation();
     97        if (config.cpu_active == 1) {
     98                /*
     99                 * This has to be done only on UP.
     100                 * On SMP, i8254 is not used for time keeping and its interrupt pin remains masked.
     101                 */
     102                i8254_normal_operation();
     103        }
    98104}
  • 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.