aboutsummaryrefslogtreecommitdiff
path: root/src/sys
diff options
context:
space:
mode:
authorChristian Cunningham <cc@localhost>2021-12-04 17:09:22 -0700
committerChristian Cunningham <cc@localhost>2021-12-04 17:09:22 -0700
commit1c6cd8e1ea53275cc44b2a0ee5a8448cbc4a3f0d (patch)
tree8ba9eed6acebbd0940898e5c46b35caed7e03792 /src/sys
parent0ee2aaaa26441e37ed27e6c83cf9b65202596a4e (diff)
Restructured project
Diffstat (limited to 'src/sys')
-rw-r--r--src/sys/core.c124
-rw-r--r--src/sys/core.h121
-rw-r--r--src/sys/power.c7
-rw-r--r--src/sys/power.h6
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