diff options
Diffstat (limited to 'kernel/cpu/irq.c')
-rw-r--r-- | kernel/cpu/irq.c | 93 |
1 files changed, 93 insertions, 0 deletions
diff --git a/kernel/cpu/irq.c b/kernel/cpu/irq.c new file mode 100644 index 0000000..f89bba9 --- /dev/null +++ b/kernel/cpu/irq.c @@ -0,0 +1,93 @@ +#include <cpu.h> +#include <cpu/irq.h> +#include <globals.h> +#include <graphics/lfb.h> +#include <symbols.h> +#include <sys/core.h> +#include <sys/schedule.h> +#include <tests/test.h> +#include <util/mutex.h> +#include <util/status.h> +#include <util/time.h> +#include <usr/main.h> + +#define CPS 1000 + +void handle_data(unsigned char); + +static unsigned long counter = 0; +unsigned long c_irq_handler(void) +{ + unsigned long source = load32(CORE0_IRQ_SOURCE); + // Check if GPU Interrupt + if (source & (1 << 8)) { + // Check if UART Interrupt + if(load32(IRQ_PENDING2) & (1 << 25)) { + // Check if UART Interrupt is Masked + if(load32(UART0_MIS) & (1<<4)) { + // Get the UART data + unsigned long data = load32(UART0_DR); + + // Handle the recieved data +#ifdef DEBUG + // Ctrl+G to output scheduler debug info + if (data == 0x7) { + uart_scheduler(); + uart_mutexes(); + } +#endif + // Add task to handle the data + { + add_thread(handle_data, (void*)data, PRIORITIES-1); + return 1; + } + } + } + // Check if System Time Compare 0 Triggered the Interrupt + if (*(volatile unsigned long*)SYS_TIMER_CS & SYS_TIMER_SC_M0) { + 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; + *timer_cs = SYS_TIMER_SC_M0; + return 1; + } + } + // Check if CNTV triggered the interrupt + else if (source & (1 << 3)) { + // Reset the counter + write_cntv_tval(cntfrq); + counter++; + if (counter % 0x6000 == 0) + counter = 0; + } + return 0; +} + +unsigned long c_fiq_handler(void) +{ + unsigned long source = load32(CORE0_FIQ_SOURCE); + // Check if CNTV triggered the interrupt + if (source & (1 << 3)) { + write_cntv_tval(cntfrq); + } + return 0; +} + +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); + } +} |