Skip to content

Commit

Permalink
Merge pull request #1815 from motec-research/irq_attach
Browse files Browse the repository at this point in the history
soc/software: add irq_attach() / irq_detach()
  • Loading branch information
AndrewD authored Nov 13, 2023
2 parents 77ca872 + 737ced8 commit 968bd28
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 9 deletions.
1 change: 1 addition & 0 deletions litex/soc/integration/soc.py
Original file line number Diff line number Diff line change
Expand Up @@ -1320,6 +1320,7 @@ def finalize(self):

# SoC IRQ Interconnect ---------------------------------------------------------------------
if hasattr(self, "cpu") and hasattr(self.cpu, "interrupt"):
self.add_constant("NR_IRQ", max(self.irq.locs.values()) + 1)
for name, loc in sorted(self.irq.locs.items()):
if name in self.cpu.interrupts.keys():
continue
Expand Down
15 changes: 15 additions & 0 deletions litex/soc/software/include/irq.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#pragma once
#include_next<irq.h>

typedef void (*isr_t)(void);

#ifdef __cplusplus
extern "C" {
#endif

extern int irq_attach(unsigned int irq, isr_t isr) __attribute__((weak));
extern int irq_detach(unsigned int irq) __attribute__((weak));

#ifdef __cplusplus
}
#endif
45 changes: 36 additions & 9 deletions litex/soc/software/libbase/isr.c
Original file line number Diff line number Diff line change
Expand Up @@ -191,18 +191,45 @@ void isr(void)
}

#else
void isr(void)
struct irq_table
{
__attribute__((unused)) unsigned int irqs;
isr_t isr;
} irq_table[NR_IRQ];

irqs = irq_pending() & irq_getmask();
int irq_attach(unsigned int irq, isr_t isr)
{
if (irq >= NR_IRQ) {
printf("Inv irq %d\n", irq);
return -1;
}

#ifdef CSR_UART_BASE
#ifndef UART_POLLING
if(irqs & (1 << UART_INTERRUPT))
uart_isr();
#endif
#endif
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);
}

void isr(void)
{
unsigned int irqs = irq_pending() & irq_getmask();

while (irqs)
{
const unsigned int irq = __builtin_ctz(irqs);
if (irq < NR_IRQ && irq_table[irq].isr)
irq_table[irq].isr();
else {
irq_setmask(irq_getmask() & ~(1<<irq));
printf("\n*** disabled spurious irq %d ***\n", irq);
}
irqs &= irqs - 1; // clear this irq (the first bit set)
}
}
#endif

Expand Down
2 changes: 2 additions & 0 deletions litex/soc/software/libbase/uart.c
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,8 @@ void uart_init(void)

uart_ev_pending_write(uart_ev_pending_read());
uart_ev_enable_write(UART_EV_TX | UART_EV_RX);
if (irq_attach)
irq_attach(UART_INTERRUPT, uart_isr);
irq_setmask(irq_getmask() | (1 << UART_INTERRUPT));
}

Expand Down

0 comments on commit 968bd28

Please sign in to comment.