Changeset 2a103b5 in mainline for kernel/arch/amd64/src


Ignore:
Timestamp:
2019-06-09T11:31:38Z (6 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
c48de91
Parents:
b401b33
Message:

Introduce PIC operations indirection mechanism

Some architectures switch from one interrupt controller implementation
to another during runtime. By providing a cleaner indirection mechanism,
it is possible e.g. for the ia32 IRQ 7 handler to distinguish i8259
spurious interrupts from actual IRQ 7 device interrupts, even when the
i8259 interrupt controller is no longer active.

Location:
kernel/arch/amd64/src
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • kernel/arch/amd64/src/amd64.c

    rb401b33 r2a103b5  
    6060#include <arch/vreg.h>
    6161#include <arch/kseg.h>
     62#include <genarch/pic/pic_ops.h>
    6263
    6364#ifdef CONFIG_SMP
     
    123124                    (i8259_t *) I8259_PIC1_BASE, IVT_IRQBASE);
    124125
    125                 /*
    126                  * Set the enable/disable IRQs handlers.
    127                  * Set the End-of-Interrupt handler.
    128                  */
    129                 enable_irqs_function = pic_enable_irqs;
    130                 disable_irqs_function = pic_disable_irqs;
    131                 eoi_function = pic_eoi;
    132                 irqs_info = "i8259";
     126                /* Set PIC operations. */
     127                pic_ops = &i8259_pic_ops;
    133128        }
    134129}
     
    209204                        indev_t *kbrd = kbrd_wire(kbrd_instance, sink);
    210205                        i8042_wire(i8042_instance, kbrd);
    211                         trap_virtual_enable_irqs(1 << IRQ_KBD);
    212                         trap_virtual_enable_irqs(1 << IRQ_MOUSE);
     206                        pic_ops->enable_irqs(1 << IRQ_KBD);
     207                        pic_ops->enable_irqs(1 << IRQ_MOUSE);
    213208                }
    214209        }
     
    235230                        indev_t *srln = srln_wire(srln_instance, sink);
    236231                        ns16550_wire(ns16550_instance, srln);
    237                         trap_virtual_enable_irqs(1 << IRQ_NS16550);
     232                        pic_ops->enable_irqs(1 << IRQ_NS16550);
    238233                }
    239234#endif
     
    246241#endif
    247242
    248         if (irqs_info != NULL)
    249                 sysinfo_set_item_val(irqs_info, NULL, true);
     243        sysinfo_set_item_val(pic_ops->get_name(), NULL, true);
    250244}
    251245
  • kernel/arch/amd64/src/interrupt.c

    rb401b33 r2a103b5  
    3838#include <panic.h>
    3939#include <genarch/drivers/i8259/i8259.h>
     40#include <genarch/pic/pic_ops.h>
    4041#include <halt.h>
    4142#include <cpu.h>
     
    5758 * Interrupt and exception dispatching.
    5859 */
    59 
    60 void (*disable_irqs_function)(uint16_t irqmask) = NULL;
    61 void (*enable_irqs_function)(uint16_t irqmask) = NULL;
    62 void (*eoi_function)(unsigned int) = NULL;
    63 const char *irqs_info = NULL;
     60pic_ops_t *pic_ops = NULL;
    6461
    6562void istate_decode(istate_t *istate)
     
    8986            "r14=%0#18" PRIx64 "\tr15=%0#18" PRIx64 "\n",
    9087            istate->r12, istate->r13, istate->r14, istate->r15);
    91 }
    92 
    93 static void trap_virtual_eoi(unsigned int irq)
    94 {
    95         if (eoi_function)
    96                 eoi_function(irq);
    97         else
    98                 panic("No eoi_function.");
    99 
    10088}
    10189
     
    157145static void tlb_shootdown_ipi(unsigned int n, istate_t *istate)
    158146{
    159         trap_virtual_eoi(0);
     147        pic_ops->eoi(0);
    160148        tlb_shootdown_ipi_recv();
    161149}
     
    182170                if (irq->preack) {
    183171                        /* Send EOI before processing the interrupt */
    184                         trap_virtual_eoi(inum);
     172                        pic_ops->eoi(inum);
    185173                        ack = true;
    186174                }
     
    195183
    196184        if (!ack)
    197                 trap_virtual_eoi(inum);
     185                pic_ops->eoi(inum);
    198186}
    199187
     
    201189{
    202190        unsigned int inum = n - IVT_IRQBASE;
    203         if (!pic_is_spurious(inum)) {
     191        if (!pic_ops->is_spurious(inum)) {
    204192                /* This is actually not a spurious IRQ, so proceed as usual. */
    205193                irq_interrupt(n, istate);
    206194                return;
    207195        }
    208         pic_handle_spurious(n);
     196        pic_ops->handle_spurious(n);
    209197#ifdef CONFIG_DEBUG
    210198        log(LF_ARCH, LVL_DEBUG, "cpu%u: PIC spurious interrupt %u", CPU->id,
     
    242230}
    243231
    244 void trap_virtual_enable_irqs(uint16_t irqmask)
    245 {
    246         if (enable_irqs_function)
    247                 enable_irqs_function(irqmask);
    248         else
    249                 panic("No enable_irqs_function.");
    250 }
    251 
    252 void trap_virtual_disable_irqs(uint16_t irqmask)
    253 {
    254         if (disable_irqs_function)
    255                 disable_irqs_function(irqmask);
    256         else
    257                 panic("No disable_irqs_function.");
    258 }
    259 
    260232/** @}
    261233 */
Note: See TracChangeset for help on using the changeset viewer.