aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore2
-rw-r--r--docs/interrupts.pngbin0 -> 38473 bytes
-rw-r--r--interrupt_vector.S6
-rw-r--r--interrupts.c33
-rw-r--r--interrupts.h128
-rw-r--r--kernel.c0
-rw-r--r--psr.h2
-rwxr-xr-xreadfromrpi.sh4
8 files changed, 172 insertions, 3 deletions
diff --git a/.gitignore b/.gitignore
index 480597b..53f9ed5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,5 @@
+.gitignore
+.idea
*.o
*.elf
*.img
diff --git a/docs/interrupts.png b/docs/interrupts.png
new file mode 100644
index 0000000..8973fa8
--- /dev/null
+++ b/docs/interrupts.png
Binary files differ
diff --git a/interrupt_vector.S b/interrupt_vector.S
index 9404839..1ec80f7 100644
--- a/interrupt_vector.S
+++ b/interrupt_vector.S
@@ -49,4 +49,8 @@ fiq_handler_caller:
ldr sp, =_fiq_stack_top
ldr r5, =fiq_handler
bx r5
-
+
+irq:
+ mov sp, #0x8000
+ ldr r5, =abort_handler
+ subs pc,lr,#4
diff --git a/interrupts.c b/interrupts.c
index bf7ed02..51cab25 100644
--- a/interrupts.c
+++ b/interrupts.c
@@ -3,6 +3,10 @@
#include "svc_interface.h"
#include "armclock.h"
#include "scheduler.h"
+/**
+ @brief The undefined instruction interrupt handler
+**/
+
void __attribute__((noreturn)) setup(void);
@@ -31,7 +35,7 @@ uint32_t supervisor_call_handler(uint32_t regs[14])
int c;
if ((c = getchar_non_blocking()) == -1)
schedule_wait_for_input(regs);
-
+
regs[0] = c;
break;
}
@@ -102,3 +106,30 @@ void fiq_handler(void)
error("fiq happened");
}
+
+/* Here is your interrupt function */
+void
+__attribute__((interrupt("IRQ")))
+__attribute__((section(".interrupt_vectors.text")))
+irq_handler2(void) {
+ /* You code goes here */
+// uart_puts("GOT INTERRUPT!\r\n");
+
+ local_timer_clr_reload_reg_t temp = { .IntClear = 1, .Reload = 1 };
+ QA7->TimerClearReload = temp; // Clear interrupt & reload
+}
+
+/* here is your main */
+int enable_timer(void) {
+
+ QA7->TimerRouting.Routing = LOCALTIMER_TO_CORE0_IRQ; // Route local timer IRQ to Core0
+ QA7->TimerControlStatus.ReloadValue = 100; // Timer period set
+ QA7->TimerControlStatus.TimerEnable = 1; // Timer enabled
+ QA7->TimerControlStatus.IntEnable = 1; // Timer IRQ enabled
+ QA7->TimerClearReload.IntClear = 1; // Clear interrupt
+ QA7->TimerClearReload.Reload = 1; // Reload now
+ QA7->Core0TimerIntControl.nCNTPNSIRQ_IRQ = 1; // We are in NS EL1 so enable IRQ to core0 that level
+ QA7->Core0TimerIntControl.nCNTPNSIRQ_FIQ = 0; // Make sure FIQ is zero
+// uart_puts("Enabled Timer\r\n");
+ return(0);
+} \ No newline at end of file
diff --git a/interrupts.h b/interrupts.h
new file mode 100644
index 0000000..e9ade80
--- /dev/null
+++ b/interrupts.h
@@ -0,0 +1,128 @@
+#ifndef RPI_MMU_EXAMPLE_INTERRUPTS_H
+#define RPI_MMU_EXAMPLE_INTERRUPTS_H
+
+#include <stdint.h>
+
+ //offset of peripherals+ offset for first addresable register for interupt controller
+#define RPI_INTERRUPT_CONTROLLER_BASE ( 0x3F000000UL + 0xB200 )
+
+// Bits in the Enable_Basic_IRQs register to enable various interrupts.
+// According to the BCM2835 ARM Peripherals manual, section 7.5 */
+
+#define RPI_BASIC_ARM_TIMER_IRQ (1 << 0)
+#define RPI_BASIC_ARM_MAILBOX_IRQ (1 << 1)
+#define RPI_BASIC_ARM_DOORBELL_0_IRQ (1 << 2)
+#define RPI_BASIC_ARM_DOORBELL_1_IRQ (1 << 3)
+#define RPI_BASIC_GPU_0_HALTED_IRQ (1 << 4)
+#define RPI_BASIC_GPU_1_HALTED_IRQ (1 << 5)
+#define RPI_BASIC_ACCESS_ERROR_1_IRQ (1 << 6)
+#define RPI_BASIC_ACCESS_ERROR_0_IRQ (1 << 7)
+
+// @brief The interrupt controller memory mapped register set
+typedef struct {
+ volatile uint32_t IRQ_basic_pending;
+ volatile uint32_t IRQ_pending_1;
+ volatile uint32_t IRQ_pending_2;
+ volatile uint32_t FIQ_control;
+ volatile uint32_t Enable_IRQs_1;
+ volatile uint32_t Enable_IRQs_2;
+ volatile uint32_t Enable_Basic_IRQs;
+ volatile uint32_t Disable_IRQs_1;
+ volatile uint32_t Disable_IRQs_2;
+ volatile uint32_t Disable_Basic_IRQs;
+} rpi_irq_controller_t;
+
+extern rpi_irq_controller_t* RPI_GetIrqController(void);
+
+//TIMER
+
+/*--------------------------------------------------------------------------}
+{ LOCAL TIMER INTERRUPT ROUTING REGISTER - QA7_rev3.4.pdf page 18 }
+{--------------------------------------------------------------------------*/
+typedef union
+{
+ struct
+ {
+ enum {
+ LOCALTIMER_TO_CORE0_IRQ = 0,
+ LOCALTIMER_TO_CORE1_IRQ = 1,
+ LOCALTIMER_TO_CORE2_IRQ = 2,
+ LOCALTIMER_TO_CORE3_IRQ = 3,
+ LOCALTIMER_TO_CORE0_FIQ = 4,
+ LOCALTIMER_TO_CORE1_FIQ = 5,
+ LOCALTIMER_TO_CORE2_FIQ = 6,
+ LOCALTIMER_TO_CORE3_FIQ = 7,
+ } Routing: 3; // @0-2 Local Timer routing
+ unsigned unused : 29; // @3-31
+ };
+ uint32_t Raw32; // Union to access all 32 bits as a uint32_t
+} local_timer_int_route_reg_t;
+
+/*--------------------------------------------------------------------------}
+{ LOCAL TIMER CONTROL AND STATUS REGISTER - QA7_rev3.4.pdf page 17 }
+{--------------------------------------------------------------------------*/
+typedef union
+{
+ struct
+ {
+ unsigned ReloadValue : 28; // @0-27 Reload value
+ unsigned TimerEnable : 1; // @28 Timer enable (1 = enabled)
+ unsigned IntEnable : 1; // @29 Interrupt enable (1= enabled)
+ unsigned unused : 1; // @30 Unused
+ unsigned IntPending : 1; // @31 Timer Interrupt flag (Read-Only)
+ };
+ uint32_t Raw32; // Union to access all 32 bits as a uint32_t
+} local_timer_ctrl_status_reg_t;
+
+/*--------------------------------------------------------------------------}
+{ LOCAL TIMER CLEAR AND RELOAD REGISTER - QA7_rev3.4.pdf page 18 }
+{--------------------------------------------------------------------------*/
+typedef union
+{
+ struct
+ {
+ unsigned unused : 30; // @0-29 unused
+ unsigned Reload : 1; // @30 Local timer-reloaded when written as 1
+ unsigned IntClear : 1; // @31 Interrupt flag clear when written as 1
+ };
+ uint32_t Raw32; // Union to access all 32 bits as a uint32_t
+} local_timer_clr_reload_reg_t;
+
+/*--------------------------------------------------------------------------}
+{ GENERIC TIMER INTERRUPT CONTROL REGISTER - QA7_rev3.4.pdf page 13 }
+{--------------------------------------------------------------------------*/
+typedef union
+{
+ struct
+ {
+ unsigned nCNTPSIRQ_IRQ : 1; // @0 Secure physical timer event IRQ enabled, This bit is only valid if bit 4 is clear otherwise it is ignored.
+ unsigned nCNTPNSIRQ_IRQ : 1; // @1 Non-secure physical timer event IRQ enabled, This bit is only valid if bit 5 is clear otherwise it is ignored
+ unsigned nCNTHPIRQ_IRQ : 1; // @2 Hypervisor physical timer event IRQ enabled, This bit is only valid if bit 6 is clear otherwise it is ignored
+ unsigned nCNTVIRQ_IRQ : 1; // @3 Virtual physical timer event IRQ enabled, This bit is only valid if bit 7 is clear otherwise it is ignored
+ unsigned nCNTPSIRQ_FIQ : 1; // @4 Secure physical timer event FIQ enabled, If set, this bit overrides the IRQ bit (0)
+ unsigned nCNTPNSIRQ_FIQ : 1; // @5 Non-secure physical timer event FIQ enabled, If set, this bit overrides the IRQ bit (1)
+ unsigned nCNTHPIRQ_FIQ : 1; // @6 Hypervisor physical timer event FIQ enabled, If set, this bit overrides the IRQ bit (2)
+ unsigned nCNTVIRQ_FIQ : 1; // @7 Virtual physical timer event FIQ enabled, If set, this bit overrides the IRQ bit (3)
+ unsigned reserved : 24; // @8-31 reserved
+ };
+ uint32_t Raw32; // Union to access all 32 bits as a uint32_t
+} generic_timer_int_ctrl_reg_t;
+
+struct __attribute__((__packed__, aligned(4))) QA7Registers {
+ local_timer_int_route_reg_t TimerRouting; // 0x24
+ uint32_t GPIORouting; // 0x28
+ uint32_t AXIOutstandingCounters; // 0x2C
+ uint32_t AXIOutstandingIrq; // 0x30
+ local_timer_ctrl_status_reg_t TimerControlStatus; // 0x34
+ local_timer_clr_reload_reg_t TimerClearReload; // 0x38
+ uint32_t unused; // 0x3C
+ generic_timer_int_ctrl_reg_t Core0TimerIntControl; // 0x40
+ generic_timer_int_ctrl_reg_t Core1TimerIntControl; // 0x44
+ generic_timer_int_ctrl_reg_t Core2TimerIntControl; // 0x48
+ generic_timer_int_ctrl_reg_t Core3TimerIntControl; // 0x4C
+};
+#define QA7 ((volatile __attribute__((aligned(4))) struct QA7Registers*)(uintptr_t)(0x40000024))
+//40000040
+
+int enable_timer(void);
+#endif //RPI_MMU_EXAMPLE_INTERRUPTS_H
diff --git a/kernel.c b/kernel.c
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/kernel.c
diff --git a/psr.h b/psr.h
index 5efc6d9..f300a7a 100644
--- a/psr.h
+++ b/psr.h
@@ -60,7 +60,7 @@ inline static PSR_t read_CPSR(void)
PSR_t CPSR;
// get content of current program status register
asm("mrs %0, cpsr" : "=r" (CPSR.raw) :: "memory");
-
+
return CPSR;
}
diff --git a/readfromrpi.sh b/readfromrpi.sh
new file mode 100755
index 0000000..3ebc469
--- /dev/null
+++ b/readfromrpi.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+sudo stty -F /dev/ttyUSB0 115200 cs8 -cstopb -parenb
+sudo chmod 777 /dev/ttyUSB0
+#cat -v < /dev/ttyUSB0