From ac380738c682aab754c520fd3cf65113f320f49e Mon Sep 17 00:00:00 2001 From: vetch Date: Sat, 4 Jan 2020 20:13:06 +0100 Subject: move interrupts things to interrupts.h --- HISTORY.md | 4 +- src/clock/armclock.h | 2 +- src/clock/bcmclock.h | 2 +- src/global.h | 15 ------ src/interrupts/interrupts.h | 109 ++++++-------------------------------------- src/utils/uart.h | 1 + 6 files changed, 20 insertions(+), 113 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index e63397d..21dee9f 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -51,4 +51,6 @@ used to do - echoing everything on uart. The privileged code would mark a memory This was also an opportunity for us to check that the memory mapping truly works. We mapped virtual addresses 0xAAA00000 - 0xAAAFFFFF to physical addresses just after our kernel image and translation table (probably 0x00100000 - 0x001FFFFF given the small size of our kernel). The virtual address range 0xAAA00000 - 0xAAAFFFFF was also marked available for use by PL0 code. We then made kernel write the blob at 0x00100000 knowing it will also appear at virtual 0xAAA00000. Then, successfully running the unprivileged code from that address confirmed, that the mapping really works. -There were 2 important things forgetting about which would stop us from succeeding in this step. The first one was the stack. Kernel used to use the memory just below itself (physical 0x8000) as the stack and since these addresses would not be available for PL0 code, a new stack had to be chosen - we set it somewhere on the high part of our unprivileged memory. The second important thing was marking the section in which the memory-mapped uart registers reside as accessible form PL0. This is because we were going to have unprivileged code write to uart by itself (and use the same uart code kernel uses...). Once we had interrupts programmed, this demo was to be improved to actually call the privileged code for writing and reading. \ No newline at end of file +There were 2 important things forgetting about which would stop us from succeeding in this step. The first one was the stack. Kernel used to use the memory just below itself (physical 0x8000) as the stack and since these addresses would not be available for PL0 code, a new stack had to be chosen - we set it somewhere on the high part of our unprivileged memory. The second important thing was marking the section in which the memory-mapped uart registers reside as accessible form PL0. This is because we were going to have unprivileged code write to uart by itself (and use the same uart code kernel uses...). Once we had interrupts programmed, this demo was to be improved to actually call the privileged code for writing and reading. + +At that point we rearranged files, as it was becoming pretty unreadable having over 50 files cluttered in one directory so now we could start writing proper docs and modularize project. \ No newline at end of file diff --git a/src/clock/armclock.h b/src/clock/armclock.h index a109f9a..0d83fc2 100644 --- a/src/clock/armclock.h +++ b/src/clock/armclock.h @@ -4,7 +4,7 @@ #include #include "../global.h" - +#include "../interrupts/interrupts.h" #define ARMCLK_LOAD (ARM_BASE + 0x400) #define ARMCLK_VALUE (ARM_BASE + 0x404) #define ARMCLK_CONTROL (ARM_BASE + 0x408) diff --git a/src/clock/bcmclock.h b/src/clock/bcmclock.h index f7535ae..d08912b 100644 --- a/src/clock/bcmclock.h +++ b/src/clock/bcmclock.h @@ -2,7 +2,7 @@ #define BCMCLOCK_H #include - +#include "../interrupts/interrupts.h" #include "../global.h" #define ST_BASE (PERIF_BASE + 0x3000) // System Timer diff --git a/src/global.h b/src/global.h index c461703..4e17b44 100644 --- a/src/global.h +++ b/src/global.h @@ -25,21 +25,6 @@ // (as in sane kernels - like linux, not like in wiki.osdev codes...) #define GPIO_BASE (PERIF_BASE + 0x200000) -// ARM control block -// called "base address for the ARM interrupt register" elsewhere -#define ARM_BASE (PERIF_BASE + 0xB000) - -#define ARM_IRQ_BASIC_PENDING (ARM_BASE + 0x200) -#define ARM_IRQ_PENDING_1 (ARM_BASE + 0x204) -#define ARM_IRQ_PENDING_2 (ARM_BASE + 0x208) -#define ARM_FIQ_CONTROL (ARM_BASE + 0x20C) -#define ARM_ENABLE_IRQS_1 (ARM_BASE + 0x210) -#define ARM_ENABLE_IRQS_2 (ARM_BASE + 0x214) -#define ARM_ENABLE_BASIC_IRQS (ARM_BASE + 0x218) -#define ARM_DISABLE_IRQS_1 (ARM_BASE + 0x21C) -#define ARM_DISABLE_IRQS_2 (ARM_BASE + 0x220) -#define ARM_DISABLE_BASIC_IRQS (ARM_BASE + 0x224) - inline static uint32_t rd32(uint32_t addr) { return *(uint32_t volatile*) addr; diff --git a/src/interrupts/interrupts.h b/src/interrupts/interrupts.h index e9ade80..c2818ee 100644 --- a/src/interrupts/interrupts.h +++ b/src/interrupts/interrupts.h @@ -3,12 +3,23 @@ #include - //offset of peripherals+ offset for first addresable register for interupt controller +// ARM control block +// called "base address for the ARM interrupt register" elsewhere +#define ARM_BASE (PERIF_BASE + 0xB000) +#define ARM_IRQ_BASIC_PENDING (ARM_BASE + 0x200) +#define ARM_IRQ_PENDING_1 (ARM_BASE + 0x204) +#define ARM_IRQ_PENDING_2 (ARM_BASE + 0x208) +#define ARM_FIQ_CONTROL (ARM_BASE + 0x20C) +#define ARM_ENABLE_IRQS_1 (ARM_BASE + 0x210) +#define ARM_ENABLE_IRQS_2 (ARM_BASE + 0x214) +#define ARM_ENABLE_BASIC_IRQS (ARM_BASE + 0x218) +#define ARM_DISABLE_IRQS_1 (ARM_BASE + 0x21C) +#define ARM_DISABLE_IRQS_2 (ARM_BASE + 0x220) +#define ARM_DISABLE_BASIC_IRQS (ARM_BASE + 0x224) +//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) @@ -33,96 +44,4 @@ typedef struct { } 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/src/utils/uart.h b/src/utils/uart.h index 241b94b..2a8b7d4 100644 --- a/src/utils/uart.h +++ b/src/utils/uart.h @@ -3,6 +3,7 @@ #include #include "../global.h" +#include "../interrupts/interrupts.h" // The offsets for reach register. -- cgit v1.2.3