From 1c6cd8e1ea53275cc44b2a0ee5a8448cbc4a3f0d Mon Sep 17 00:00:00 2001
From: Christian Cunningham <cc@localhost>
Date: Sat, 4 Dec 2021 17:09:22 -0700
Subject: Restructured project

---
 src/sys/core.c  | 124 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/sys/core.h  | 121 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/sys/power.c |   7 ++++
 src/sys/power.h |   6 +++
 4 files changed, 258 insertions(+)
 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

(limited to 'src/sys')

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
-- 
cgit v1.2.1