diff options
Diffstat (limited to 'src/sys')
-rw-r--r-- | src/sys/core.c | 124 | ||||
-rw-r--r-- | src/sys/core.h | 121 | ||||
-rw-r--r-- | src/sys/power.c | 7 | ||||
-rw-r--r-- | src/sys/power.h | 6 |
4 files changed, 258 insertions, 0 deletions
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 |