From 38e060c35479223dbea3761a8643c040f6b1f325 Mon Sep 17 00:00:00 2001 From: Florent Kermarrec Date: Fri, 14 Jun 2024 11:47:02 +0200 Subject: [PATCH] software/libbase/isr.c: Cleanup code a bit. --- litex/soc/software/libbase/isr.c | 207 ++++++++++++++++--------------- 1 file changed, 110 insertions(+), 97 deletions(-) diff --git a/litex/soc/software/libbase/isr.c b/litex/soc/software/libbase/isr.c index c18a5ad7a..6f825e8f3 100644 --- a/litex/soc/software/libbase/isr.c +++ b/litex/soc/software/libbase/isr.c @@ -3,7 +3,6 @@ // This file is Copyright (c) 2020 Raptor Engineering, LLC // License: BSD - #include #include #include @@ -19,64 +18,73 @@ void isr(void); #ifdef CONFIG_CPU_HAS_INTERRUPT -#if defined(__blackparrot__) /*TODO: Update this function for BP*/ // +/*************************************/ +/* ISR Handling for BlackParrot CPU. */ +/*************************************/ + +#if defined(__blackparrot__) /*TODO: Update this function for BP.*/ void isr(void) { - static int onetime = 0; - if ( onetime == 0){ - printf("ISR blackparrot\n"); - printf("TRAP!!\n"); - onetime++; - } + static int onetime = 0; + if (onetime == 0) { + printf("ISR blackparrot\n"); + printf("TRAP!!\n"); + onetime++; + } } +/***********************************************************/ +/* ISR and PLIC Initialization for RISC-V PLIC-based CPUs. */ +/***********************************************************/ #elif defined(__riscv_plic__) -// PLIC initialization. -void plic_init(void); +/* PLIC initialization. */ void plic_init(void) { - int i; + int i; + /* Set priorities for the first 8 external interrupts to 1. */ + for (i = 0; i < 8; i++) + *((unsigned int *)(PLIC_BASE + PLIC_EXT_IRQ_BASE + i)) = 1; - // Set priorities for the first 8 external interrupts to 1. - for (i = 0; i < 8; i++) - *((unsigned int *)PLIC_BASE + PLIC_EXT_IRQ_BASE + i) = 1; + /* Enable the first 8 external interrupts. */ + *((unsigned int *)PLIC_ENABLED) = 0xff << PLIC_EXT_IRQ_BASE; - // Enable the first 8 external interrupts - *((unsigned int *)PLIC_ENABLED) = 0xff << PLIC_EXT_IRQ_BASE; - - // Set priority threshold to 0 (any priority > 0 triggers an interrupt). - *((unsigned int *)PLIC_THRSHLD) = 0; + /* Set priority threshold to 0 (any priority > 0 triggers an interrupt). */ + *((unsigned int *)PLIC_THRSHLD) = 0; } -// Interrupt Service Routine. +/* Interrupt Service Routine. */ void isr(void) { - unsigned int claim; + unsigned int claim; - // Claim and handle pending interrupts. - while ((claim = *((unsigned int *)PLIC_CLAIM))) { - switch (claim - PLIC_EXT_IRQ_BASE) { - case UART_INTERRUPT: - uart_isr(); // Handle UART interrupt. - break; - default: - // Unhandled interrupt source, print diagnostic information. - printf("## PLIC: Unhandled claim: %d\n", claim); - printf("# plic_enabled: %08x\n", irq_getmask()); - printf("# plic_pending: %08x\n", irq_pending()); - printf("# mepc: %016lx\n", csrr(mepc)); - printf("# mcause: %016lx\n", csrr(mcause)); - printf("# mtval: %016lx\n", csrr(mtval)); - printf("# mie: %016lx\n", csrr(mie)); - printf("# mip: %016lx\n", csrr(mip)); - printf("###########################\n\n"); - break; - } - // Acknowledge the interrupt. - *((unsigned int *)PLIC_CLAIM) = claim; - } + /* Claim and handle pending interrupts. */ + while ((claim = *((unsigned int *)PLIC_CLAIM))) { + switch (claim - PLIC_EXT_IRQ_BASE) { + case UART_INTERRUPT: + uart_isr(); /* Handle UART interrupt. */ + break; + default: + /* Unhandled interrupt source, print diagnostic information. */ + printf("## PLIC: Unhandled claim: %d\n", claim); + printf("# plic_enabled: %08x\n", irq_getmask()); + printf("# plic_pending: %08x\n", irq_pending()); + printf("# mepc: %016lx\n", csrr(mepc)); + printf("# mcause: %016lx\n", csrr(mcause)); + printf("# mtval: %016lx\n", csrr(mtval)); + printf("# mie: %016lx\n", csrr(mie)); + printf("# mip: %016lx\n", csrr(mip)); + printf("###########################\n\n"); + break; + } + /* Acknowledge the interrupt. */ + *((unsigned int *)PLIC_CLAIM) = claim; + } } -#elif defined(__cv32e40p__) || defined(__cv32e41p__) + +/************************************************/ +/* ISR Handling for CV32E40P and CV32E41P CPUs. */ +/************************************************/ +#elif defined(__cv32e40p__) || defined(__cv32e41p__) #define FIRQ_OFFSET 16 #define IRQ_MASK 0x7FFFFFFF @@ -90,119 +98,124 @@ void isr(void) if (csrr(mcause) & 0x80000000) { #ifndef UART_POLLING - if (cause == (UART_INTERRUPT+FIRQ_OFFSET)){ + if (cause == (UART_INTERRUPT + FIRQ_OFFSET)) { uart_isr(); } #endif } else { #ifdef RISCV_TEST int gp; - asm volatile ("mv %0, gp" : "=r"(gp)); + asm volatile("mv %0, gp" : "=r"(gp)); printf("E %d\n", cause); if (cause == INVINST) { printf("Inv Instr\n"); - for(;;); + for (;;); } if (cause == ECALL) { printf("Ecall (gp: %d)\n", gp); - csrw(mepc, csrr(mepc)+4); + csrw(mepc, csrr(mepc) + 4); } #endif } } +/***********************************/ +/* ISR Handling for Microwatt CPU. */ +/***********************************/ #elif defined(__microwatt__) void isr(uint64_t vec) { - if (vec == 0x900) - return isr_dec(); + if (vec == 0x900) + return isr_dec(); - if (vec == 0x500) { - // Read interrupt source - uint32_t xirr = xics_icp_readw(PPC_XICS_XIRR); - uint32_t irq_source = xirr & 0x00ffffff; + if (vec == 0x500) { + /* Read interrupt source. */ + uint32_t xirr = xics_icp_readw(PPC_XICS_XIRR); + uint32_t irq_source = xirr & 0x00ffffff; - __attribute__((unused)) unsigned int irqs; + __attribute__((unused)) unsigned int irqs; - // Handle IPI interrupts separately - if (irq_source == 2) { - // IPI interrupt - xics_icp_writeb(PPC_XICS_MFRR, 0xff); - } - else { - // External interrupt - irqs = irq_pending() & irq_getmask(); + /* Handle IPI interrupts separately. */ + if (irq_source == 2) { + /* IPI interrupt. */ + xics_icp_writeb(PPC_XICS_MFRR, 0xff); + } else { + /* External interrupt. */ + irqs = irq_pending() & irq_getmask(); #ifndef UART_POLLING - if(irqs & (1 << UART_INTERRUPT)) - uart_isr(); + if (irqs & (1 << UART_INTERRUPT)) + uart_isr(); #endif - } + } - // Clear interrupt - xics_icp_writew(PPC_XICS_XIRR, xirr); + /* Clear interrupt. */ + xics_icp_writew(PPC_XICS_XIRR, xirr); - return; - } + return; + } } void isr_dec(void) { - // For now, just set DEC back to a large enough value to slow the flood of DEC-initiated timer interrupts - mtdec(0x000000000ffffff); + /* Set DEC back to a large enough value to slow the flood of DEC-initiated timer interrupts. */ + mtdec(0x000000000ffffff); } +/*******************************************************/ +/* Generic ISR Handling for CPUs with Interrupt Table. */ +/*******************************************************/ #else struct irq_table { - isr_t isr; + isr_t isr; } irq_table[CONFIG_CPU_INTERRUPTS]; int irq_attach(unsigned int irq, isr_t isr) { - if (irq >= CONFIG_CPU_INTERRUPTS) { - printf("Inv irq %d\n", irq); - return -1; - } + if (irq >= CONFIG_CPU_INTERRUPTS) { + printf("Inv irq %d\n", irq); + return -1; + } - unsigned int ie = irq_getie(); - irq_setie(0); - irq_table[irq].isr = isr; - irq_setie(ie); - return irq; + unsigned int ie = irq_getie(); + irq_setie(0); + irq_table[irq].isr = isr; + irq_setie(ie); + return irq; } int irq_detach(unsigned int irq) { - return irq_attach(irq, NULL); + return irq_attach(irq, NULL); } +/* Interrupt Service Routine. */ void isr(void) { - unsigned int irqs = irq_pending() & irq_getmask(); + unsigned int irqs = irq_pending() & irq_getmask(); - while (irqs) - { - const unsigned int irq = __builtin_ctz(irqs); - if ((irq < CONFIG_CPU_INTERRUPTS) && irq_table[irq].isr) - irq_table[irq].isr(); - else { - irq_setmask(irq_getmask() & ~(1<