aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore2
-rw-r--r--demo_functionality.h4
-rw-r--r--docs/interrupts.pngbin0 -> 38473 bytes
-rw-r--r--interrupt_vector.S49
-rw-r--r--interrupts.c38
-rw-r--r--interrupts.h128
-rw-r--r--kernel.c0
-rw-r--r--psr.h2
-rwxr-xr-xreadfromrpi.sh4
9 files changed, 216 insertions, 11 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/demo_functionality.h b/demo_functionality.h
index 12f5807..57fd6f0 100644
--- a/demo_functionality.h
+++ b/demo_functionality.h
@@ -5,10 +5,6 @@ void demo_paging_support(void);
void demo_current_mode(void);
-void demo_setup_libkernel(void);
-
-void demo_setup_PL0(void);
-
void demo_go_unprivileged(void);
void demo_setup_interrupts(void);
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 af80eec..1f5bb3a 100644
--- a/interrupt_vector.S
+++ b/interrupt_vector.S
@@ -1,4 +1,40 @@
+.section ".interrupt_vectors.text"
+
+.global abort_handler
+.local generic_handler
+.global _interrupt_vectors
_interrupt_vectors:
+ ldr pc,reset_handler
+ ldr pc,undefined_handler
+ ldr pc,swi_handler
+ ldr pc,prefetch_handler
+ ldr pc,data_handler
+ ldr pc,unused_handler
+ ldr pc,irq_handler_caller
+ ldr pc,fiq_handler
+ reset_handler: .word abort
+ undefined_handler: .word abort
+ swi_handler: .word abort
+ prefetch_handler: .word abort
+ data_handler: .word abort
+ unused_handler: .word abort
+ irq_handler_caller: .word irq
+ fiq_handler: .word abort
+ //b abort_handler_caller
+ //b abort_handler_caller
+ //b abort_handler_caller
+ //b abort_handler_caller
+ //b abort_handler_caller
+ //b abort_handler_caller
+ //b abort_handler_caller
+
+
+.globl enable_irq
+enable_irq:
+ mrs r0,cpsr
+ bic r0,r0,#0x80
+ msr cpsr_c,r0
+ bx lr
b reset_handler_caller
b undef_handler_caller
b svc_handler_caller
@@ -7,12 +43,12 @@ _interrupt_vectors:
b generic_handler_caller
b irq_handler_caller
b fiq_handler_caller
-
+
reset_handler_caller:
ldr sp, =_supervisor_stack_top
ldr r5, =reset_handler
bx r5
-
+
undef_handler_caller:
ldr sp, =_supervisor_stack_top
ldr r5, =undefined_instruction_vector
@@ -24,7 +60,7 @@ svc_handler_caller:
ldr r5, =supervisor_call_handler
blx r5
ldm sp!, {r5, pc} ^
-
+
abort_handler_caller:
ldr sp, =_supervisor_stack_top
ldr r5, =abort_handler
@@ -47,4 +83,9 @@ 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 \ No newline at end of file
diff --git a/interrupts.c b/interrupts.c
index f4192a0..2dd7fbd 100644
--- a/interrupts.c
+++ b/interrupts.c
@@ -1,7 +1,11 @@
+#include "uart.h"
+#include "interrupts.h"
#include "io.h"
#include "svc_interface.h"
#include "armclock.h"
-
+/**
+ @brief The undefined instruction interrupt handler
+ */
void __attribute__((noreturn)) setup(void);
// from what I've heard, reset is never used on the Pi;
@@ -25,7 +29,7 @@ uint32_t supervisor_call_handler(enum svc_type request, uint32_t arg1,
uint32_t arg2, uint32_t arg3)
{
(void) arg2; (void) arg3; // unused for now
-
+
switch(request) {
case UART_PUTCHAR:
putchar(arg1);
@@ -59,6 +63,9 @@ void generic_handler(void)
void irq_handler(void)
{
+ uart_puts("nwm\r\n");
+
+ system_reentry_point();
if (armclk_irq_pending())
{
puts("<<irq from timer>>");
@@ -78,3 +85,30 @@ void fiq_handler(void)
while(1);
}
+
+/* Here is your interrupt function */
+void
+__attribute__((interrupt("IRQ")))
+__attribute__((section(".interrupt_vectors.text")))
+irq_handler(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