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 | } |