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 | 
