aboutsummaryrefslogtreecommitdiff
path: root/kernel/cpu/irq.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/cpu/irq.c')
-rw-r--r--kernel/cpu/irq.c93
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);
+ }
+}