Subversion Repositories HelenOS

Rev

Rev 2218 | Rev 3906 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 2218 Rev 2441
Line 123... Line 123...
123
/** APIC spurious interrupt handler.
123
/** APIC spurious interrupt handler.
124
 *
124
 *
125
 * @param n Interrupt vector.
125
 * @param n Interrupt vector.
126
 * @param istate Interrupted state.
126
 * @param istate Interrupted state.
127
 */
127
 */
128
static void apic_spurious(int n, istate_t *istate)
128
static void apic_spurious(int n __attribute__((unused)), istate_t *istate __attribute__((unused)))
129
{
129
{
130
#ifdef CONFIG_DEBUG
130
#ifdef CONFIG_DEBUG
131
    printf("cpu%d: APIC spurious interrupt\n", CPU->id);
131
    printf("cpu%u: APIC spurious interrupt\n", CPU->id);
132
#endif
132
#endif
133
}
133
}
134
 
134
 
135
static irq_ownership_t l_apic_timer_claim(void)
135
static irq_ownership_t l_apic_timer_claim(void)
136
{
136
{
137
    return IRQ_ACCEPT;
137
    return IRQ_ACCEPT;
138
}
138
}
139
 
139
 
140
static void l_apic_timer_irq_handler(irq_t *irq, void *arg, ...)
140
static void l_apic_timer_irq_handler(irq_t *irq, void *arg __attribute__((unused)), ...)
141
{
141
{
142
    /*
142
    /*
143
     * Holding a spinlock could prevent clock() from preempting
143
     * Holding a spinlock could prevent clock() from preempting
144
     * the current thread. In this case, we don't need to hold the
144
     * the current thread. In this case, we don't need to hold the
145
     * irq->lock so we just unlock it and then lock it again.
145
     * irq->lock so we just unlock it and then lock it again.
Line 151... Line 151...
151
 
151
 
152
/** Initialize APIC on BSP. */
152
/** Initialize APIC on BSP. */
153
void apic_init(void)
153
void apic_init(void)
154
{
154
{
155
    io_apic_id_t idreg;
155
    io_apic_id_t idreg;
156
    unsigned int i;
-
 
157
 
156
   
158
    exc_register(VECTOR_APIC_SPUR, "apic_spurious", (iroutine) apic_spurious);
157
    exc_register(VECTOR_APIC_SPUR, "apic_spurious", (iroutine) apic_spurious);
159
 
158
 
160
    enable_irqs_function = io_apic_enable_irqs;
159
    enable_irqs_function = io_apic_enable_irqs;
161
    disable_irqs_function = io_apic_disable_irqs;
160
    disable_irqs_function = io_apic_disable_irqs;
162
    eoi_function = l_apic_eoi;
161
    eoi_function = l_apic_eoi;
Line 174... Line 173...
174
    l_apic_timer_irq.inr = IRQ_CLK;
173
    l_apic_timer_irq.inr = IRQ_CLK;
175
    l_apic_timer_irq.claim = l_apic_timer_claim;
174
    l_apic_timer_irq.claim = l_apic_timer_claim;
176
    l_apic_timer_irq.handler = l_apic_timer_irq_handler;
175
    l_apic_timer_irq.handler = l_apic_timer_irq_handler;
177
    irq_register(&l_apic_timer_irq);
176
    irq_register(&l_apic_timer_irq);
178
   
177
   
-
 
178
    uint8_t i;
179
    for (i = 0; i < IRQ_COUNT; i++) {
179
    for (i = 0; i < IRQ_COUNT; i++) {
180
        int pin;
180
        int pin;
181
   
181
   
182
        if ((pin = smp_irq_to_pin(i)) != -1)
182
        if ((pin = smp_irq_to_pin(i)) != -1)
183
            io_apic_change_ioredtbl(pin, DEST_ALL, IVT_IRQBASE + i, LOPRI);
183
            io_apic_change_ioredtbl((uint8_t) pin, DEST_ALL, (uint8_t) (IVT_IRQBASE + i), LOPRI);
184
    }
184
    }
185
   
185
   
186
    /*
186
    /*
187
     * Ensure that io_apic has unique ID.
187
     * Ensure that io_apic has unique ID.
188
     */
188
     */
Line 326... Line 326...
326
        /*
326
        /*
327
         * If this is not 82489DX-based l_apic we must send two STARTUP IPI's.
327
         * If this is not 82489DX-based l_apic we must send two STARTUP IPI's.
328
         */
328
         */
329
        for (i = 0; i<2; i++) {
329
        for (i = 0; i<2; i++) {
330
            icr.lo = l_apic[ICRlo];
330
            icr.lo = l_apic[ICRlo];
331
            icr.vector = ((uintptr_t) ap_boot) / 4096; /* calculate the reset vector */
331
            icr.vector = (uint8_t) (((uintptr_t) ap_boot) >> 12); /* calculate the reset vector */
332
            icr.delmod = DELMOD_STARTUP;
332
            icr.delmod = DELMOD_STARTUP;
333
            icr.destmod = DESTMOD_PHYS;
333
            icr.destmod = DESTMOD_PHYS;
334
            icr.level = LEVEL_ASSERT;
334
            icr.level = LEVEL_ASSERT;
335
            icr.shorthand = SHORTHAND_NONE;
335
            icr.shorthand = SHORTHAND_NONE;
336
            icr.trigger_mode = TRIGMOD_LEVEL;
336
            icr.trigger_mode = TRIGMOD_LEVEL;
Line 423... Line 423...
423
    t2 = l_apic[CCRT];
423
    t2 = l_apic[CCRT];
424
   
424
   
425
    l_apic[ICRT] = t1-t2;
425
    l_apic[ICRT] = t1-t2;
426
   
426
   
427
    /* Program Logical Destination Register. */
427
    /* Program Logical Destination Register. */
-
 
428
    ASSERT(CPU->id < 8)
428
    ldr.value = l_apic[LDR];
429
    ldr.value = l_apic[LDR];
429
    if (CPU->id < sizeof(CPU->id)*8)    /* size in bits */
-
 
430
        ldr.id = (1<<CPU->id);
430
    ldr.id = (uint8_t) (1 << CPU->id);
431
    l_apic[LDR] = ldr.value;
431
    l_apic[LDR] = ldr.value;
432
   
432
   
433
    /* Program Destination Format Register for Flat mode. */
433
    /* Program Destination Format Register for Flat mode. */
434
    dfr.value = l_apic[DFR];
434
    dfr.value = l_apic[DFR];
435
    dfr.model = MODEL_FLAT;
435
    dfr.model = MODEL_FLAT;
Line 511... Line 511...
511
 * @param pin IO APIC pin number.
511
 * @param pin IO APIC pin number.
512
 * @param dest Interrupt destination address.
512
 * @param dest Interrupt destination address.
513
 * @param v Interrupt vector to trigger.
513
 * @param v Interrupt vector to trigger.
514
 * @param flags Flags.
514
 * @param flags Flags.
515
 */
515
 */
516
void io_apic_change_ioredtbl(int pin, int dest, uint8_t v, int flags)
516
void io_apic_change_ioredtbl(uint8_t pin, uint8_t dest, uint8_t v, int flags)
517
{
517
{
518
    io_redirection_reg_t reg;
518
    io_redirection_reg_t reg;
519
    int dlvr = DELMOD_FIXED;
519
    int dlvr = DELMOD_FIXED;
520
   
520
   
521
    if (flags & LOPRI)
521
    if (flags & LOPRI)
522
        dlvr = DELMOD_LOWPRI;
522
        dlvr = DELMOD_LOWPRI;
523
 
523
 
524
    reg.lo = io_apic_read(IOREDTBL + pin*2);
524
    reg.lo = io_apic_read((uint8_t) (IOREDTBL + pin * 2));
525
    reg.hi = io_apic_read(IOREDTBL + pin*2 + 1);
525
    reg.hi = io_apic_read((uint8_t) (IOREDTBL + pin * 2 + 1));
526
   
526
   
527
    reg.dest = dest;
527
    reg.dest = dest;
528
    reg.destmod = DESTMOD_LOGIC;
528
    reg.destmod = DESTMOD_LOGIC;
529
    reg.trigger_mode = TRIGMOD_EDGE;
529
    reg.trigger_mode = TRIGMOD_EDGE;
530
    reg.intpol = POLARITY_HIGH;
530
    reg.intpol = POLARITY_HIGH;
531
    reg.delmod = dlvr;
531
    reg.delmod = dlvr;
532
    reg.intvec = v;
532
    reg.intvec = v;
533
 
533
 
534
    io_apic_write(IOREDTBL + pin*2, reg.lo);
534
    io_apic_write((uint8_t) (IOREDTBL + pin * 2), reg.lo);
535
    io_apic_write(IOREDTBL + pin*2 + 1, reg.hi);
535
    io_apic_write((uint8_t) (IOREDTBL + pin * 2 + 1), reg.hi);
536
}
536
}
537
 
537
 
538
/** Mask IRQs in IO APIC.
538
/** Mask IRQs in IO APIC.
539
 *
539
 *
540
 * @param irqmask Bitmask of IRQs to be masked (0 = do not mask, 1 = mask).
540
 * @param irqmask Bitmask of IRQs to be masked (0 = do not mask, 1 = mask).
Line 551... Line 551...
551
             * Mask the signal input in IO APIC if there is a
551
             * Mask the signal input in IO APIC if there is a
552
             * mapping for the respective IRQ number.
552
             * mapping for the respective IRQ number.
553
             */
553
             */
554
            pin = smp_irq_to_pin(i);
554
            pin = smp_irq_to_pin(i);
555
            if (pin != -1) {
555
            if (pin != -1) {
556
                reg.lo = io_apic_read(IOREDTBL + pin * 2);
556
                reg.lo = io_apic_read((uint8_t) (IOREDTBL + pin * 2));
557
                reg.masked = true;
557
                reg.masked = true;
558
                io_apic_write(IOREDTBL + pin * 2, reg.lo);
558
                io_apic_write((uint8_t) (IOREDTBL + pin * 2), reg.lo);
559
            }
559
            }
560
           
560
           
561
        }
561
        }
562
    }
562
    }
563
}
563
}
Line 570... Line 570...
570
{
570
{
571
    unsigned int i;
571
    unsigned int i;
572
    int pin;
572
    int pin;
573
    io_redirection_reg_t reg;  
573
    io_redirection_reg_t reg;  
574
   
574
   
575
    for (i = 0;i < 16; i++) {
575
    for (i = 0; i < 16; i++) {
576
        if (irqmask & (1 << i)) {
576
        if (irqmask & (1 << i)) {
577
            /*
577
            /*
578
             * Unmask the signal input in IO APIC if there is a
578
             * Unmask the signal input in IO APIC if there is a
579
             * mapping for the respective IRQ number.
579
             * mapping for the respective IRQ number.
580
             */
580
             */
581
            pin = smp_irq_to_pin(i);
581
            pin = smp_irq_to_pin(i);
582
            if (pin != -1) {
582
            if (pin != -1) {
583
                reg.lo = io_apic_read(IOREDTBL + pin * 2);
583
                reg.lo = io_apic_read((uint8_t) (IOREDTBL + pin * 2));
584
                reg.masked = false;
584
                reg.masked = false;
585
                io_apic_write(IOREDTBL + pin * 2, reg.lo);
585
                io_apic_write((uint8_t) (IOREDTBL + pin * 2), reg.lo);
586
            }
586
            }
587
           
587
           
588
        }
588
        }
589
    }
589
    }
590
}
590
}