From 49bd4c133fc83de1cb1761ff089a2de03699d991 Mon Sep 17 00:00:00 2001 From: Christian Cunningham Date: Thu, 24 Mar 2022 16:44:51 -0700 Subject: IRQ Subscription --- include/cpu/irq.h | 14 ++++++++++++++ include/globals.h | 2 ++ include/symbols.h | 2 +- include/usr/main.h | 3 ++- kernel/cpu/irq.c | 54 +++++++++++++++++++++++++++++++++--------------------- kernel/globals.c | 2 ++ kernel/sys/core.c | 38 ++++++++++++++++++++------------------ usr/main.c | 49 ++++++++++++++++++++++++++++++++++++++++++++++--- 8 files changed, 120 insertions(+), 44 deletions(-) diff --git a/include/cpu/irq.h b/include/cpu/irq.h index 1879707..c5e59bb 100644 --- a/include/cpu/irq.h +++ b/include/cpu/irq.h @@ -1,6 +1,19 @@ #ifndef CPU_IRQ_H #define CPU_IRQ_H +#define UART_IRQ 0 +#define SYS_TIMER_0_IRQ 1 +#define SYS_TIMER_1_IRQ 2 +#define SYS_TIMER_2_IRQ 3 +#define SYS_TIMER_3_IRQ 4 +#define LOCAL_TIMER_IRQ 5 +#define MAX_IRQS LOCAL_TIMER_IRQ+1 + +struct IrqEntry { + void* handler; + void* handler_info; +}; + static inline void enableirq(void) { asm volatile("cpsie i"); @@ -20,5 +33,6 @@ static inline void disablefiq(void) unsigned long c_irq_handler(void); unsigned long c_fiq_handler(void); +void subscribe_irq(unsigned long irq_num, void* handler, void* handler_info); #endif diff --git a/include/globals.h b/include/globals.h index 6c7e1f1..478b62e 100644 --- a/include/globals.h +++ b/include/globals.h @@ -1,5 +1,6 @@ #ifndef GLOBALS_H #define GLOBALS_H +#include #include #include @@ -20,6 +21,7 @@ extern struct Mutex mutexs[MAX_MUTEXS]; extern struct Entry mutex_entries[MAX_MUTEXS]; extern struct Thread threads[MAX_THREADS]; extern struct Entry thread_entries[MAX_THREADS]; +extern struct IrqEntry irqs[MAX_IRQS]; #endif #endif diff --git a/include/symbols.h b/include/symbols.h index 90cfcf0..b81b1a9 100644 --- a/include/symbols.h +++ b/include/symbols.h @@ -50,7 +50,7 @@ enum IRQ_BASIC_DISABLE = (IRQ_BASE + 0x224), // Peripherals Interrupts - UART_IRQ = 57, + //UART_IRQ = 57, GPIO_IRQ_0 = 49, GPIO_IRQ_1 = 50, GPIO_IRQ_2 = 51, diff --git a/include/usr/main.h b/include/usr/main.h index 5fd29f9..3aec5a9 100644 --- a/include/usr/main.h +++ b/include/usr/main.h @@ -2,11 +2,12 @@ #define USR_MAIN_H #ifdef RPI_BUILD - #define USR_TIME 40 + #define USR_TIME 260 #else #define USR_TIME 2000 #endif void main(void); +void handle_data(unsigned char); #endif diff --git a/kernel/cpu/irq.c b/kernel/cpu/irq.c index f89bba9..9490489 100644 --- a/kernel/cpu/irq.c +++ b/kernel/cpu/irq.c @@ -13,8 +13,6 @@ #define CPS 1000 -void handle_data(unsigned char); - static unsigned long counter = 0; unsigned long c_irq_handler(void) { @@ -37,19 +35,19 @@ unsigned long c_irq_handler(void) } #endif // Add task to handle the data - { - add_thread(handle_data, (void*)data, PRIORITIES-1); + if (irqs[UART_IRQ].handler != 0) { + add_thread(irqs[UART_IRQ].handler, (void*)data, *(unsigned long*)irqs[UART_IRQ].handler_info); return 1; } } } // Check if System Time Compare 0 Triggered the Interrupt - if (*(volatile unsigned long*)SYS_TIMER_CS & SYS_TIMER_SC_M0) { + if (*(volatile unsigned long*)SYS_TIMER_CS & SYS_TIMER_SC_M0 && irqs[SYS_TIMER_0_IRQ].handler != 0) { volatile unsigned long* timer_cs = (volatile unsigned long*)SYS_TIMER_CS; volatile unsigned long* timer_chi = (volatile unsigned long*)SYS_TIMER_CHI; volatile unsigned long* nexttime = (volatile unsigned long*)SYS_TIMER_C0; - add_thread_without_duplicate(main, 0, 0); - *nexttime = *timer_chi + USR_TIME; + add_thread(irqs[SYS_TIMER_0_IRQ].handler, 0, 1); + *nexttime = *timer_chi + *(unsigned long*)irqs[SYS_TIMER_0_IRQ].handler_info; *timer_cs = SYS_TIMER_SC_M0; return 1; } @@ -69,25 +67,39 @@ unsigned long c_fiq_handler(void) { unsigned long source = load32(CORE0_FIQ_SOURCE); // Check if CNTV triggered the interrupt - if (source & (1 << 3)) { + if (source & (1 << 3) && irqs[LOCAL_TIMER_IRQ].handler != 0) { + add_thread(irqs[LOCAL_TIMER_IRQ].handler, 0, 1); write_cntv_tval(cntfrq); } return 0; } -void handle_data(unsigned char data) +void subscribe_irq(unsigned long irq_num, void* handler, void* handler_info) { - // Newline Case - if (data == 0x0D) { - // Backspace Case - } else if (data == 0x08 || data == 0x7F) { - } else if (data == 0x61) { - add_thread(uart_scheduler, 0, 2); - } else if (data == 0x62) { - //add_thread(test_entry, 0, 2); - } - // Draw it on the screen - { - draw_chex32(0, 9, data, 0xAA00FF); + if (irq_num >= MAX_IRQS) + return; + irqs[irq_num].handler = handler; + irqs[irq_num].handler_info = handler_info; + switch (irq_num) { + case UART_IRQ: + store32(1<<4, UART0_IMSC); + store32(1<<25, IRQ_ENABLE2); + break; + case SYS_TIMER_0_IRQ: + store32(SYS_TIMER_SC_M0, IRQ_ENABLE1); + *(volatile unsigned long*)SYS_TIMER_C0 = *(volatile unsigned long*)SYS_TIMER_CHI + *(unsigned long*)handler_info; + break; + case SYS_TIMER_1_IRQ: + store32(SYS_TIMER_SC_M1, IRQ_ENABLE1); + *(volatile unsigned long*)SYS_TIMER_C1 = *(volatile unsigned long*)SYS_TIMER_CHI + *(unsigned long*)handler_info; + break; + case SYS_TIMER_2_IRQ: + store32(SYS_TIMER_SC_M2, IRQ_ENABLE1); + *(volatile unsigned long*)SYS_TIMER_C2 = *(volatile unsigned long*)SYS_TIMER_CHI + *(unsigned long*)handler_info; + break; + case SYS_TIMER_3_IRQ: + store32(SYS_TIMER_SC_M3, IRQ_ENABLE1); + *(volatile unsigned long*)SYS_TIMER_C3 = *(volatile unsigned long*)SYS_TIMER_CHI + *(unsigned long*)handler_info; + break; } } diff --git a/kernel/globals.c b/kernel/globals.c index 5118e96..5cdab01 100644 --- a/kernel/globals.c +++ b/kernel/globals.c @@ -1,4 +1,5 @@ #define GLOBALS_C +#include #include #include char* os_name = "Jobbed"; @@ -18,6 +19,7 @@ __attribute__((section(".bss"))) unsigned int gwidth; __attribute__((section(".bss"))) unsigned int gheight; __attribute__((section(".bss"))) unsigned int gpitch; __attribute__((section(".bss"))) unsigned int gisrgb; +__attribute__((section(".bss"))) struct IrqEntry irqs[MAX_IRQS]; __attribute__((section(".bss.mutexs"))) struct Mutex mutexs[MAX_MUTEXS]; __attribute__((section(".bss.mutexe"))) struct Entry mutex_entries[MAX_MUTEXS]; __attribute__((section(".bss.threads"))) struct Thread threads[MAX_THREADS]; diff --git a/kernel/sys/core.c b/kernel/sys/core.c index d76b712..7f42d6e 100644 --- a/kernel/sys/core.c +++ b/kernel/sys/core.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -18,30 +19,30 @@ void sysinit(void) { // Initialize System Globals - stimeh = *(unsigned long*)SYS_TIMER_CHI; - stimel = *(unsigned long*)SYS_TIMER_CLO; - *(unsigned long*) SYS_TIMER_C0 = 2000000 + stimeh; // 2 second trigger + //stimeh = *(unsigned long*)SYS_TIMER_CHI; + //stimel = *(unsigned long*)SYS_TIMER_CLO; + //*(unsigned long*) SYS_TIMER_C0 = 2000000 + stimeh; // 2 second trigger uart_init(); ///... // Route GPU interrupts to Core 0 store32(0x00, GPU_INTERRUPTS_ROUTING); - // Mask Overrun of UART0 - store32(1<<4, UART0_IMSC); - // Enable UART GPU IRQ - store32(1<<25, IRQ_ENABLE2); - // Enable Timer - //// Get the frequency - cntfrq = read_cntfrq(); - // Clear cntv interrupt and set next 1 second timer - write_cntv_tval(cntfrq); - // Route timer to core0 fiq - routing_core0cntv_to_core0fiq(); - // Enable timer - enablecntv(); - // Enable system timer - store32(SYS_TIMER_SC_M0, IRQ_ENABLE1); + //// Mask Overrun of UART0 + //store32(1<<4, UART0_IMSC); + //// Enable UART GPU IRQ + //store32(1<<25, IRQ_ENABLE2); + //// Enable Timer + ////// Get the frequency + //cntfrq = read_cntfrq(); + //// Clear cntv interrupt and set next 1 second timer + //write_cntv_tval(cntfrq); + //// Route timer to core0 fiq + //routing_core0cntv_to_core0fiq(); + //// Enable timer + //enablecntv(); + //// Enable system timer + //store32(SYS_TIMER_SC_M0, IRQ_ENABLE1); // Graphics Initialize lfb_init(); @@ -55,4 +56,5 @@ void sysinit(void) // Start Scheduler init_scheduler(); + add_thread(main, 0, 0); } diff --git a/usr/main.c b/usr/main.c index 3543c31..9c8a7d8 100644 --- a/usr/main.c +++ b/usr/main.c @@ -1,5 +1,27 @@ #include +#include #include +#include +#include + +void loop(void); + +void handle_data(unsigned char data) +{ + // Newline Case + if (data == 0x0D) { + // Backspace Case + } else if (data == 0x08 || data == 0x7F) { + } else if (data == 0x61) { + add_thread(uart_scheduler, 0, 2); + } else if (data == 0x62) { + //add_thread(test_entry, 0, 2); + } + // Draw it on the screen + { + draw_chex32(0, 9, data, 0xAA00FF); + } +} char* ulong_to_string(unsigned long value, char* data) { @@ -21,16 +43,37 @@ char* ulong_to_string(unsigned long value, char* data) return dptr; } -void main(void) +void loop(void) { static char str[13]; static unsigned long previous = 0; char* start; unsigned long current = *(volatile unsigned long*)SYS_TIMER_CHI; start = ulong_to_string(current, str); + draw_string(0, 10, " "); draw_string(0, 10, start); - start = ulong_to_string(current - previous, str); + start = ulong_to_string(previous, str); draw_string(0, 11, " "); draw_string(0, 11, start); - previous = current; + start = ulong_to_string(nextpid, str); + draw_string(0, 12, " "); + draw_string(0, 12, start); + previous++; + wait_msec(3000); + add_thread(loop, 0, 3); +} + +void loopt(void) +{ + static char str[13]; + draw_string(0, 9, ulong_to_string(*(volatile unsigned long*)SYS_TIMER_CHI, str)); +} + +static unsigned long TICK_RATE = 5000000; +static unsigned long UART_PRIORITY = 2; +void main(void) +{ + subscribe_irq(UART_IRQ, handle_data, &UART_PRIORITY); + subscribe_irq(SYS_TIMER_0_IRQ, loopt, &TICK_RATE); + add_thread(loop, 0, 0); } -- cgit v1.2.1