X-Git-Url: https://gerrit.opnfv.org/gerrit/gitweb?a=blobdiff_plain;f=qemu%2Froms%2Fu-boot%2Farch%2Fopenrisc%2Fcpu%2Finterrupts.c;fp=qemu%2Froms%2Fu-boot%2Farch%2Fopenrisc%2Fcpu%2Finterrupts.c;h=1ecfbf03ac0891678a7ca17b315efd6d17005441;hb=e44e3482bdb4d0ebde2d8b41830ac2cdb07948fb;hp=0000000000000000000000000000000000000000;hpb=9ca8dbcc65cfc63d6f5ef3312a33184e1d726e00;p=kvmfornfv.git diff --git a/qemu/roms/u-boot/arch/openrisc/cpu/interrupts.c b/qemu/roms/u-boot/arch/openrisc/cpu/interrupts.c new file mode 100644 index 000000000..1ecfbf03a --- /dev/null +++ b/qemu/roms/u-boot/arch/openrisc/cpu/interrupts.c @@ -0,0 +1,108 @@ +/* + * (C) Copyright 2011, Stefan Kristiansson + * (C) Copyright 2011, Julius Baxter + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include + +struct irq_action { + interrupt_handler_t *handler; + void *arg; + int count; +}; + +static struct irq_action handlers[32]; + +void interrupt_handler(void) +{ + int irq; + + while ((irq = ffs(mfspr(SPR_PICSR)))) { + if (handlers[--irq].handler) { + handlers[irq].handler(handlers[irq].arg); + handlers[irq].count++; + } else { + /* disable the interrupt */ + mtspr(SPR_PICMR, mfspr(SPR_PICMR) & ~(1 << irq)); + printf("Unhandled interrupt: %d\n", irq); + } + /* clear the interrupt */ + mtspr(SPR_PICSR, mfspr(SPR_PICSR) & ~(1 << irq)); + } +} + +int interrupt_init(void) +{ + /* install handler for external interrupt exception */ + exception_install_handler(EXC_EXT_IRQ, interrupt_handler); + /* Enable interrupts in supervisor register */ + mtspr(SPR_SR, mfspr(SPR_SR) | SPR_SR_IEE); + + return 0; +} + +void enable_interrupts(void) +{ + /* Set interrupt enable bit in supervisor register */ + mtspr(SPR_SR, mfspr(SPR_SR) | SPR_SR_IEE); + /* Enable timer exception */ + mtspr(SPR_SR, mfspr(SPR_SR) | SPR_SR_TEE); +} + +int disable_interrupts(void) +{ + /* Clear interrupt enable bit in supervisor register */ + mtspr(SPR_SR, mfspr(SPR_SR) & ~SPR_SR_IEE); + /* Disable timer exception */ + mtspr(SPR_SR, mfspr(SPR_SR) & ~SPR_SR_TEE); + + return 0; +} + +void irq_install_handler(int irq, interrupt_handler_t *handler, void *arg) +{ + if (irq < 0 || irq > 31) + return; + + handlers[irq].handler = handler; + handlers[irq].arg = arg; +} + +void irq_free_handler(int irq) +{ + if (irq < 0 || irq > 31) + return; + + handlers[irq].handler = 0; + handlers[irq].arg = 0; +} + +#if defined(CONFIG_CMD_IRQ) +int do_irqinfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + int i; + + printf("\nInterrupt-Information:\n\n"); + printf("Nr Routine Arg Count\n"); + printf("-----------------------------\n"); + + for (i = 0; i < 32; i++) { + if (handlers[i].handler) { + printf("%02d %08lx %08lx %d\n", + i, + (ulong)handlers[i].handler, + (ulong)handlers[i].arg, + handlers[i].count); + } + } + printf("\n"); + + return 0; +} +#endif