From 1c6cd8e1ea53275cc44b2a0ee5a8448cbc4a3f0d Mon Sep 17 00:00:00 2001 From: Christian Cunningham Date: Sat, 4 Dec 2021 17:09:22 -0700 Subject: Restructured project --- Unix.mk | 2 + Win.mk | 2 + src/boot.S | 3 +- src/cpu/irq.c | 38 ++++++++++++ src/cpu/irq.h | 6 ++ src/drivers/uart.a.h | 8 +++ src/drivers/uart.c | 22 +++++++ src/drivers/uart.h | 7 +++ src/lib.c | 168 --------------------------------------------------- src/lib.h | 79 ------------------------ src/sys/core.c | 124 +++++++++++++++++++++++++++++++++++++ src/sys/core.h | 121 +++++++++++++++++++++++++++++++++++++ src/sys/power.c | 7 +++ src/sys/power.h | 6 ++ src/time.c | 76 ----------------------- src/util/time.c | 64 ++++++++++++++++++++ src/util/time.h | 14 +++++ 17 files changed, 423 insertions(+), 324 deletions(-) create mode 100644 src/cpu/irq.c create mode 100644 src/cpu/irq.h create mode 100644 src/drivers/uart.a.h create mode 100644 src/drivers/uart.c create mode 100644 src/drivers/uart.h delete mode 100644 src/lib.c delete mode 100644 src/lib.h create mode 100644 src/sys/core.c create mode 100644 src/sys/core.h create mode 100644 src/sys/power.c create mode 100644 src/sys/power.h delete mode 100644 src/time.c create mode 100644 src/util/time.c create mode 100644 src/util/time.h diff --git a/Unix.mk b/Unix.mk index 5bc4697..3863264 100644 --- a/Unix.mk +++ b/Unix.mk @@ -58,9 +58,11 @@ obj/%.ao: src/%.S ${AS} ${AFLAGS} -c $< -o $@ run: build/kernel.elf + @echo Starting QEMU @${QEMU} -kernel $< ${QFLAGS} run-debug: build/kernel-g.elf + @echo Starting QEMU in Debug Mode @${QEMU} -kernel $< -s -S ${QFLAGS} debug: build/kernel-g.elf build/kernel.list diff --git a/Win.mk b/Win.mk index efc0123..cd268fe 100644 --- a/Win.mk +++ b/Win.mk @@ -58,9 +58,11 @@ obj/%.ao: src/%.S ${AS} ${AFLAGS} -c $< -o $@ run: build/kernel.elf + @echo Starting QEMU @${QEMU} -kernel $< ${QFLAGS} run-debug: build/kernel-g.elf + @echo Starting QEMU in Debug Mode @${QEMU} -kernel $< -s -S ${QFLAGS} debug: build/kernel-g.elf build/kernel.list diff --git a/src/boot.S b/src/boot.S index 7aa21fc..b1adae7 100644 --- a/src/boot.S +++ b/src/boot.S @@ -55,7 +55,8 @@ reset: irq: push {r0,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,r12,lr} - bl a_irq_handler + //bl a_irq_handler + bl c_irq_handler pop {r0,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,r12,lr} subs pc, lr, #4 diff --git a/src/cpu/irq.c b/src/cpu/irq.c new file mode 100644 index 0000000..26883a2 --- /dev/null +++ b/src/cpu/irq.c @@ -0,0 +1,38 @@ +#include "../cpu/irq.h" +#include "../sys/core.h" +#include "../drivers/uart.a.h" +#include "../util/time.h" + +extern void disable_irq(void); +extern void enable_irq(void); + +void c_irq_handler(void) { + disable_irq(); + unsigned long source = load32(CORE0_IRQ_SOURCE); + if (source & (1 << 8)) { + if(load32(IRQ_PENDING2) & (1 << 25)) { + if(load32(UART0_MIS) & (1<<4)) { + unsigned long data = load32(UART0_DR); + if(data == 0x74) { + unsigned long timer_status; + asm volatile("mrc p15, 0, %0, c14, c3, 1" : "=r"(timer_status)); + if(timer_status == 0) { + cntfrq = read_cntfrq(); + write_cntv_tval(cntfrq); + enable_cntv(); + } else { + disable_cntv(); + } + } + uart_char((unsigned char)data); + //uart_string((char*)" c_irq_handler\n"); + enable_irq(); + return; + } + } + } else if (source & (1 << 3)) { + c_timer(); + enable_irq(); + } + return; +} diff --git a/src/cpu/irq.h b/src/cpu/irq.h new file mode 100644 index 0000000..f0a2656 --- /dev/null +++ b/src/cpu/irq.h @@ -0,0 +1,6 @@ +#ifndef IRQ_H +#define IRQ_H + +void c_irq_handler(void); + +#endif diff --git a/src/drivers/uart.a.h b/src/drivers/uart.a.h new file mode 100644 index 0000000..d4bf199 --- /dev/null +++ b/src/drivers/uart.a.h @@ -0,0 +1,8 @@ +#ifndef UART_AH +#define UART_AH + +extern void uart_char(unsigned char c); +extern void uart_hex(unsigned long data); +extern void uart_string(char* message); + +#endif diff --git a/src/drivers/uart.c b/src/drivers/uart.c new file mode 100644 index 0000000..f7f15c2 --- /dev/null +++ b/src/drivers/uart.c @@ -0,0 +1,22 @@ +#include "uart.a.h" + +void uart_hexn(unsigned long c_val) { + uart_hex(c_val); + uart_char(0x0a); +} + +void uart_10(unsigned long val) { + unsigned long t = val; + unsigned long c; + char buffer[11] = "0000000000\0"; + char* dptr = buffer + 9; + for(int i = 0; i <= 10; i++) { + c = t%10; + *dptr = 0x30 + (c&0xF); + t /= 10; + if (t==0) + break; + dptr -= 1; + } + uart_string(dptr); +} diff --git a/src/drivers/uart.h b/src/drivers/uart.h new file mode 100644 index 0000000..c78398b --- /dev/null +++ b/src/drivers/uart.h @@ -0,0 +1,7 @@ +#ifndef UART_H +#define UART_H + +void uart_hexn(unsigned long); +void uart_10(unsigned long); + +#endif diff --git a/src/lib.c b/src/lib.c deleted file mode 100644 index d21009b..0000000 --- a/src/lib.c +++ /dev/null @@ -1,168 +0,0 @@ -#include "lib.h" - -extern void uart_char(unsigned char c); -extern void uart_hex(unsigned long data); -extern void uart_string(char* message); - -extern unsigned long read_cntv_tval(); -extern unsigned long read_cntfrq(); -extern void write_cntv_tval(unsigned long); // Clear cntv interrupt and set next 1 second timer -extern void routing_core0cntv_to_core0irq(); -extern void enable_cntv(); - -void uart_10(unsigned long); - -extern unsigned long cntfrq; - -static char* os_info_h = "\033[93mInitialized the Real Time Operating System\033[0m\n\033[96mName\033[0m: \033[94mDendritOS\033[0m\n\033[96mVersion\033[0m: \033[95m"; -static char* os_info_t = "\033[0m\n\nQEMU\n====\n Exit : Ctrl-A x\n Monitor : Ctrl-A c\n\n"; -#ifndef VERSION -static char* os_info_v = "?"; -#else -static char* os_info_v = VERSION; -#endif - -static char* irq_on = " \033[92mEnabled\033[0m\n"; -static char* irq_off = " \033[91mDisabled\033[0m\n"; - -static inline unsigned long load32(unsigned long addr) { - return *(volatile unsigned long*)addr; -} - -static inline void store32(unsigned long value, unsigned long addr) { - *(volatile unsigned long*)addr = value; -} - -static inline void delay(unsigned long cycles) { - asm volatile("__delay_%=: subs %[cycles], %[cycles], #1;bne __delay_%=\n" - : "=r"(cycles): [cycles]"0"(cycles) : "cc"); -} - -void uart_hexn(unsigned long c_val) { - uart_hex(c_val); - uart_char(0x0a); -} - -// Initialize IRQs -void sysinit() { - // Mask Overrun of UART0 - store32(1<<4, UART0_IMSC); - - // Enable UART GPU IRQ - store32(1<<25, IRQ_ENABLE2); - - // Route GPU interrupts to Core 0 - store32(0x00, GPU_INTERRUPTS_ROUTING); - //*(unsigned long*) - - // Enable Timer - // As an IRQ - store32(1<<0, IRQ_BASIC_ENABLE); - // As a FIQ - //store32(0xC0, FIQ_CONTROL); - // Get the frequency - cntfrq = read_cntfrq(); - // Clear cntv interrupt and set next 1 second timer - write_cntv_tval(cntfrq); - // Route timer to core0 irq - routing_core0cntv_to_core0irq(); - // Enable timer - enable_cntv(); -} - -void c_timer() { - // Reset the counter - write_cntv_tval(cntfrq); - - // Output the value - uart_string((char*)"Timer Value: "); - unsigned long v = read_cntv_tval(); - uart_10(v); - uart_char(0x20); - uart_hexn(v); -} - -// Checks IRQ status -void chk_irq_stat() { - uart_string((char*)"Checking Enabled Services...\n"); - - // Basic IRQ - unsigned long ib_val = load32(IRQ_BASIC_ENABLE); - uart_string((char*)"IRQB Status: "); - uart_hexn(ib_val); - - // IRQ 1 - unsigned long i1_val = load32(IRQ_ENABLE1); - uart_string((char*)"IRQ1 Status: "); - uart_hexn(i1_val); - - // IRQ 2 - unsigned long i2_val = load32(IRQ_ENABLE2); - uart_string((char*)"IRQ2 Status: "); - uart_hexn(i2_val); - - // Check UART IRQ - uart_string((char*)" UART:"); - if (i2_val & (1<<25)) { - uart_string(irq_on); - } else { - uart_string(irq_off); - } - - // Check TIMER IRQ - uart_string((char*)" TIMER:"); - if (ib_val & (1<<0)) { - uart_string(irq_on); - // Output the frequency - uart_string((char*)" Frequency: "); - cntfrq = read_cntfrq(); - //uart_hexn(cntfrq); - uart_10(cntfrq); - uart_string((char*)" Hz\n"); - } else { - uart_string(irq_off); - } - - // Check FIQ - unsigned long f_val = load32(FIQ_CONTROL); - uart_string((char*)"FIQ Status: "); - uart_hexn(f_val); - if (f_val & 0x80) { - uart_string(irq_on); - } else { - uart_string(irq_off); - } - - // Check GPU Interrupt Routing - unsigned long g_val = load32(GPU_INTERRUPTS_ROUTING); - uart_string((char*)"GPU IRQ Routed to Core "); - uart_char(0x30 + (g_val & 0x3)); - uart_char(0x0a); - uart_string((char*)"GPU FIQ Routed to Core "); - uart_char(0x30 + ((g_val>>2) & 0x3)); - uart_char(0x0a); - - uart_char(0x0a); -} - -void postinit() { - uart_string(os_info_h); - uart_string(os_info_v); - uart_string(os_info_t); -} - -void uart_10(unsigned long val) { - unsigned long t = val; - unsigned long c; - char buffer[11] = "0000000000\0"; - char* dptr = buffer + 9; - for(int i = 0; i <= 10; i++) { - c = t%10; - *dptr = 0x30 + (c&0xF); - t /= 10; - if (t==0) - break; - dptr -= 1; - } - uart_string(dptr); -} diff --git a/src/lib.h b/src/lib.h deleted file mode 100644 index 936a582..0000000 --- a/src/lib.h +++ /dev/null @@ -1,79 +0,0 @@ -enum -{ - // The offset for the MMIO area -#ifdef BSP23 - MMIO_BASE = 0x3F000000, // For Raspberry Pi 2 and 3 -#else - MMIO_BASE = 0xFE000000, // For Raspberry Pi 2 and 3 -#endif - - // The offsets for reach register. - GPIO_BASE = (MMIO_BASE + 0x200000), - - // Controls actuation of pull up/down to ALL GPIO pins. - GPPUD = (GPIO_BASE + 0x94), - - // Controls actuation of pull up/down for specific GPIO pin. - GPPUDCLK0 = (GPIO_BASE + 0x98), - - // The base address for UART. - UART0_BASE = (GPIO_BASE + 0x1000), // for raspi4 0xFE201000, raspi2 & 3 0x3F201000, and 0x20201000 for raspi1 - - // The offsets for reach register for the UART. - UART0_DR = (UART0_BASE + 0x00), - UART0_RSRECR = (UART0_BASE + 0x04), - UART0_FR = (UART0_BASE + 0x18), - UART0_ILPR = (UART0_BASE + 0x20), - UART0_IBRD = (UART0_BASE + 0x24), - UART0_FBRD = (UART0_BASE + 0x28), - UART0_LCRH = (UART0_BASE + 0x2C), - UART0_CR = (UART0_BASE + 0x30), - UART0_IFLS = (UART0_BASE + 0x34), - UART0_IMSC = (UART0_BASE + 0x38), - UART0_RIS = (UART0_BASE + 0x3C), - UART0_MIS = (UART0_BASE + 0x40), - UART0_ICR = (UART0_BASE + 0x44), - UART0_DMACR = (UART0_BASE + 0x48), - UART0_ITCR = (UART0_BASE + 0x80), - UART0_ITIP = (UART0_BASE + 0x84), - UART0_ITOP = (UART0_BASE + 0x88), - UART0_TDR = (UART0_BASE + 0x8C), - - // IRQ REGISTERS - IRQ_BASE = (MMIO_BASE + 0xB000), - IRQ_BASIC_PENDING = (IRQ_BASE + 0x200), - IRQ_PENDING1 = (IRQ_BASE + 0x204), - IRQ_PENDING2 = (IRQ_BASE + 0x208), - FIQ_CONTROL = (IRQ_BASE + 0x20C), - IRQ_ENABLE1 = (IRQ_BASE + 0x210), - IRQ_ENABLE2 = (IRQ_BASE + 0x214), - IRQ_BASIC_ENABLE = (IRQ_BASE + 0x218), - IRQ_DISABLE1 = (IRQ_BASE + 0x21C), - IRQ_DISABLE2 = (IRQ_BASE + 0x220), - IRQ_BASIC_DISABLE = (IRQ_BASE + 0x224), - - // Peripherals Interrupts - UART_IRQ = 57, - GPIO_IRQ_0 = 49, - GPIO_IRQ_1 = 50, - GPIO_IRQ_2 = 51, - GPIO_IRQ_3 = 52, - - FIQ_ENABLE_FLAG = 1<<7, - - // ARM Peripheral Interrupts - TIMER_ARM_IRQ = 0, - MAILBOX_ARM_IRQ = 1, - DOORBELL0_ARM_IRQ = 2, - DOORBELL1_ARM_IRQ = 3, - GPU0HALT_ARM_IRQ = 4, - GPU1HALT_ARM_IRQ = 5, - - // The offsets for Mailbox registers - MBOX_BASE = 0xB880, - MBOX_READ = (MBOX_BASE + 0x00), - MBOX_STATUS = (MBOX_BASE + 0x18), - MBOX_WRITE = (MBOX_BASE + 0x20), - - GPU_INTERRUPTS_ROUTING = 0x4000000C -}; diff --git a/src/sys/core.c b/src/sys/core.c new file mode 100644 index 0000000..0420df0 --- /dev/null +++ b/src/sys/core.c @@ -0,0 +1,124 @@ +#include "../drivers/uart.a.h" +#include "../drivers/uart.h" +#include "../util/time.h" +#include "../sys/core.h" +#include "../sys/power.h" + +static char* os_info_h = "\033[93mInitialized the Real Time Operating System\033[0m\n\033[96mName\033[0m: \033[94mDendritOS\033[0m\n\033[96mVersion\033[0m: \033[95m"; +static char* os_info_t = "\033[0m\n\nQEMU\n====\n Exit : Ctrl-A x\n Monitor : Ctrl-A c\n\n"; +#ifndef VERSION +static char* os_info_v = "?"; +#else +static char* os_info_v = VERSION; +#endif + +static char* irq_on = " \033[92mEnabled\033[0m\n"; +static char* irq_off = " \033[91mDisabled\033[0m\n"; + +// Initialize IRQs +void sysinit() { + // Mask Overrun of UART0 + store32(1<<4, UART0_IMSC); + + // Enable UART GPU IRQ + store32(1<<25, IRQ_ENABLE2); + + // Route GPU interrupts to Core 0 + store32(0x00, GPU_INTERRUPTS_ROUTING); + //*(unsigned long*) + + // Enable Timer + // As an IRQ + store32(1<<0, IRQ_BASIC_ENABLE); + // As a FIQ + //store32(0xC0, FIQ_CONTROL); + // Get the frequency + cntfrq = read_cntfrq(); + // Clear cntv interrupt and set next 1 second timer + write_cntv_tval(cntfrq); + // Route timer to core0 irq + routing_core0cntv_to_core0irq(); + // Enable timer + enable_cntv(); +} + +void c_timer() { + // Reset the counter + write_cntv_tval(cntfrq); + + // Output the value + uart_string((char*)"Timer Value: "); + unsigned long v = read_cntv_tval(); + uart_10(v); + uart_char(0x20); + uart_hexn(v); +} + +// Checks IRQ status +void chk_irq_stat() { + uart_string((char*)"Checking Enabled Services...\n"); + + // Basic IRQ + unsigned long ib_val = load32(IRQ_BASIC_ENABLE); + uart_string((char*)"IRQB Status: "); + uart_hexn(ib_val); + + // IRQ 1 + unsigned long i1_val = load32(IRQ_ENABLE1); + uart_string((char*)"IRQ1 Status: "); + uart_hexn(i1_val); + + // IRQ 2 + unsigned long i2_val = load32(IRQ_ENABLE2); + uart_string((char*)"IRQ2 Status: "); + uart_hexn(i2_val); + + // Check UART IRQ + uart_string((char*)" UART:"); + if (i2_val & (1<<25)) { + uart_string(irq_on); + } else { + uart_string(irq_off); + } + + // Check TIMER IRQ + uart_string((char*)" TIMER:"); + if (ib_val & (1<<0)) { + uart_string(irq_on); + // Output the frequency + uart_string((char*)" Frequency: "); + cntfrq = read_cntfrq(); + //uart_hexn(cntfrq); + uart_10(cntfrq); + uart_string((char*)" Hz\n"); + } else { + uart_string(irq_off); + } + + // Check FIQ + unsigned long f_val = load32(FIQ_CONTROL); + uart_string((char*)"FIQ Status: "); + uart_hexn(f_val); + if (f_val & 0x80) { + uart_string(irq_on); + } else { + uart_string(irq_off); + } + + // Check GPU Interrupt Routing + unsigned long g_val = load32(GPU_INTERRUPTS_ROUTING); + uart_string((char*)"GPU IRQ Routed to Core "); + uart_char(0x30 + (g_val & 0x3)); + uart_char(0x0a); + uart_string((char*)"GPU FIQ Routed to Core "); + uart_char(0x30 + ((g_val>>2) & 0x3)); + uart_char(0x0a); + + uart_char(0x0a); +} + +void postinit() { + uart_string(os_info_h); + uart_string(os_info_v); + uart_string(os_info_t); +} diff --git a/src/sys/core.h b/src/sys/core.h new file mode 100644 index 0000000..d2b4c1b --- /dev/null +++ b/src/sys/core.h @@ -0,0 +1,121 @@ +#ifndef CORE_H +#define CORE_H + +extern unsigned long cntfrq; + +static inline unsigned long load32(unsigned long addr) { + return *(volatile unsigned long*)addr; +} + +static inline void store32(unsigned long value, unsigned long addr) { + *(volatile unsigned long*)addr = value; +} + +static inline void delay(unsigned long cycles) { + asm volatile("__delay_%=: subs %[cycles], %[cycles], #1;bne __delay_%=\n" + : "=r"(cycles): [cycles]"0"(cycles) : "cc"); +} + +enum +{ + // The offset for the MMIO area +#ifdef BSP23 + MMIO_BASE = 0x3F000000, // For Raspberry Pi 2 and 3 +#else + MMIO_BASE = 0xFE000000, // For Raspberry Pi 2 and 3 +#endif + + // The offsets for reach register. + GPIO_BASE = (MMIO_BASE + 0x200000), + + // Controls actuation of pull up/down to ALL GPIO pins. + GPPUD = (GPIO_BASE + 0x94), + + // Controls actuation of pull up/down for specific GPIO pin. + GPPUDCLK0 = (GPIO_BASE + 0x98), + + // The base address for UART. + UART0_BASE = (GPIO_BASE + 0x1000), // for raspi4 0xFE201000, raspi2 & 3 0x3F201000, and 0x20201000 for raspi1 + + // The offsets for reach register for the UART. + UART0_DR = (UART0_BASE + 0x00), + UART0_RSRECR = (UART0_BASE + 0x04), + UART0_FR = (UART0_BASE + 0x18), + UART0_ILPR = (UART0_BASE + 0x20), + UART0_IBRD = (UART0_BASE + 0x24), + UART0_FBRD = (UART0_BASE + 0x28), + UART0_LCRH = (UART0_BASE + 0x2C), + UART0_CR = (UART0_BASE + 0x30), + UART0_IFLS = (UART0_BASE + 0x34), + UART0_IMSC = (UART0_BASE + 0x38), + UART0_RIS = (UART0_BASE + 0x3C), + UART0_MIS = (UART0_BASE + 0x40), + UART0_ICR = (UART0_BASE + 0x44), + UART0_DMACR = (UART0_BASE + 0x48), + UART0_ITCR = (UART0_BASE + 0x80), + UART0_ITIP = (UART0_BASE + 0x84), + UART0_ITOP = (UART0_BASE + 0x88), + UART0_TDR = (UART0_BASE + 0x8C), + + // IRQ REGISTERS + IRQ_BASE = (MMIO_BASE + 0xB000), + IRQ_BASIC_PENDING = (IRQ_BASE + 0x200), + IRQ_PENDING1 = (IRQ_BASE + 0x204), + IRQ_PENDING2 = (IRQ_BASE + 0x208), + FIQ_CONTROL = (IRQ_BASE + 0x20C), + IRQ_ENABLE1 = (IRQ_BASE + 0x210), + IRQ_ENABLE2 = (IRQ_BASE + 0x214), + IRQ_BASIC_ENABLE = (IRQ_BASE + 0x218), + IRQ_DISABLE1 = (IRQ_BASE + 0x21C), + IRQ_DISABLE2 = (IRQ_BASE + 0x220), + IRQ_BASIC_DISABLE = (IRQ_BASE + 0x224), + + // Peripherals Interrupts + UART_IRQ = 57, + GPIO_IRQ_0 = 49, + GPIO_IRQ_1 = 50, + GPIO_IRQ_2 = 51, + GPIO_IRQ_3 = 52, + + FIQ_ENABLE_FLAG = 1<<7, + + // ARM Peripheral Interrupts + TIMER_ARM_IRQ = 0, + MAILBOX_ARM_IRQ = 1, + DOORBELL0_ARM_IRQ = 2, + DOORBELL1_ARM_IRQ = 3, + GPU0HALT_ARM_IRQ = 4, + GPU1HALT_ARM_IRQ = 5, + + // The offsets for Mailbox registers + MBOX_BASE = 0xB880, + MBOX_READ = (MBOX_BASE + 0x00), + MBOX_STATUS = (MBOX_BASE + 0x18), + MBOX_WRITE = (MBOX_BASE + 0x20), + + GPU_INTERRUPTS_ROUTING = 0x4000000C, + + CORE0_TIMER_IRQCNTL = 0x40000040, + CORE0_IRQ_SOURCE = 0x40000060, + + /* Power Management, Reset controller and Watchdog registers */ + //BCM2835_PERI_BASE = 0x3F000000, + BCM2835_PERI_BASE = 0x20000000, + PM_BASE = (BCM2835_PERI_BASE + 0x100000), + PM_RSTC = (PM_BASE+0x1c), + PM_WDOG = (PM_BASE+0x24), + PM_WDOG_RESET = 0x00000000, + PM_PASSWORD = 0x5a000000, + PM_WDOG_TIME_SET = 0x000fffff, + PM_RSTC_WRCFG_CLR = 0xffffffcf, + PM_RSTC_WRCFG_SET = 0x00000030, + PM_RSTC_WRCFG_FULL_RESET = 0x00000020, + PM_RSTC_RESET = 0x00000102 +}; + +void sysinit(); +void c_timer(); +void chk_irq_stat(); +void postinit(); + +#endif diff --git a/src/sys/power.c b/src/sys/power.c new file mode 100644 index 0000000..4abee01 --- /dev/null +++ b/src/sys/power.c @@ -0,0 +1,7 @@ +#include "../sys/core.h" +#include "../sys/power.h" + +void reboot(void) { + store32(PM_WDOG, PM_PASSWORD | 1); + store32(PM_RSTC, PM_PASSWORD | PM_RSTC_WRCFG_FULL_RESET); +} diff --git a/src/sys/power.h b/src/sys/power.h new file mode 100644 index 0000000..711842b --- /dev/null +++ b/src/sys/power.h @@ -0,0 +1,6 @@ +#ifndef SYS_POWER_H +#define SYS_POWER_H + +void reboot(void); + +#endif diff --git a/src/time.c b/src/time.c deleted file mode 100644 index d637612..0000000 --- a/src/time.c +++ /dev/null @@ -1,76 +0,0 @@ -static inline unsigned long load32(unsigned long addr) { - return *(volatile unsigned long*)addr; -} - -static inline void store32(unsigned long value, unsigned long addr) { - *(volatile unsigned long*)addr = value; -} - -#define uint64_t unsigned long long -#define uint32_t unsigned long - -#define CORE0_TIMER_IRQCNTL 0x40000040 -#define CORE0_IRQ_SOURCE 0x40000060 - -void routing_core0cntv_to_core0irq(void) -{ - // IRQ - store32(0x08, CORE0_TIMER_IRQCNTL); - // FIQ - //store32(0x80, CORE0_TIMER_IRQCNTL); -} - -uint32_t read_core0timer_pending(void) -{ - uint32_t tmp; - tmp = load32(CORE0_IRQ_SOURCE); - return tmp; -} - -void enable_cntv(void) -{ - uint32_t cntv_ctl; - cntv_ctl = 1; - asm volatile ("mcr p15, 0, %0, c14, c3, 1" :: "r"(cntv_ctl) ); // write CNTV_CTL -} - -void disable_cntv(void) -{ - uint32_t cntv_ctl; - cntv_ctl = 0; - asm volatile ("mcr p15, 0, %0, c14, c3, 1" :: "r"(cntv_ctl) ); // write CNTV_CTL -} - -uint64_t read_cntvct(void) -{ - uint64_t val; - asm volatile("mrrc p15, 1, %Q0, %R0, c14" : "=r" (val)); - return (val); -} - -uint64_t read_cntvoff(void) -{ - uint64_t val; - asm volatile("mrrc p15, 4, %Q0, %R0, c14" : "=r" (val)); - return (val); -} - -uint32_t read_cntv_tval(void) -{ - uint32_t val; - asm volatile ("mrc p15, 0, %0, c14, c3, 0" : "=r"(val) ); - return val; -} - -void write_cntv_tval(uint32_t val) -{ - asm volatile ("mcr p15, 0, %0, c14, c3, 0" :: "r"(val) ); - return; -} - -uint32_t read_cntfrq(void) -{ - uint32_t val; - asm volatile ("mrc p15, 0, %0, c14, c0, 0" : "=r"(val) ); - return val; -} diff --git a/src/util/time.c b/src/util/time.c new file mode 100644 index 0000000..72fc52b --- /dev/null +++ b/src/util/time.c @@ -0,0 +1,64 @@ +#include "../sys/core.h" + +void routing_core0cntv_to_core0irq(void) +{ + // IRQ + store32(0x08, CORE0_TIMER_IRQCNTL); + // FIQ + //store32(0x80, CORE0_TIMER_IRQCNTL); +} + +unsigned long read_core0timer_pending(void) +{ + unsigned long tmp; + tmp = load32(CORE0_IRQ_SOURCE); + return tmp; +} + +void enable_cntv(void) +{ + unsigned long cntv_ctl; + cntv_ctl = 1; + asm volatile ("mcr p15, 0, %0, c14, c3, 1" :: "r"(cntv_ctl) ); // write CNTV_CTL +} + +void disable_cntv(void) +{ + unsigned long cntv_ctl; + cntv_ctl = 0; + asm volatile ("mcr p15, 0, %0, c14, c3, 1" :: "r"(cntv_ctl) ); // write CNTV_CTL +} + +unsigned long long read_cntvct(void) +{ + unsigned long long val; + asm volatile("mrrc p15, 1, %Q0, %R0, c14" : "=r" (val)); + return (val); +} + +unsigned long long read_cntvoff(void) +{ + unsigned long long val; + asm volatile("mrrc p15, 4, %Q0, %R0, c14" : "=r" (val)); + return (val); +} + +unsigned long read_cntv_tval(void) +{ + unsigned long val; + asm volatile ("mrc p15, 0, %0, c14, c3, 0" : "=r"(val) ); + return val; +} + +void write_cntv_tval(unsigned long val) +{ + asm volatile ("mcr p15, 0, %0, c14, c3, 0" :: "r"(val) ); + return; +} + +unsigned long read_cntfrq(void) +{ + unsigned long val; + asm volatile ("mrc p15, 0, %0, c14, c0, 0" : "=r"(val) ); + return val; +} diff --git a/src/util/time.h b/src/util/time.h new file mode 100644 index 0000000..1fb3906 --- /dev/null +++ b/src/util/time.h @@ -0,0 +1,14 @@ +#ifndef TIME_H +#define TIME_H + +void routing_core0cntv_to_core0irq(void); +unsigned long read_core0timer_pending(void); +void enable_cntv(void); +void disable_cntv(void); +unsigned long long read_cntvct(void); +unsigned long long read_cntvoff(void); +unsigned long read_cntv_tval(void); +void write_cntv_tval(unsigned long val); +unsigned long read_cntfrq(void); + +#endif -- cgit v1.2.1