voron

experimental ARM OS
git clone git://git.2f30.org/voron
Log | Files | Refs | README | LICENSE

commit b9f1263897df850447d121dadd40182309406668
parent 5fda517df305792ab2430c287130ebfbd8c98adf
Author: oblique <psyberbits@gmail.com>
Date:   Mon, 29 Oct 2012 13:41:47 +0200

add software generated interrupt support

Diffstat:
Minclude/gic.h | 1+
Minclude/irq.h | 1+
Mkernel/gic.c | 19+++++++++++++++++--
Mkernel/irq.c | 6++++++
Mkernel/kmain.c | 3---
5 files changed, 25 insertions(+), 5 deletions(-)

diff --git a/include/gic.h b/include/gic.h @@ -6,6 +6,7 @@ int gic_register(u32 irq_num, irq_callback_func func); void gic_handler(struct regs *regs); +int gic_trigger_sgi(u32 irq_num); void gic_init(void); #endif /* __GIC_H */ diff --git a/include/irq.h b/include/irq.h @@ -6,6 +6,7 @@ typedef void (*irq_callback_func)(u32 irq_num, struct regs *regs); int irq_register(u32 irq_num, irq_callback_func func); +int irq_trigger_sgi(u32 irq_num); /* board specific */ #define HW_IRQ(x) (x + 32) diff --git a/kernel/gic.c b/kernel/gic.c @@ -18,7 +18,12 @@ struct gicc { u32 iidr; }; -#define MAX_IT_LINES_NUMBER 32 +#define MAX_IT_LINES_NUMBER 32 +/* Forward the interrupt only to the CPU interface + * of the processor that requested the interrupt. */ +#define SGIR_TARGER_CPU_REQ (2 << 24) + +#define NUM_OF_SGI 15 /* GICv1 Distributor registers */ struct gicd { @@ -44,7 +49,6 @@ static struct gicc *gicc = (struct gicc*)0x48240100; static struct gicd *gicd = (struct gicd*)0x48241000; static irq_callback_func irq_handlers[NUM_OF_IRQ]; - int gic_register(u32 irq_num, irq_callback_func func) { @@ -90,6 +94,17 @@ gic_handler(struct regs *regs) writel(iar, &gicc->eoir); } +int +gic_trigger_sgi(u32 irq_num) +{ + if (irq_num > NUM_OF_SGI) + return -EINVAL; + + writel(irq_num | SGIR_TARGER_CPU_REQ, &gicd->sgir); + + return 0; +} + void gic_init(void) { diff --git a/kernel/irq.c b/kernel/irq.c @@ -8,6 +8,12 @@ irq_register(u32 irq_num, irq_callback_func func) return gic_register(irq_num, func); } +int +irq_trigger_sgi(u32 irq_num) +{ + return gic_trigger_sgi(irq_num); +} + void irq_handler(struct regs *regs) { diff --git a/kernel/kmain.c b/kernel/kmain.c @@ -1,7 +1,4 @@ #include <kernel.h> -#include <alloc.h> -#include <string.h> -#include <gic.h> #include <sched.h> static void