aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChristian Cunningham <cc@localhost>2022-03-24 09:38:08 -0700
committerChristian Cunningham <cc@localhost>2022-03-24 09:38:08 -0700
commit93bf62580a68533dc8252b9a2a055c02f34ecb67 (patch)
tree1b1ca92ebbe107a998136a1442c0dba5be885e13 /src
parent3e64dda5d5c350cc325650133f7e64967f1efe84 (diff)
Modularized
Diffstat (limited to 'src')
-rw-r--r--src/boot.S118
-rw-r--r--src/cpu/irq.c105
-rw-r--r--src/drivers/uart.S53
-rw-r--r--src/drivers/uart.c83
-rw-r--r--src/exceptions/data.S29
-rw-r--r--src/exceptions/fiq.S27
-rw-r--r--src/exceptions/irq.S28
-rw-r--r--src/exceptions/prefetch.S13
-rw-r--r--src/exceptions/svc.S145
-rw-r--r--src/exceptions/undefined.S21
-rw-r--r--src/globals.S7
-rw-r--r--src/globals.c24
-rw-r--r--src/graphics/lfb.c218
-rw-r--r--src/graphics/mbox.c37
-rw-r--r--src/lib/kmem.c38
-rw-r--r--src/lib/mmu.S45
-rw-r--r--src/lib/mmu.c33
-rw-r--r--src/lib/queue.c55
-rw-r--r--src/lib/strings.c119
-rw-r--r--src/sys/core.c58
-rw-r--r--src/sys/kernel.S32
-rw-r--r--src/sys/power.c39
-rw-r--r--src/sys/schedule.S53
-rw-r--r--src/sys/schedule.c468
-rw-r--r--src/tests/test.S31
-rw-r--r--src/tests/test.c545
-rw-r--r--src/usr/main.c25
-rw-r--r--src/util/lock.c20
-rw-r--r--src/util/mutex.c110
-rw-r--r--src/util/status.c133
-rw-r--r--src/util/time.c76
31 files changed, 0 insertions, 2788 deletions
diff --git a/src/boot.S b/src/boot.S
deleted file mode 100644
index 46ef3d0..0000000
--- a/src/boot.S
+++ /dev/null
@@ -1,118 +0,0 @@
-// To keep this in the first portion of the binary.
-.section ".text.boot"
-
-// Make _start global.
-.globl _start
-
-.include "macros.inc"
-
-_start:
-reset:
- cpsid aif
-
- // Exit Hypervisor Mode
- mrs r0, cpsr
- and r1, r0, #0x1F
- cmp r1, #0x1A
- bne 1f
- bic r0, r0, #0x1f
- orr r0, r0, #0x13
- msr spsr_cxsf, r0
- add r0, pc, #4
- msr ELR_hyp, r0
- eret
-
-1:
- // disable core0,1,2.
- mrc p15, #0, r1, c0, c0, #5
- and r1, r1, #3
- cmp r1, #1
- beq runcore1
- cmp r1, #2
- beq runcore2
- cmp r1, #3
- bge runcore3
-
- init_core 0
-
- // Clear out bss.
- ldr r4, =__bss_start
- ldr r9, =__bss_end
- mov r5, #0
- mov r6, #0
- mov r7, #0
- mov r8, #0
- b 2f
-
-1: // store multiple at r4.
- stmia r4!, {r5-r8}
-
-2: // If we are still below bss_end, loop.
- cmp r4, r9
- blo 1b
-
- // Clear mailboxes
- mov r4, #0
- ldr r5, =mbox_core0
- str r4, [r5]
- ldr r5, =mbox_core1
- str r4, [r5]
- ldr r5, =mbox_core2
- str r4, [r5]
- ldr r5, =mbox_core3
- str r4, [r5]
-
- // Call kernel_main
- ldr r3, =kernel_main
- blx r3
-
-runcore1:
- init_core 1
- b io_halt
-runcore2:
- init_core 2
- b io_halt
-runcore3:
- init_core 3
- b io_halt
-
-.globl io_halt
-io_halt:
- wfi
- b io_halt
-
-.align 5
-vector:
- ldr pc, reset_handler
- ldr pc, undefined_handler
- ldr pc, svc_handler
- ldr pc, prefetch_handler
- ldr pc, data_handler
- ldr pc, unused_handler
- ldr pc, irq_handler
- ldr pc, fiq_handler
-
-reset_handler: .word reset
-undefined_handler: .word undefined
-svc_handler: .word svc
-prefetch_handler: .word prefetch
-data_handler: .word data
-unused_handler: .word io_halt
-irq_handler: .word irq
-fiq_handler: .word fiq
-
-.section .data
-.globl mbox_core0
-mbox_core0: .word 0
-.globl mbox_core1
-mbox_core1: .word 0
-.globl mbox_core2
-mbox_core2: .word 0
-.globl mbox_core3
-mbox_core3: .word 0
-
-.section .bss.estacks
-core_stacks 0
-core_stacks 1
-core_stacks 2
-core_stacks 3
diff --git a/src/cpu/irq.c b/src/cpu/irq.c
deleted file mode 100644
index d3eefa2..0000000
--- a/src/cpu/irq.c
+++ /dev/null
@@ -1,105 +0,0 @@
-#include <cpu.h>
-#include <cpu/irq.h>
-#include <globals.h>
-#include <graphics/lfb.h>
-#include <symbols.h>
-#include <sys/core.h>
-#include <sys/schedule.h>
-#include <tests/test.h>
-#include <util/mutex.h>
-#include <util/status.h>
-#include <util/time.h>
-#include <usr/main.h>
-
-#define CPS 1000
-
-void handle_data(unsigned char);
-
-static unsigned long counter = 0;
-unsigned long c_irq_handler(void)
-{
- unsigned long source = load32(CORE0_IRQ_SOURCE);
- // Check if GPU Interrupt
- if (source & (1 << 8)) {
- // Check if UART Interrupt
- if(load32(IRQ_PENDING2) & (1 << 25)) {
- // Check if UART Interrupt is Masked
- if(load32(UART0_MIS) & (1<<4)) {
- // Get the UART data
- unsigned long data = load32(UART0_DR);
-
- // Handle the recieved data
- // Ctrl+G to output scheduler debug info
- if (data == 0x7) {
- uart_scheduler();
- uart_mutexes();
- }
- //// Ctrl+T to toggle timer
- //else if(data == 0x14) {
- // 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/CPS);
- // enablecntv();
- // draw_cstring(0, 3, "TIMER", 0x00FF00);
- // } else {
- // disablecntv();
- // draw_cstring(0, 3, "TIMER", 0xFF0000);
- // }
- //}
- // Add task to handle the data
- else {
- add_thread(handle_data, (void*)data, PRIORITIES-1);
- return 1;
- }
- }
- }
- // Check if System Time Compare 0 Triggered the Interrupt
- if (*(volatile unsigned long*)SYS_TIMER_CS & SYS_TIMER_SC_M0) {
- volatile unsigned long* timer_cs = (volatile unsigned long*)SYS_TIMER_CS;
- volatile unsigned long* timer_chi = (volatile unsigned long*)SYS_TIMER_CHI;
- volatile unsigned long* nexttime = (volatile unsigned long*)SYS_TIMER_C0;
- add_thread_without_duplicate(main, 0, 0);
- *nexttime = *timer_chi + 40;
- *timer_cs = SYS_TIMER_SC_M0;
- return 1;
- }
- }
- // Check if CNTV triggered the interrupt
- else if (source & (1 << 3)) {
- // Reset the counter
- write_cntv_tval(cntfrq/CPS);
- counter++;
- if (counter % 0x6000 == 0)
- counter = 0;
- }
- return 0;
-}
-
-unsigned long c_fiq_handler(void)
-{
- unsigned long source = load32(CORE0_FIQ_SOURCE);
- // Check if CNTV triggered the interrupt
- if (source & (1 << 3)) {
- write_cntv_tval(cntfrq);
- }
- return 0;
-}
-
-void handle_data(unsigned char data)
-{
- // Newline Case
- if (data == 0x0D) {
- // Backspace Case
- } else if (data == 0x08 || data == 0x7F) {
- } else if (data == 0x61) {
- add_thread(uart_scheduler, 0, 2);
- } else if (data == 0x62) {
- //add_thread(test_entry, 0, 2);
- }
- // Draw it on the screen
- {
- draw_chex32(0, 9, data, 0xAA00FF);
- }
-}
diff --git a/src/drivers/uart.S b/src/drivers/uart.S
deleted file mode 100644
index 38957c2..0000000
--- a/src/drivers/uart.S
+++ /dev/null
@@ -1,53 +0,0 @@
-.section ".text"
-
-.globl uart_char
-uart_char:
- mov r2, #0x1000
- movt r2, #0x3f20
-1:
- ldr r3, [r2, #24]
- tst r3, #0b100000
- bne 1b
- str r0, [r2]
- bx lr
-
-.globl uart_string
-uart_string:
- push {r4, lr}
- mov r4, r0
- ldrb r0, [r0]
- cmp r0, #0
- popeq {r4, pc}
-1:
- bl uart_char
- ldrb r0, [r4, #1]!
- cmp r0, #0
- bne 1b
- pop {r4, pc}
-
-.globl uart_hex
-uart_hex:
- push {r4, lr}
- mov r2, #0x1000
- movt r2, #0x3f20
-1:
- ldr r3, [r2, #24]
- tst r3, #0b100000
- bne 1b
- mov r3, #7
-2:
- mov r1, r0
- asr r1, r3
- asr r1, r3
- asr r1, r3
- asr r1, r3
- and r1, #0xf
- add r1, #0x30
- cmp r1, #0x3A
- blt 3f
- add r1, #7
-3:
- str r1, [r2]
- subs r3, #1
- bge 2b // Jump back to wait for availablilty
- pop {r4, pc}
diff --git a/src/drivers/uart.c b/src/drivers/uart.c
deleted file mode 100644
index 68c70d6..0000000
--- a/src/drivers/uart.c
+++ /dev/null
@@ -1,83 +0,0 @@
-#include <drivers/uart.h>
-#include <lib/kmem.h>
-#include <lib/strings.h>
-#include <sys/core.h>
-#include <sys/schedule.h>
-#include <symbols.h>
-#include <util/lock.h>
-
-#define UART_BUFFER_SIZE 0x400
-struct UartBuffer {
- char buffer[UART_BUFFER_SIZE];
- unsigned long roffset;
- unsigned long woffset;
- struct Lock l;
-} ubuffer;
-
-void uart_init(void)
-{
- ubuffer.roffset = 0;
- ubuffer.woffset = 0;
- ubuffer.l.pid = 0;
-
- // Disable UART0
- store32(0x0, UART0_CR);
- // Setup GPIO on pin 14 and 15
- store32(0x0, (unsigned long)GPPUD);
- delay(150);
- store32((1 << 14) | (1 << 15), (unsigned long)GPPUDCLK0);
- delay(150);
- store32(0x0, (unsigned long)GPPUDCLK0);
- // Clear pending interrupts
- store32(0x7FF, UART0_ICR);
- // Set to 3Mhz
- store32(1, UART0_IBRD);
- store32(40, UART0_FBRD);
- // Enable FIFO and 8 bit transmission
- store32((1<<4)|(1<<5)|(1<<6), UART0_LCRH);
- // Mask all interrupts
- store32((1<<1)|(1<<4)|(1<<5)|(1<<6)|(1<<7)|(1<<8)|(1<<9)|(1<<10), UART0_IMSC);
- // Enable UART0
- store32((1<<0)|(1<<8)|(1<<9), UART0_CR);
-}
-
-// s = zero-terminated string
-void* uart_print(char* s)
-{
- lock(&ubuffer.l);
- char* ptr = s;
- while (1) {
- if (*ptr == 0)
- break;
- ubuffer.buffer[ubuffer.woffset] = *ptr;
- if ((ubuffer.woffset+1)%UART_BUFFER_SIZE == ubuffer.roffset)
- return ptr;
- ubuffer.woffset++;
- ubuffer.woffset %= UART_BUFFER_SIZE;
- ptr += 1;
- }
- // Low priority flush run whenever
- add_thread_without_duplicate(uart_flush, 0, PRIORITIES-1);
- unlock(&ubuffer.l);
- return 0;
-}
-
-void uart_flush(void)
-{
- while (ubuffer.roffset != ubuffer.woffset) {
- uart_char(ubuffer.buffer[ubuffer.roffset++]);
- ubuffer.roffset %= UART_BUFFER_SIZE;
- }
-}
-
-void uart_10(unsigned long val)
-{
- char* dptr = u32_to_str(val);
- uart_string(dptr);
-}
-
-void uart_hexn(unsigned long c_val)
-{
- uart_hex(c_val);
- uart_char('\n');
-}
diff --git a/src/exceptions/data.S b/src/exceptions/data.S
deleted file mode 100644
index fe33215..0000000
--- a/src/exceptions/data.S
+++ /dev/null
@@ -1,29 +0,0 @@
-.section ".text.exceptions"
-.globl data
-data:
- cpsid aif
- stmfd sp!, {r0-r12,lr}
- ldr r4, [lr, #-4]
- // Output return address
- mov r0, #80
- mov r1, #0
- mov r2, r4
- sub r2, #8
- bl draw_hex32
- // Output the data at the address
- mov r0, #80
- mov r1, #1
- ldr r2, [r4, #-8]
- bl draw_hex32
- // Output the Program Status
- mov r0, #80
- mov r1, #2
- mrs r2, spsr
- bl draw_hex32
- // Output the data-fault register
- mov r0, #80
- mov r1, #3
- mrc p15, 0, r2, c5, c0, 0 //// https://developer.arm.com/documentation/ddi0464/d/System-Control/Register-descriptions/Data-Fault-Status-Register?lang=en
- bl draw_hex32
- ldmfd sp!, {r0-r12,lr}
- subs pc, lr, #4 // Should be 8 once I can actually handle the abort
diff --git a/src/exceptions/fiq.S b/src/exceptions/fiq.S
deleted file mode 100644
index 005ed76..0000000
--- a/src/exceptions/fiq.S
+++ /dev/null
@@ -1,27 +0,0 @@
-.section ".text.exceptions"
-.globl fiq
-fiq:
- cpsid aif
- stmfd sp!, {r0-r12,lr}
- bl c_fiq_handler
- cmp r0, #1
- bne 1f
- // Schedule if interrupted a thread
- mrs r1, spsr
- and r1, r1, #0x1f
- cmp r1, #0x10
- bne 1f
- ldmfd sp!, {r0-r12,lr}
- // Don't skip missed instruction upon return
- sub lr, #4
- push {r3}
- // Store the instruction in a special area for
- // future processing
- ldr r3, =irqlr
- str lr, [r3, #0]
- pop {r3}
- cps #0x13
- b schedule
-1:
- ldmfd sp!, {r0-r12,lr}
- subs pc, lr, #4
diff --git a/src/exceptions/irq.S b/src/exceptions/irq.S
deleted file mode 100644
index a7e78bc..0000000
--- a/src/exceptions/irq.S
+++ /dev/null
@@ -1,28 +0,0 @@
-.section ".text.exceptions"
-.globl irq
-irq:
- cpsid ai
- stmfd sp!, {r0-r12,lr}
- // Run IRQ handler
- bl c_irq_handler
- cmp r0, #1
- bne 1f
- // Schedule if interrupted a thread
- mrs r1, spsr
- and r1, r1, #0x1f
- cmp r1, #0x10
- bne 1f
- ldmfd sp!, {r0-r12,lr}
- // Don't skip missed instruction upon return
- sub lr, #4
- push {r3}
- // Store the instruction in a special area for
- // future processing
- ldr r3, =irqlr
- str lr, [r3, #0]
- pop {r3}
- cps #0x13
- b schedule
-1:
- ldmfd sp!, {r0-r12,lr}
- subs pc, lr, #4
diff --git a/src/exceptions/prefetch.S b/src/exceptions/prefetch.S
deleted file mode 100644
index 59674bd..0000000
--- a/src/exceptions/prefetch.S
+++ /dev/null
@@ -1,13 +0,0 @@
-.section ".text.exceptions"
-.globl prefetch
-prefetch:
- cpsid aif
- stmfd sp!, {r0-r12,lr}
- ldr r4, [lr, #-4]
- // Output return address
- mov r0, #98
- mov r1, #0
- mov r2, r4
- bl draw_hex32
- ldmfd sp!, {r0-r12,lr}
- subs pc, lr, #4
diff --git a/src/exceptions/svc.S b/src/exceptions/svc.S
deleted file mode 100644
index a24bac9..0000000
--- a/src/exceptions/svc.S
+++ /dev/null
@@ -1,145 +0,0 @@
-.section ".text.exceptions"
-.globl svc
-svc:
- cpsid aif
- stmfd sp!, {r0-r12,lr}
- // Get the SVC Exception #
- ldr r0, [lr, #-4]
- bic r0, #0xFF000000
- // Check it is within our defined SVC
- cmp r0, #7
- adrle r3, svc_table_1
- ldrle pc, [r3, r0, LSL #2]
- sub r0, #8
- cmp r0, #7
- bgt svc_exit
- //// Jump to the appropriate Call
- adr r3, svc_table_2
- ldr pc, [r3, r0, LSL #2]
-svc_000000: // SYS_YIELD
- bl yield
- ldmfd sp!, {r0-r12,lr}
- b schedule
-svc_000001: // SYS_TIME
- mov r2, #0x3004
- movt r2, #0x3F00
- ldr r0, [r2, #4] // <- SYS_TIMER_CLO
- ldr r1, [r2, #0] // <- SYS_TIMER_CHI
- str r0, [sp] // Return value
- str r1, [sp, #4] // Return value hi
- b svc_exit
-svc_000002: // Run Schedule
- ldmfd sp!, {r0-r12,lr}
- b schedule
-svc_000003: // Add Thread
- ldr r0, [sp, #0]
- ldr r1, [sp, #4]
- ldr r2, [sp, #8]
- and r2, #0xFF
- bl svc_add_thread
- str r0, [sp, #0]
- ldmfd sp!, {r0-r12,lr}
- b schedule
-svc_000004: // Lock Lock (usr_r0 = struct Lock*)
- ldr r3, =scheduler
- ldr r2, [r3, #0] // struct Thread* rthread
- ldr r1, [r2, #0x10] // unsigned long pid
- ldr r0, [sp, #0] // struct Lock* m
-1: clrex
- ldrex r2, [r0, #0]
- cmp r2, #0
- // If it is not available, wait-queue the thread
- bne svc_000004_delay_mutex
- // Otherwise lock it
- strexeq r2, r1, [r0, #0]
- teq r2, #0
- bne 1b
- dmb
- b svc_exit
-svc_000004_delay_mutex: // Wait-queue the current thread
- // r0 = struct Lock* m
- bl sched_mutex_yield
- ldmfd sp!, {r0-r12,lr}
- sub lr, #4
- b schedule
-svc_000005: // Release Lock
- ldr r0, [sp, #0] // struct Lock* m
- mov r1, #0
- dmb
- // Unlock
- str r1, [r0, #0]
- dsb
- sev
- // Awake any threads waiting for this lock
- bl sched_mutex_resurrect
- ldmfd sp!, {r0-r12,lr}
- b schedule
- b svc_exit
-svc_000006: // Semaphore decrease
- ldr r0, [sp, #0] // struct Semaphore* s
-1: clrex
- ldrex r2, [r0, #0]
- cmp r2, #0
- beq svc_000006_delay_semaphore
- sub r1, r2, #1
- strex r2, r1, [r0, #0]
- teq r2, #0
- bne 1b
- dmb
- b svc_exit
-svc_000006_delay_semaphore:
- bl sched_semaphore_yield
- ldmfd sp!, {r0-r12,lr}
- sub lr, #4
- b schedule
- b svc_exit
-svc_000007: // Semaphore increase
- ldr r0, [sp, #0] // struct Semaphore* s
-1: clrex
- ldrex r2, [r0, #0]
- add r1, r2, #1
- strexeq r2, r1, [r0, #0]
- teq r2, #0
- bne 1b
- dmb
- cmp r1, #1
- bne svc_exit
- mov r1, #1
- bl sched_semaphore_resurrect
- ldmfd sp!, {r0-r12,lr}
- b schedule
- b svc_exit
-svc_000008: // Semaphore add #
- ldr r0, [sp, #0] // struct Semaphore* s
- ldr r3, [sp, #1] // unsigned long # times to increase
-1: clrex
- ldrex r2, [r0, #0]
- add r1, r2, #1
- strexeq r2, r1, [r0, #0]
- teq r2, #0
- bne 1b
- dmb
- mov r1, r3
- bl sched_semaphore_resurrect
- ldmfd sp!, {r0-r12,lr}
- b schedule
- b svc_exit
-svc_000009: // SYS_TIME_2
- mrc p15, 0, r0, c9, c13, 0
- str r0, [sp, #0]
- b svc_exit
-svc_exit:
- ldmfd sp!, {r0-r12,pc}^
-
-svc_table_1:
- .word svc_000000
- .word svc_000001
- .word svc_000002
- .word svc_000003
- .word svc_000004
- .word svc_000005
- .word svc_000006
- .word svc_000007
-svc_table_2:
- .word svc_000008
- .word svc_000009
diff --git a/src/exceptions/undefined.S b/src/exceptions/undefined.S
deleted file mode 100644
index 856e30f..0000000
--- a/src/exceptions/undefined.S
+++ /dev/null
@@ -1,21 +0,0 @@
-.section ".text.exceptions"
-.globl undefined
-undefined:
- cpsid aif
- stmfd sp!, {r0-r12,lr}
- ldr r4, [lr, #-4]
- mov r0, #62
- mov r1, #0
- mov r2, r4
- bl draw_hex32
- // Output lr
- ldr r0, [sp, #0x34]
- sub r2, r0, #4
- mov r0, #62
- mov r1, #1
- bl draw_hex32
- // Skip instruction for now
- // In future,
- // ldmfd sp!, {r0-r12,lr} // Note the lack of ^ since subs will handle it
- // subs pc, lr, #4
- ldmfd sp!, {r0-r12,pc}^
diff --git a/src/globals.S b/src/globals.S
deleted file mode 100644
index b808053..0000000
--- a/src/globals.S
+++ /dev/null
@@ -1,7 +0,0 @@
-.section ".bss"
-.globl irqlr
-irqlr:
- .word 0
-.globl cntfrq
-cntfrq:
- .word 0
diff --git a/src/globals.c b/src/globals.c
deleted file mode 100644
index 5118e96..0000000
--- a/src/globals.c
+++ /dev/null
@@ -1,24 +0,0 @@
-#define GLOBALS_C
-#include <sys/schedule.h>
-#include <util/mutex.h>
-char* os_name = "Jobbed";
-#ifndef VERSION
-char* os_info_v = "?";
-#else
-char* os_info_v = VERSION;
-#endif
-
-__attribute__((section(".bss"))) unsigned long nextpid;
-__attribute__((section(".bss"))) unsigned long stimel;
-__attribute__((section(".bss"))) unsigned long stimeh;
-__attribute__((section(".bss"))) struct Scheduler scheduler;
-__attribute__((section(".bss"))) struct MutexManager mutex_manager;
-__attribute__((section(".bss"))) struct Thread usrloopthread;
-__attribute__((section(".bss"))) unsigned int gwidth;
-__attribute__((section(".bss"))) unsigned int gheight;
-__attribute__((section(".bss"))) unsigned int gpitch;
-__attribute__((section(".bss"))) unsigned int gisrgb;
-__attribute__((section(".bss.mutexs"))) struct Mutex mutexs[MAX_MUTEXS];
-__attribute__((section(".bss.mutexe"))) struct Entry mutex_entries[MAX_MUTEXS];
-__attribute__((section(".bss.threads"))) struct Thread threads[MAX_THREADS];
-__attribute__((section(".bss.threade"))) struct Entry thread_entries[MAX_THREADS];
diff --git a/src/graphics/lfb.c b/src/graphics/lfb.c
deleted file mode 100644
index 8c41b1c..0000000
--- a/src/graphics/lfb.c
+++ /dev/null
@@ -1,218 +0,0 @@
-#include <drivers/uart.h>
-#include <globals.h>
-#include <graphics/glyphs.h>
-#include <graphics/lfb.h>
-#include <graphics/mbox.h>
-#include <lib/strings.h>
-
-unsigned char *lfb; /* raw frame buffer address */
-
-#define SCR_WIDTH 1920
-#define SCR_HEIGHT 1080
-
-/**
- * Set screen resolution
- */
-void lfb_init(void)
-{
- mbox[0] = 35*4;
- mbox[1] = MBOX_REQUEST;
-
- mbox[2] = 0x48003; //set phy wh
- mbox[3] = 8;
- mbox[4] = 8;
- mbox[5] = SCR_WIDTH; //FrameBufferInfo.width
- mbox[6] = SCR_HEIGHT; //FrameBufferInfo.height
-
- mbox[7] = 0x48004; //set virt wh
- mbox[8] = 8;
- mbox[9] = 8;
- mbox[10] = SCR_WIDTH; //FrameBufferInfo.virtual_width
- mbox[11] = SCR_HEIGHT; //FrameBufferInfo.virtual_height
-
- mbox[12] = 0x48009; //set virt offset
- mbox[13] = 8;
- mbox[14] = 8;
- mbox[15] = 0; //FrameBufferInfo.x_offset
- mbox[16] = 0; //FrameBufferInfo.y.offset
-
- mbox[17] = 0x48005; //set depth
- mbox[18] = 4;
- mbox[19] = 4;
- mbox[20] = 32; //FrameBufferInfo.depth
-
- mbox[21] = 0x48006; //set pixel order
- mbox[22] = 4;
- mbox[23] = 4;
- mbox[24] = 1; //RGB, not BGR preferably
-
- mbox[25] = 0x40001; //get framebuffer, gets alignment on request
- mbox[26] = 8;
- mbox[27] = 8;
- mbox[28] = 4096; //FrameBufferInfo.pointer
- mbox[29] = 0; //FrameBufferInfo.size
-
- mbox[30] = 0x40008; //get pitch
- mbox[31] = 4;
- mbox[32] = 4;
- mbox[33] = 0; //FrameBufferInfo.pitch
-
- mbox[34] = MBOX_TAG_LAST;
-
- //this might not return exactly what we asked for, could be
- //the closest supported resolution instead
- if(mbox_call(MBOX_CH_PROP) && mbox[20]==32 && mbox[28]!=0) {
- mbox[28]&=0x3FFFFFFF; //convert GPU address to ARM address
- gwidth=mbox[5]; //get actual physical width
- gheight=mbox[6]; //get actual physical height
- gpitch=mbox[33]; //get number of bytes per line
- gisrgb=mbox[24]; //get the actual channel order
- lfb=(void*)((unsigned long)mbox[28]);
- } else {
- uart_string("Unable to set screen resolution to 1024x768x32\n");
- }
-}
-
-void clear_screen(void)
-{
- unsigned char *ptr=lfb;
- for(unsigned int y = 0; y < gheight; y++) {
- for(unsigned int x = 0; x < gwidth; x++) {
- *(unsigned int*)ptr = 0x000000;
- ptr += 4;
- }
- }
-}
-
-/**
- * Show a picture
- */
-void lfb_showpicture(void)
-{
- clear_screen();
-#define FWIDTH 240
-#define FHEIGHT 80
- draw_cbox(SCR_WIDTH-FWIDTH, SCR_HEIGHT-FHEIGHT*2, FWIDTH, FHEIGHT, 0x0057b7);
- draw_cbox(SCR_WIDTH-FWIDTH, SCR_HEIGHT-FHEIGHT, FWIDTH, FHEIGHT, 0xffd700);
-}
-
-void draw_cpixel(unsigned int lx, unsigned int ly, unsigned int c)
-{
- unsigned char* ptr = lfb;
- ptr += (gpitch*ly+lx*4);
- *((unsigned int*)ptr) = gisrgb ? (unsigned int)((c&0xFF)<<16 | (c&0xFF00) | (c&0xFF0000)>>16) : c;
-}
-
-void draw_cbox(unsigned int lx, unsigned int ly, unsigned int dx, unsigned int dy, unsigned int c)
-{
- unsigned char* ptr = lfb;
- ptr += (gpitch*ly+lx*4);
- for(unsigned int y = 0; y < dy; y++) {
- for(unsigned int x = 0; x < dx; x++) {
- *((unsigned int*)ptr) = gisrgb ? (unsigned int)((c&0xFF)<<16 | (c&0xFF00) | (c&0xFF0000)>>16) : c;
- ptr += 4;
- }
- ptr += gpitch - dx*4;
- }
-}
-
-void draw_cbyte(unsigned int lx, unsigned int ly, unsigned char letter, unsigned int c)
-{
- unsigned int x, y;
- unsigned char* ptr = lfb;
- ptr += (gpitch*ly*GLYPH_Y+lx*4*GLYPH_X);
- unsigned char ltr = (letter & 0xF) + 0x30;
- if (ltr > 0x39) {
- ltr += 7;
- }
- for(y=0; y<GLYPH_Y; y++) {
- for(x=0; x<GLYPH_X; x++) {
- if((0x80 >> ((GLYPH_X-1)-x)) & glyphs[y+GLYPH_Y*(ltr)]) {
- *((unsigned int*)ptr) = gisrgb ? (unsigned int)((c&0xFF)<<16 | (c&0xFF00) | (c&0xFF0000)>>16) : c;
- } else {
- *((unsigned int*)ptr) = 0x000000;
- }
- ptr += 4;
- }
- ptr += gpitch - GLYPH_X*4;
- }
-}
-
-void draw_byte(unsigned int lx, unsigned int ly, unsigned char letter)
-{
- draw_cbyte(lx, ly, letter, 0xFFFFFF);
-}
-
-void draw_cletter(unsigned int lx, unsigned int ly, unsigned char letter, unsigned int c)
-{
- unsigned int x, y;
- unsigned char* ptr = lfb;
- ptr += (gpitch*ly*GLYPH_Y+lx*4*GLYPH_X);
- unsigned char ltr = letter & 0x7F;
- for(y=0; y<GLYPH_Y; y++) {
- for(x=0; x<GLYPH_X; x++) {
- if((0x80 >> ((GLYPH_X-1)-x)) & glyphs[y+GLYPH_Y*(ltr)]) {
- *((unsigned int*)ptr) = gisrgb ? (unsigned int)((c&0xFF)<<16 | (c&0xFF00) | (c&0xFF0000)>>16) : c;
- } else {
- *((unsigned int*)ptr) = 0x000000;
- }
- ptr += 4;
- }
- ptr += gpitch - GLYPH_X*4;
- }
-}
-
-void draw_letter(unsigned int lx, unsigned int ly, unsigned char letter)
-{
- draw_cletter(lx, ly, letter, 0xFFFFFF);
-}
-
-void draw_cstring(unsigned int lx, unsigned int ly, char* s, unsigned int c)
-{
- unsigned int x = lx % GG_MAX_X, y = ly % GG_MAX_Y;
- unsigned int idx = 0;
- while(s[idx] != 0) {
- draw_cletter(x++, y, s[idx++], c);
- if (x > GG_MAX_X) {
- y += 1;
- x = 0;
- }
- // CHECK Y EVENTUALLY
- }
-}
-
-void draw_string(unsigned int lx, unsigned int ly, char* s)
-{
- draw_cstring(lx, ly, s, 0xFFFFFF);
-}
-
-void draw_chex32(unsigned int lx, unsigned int ly, unsigned long val, unsigned int c)
-{
- unsigned int x = lx % GG_MAX_X, y = ly % GG_MAX_Y;
- for(unsigned int i = 0; i < GLYPH_X; i++) {
- draw_cbyte(x++, y, 0xF & (val >> ((GLYPH_X-1)-i)*4), c);
- if (x > GG_MAX_X) {
- y += 1;
- x = 0;
- }
- // CHECK Y EVENTUALLY
- }
-}
-
-void draw_hex32(unsigned int lx, unsigned int ly, unsigned long val)
-{
- draw_chex32(lx, ly, val, 0xFFFFFF);
-}
-
-unsigned long draw_cu10(unsigned int lx, unsigned int ly, unsigned long val, unsigned int c)
-{
- string_t vals = u32_to_str(val);
- unsigned long len = strlen(vals);
- draw_cstring(lx, ly, vals, c);
- return len;
-}
-
-unsigned long draw_u10(unsigned int lx, unsigned int ly, unsigned long val)
-{
- return draw_cu10(lx, ly, val, 0xFFFFFF);
-}
diff --git a/src/graphics/mbox.c b/src/graphics/mbox.c
deleted file mode 100644
index 0dac497..0000000
--- a/src/graphics/mbox.c
+++ /dev/null
@@ -1,37 +0,0 @@
-#include <symbols.h>
-
-/* mailbox message buffer */
-volatile unsigned int __attribute__((aligned(16))) mbox[36];
-
-#define VIDEOCORE_MBOX (MMIO_BASE+0x0000B880)
-#define MBOX_READ ((volatile unsigned int*)(VIDEOCORE_MBOX+0x0))
-#define MBOX_POLL ((volatile unsigned int*)(VIDEOCORE_MBOX+0x10))
-#define MBOX_SENDER ((volatile unsigned int*)(VIDEOCORE_MBOX+0x14))
-#define MBOX_STATUS ((volatile unsigned int*)(VIDEOCORE_MBOX+0x18))
-#define MBOX_CONFIG ((volatile unsigned int*)(VIDEOCORE_MBOX+0x1C))
-#define MBOX_WRITE ((volatile unsigned int*)(VIDEOCORE_MBOX+0x20))
-#define MBOX_RESPONSE 0x80000000
-#define MBOX_FULL 0x80000000
-#define MBOX_EMPTY 0x40000000
-
-/**
- * Make a mailbox call. Returns 0 on failure, non-zero on success
- */
-int mbox_call(unsigned char ch)
-{
- unsigned int r = (((unsigned int)((unsigned long)&mbox)&~0xF) | (ch&0xF));
- /* wait until we can write to the mailbox */
- do{asm volatile("nop");}while(*MBOX_STATUS & MBOX_FULL);
- /* write the address of our message to the mailbox with channel identifier */
- *MBOX_WRITE = r;
- /* now wait for the response */
- while(1) {
- /* is there a response? */
- do{asm volatile("nop");}while(*MBOX_STATUS & MBOX_EMPTY);
- /* is it a response to our message? */
- if(r == *MBOX_READ)
- /* is it a valid successful response? */
- return mbox[1]==MBOX_RESPONSE;
- }
- return 0;
-}
diff --git a/src/lib/kmem.c b/src/lib/kmem.c
deleted file mode 100644
index 9861f12..0000000
--- a/src/lib/kmem.c
+++ /dev/null
@@ -1,38 +0,0 @@
-#include <globals.h>
-#include <drivers/uart.h>
-#include <lib/kmem.h>
-
-// Output longs at address
-void kmemshow32(void* data, unsigned long length)
-{
- unsigned long* ptr = data;
- for(unsigned long i = 0; i < length; i++) {
- uart_hex(*ptr);
- ptr+=1;
- if (i != length-1)
- uart_char(' ');
- }
- uart_char('\n');
-}
-
-// Output bytes at address
-void kmemshow(void* data, unsigned long length)
-{
- unsigned char* ptr = data;
- for(unsigned long i = 0; i < length; i++) {
- char tmp = *ptr>>4;
- tmp += 0x30;
- if (tmp > 0x39)
- tmp += 0x7;
- uart_char(tmp);
- tmp = *ptr&0xF;
- tmp += 0x30;
- if (tmp > 0x39)
- tmp += 0x7;
- uart_char(tmp);
- ptr+=1;
- if (i != length-1)
- uart_char(' ');
- }
- uart_char('\n');
-}
diff --git a/src/lib/mmu.S b/src/lib/mmu.S
deleted file mode 100644
index faca3cc..0000000
--- a/src/lib/mmu.S
+++ /dev/null
@@ -1,45 +0,0 @@
-.section .text
-.globl mmu_start
-mmu_start:
- mov r2, #0
- // Invalidate Caches
- mcr p15,0,r2,c7,c1,6
- // Invalidate TLB entries
- mcr p15,0,r2,c8,c7,0
- // Data synchronisation barrier
- mcr p15,0,r2,c7,c10,4
-
- // Set all domains to 0b11
- mvn r2, #0
- bic r2, #0xC
- mcr p15,0,r2,c3,c0,0
-
- // Set the translation table base address (remember to align 16 KiB!)
- mcr p15,0,r0,c2,c0,0
- mcr p15,0,r0,c2,c0,1
- mov r3, #0
- mcr p15,0,r3,c2,c0,2
-
- // Set the bits mentioned above
- mrc p15,0,r2,c1,c0,0
- orr r2,r2,r1
- mcr p15,0,r2,c1,c0,0
- bx lr
-
-.globl mmu_stop
-mmu_stop:
- mrc p15,0,r2,c1,c0,0
- bic r2,#0x1000
- bic r2,#0x0004
- bic r2,#0x0001
- mcr p15,0,r2,c1,c0,0
- bx lr
-
-.globl tlb_invalidate
-tlb_invalidate:
- mov r2, #0
- // Invalidate Entries
- mcr p15, 0, r2, c8, c7, 0
- // DSB
- mcr p15, 0, r2, c7, c10, 4
- bx lr
diff --git a/src/lib/mmu.c b/src/lib/mmu.c
deleted file mode 100644
index e9dda7a..0000000
--- a/src/lib/mmu.c
+++ /dev/null
@@ -1,33 +0,0 @@
-#include <lib/mmu.h>
-
-#define CACHABLE 0x08
-#define BUFFERABLE 0x04
-#define NO_PERMISSIONS_REQUIRED 0b11 << 10
-#define MMU_TABLE_BASE 0x00004000
-
-void mmu_start(unsigned long base, unsigned long flags);
-
-void mmu_section(unsigned long virtual, unsigned long physical, unsigned long flags)
-{
- unsigned long offset = virtual >> 20;
- unsigned long* entry = (unsigned long*)(MMU_TABLE_BASE | (offset << 2));
- unsigned long physval = (physical & 0xFFF00000) | (flags & 0x7FFC) | 0x00C02;
- *entry = physval;
-}
-
-extern unsigned long __bss_end;
-void mmu_init(void)
-{
- for (unsigned long addr = 0x00000000;; addr += 0x00100000) {
- if (addr < (unsigned long)&__bss_end + 0x00100000) {
- mmu_section(addr, addr, CACHABLE | BUFFERABLE);
- } else {
- mmu_section(addr, addr, NO_PERMISSIONS_REQUIRED);
- }
- if (addr == 0x02000000)
- mmu_section(addr, addr, CACHABLE | BUFFERABLE | NO_PERMISSIONS_REQUIRED);
- if (addr == 0xFFF00000)
- break;
- }
- mmu_start(MMU_TABLE_BASE,0x00000001|0x1000|0x0004);
-}
diff --git a/src/lib/queue.c b/src/lib/queue.c
deleted file mode 100644
index 1fc35f6..0000000
--- a/src/lib/queue.c
+++ /dev/null
@@ -1,55 +0,0 @@
-#include <lib/queue.h>
-
-void push_to_queue(struct Entry* e, struct Queue* q)
-{
- q->end.next->next = e;
- q->end.next = e;
- e->next = &q->end;
-}
-
-void prepend_to_queue(struct Entry* e, struct Queue* q)
-{
- e->next = q->start.next;
- q->start.next = e;
- if (e->next->entry_type == END_ENTRY)
- q->end.next = e;
-}
-
-struct Entry* pop_from_queue(struct Queue* q)
-{
- if (q->start.next->entry_type == END_ENTRY)
- return 0;
- struct Entry* e = q->start.next;
- q->start.next = e->next;
- if (e->next->entry_type == END_ENTRY)
- q->end.next = &q->start;
- return e;
-}
-
-struct Entry* remove_next_from_queue(struct Entry* e)
-{
- struct Entry* prev = e;
- struct Entry* remove = e->next;
- struct Entry* next = remove->next;
- if (remove->entry_type != VALUE_ENTRY)
- return 0;
- prev->next = next;
- if (next->entry_type == END_ENTRY)
- next->next = prev;
- return remove;
-}
-
-struct Entry* find_value(void* value, struct Queue* q)
-{
- struct Entry* prev;
- struct Entry* entry;
- prev = &q->start;
- entry = prev->next;
- while (entry->entry_type != END_ENTRY) {
- if (entry->value == value)
- return prev;
- prev = entry;
- entry = prev->next;
- }
- return 0;
-}
diff --git a/src/lib/strings.c b/src/lib/strings.c
deleted file mode 100644
index 674af19..0000000
--- a/src/lib/strings.c
+++ /dev/null
@@ -1,119 +0,0 @@
-#include <lib/kmem.h>
-#include <lib/strings.h>
-
-unsigned long strlen(string_t s)
-{
- unsigned long len = 0;
- while (s[len] != 0) {
- len += 1;
- }
- return len;
-}
-
-void strcpy(string_t src, string_t dest)
-{
- unsigned long idx = 0;
- while (src[idx] != 0) {
- dest[idx] = src[idx];
- idx++;
- }
- dest[idx] = src[idx];
-}
-
-unsigned char strcmp(string_t a, string_t b)
-{
- unsigned long idx = 0;
- while (a[idx] != 0 && b[idx] != 0) {
- if (a[idx] != b[idx]) {
- return 0;
- }
- idx += 1;
- }
- return a[idx] == b[idx];
-}
-
-unsigned char strcmpn(string_t a, string_t b, unsigned int n)
-{
- unsigned long idx = 0;
- while (a[idx] != 0 && b[idx] != 0 && idx+1 < n) {
- if (a[idx] != b[idx]) {
- return 0;
- }
- idx += 1;
- }
- return a[idx] == b[idx];
-}
-
-char* zhex32_to_str(unsigned long value)
-{
- static char data[10];
- char tmp = 0;
- char isz = -1;
- for (int i = 0; i < 8; i++) {
- tmp = (value >> 4*(8-i-1))&0xF;
- if (isz == 0xFF && tmp != 0)
- isz = i;
- if(tmp > 0x9)
- tmp += 7;
- tmp += 0x30;
- data[i] = tmp;
- }
- return data+isz;
-}
-
-char* hex32_to_str(unsigned long value)
-{
- static char data[10];
- char tmp = 0;
- for (int i = 0; i < 8; i++) {
- tmp = (value >> 4*(8-i-1))&0xF;
- if(tmp > 0x9)
- tmp += 7;
- tmp += 0x30;
- data[i] = tmp;
- }
- return data;
-}
-
-char* u32_to_str(unsigned long value)
-{
- unsigned long t = value;
- unsigned long c;
- static char data[12];
- char* dptr = data + 9;
- for (int i = 0; i <= 10; i++) {
- c = t%10;
- *dptr = 0x30 + (c&0xF);
- t /= 10;
- if (t==0)
- break;
- dptr -= 1;
- }
- return dptr;
-}
-
-char* s32_to_str(unsigned long value)
-{
- long t = value;
- unsigned long c;
- char is_neg = 0;
- if (t < 0) {
- t = -t;
- is_neg = 1;
- }
- static char data[13];
- char* dptr = data + 10;
- for (int i = 0; i <= 10; i++) {
- c = t%10;
- *dptr = 0x30 + (c&0xF);
- t /= 10;
- if (t==0)
- break;
- dptr -= 1;
- }
- if (is_neg) {
- dptr -= 1;
- *dptr = '-';
- }
- return dptr;
-}
diff --git a/src/sys/core.c b/src/sys/core.c
deleted file mode 100644
index d76b712..0000000
--- a/src/sys/core.c
+++ /dev/null
@@ -1,58 +0,0 @@
-#include <cpu/irq.h>
-#include <cpu.h>
-#include <drivers/uart.h>
-#include <globals.h>
-#include <graphics/lfb.h>
-#include <lib/kmem.h>
-#include <lib/mmu.h>
-#include <lib/strings.h>
-#include <symbols.h>
-#include <sys/core.h>
-#include <sys/power.h>
-#include <sys/schedule.h>
-#include <util/mutex.h>
-#include <util/status.h>
-#include <util/time.h>
-
-// Initialize IRQs
-void sysinit(void)
-{
- // Initialize System Globals
- stimeh = *(unsigned long*)SYS_TIMER_CHI;
- stimel = *(unsigned long*)SYS_TIMER_CLO;
- *(unsigned long*) SYS_TIMER_C0 = 2000000 + stimeh; // 2 second trigger
- uart_init();
- ///...
-
- // Route GPU interrupts to Core 0
- store32(0x00, GPU_INTERRUPTS_ROUTING);
-
- // Mask Overrun of UART0
- store32(1<<4, UART0_IMSC);
- // Enable UART GPU IRQ
- store32(1<<25, IRQ_ENABLE2);
- // Enable Timer
- //// Get the frequency
- cntfrq = read_cntfrq();
- // Clear cntv interrupt and set next 1 second timer
- write_cntv_tval(cntfrq);
- // Route timer to core0 fiq
- routing_core0cntv_to_core0fiq();
- // Enable timer
- enablecntv();
- // Enable system timer
- store32(SYS_TIMER_SC_M0, IRQ_ENABLE1);
-
- // Graphics Initialize
- lfb_init();
- lfb_showpicture();
-
- // Initialize Memory Management Unit
- mmu_init();
-
- // Initialize Mutex Manager
- mutex_init();
-
- // Start Scheduler
- init_scheduler();
-}
diff --git a/src/sys/kernel.S b/src/sys/kernel.S
deleted file mode 100644
index 71b22a1..0000000
--- a/src/sys/kernel.S
+++ /dev/null
@@ -1,32 +0,0 @@
-.section ".text.kernel"
-
-.include "macros.inc"
-
-.globl kernel_main
-kernel_main:
- bl sysinit
- bl status
- ldr r2, =ttbr_msg
- mov r0, #23
- mov r1, #0
- mov r3, #0xFF00
- bl draw_cstring
- // Initialize System Cycle Counter
- mov r0, #1
- mcr p15, 0, r0, c9, c14, 0
- mov r0, #1
- mcr p15, 0, r0, c9, c12, 0
- mov r0, #0x80000000
- mcr p15, 0, r0, c9, c12, 1
-
- // Intentional undefined instruction
- // .word 0xf7f0a000
- cpsie ai, #0x10
- svc #2 // Start scheduling!
-2:
- wfe
- b 2b
-
-.section .data
-ttbr_msg:
- .asciz "MMU Initialized!"
diff --git a/src/sys/power.c b/src/sys/power.c
deleted file mode 100644
index c4f12a9..0000000
--- a/src/sys/power.c
+++ /dev/null
@@ -1,39 +0,0 @@
-#include <symbols.h>
-#include <sys/core.h>
-#include <sys/power.h>
-
-//https://github.com/raspberrypi/linux/blob/aeaa2460db088fb2c97ae56dec6d7d0058c68294/drivers/watchdog/bcm2835_wdt.c
-void wdt_start(void)
-{
- store32(BCM2835_PERI_BASE + PM_WDOG, PM_PASSWORD | (SECS_TO_WDOG_TICS(100) & PM_WDOG_TIME_SET));
- unsigned long cur = load32(BCM2835_PERI_BASE + PM_RSTC);
- store32(BCM2835_PERI_BASE + PM_RSTC, PM_PASSWORD | (cur & PM_RSTC_WRCFG_CLR) | PM_RSTC_WRCFG_FULL_RESET);
-}
-
-void wdt_stop(void)
-{
- store32(BCM2835_PERI_BASE + PM_RSTC, PM_PASSWORD | PM_RSTC_RESET);
-}
-
-void __bcm2835_restart(unsigned char partition)
-{
- unsigned long val, rsts;
- rsts = (partition & 1) | ((partition & 0b10) << 1) |
- ((partition & 0b100) << 2) | ((partition & 0b1000) << 3) |
- ((partition & 0b10000) << 4) | ((partition & 0b100000) << 5);
- val = load32(BCM2835_PERI_BASE + PM_RSTS);
- val &= PM_RSTS_PARTITION_CLR;
- val |= PM_PASSWORD | rsts;
- store32(BCM2835_PERI_BASE + PM_RSTS, val);
- store32(BCM2835_PERI_BASE + PM_WDOG, 10 | PM_PASSWORD);
- val = load32(BCM2835_PERI_BASE + PM_RSTC);
- val &= PM_RSTC_WRCFG_CLR;
- val |= PM_PASSWORD | PM_RSTC_WRCFG_FULL_RESET;
- store32(BCM2835_PERI_BASE + PM_RSTC, val);
- delay(1);
-}
-
-void bcm2835_power_off(void)
-{
- __bcm2835_restart(63); // Partition 63 => Halt
-}
diff --git a/src/sys/schedule.S b/src/sys/schedule.S
deleted file mode 100644
index a47252c..0000000
--- a/src/sys/schedule.S
+++ /dev/null
@@ -1,53 +0,0 @@
-.section ".text"
-.globl schedule
-
-.include "macros.inc"
-
-// Assumption: Enter in SVC mode
-schedule:
- preserve_ctx
- ldr r1, =irqlr
- ldr r0, [r1]
- cmp r0, #0
- beq 1f
- // Replace LR with IRQ's LR
- ldr r3, =scheduler
- ldr r2, [r3, #0] // struct Thread* rthread
- str r0, [r2, #0] // svc_lr -> void* pc
- // Clear IRQ's LR
- mov r0, #0
- str r0, [r1]
-1:
- bl next_thread // Thread* next -> r0
- ldr r3, =scheduler
- str r0, [r3, #0] // next -> rthread
- restore_ctx
- subs pc, lr, #0
-
-.globl cleanup
-cleanup:
- bl c_cleanup
- // usrloop -> rthread
- ldr r3, =scheduler
- ldr r2, =usrloopthread
- str r2, [r3, #0]
- ldr sp, [r2, #4]
- ldmfd sp!,{lr}
- ldmfd sp!,{r0-r12}
- ldr lr, =kernel_usr_task_loop
- // svc sched
- svc #2
-.globl kernel_usr_task_loop
-kernel_usr_task_loop:
- wfe
- b kernel_usr_task_loop
-
-.globl add_thread
-add_thread:
- mrs r3, cpsr
- and r3, #0x1F
- cmp r3, #0x10
- beq 1f
- b svc_add_thread
-1: svc #3
- bx lr
diff --git a/src/sys/schedule.c b/src/sys/schedule.c
deleted file mode 100644
index 9b6d46e..0000000
--- a/src/sys/schedule.c
+++ /dev/null
@@ -1,468 +0,0 @@
-#include <cpu.h>
-#include <globals.h>
-#include <graphics/lfb.h>
-#include <drivers/uart.h>
-#include <lib/kmem.h>
-#include <sys/schedule.h>
-#include <util/mutex.h>
-
-extern void kernel_usr_task_loop(void);
-
-void init_scheduler(void)
-{
- // Set rthread to usrloopthread - an infinitely running thread so that the pointer will never be null
- usrloopthread.pc = (void*)kernel_usr_task_loop;
- usrloopthread.sp = (void*)0x5FC8;
- *(unsigned long**)usrloopthread.sp = (unsigned long*)kernel_usr_task_loop;
- usrloopthread.sp_base = -1;
- usrloopthread.mptr = 0;
- usrloopthread.pid = -1;
- usrloopthread.priority = -1;
- usrloopthread.old_priority = -1;
- usrloopthread.status = THREAD_READY;
- usrloopthread.offset = -1;
- scheduler.rthread = &usrloopthread;
-
- // Initialize Scheduling Queues
- for (unsigned long p = 0; p < PRIORITIES; p++) {
- // Ready Init
- scheduler.ready[p].start.value = 0;
- scheduler.ready[p].start.next = &scheduler.ready[p].end;
- scheduler.ready[p].start.entry_type = START_ENTRY;
- scheduler.ready[p].end.value = 0;
- scheduler.ready[p].end.next = &scheduler.ready[p].start;
- scheduler.ready[p].end.entry_type = END_ENTRY;
- // Mutex Wait Init
- scheduler.mwait[p].start.value = 0;
- scheduler.mwait[p].start.next = &scheduler.mwait[p].end;
- scheduler.mwait[p].start.entry_type = START_ENTRY;
- scheduler.mwait[p].end.value = 0;
- scheduler.mwait[p].end.next = &scheduler.mwait[p].start;
- scheduler.mwait[p].end.entry_type = END_ENTRY;
- // Signal Wait Init
- scheduler.swait[p].start.value = 0;
- scheduler.swait[p].start.next = &scheduler.swait[p].end;
- scheduler.swait[p].start.entry_type = START_ENTRY;
- scheduler.swait[p].end.value = 0;
- scheduler.swait[p].end.next = &scheduler.swait[p].start;
- scheduler.swait[p].end.entry_type = END_ENTRY;
- }
-
- // Initialize nextpid
- nextpid = FIRST_AVAIL_PID;
-
- // Initialize Threads - Stack Base and Offsets
- for (unsigned long i = 0; i < MAX_THREADS; i++) {
- struct Thread* t = &threads[i];
- t->offset = i;
- t->sp_base = 0x20000000 - STACK_SIZE*i;
- thread_entries[i].value = t;
- thread_entries[i].next = &thread_entries[(i+1)];
- thread_entries[i].entry_type = VALUE_ENTRY;
- }
- // Initialize the free queue
- scheduler.free_threads.start.value = 0;
- scheduler.free_threads.start.entry_type = START_ENTRY;
- scheduler.free_threads.end.value = 0;
- scheduler.free_threads.end.entry_type = END_ENTRY;
- scheduler.free_threads.start.next = &thread_entries[0];
- scheduler.free_threads.end.next = &thread_entries[MAX_THREADS-1];
- thread_entries[MAX_THREADS-1].next = &scheduler.free_threads.end;
-}
-
-void push_thread_to_queue(struct Thread* t, unsigned char type, unsigned char priority)
-{
- struct Entry* entry = &thread_entries[t->offset];
- struct Queue* queue;
- if (type == THREAD_READY) {
- queue = &scheduler.ready[priority];
- } else if (type == THREAD_MWAIT) {
- queue = &scheduler.mwait[priority];
- } else if (type == THREAD_SWAIT) {
- queue = &scheduler.swait[priority];
- } else {
- return;
- }
- push_to_queue(entry, queue);
- //queue->end.next->next = entry;
- //queue->end.next = entry;
- //entry->next = &queue->end;
-}
-
-void prepend_thread_to_queue(struct Thread* t, unsigned char type, unsigned char priority)
-{
- struct Entry* entry = &thread_entries[t->offset];
- struct Queue* queue;
- if (type == THREAD_READY) {
- queue = &scheduler.ready[priority];
- } else if (type == THREAD_MWAIT) {
- queue = &scheduler.mwait[priority];
- } else if (type == THREAD_SWAIT) {
- queue = &scheduler.swait[priority];
- } else {
- return;
- }
- prepend_to_queue(entry, queue);
-}
-
-struct Entry* pop_thread_from_queue(unsigned char type, unsigned char priority)
-{
- struct Entry* entry = 0;
- struct Queue* queue;
- if (type == THREAD_READY) {
- queue = &scheduler.ready[priority];
- } else if (type == THREAD_MWAIT) {
- queue = &scheduler.mwait[priority];
- } else if (type == THREAD_SWAIT) {
- queue = &scheduler.swait[priority];
- } else {
- return entry;
- }
- return pop_from_queue(queue);
-}
-
-struct Entry* find_pid(unsigned long pid)
-{
- for (unsigned char p = 0; p < PRIORITIES; p++) {
- struct Queue* queue;
- struct Entry* prev;
- struct Entry* entry;
-
- queue = &scheduler.ready[p];
- prev = &queue->start;
- entry = prev->next;
- while (entry->entry_type != END_ENTRY) {
- if (((struct Thread*)entry->value)->pid == pid)
- return prev;
- prev = entry;
- entry = entry->next;
- }
-
- queue = &scheduler.mwait[p];
- prev = &queue->start;
- entry = prev->next;
- while (entry->entry_type != END_ENTRY) {
- if (((struct Thread*)entry->value)->pid == pid)
- return prev;
- prev = entry;
- entry = entry->next;
- }
-
- queue = &scheduler.swait[p];
- prev = &queue->start;
- entry = prev->next;
- while (entry->entry_type != END_ENTRY) {
- if (((struct Thread*)entry->value)->pid == pid)
- return prev;
- prev = entry;
- entry = entry->next;
- }
- }
- return 0;
-}
-
-struct Entry* find_mutex_wait_next(void* m)
-{
- for (unsigned char p = 0; p < PRIORITIES; p++) {
- struct Queue* queue = &scheduler.mwait[p];
- struct Entry* prev = &queue->start;
- struct Entry* entry = prev->next;
- while (entry->entry_type != END_ENTRY) {
- if (((struct Thread*)entry->value)->mptr == m)
- return prev;
- prev = entry;
- entry = entry->next;
- }
- }
- return 0;
-}
-
-struct Entry* find_signal_wait_next(void* s)
-{
- for (unsigned char p = 0; p < PRIORITIES; p++) {
- struct Queue* queue = &scheduler.swait[p];
- struct Entry* prev = &queue->start;
- struct Entry* entry = prev->next;
- while (entry->entry_type != END_ENTRY) {
- if (((struct Thread*)entry->value)->mptr == s)
- return prev;
- prev = entry;
- entry = entry->next;
- }
- }
- return 0;
-}
-
-struct Entry* get_unused_thread(void)
-{
- struct Queue* q = &scheduler.free_threads;
- // If we have no available free threads
- // return null pointer
- if (q->start.next->entry_type == END_ENTRY)
- return 0;
- // Otherwise, get the next thread
- return pop_from_queue(q);
-}
-
-unsigned char find_duplicate(void* pc)
-{
- for (unsigned char p = 0; p < PRIORITIES; p++) {
- struct Queue* queue = &scheduler.ready[p];
- struct Entry* entry = queue->start.next;
- while (entry->entry_type == VALUE_ENTRY) {
- if (((struct Thread*)entry->value)->pc == pc) {
- return 1;
- }
- }
- }
- return 0;
-}
-
-unsigned char add_thread_without_duplicate(void* pc, void* arg, unsigned char priority)
-{
- if (!find_duplicate(pc)) {
- return add_thread(pc, arg, priority);
- }
- return 1;
-}
-
-unsigned char svc_add_thread(void* pc, void* arg, unsigned char priority)
-{
- struct Entry* thread_entry = get_unused_thread();
- // The only point-of-failure is not having a thread available
- if (thread_entry == 0)
- return 1;
- struct Thread* thread = thread_entry->value;
- /// Thread Setup
- thread->pc = pc;
- unsigned long* argp = (void*)thread->sp_base;
- argp -= 13;
- *argp = (unsigned long)arg; // Set r0 to the argument
- argp -= 1;
- *(unsigned long**)argp = (unsigned long*)cleanup; // Set lr to the cleanup function
- thread->sp = argp;
- thread->status = THREAD_READY;
- thread->mptr = (void*)0;
- thread->pid = nextpid++;
- // Reset next pid on overflow
- if (nextpid < FIRST_AVAIL_PID) {
- nextpid = FIRST_AVAIL_PID;
- }
- // Cap Priority Level
- if (priority >= PRIORITIES)
- thread->priority = PRIORITIES - 1;
- else
- thread->priority = priority;
- // This thread is new
- thread->old_priority = -1;
- // Reserved for non-preemptible tasking
- thread->preempt = 0;
- /// Add Thread to Scheduler
- push_thread_to_queue(thread, THREAD_READY, thread->priority);
- return 0;
-}
-
-void uart_scheduler(void)
-{
- uart_string("Scheduler Info\n==============\nCurrent\n");
- uart_hex((unsigned long)scheduler.rthread);
- uart_char(' ');
- kmemshow32((void*)scheduler.rthread, 9);
- unsigned long length;
- for(int p = 0; p < PRIORITIES; p++) {
- uart_string("Priority ");
- uart_10(p);
- uart_char('\n');
- struct Queue* queue;
- struct Entry* entry;
-
- queue = &scheduler.ready[p];
- uart_string("Ready Queue\n");
- entry = queue->start.next;
- length = 0;
- while (entry->entry_type != END_ENTRY) {
- uart_hex((unsigned long)entry->value);
- uart_char(' ');
- kmemshow32((void*)entry->value, 9);
- entry = entry->next;
- length++;
- }
- uart_hexn(length);
-
- queue = &scheduler.mwait[p];
- uart_string("Mutex Wait Queue\n");
- entry = queue->start.next;
- length = 0;
- while (entry->entry_type != END_ENTRY) {
- uart_hex((unsigned long)entry->value);
- uart_char(' ');
- kmemshow32((void*)entry->value, 9);
- entry = entry->next;
- length++;
- }
- uart_hexn(length);
-
- queue = &scheduler.swait[p];
- uart_string("Signal Wait Queue\n");
- entry = queue->start.next;
- length = 0;
- while (entry->entry_type != END_ENTRY) {
- uart_hex((unsigned long)entry->value);
- uart_char(' ');
- kmemshow32((void*)entry->value, 9);
- entry = entry->next;
- length++;
- }
- uart_hexn(length);
- }
- // Count number of free threads
- struct Queue* queue = &scheduler.free_threads;
- struct Entry* entry = queue->start.next;
- while (entry->entry_type != END_ENTRY) {
- entry = entry->next;
- length++;
- }
- uart_hexn(length);
- uart_string("==============\n");
-}
-
-struct Thread* next_thread(void)
-{
- // Recurse through all priorities to try to find a ready thread
- for (int p = 0; p < PRIORITIES; p++) {
- struct Queue* rq = &scheduler.ready[p];
- if (rq->start.next->entry_type == END_ENTRY)
- continue;
- return rq->start.next->value;
- }
- // No thread found, use basic usrloopthread while waiting for new thread
- return &usrloopthread;
-}
-
-void c_cleanup(void)
-{
- struct Thread* rt = scheduler.rthread;
- struct Entry* e = pop_thread_from_queue(THREAD_READY, rt->priority);
- // Add to free threads
- push_to_queue(e, &scheduler.free_threads);
-}
-
-void yield(void)
-{
- struct Thread* rthread = scheduler.rthread;
- // usrloopthread should not be yielded
- if (rthread == &usrloopthread)
- return;
- // Put current thread at the end of its ready queue,
- // thus any threads of the same priority can be run first
- unsigned char priority = rthread->priority;
- struct Entry* tq;
- // Remove from top of queue
- tq = pop_thread_from_queue(THREAD_READY, priority);
- if (tq != 0) {
- // Add to bottom of queue
- push_thread_to_queue(tq->value, THREAD_READY, priority);
- }
-}
-
-void sched_mutex_yield(void* m)
-{
- struct Thread* rthread = scheduler.rthread;
- // usrloopthread should not be yielded
- if (rthread == &usrloopthread)
- return;
- unsigned char priority = rthread->priority;
- // Signify which lock this thread is waiting for
- rthread->mptr = m;
- struct Entry* rt;
- // Remove from top of running queue
- rt = pop_thread_from_queue(THREAD_READY, priority);
- if (rt != 0)
- // Push to bottom of wait queue
- push_thread_to_queue(rt->value, THREAD_MWAIT, priority);
- // Find the thread that has the mutex locked
- struct Mutex* mtex = m;
- struct Entry* mutex_next = find_pid(mtex->pid);
- if (mutex_next == 0)
- return;
- // The next thread is the one with the lock
- struct Entry* mutex_thread_entry = mutex_next->next;
- // Check if it is lower priority
- if (((struct Thread*)mutex_thread_entry->value)->priority > priority) {
- // Remove it from the old priority queue
- remove_next_from_queue(mutex_next);
- struct Thread* t = mutex_thread_entry->value;
- // Preserve the old priority
- if (t->old_priority == 0xFF)
- t->old_priority = t->priority;
- t->priority = priority;
- // Add it to the higher priority queue
- push_thread_to_queue(t, THREAD_READY, priority);
- }
-}
-
-void sched_semaphore_yield(void* s)
-{
- struct Thread* rthread = scheduler.rthread;
- // usrloopthread should not be yielded
- if (rthread == &usrloopthread)
- return;
- unsigned char priority = rthread->priority;
- // Signify which lock this thread is waiting for
- rthread->mptr = s;
- struct Entry* rt;
- // Remove from top of running queue
- rt = pop_thread_from_queue(THREAD_READY, priority);
- if (rt != 0)
- // Push to bottom of wait queue
- push_thread_to_queue(rt->value, THREAD_SWAIT, priority);
-}
-
-void sched_mutex_resurrect(void* m)
-{
- // Find any mutex to resurrect
- struct Entry* prev = find_mutex_wait_next(m);
- if (prev == 0)
- return;
- struct Entry* entry = prev->next;
- struct Thread* thread = entry->value;
- // Resurrect the thread
- thread->mptr = 0;
- // Remove from wait queue
- entry = remove_next_from_queue(prev);
- if (entry == 0)
- return;
- // Add to ready queue
- push_thread_to_queue(entry->value, THREAD_READY, ((struct Thread*)entry->value)->priority);
- // Demote current thread
- struct Thread* rthread = scheduler.rthread;
- unsigned long p = rthread->priority;
- unsigned long op = rthread->old_priority;
- // Restore the original priority level
- if (op != 0xFF) {
- struct Entry* tentry = pop_thread_from_queue(THREAD_READY, p);
- ((struct Thread*)tentry->value)->priority = op;
- ((struct Thread*)tentry->value)->old_priority = 0xFF;
- prepend_thread_to_queue(tentry->value, THREAD_READY, op);
- }
-}
-
-void sched_semaphore_resurrect(void* s, unsigned long count)
-{
- while (count--) {
- // Find any signal/ semaphore to resurrect
- struct Entry* prev = find_signal_wait_next(s);
- if (prev == 0)
- return;
- struct Entry* entry = prev->next;
- struct Thread* thread = entry->value;
- // Resurrect the thread
- thread->mptr = 0;
- // Remove from wait queue
- entry = remove_next_from_queue(prev);
- if (entry == 0)
- return;
- // Add to ready queue
- push_thread_to_queue(entry->value, THREAD_READY, ((struct Thread*)entry->value)->priority);
- }
-}
diff --git a/src/tests/test.S b/src/tests/test.S
deleted file mode 100644
index e80b6be..0000000
--- a/src/tests/test.S
+++ /dev/null
@@ -1,31 +0,0 @@
-.section .text
-
-a.btest:
- push {lr}
- mov r0, #5
- cmp r0, #4
- pop {pc}
-
-.globl atest
-atest:
- push {lr}
- ldr r0, =a.btest
- mov r1, #0
- mov r2, #0
- bl add_thread
- mov r0, #5
- subs r0, #5
- svc #0
- beq 1f
- mov r0, #0
- mov r1, #11
- mov r2, #0x4E
- mov r3, #0xFF0000
- bl draw_cletter
- pop {pc}
-1: mov r0, #0
- mov r1, #11
- mov r2, #0x59
- mov r3, #0xFF00
- bl draw_cletter
- pop {pc}
diff --git a/src/tests/test.c b/src/tests/test.c
deleted file mode 100644
index d954ade..0000000
--- a/src/tests/test.c
+++ /dev/null
@@ -1,545 +0,0 @@
-#include <cpu.h>
-//#include <drivers/uart.h>
-#include <globals.h>
-#include <graphics/lfb.h>
-#include <lib/kmem.h>
-#include <sys/core.h>
-#include <sys/schedule.h>
-#include <util/lock.h>
-#include <util/mutex.h>
-#include <util/status.h>
-
-extern void atest(void);
-void qualitative_tests(void);
-
-void nooptest(void) {}
-
-void mutex_contention_helper(struct Mutex* m)
-{
- lock_mutex(m);
- sys0(SYS_YIELD);
- unlock_mutex(m);
-}
-
-static int x = 0;
-static int y = 13;
-#define TEST_STR_CLR " "
-#define TEST_RESULT_WIDTH 15
-#define TEST_COUNT 4096
-#define TEST_BIN_COUNT 32
-void test_entry(void)
-{
- x = 0;
- draw_hex32(0, y-1, nextpid);
- draw_string(0, y+4, "Starting tests");
- unsigned long long ti, tf, dt=0,len;
- unsigned int tidx = 0;
- unsigned long bins[TEST_BIN_COUNT];
- for (int i = 0; i < TEST_BIN_COUNT; i++) {
- bins[i] = 0;
- }
-
- // Test 1: Trace Time
- dt = 0;
- for(int i = 0; i < TEST_COUNT; i++) {
- sys0_64(SYS_TIME, &ti);
- sys0_64(SYS_TIME, &tf);
- dt += tf - ti;
- if ((tf-ti) < TEST_BIN_COUNT)
- bins[(tf-ti)]++;
- }
- for (int i = 0; i < TEST_BIN_COUNT; i++) {
- draw_hex32(tidx, y+6+i, i);
- draw_string(tidx+9, y+6+i, TEST_STR_CLR);
- draw_u10(tidx+9, y+6+i, bins[i]);
- bins[i] = 0;
- }
- draw_string(tidx, y+5, " ");
- len = draw_u10(tidx, y+5, dt/TEST_COUNT);
- draw_u10(tidx+len+1, y+5, dt%TEST_COUNT);
- tidx += TEST_RESULT_WIDTH;
- draw_hex32(0, y-1, nextpid);
-
- // Test 2: Yield Time
- dt = 0;
- for(int i = 0; i < TEST_COUNT; i++) {
- sys0_64(SYS_TIME, &ti);
- sys0(SYS_YIELD);
- sys0_64(SYS_TIME, &tf);
- dt += tf - ti;
- if ((tf-ti) < TEST_BIN_COUNT)
- bins[(tf-ti)]++;
- }
- for (int i = 0; i < TEST_BIN_COUNT; i++) {
- draw_hex32(tidx, y+6+i, i);
- draw_string(tidx+9, y+6+i, TEST_STR_CLR);
- draw_u10(tidx+9, y+6+i, bins[i]);
- bins[i] = 0;
- }
- draw_string(tidx, y+5, " ");
- len = draw_u10(tidx, y+5, dt/TEST_COUNT);
- draw_u10(tidx+len+1, y+5, dt%TEST_COUNT);
- tidx += TEST_RESULT_WIDTH;
- draw_hex32(0, y-1, nextpid);
-
- // Test 3: Add Thread, Lower Priority
- dt = 0;
- for(int i = 0; i < TEST_COUNT; i++) {
- sys0_64(SYS_TIME, &ti);
- add_thread(nooptest, 0, 3);
- sys0_64(SYS_TIME, &tf);
- dt += tf - ti;
- if ((tf-ti) < TEST_BIN_COUNT)
- bins[(tf-ti)]++;
- }
- for (int i = 0; i < TEST_BIN_COUNT; i++) {
- draw_hex32(tidx, y+6+i, i);
- draw_string(tidx+9, y+6+i, TEST_STR_CLR);
- draw_u10(tidx+9, y+6+i, bins[i]);
- bins[i] = 0;
- }
- draw_string(tidx, y+5, " ");
- len = draw_u10(tidx, y+5, dt/TEST_COUNT);
- draw_u10(tidx+len+1, y+5, dt%TEST_COUNT);
- tidx += TEST_RESULT_WIDTH;
- draw_hex32(0, y-1, nextpid);
-
- // Test 4: Add Thread, Higher Priority
- dt = 0;
- for(int i = 0; i < TEST_COUNT; i++) {
- sys0_64(SYS_TIME, &ti);
- add_thread(nooptest, 0, 0);
- sys0_64(SYS_TIME, &tf);
- dt += tf - ti;
- if ((tf-ti) < TEST_BIN_COUNT)
- bins[(tf-ti)]++;
- }
- for (int i = 0; i < TEST_BIN_COUNT; i++) {
- draw_hex32(tidx, y+6+i, i);
- draw_string(tidx+9, y+6+i, TEST_STR_CLR);
- draw_u10(tidx+9, y+6+i, bins[i]);
- bins[i] = 0;
- }
- draw_string(tidx, y+5, " ");
- len = draw_u10(tidx, y+5, dt/TEST_COUNT);
- draw_u10(tidx+len+1, y+5, dt%TEST_COUNT);
- tidx += TEST_RESULT_WIDTH;
- draw_hex32(0, y-1, nextpid);
-
- // Test 5: Create Mutex
- dt = 0;
- for(int i = 0; i < TEST_COUNT; i++) {
- sys0_64(SYS_TIME, &ti);
- struct Mutex* m = create_mutex(0);
- sys0_64(SYS_TIME, &tf);
- delete_mutex(m);
- dt += tf - ti;
- if ((tf-ti) < TEST_BIN_COUNT)
- bins[(tf-ti)]++;
- }
- for (int i = 0; i < TEST_BIN_COUNT; i++) {
- draw_hex32(tidx, y+6+i, i);
- draw_string(tidx+9, y+6+i, TEST_STR_CLR);
- draw_u10(tidx+9, y+6+i, bins[i]);
- bins[i] = 0;
- }
- draw_string(tidx, y+5, " ");
- len = draw_u10(tidx, y+5, dt/TEST_COUNT);
- draw_u10(tidx+len+1, y+5, dt%TEST_COUNT);
- tidx += TEST_RESULT_WIDTH;
- draw_hex32(0, y-1, nextpid);
-
- // Test 6: Delete Mutex
- dt = 0;
- for(int i = 0; i < TEST_COUNT; i++) {
- struct Mutex* m = create_mutex(0);
- sys0_64(SYS_TIME, &ti);
- delete_mutex(m);
- sys0_64(SYS_TIME, &tf);
- dt += tf - ti;
- if ((tf-ti) < TEST_BIN_COUNT)
- bins[(tf-ti)]++;
- }
- for (int i = 0; i < TEST_BIN_COUNT; i++) {
- draw_hex32(tidx, y+6+i, i);
- draw_string(tidx+9, y+6+i, TEST_STR_CLR);
- draw_u10(tidx+9, y+6+i, bins[i]);
- bins[i] = 0;
- }
- draw_string(tidx, y+5, " ");
- len = draw_u10(tidx, y+5, dt/TEST_COUNT);
- draw_u10(tidx+len+1, y+5, dt%TEST_COUNT);
- tidx += TEST_RESULT_WIDTH;
- draw_hex32(0, y-1, nextpid);
-
- // Test 7: Lock Mutex
- dt = 0;
- for(int i = 0; i < TEST_COUNT; i++) {
- struct Mutex* m = create_mutex(0);
- sys0_64(SYS_TIME, &ti);
- lock_mutex(m);
- sys0_64(SYS_TIME, &tf);
- delete_mutex(m);
- dt += tf - ti;
- if ((tf-ti) < TEST_BIN_COUNT)
- bins[(tf-ti)]++;
- }
- for (int i = 0; i < TEST_BIN_COUNT; i++) {
- draw_hex32(tidx, y+6+i, i);
- draw_string(tidx+9, y+6+i, TEST_STR_CLR);
- draw_u10(tidx+9, y+6+i, bins[i]);
- bins[i] = 0;
- }
- draw_string(tidx, y+5, " ");
- len = draw_u10(tidx, y+5, dt/TEST_COUNT);
- draw_u10(tidx+len+1, y+5, dt%TEST_COUNT);
- tidx += TEST_RESULT_WIDTH;
- draw_hex32(0, y-1, nextpid);
-
- // Test 7a: Lock Contended Mutex
- dt = 0;
- for(int i = 0; i < TEST_COUNT; i++) {
- struct Mutex* m = create_mutex(0);
- add_thread(mutex_contention_helper, m, 2);
- sys0(SYS_YIELD);
- sys0_64(SYS_TIME, &ti);
- lock_mutex(m);
- sys0_64(SYS_TIME, &tf);
- delete_mutex(m);
- dt += tf - ti;
- if ((tf-ti) < TEST_BIN_COUNT)
- bins[(tf-ti)]++;
- }
- for (int i = 0; i < TEST_BIN_COUNT; i++) {
- draw_hex32(tidx, y+6+i, i);
- draw_string(tidx+9, y+6+i, TEST_STR_CLR);
- draw_u10(tidx+9, y+6+i, bins[i]);
- bins[i] = 0;
- }
- draw_string(tidx, y+5, " ");
- len = draw_u10(tidx, y+5, dt/TEST_COUNT);
- draw_u10(tidx+len+1, y+5, dt%TEST_COUNT);
- tidx += TEST_RESULT_WIDTH;
- draw_hex32(0, y-1, nextpid);
-
- // Test 8: Unlock Mutex
- dt = 0;
- for(int i = 0; i < TEST_COUNT; i++) {
- struct Mutex* m = create_mutex(0);
- lock_mutex(m);
- sys0_64(SYS_TIME, &ti);
- unlock_mutex(m);
- sys0_64(SYS_TIME, &tf);
- delete_mutex(m);
- dt += tf - ti;
- if ((tf-ti) < TEST_BIN_COUNT)
- bins[(tf-ti)]++;
- }
- for (int i = 0; i < TEST_BIN_COUNT; i++) {
- draw_hex32(tidx, y+6+i, i);
- draw_string(tidx+9, y+6+i, TEST_STR_CLR);
- draw_u10(tidx+9, y+6+i, bins[i]);
- bins[i] = 0;
- }
- draw_string(tidx, y+5, " ");
- len = draw_u10(tidx, y+5, dt/TEST_COUNT);
- draw_u10(tidx+len+1, y+5, dt%TEST_COUNT);
- tidx += TEST_RESULT_WIDTH;
- draw_hex32(0, y-1, nextpid);
-
- // Semaphore
- static unsigned long sem = 0;
-
- // Test 9: Semaphore Decrease
- dt = 0;
- for(int i = 0; i < TEST_COUNT; i++) {
- sem = 1;
- sys0_64(SYS_TIME, &ti);
- sys1(SYS_SEMAPHORE_P, &sem);
- sys0_64(SYS_TIME, &tf);
- dt += tf - ti;
- if ((tf-ti) < TEST_BIN_COUNT)
- bins[(tf-ti)]++;
- }
- for (int i = 0; i < TEST_BIN_COUNT; i++) {
- draw_hex32(tidx, y+6+i, i);
- draw_string(tidx+9, y+6+i, TEST_STR_CLR);
- draw_u10(tidx+9, y+6+i, bins[i]);
- bins[i] = 0;
- }
- draw_string(tidx, y+5, " ");
- len = draw_u10(tidx, y+5, dt/TEST_COUNT);
- draw_u10(tidx+len+1, y+5, dt%TEST_COUNT);
- tidx += TEST_RESULT_WIDTH;
- draw_hex32(0, y-1, nextpid);
-
- // Test 10: Semaphore Increase
- dt = 0;
- for(int i = 0; i < TEST_COUNT; i++) {
- sem = 0;
- sys0_64(SYS_TIME, &ti);
- sys1(SYS_SEMAPHORE_V, &sem);
- sys0_64(SYS_TIME, &tf);
- dt += tf - ti;
- if ((tf-ti) < TEST_BIN_COUNT)
- bins[(tf-ti)]++;
- }
- for (int i = 0; i < TEST_BIN_COUNT; i++) {
- draw_hex32(tidx, y+6+i, i);
- draw_string(tidx+9, y+6+i, TEST_STR_CLR);
- draw_u10(tidx+9, y+6+i, bins[i]);
- bins[i] = 0;
- }
- draw_string(tidx, y+5, " ");
- len = draw_u10(tidx, y+5, dt/TEST_COUNT);
- draw_u10(tidx+len+1, y+5, dt%TEST_COUNT);
- tidx += TEST_RESULT_WIDTH;
- draw_hex32(0, y-1, nextpid);
-
- // Test 10a: Semaphore Increase - No Schedule
- dt = 0;
- for(int i = 0; i < TEST_COUNT; i++) {
- sem = 1;
- sys0_64(SYS_TIME, &ti);
- sys1(SYS_SEMAPHORE_V, &sem);
- sys0_64(SYS_TIME, &tf);
- dt += tf - ti;
- if ((tf-ti) < TEST_BIN_COUNT)
- bins[(tf-ti)]++;
- }
- for (int i = 0; i < TEST_BIN_COUNT; i++) {
- draw_hex32(tidx, y+6+i, i);
- draw_string(tidx+9, y+6+i, TEST_STR_CLR);
- draw_u10(tidx+9, y+6+i, bins[i]);
- bins[i] = 0;
- }
- draw_string(tidx, y+5, " ");
- len = draw_u10(tidx, y+5, dt/TEST_COUNT);
- draw_u10(tidx+len+1, y+5, dt%TEST_COUNT);
- tidx += TEST_RESULT_WIDTH;
- draw_hex32(0, y-1, nextpid);
-
-// // Test 7: Tick Latency
-//#define DELAY_TIME 512000
-// unsigned long center = 0;
-// sys0_64(SYS_TIME, &ti);
-// delay(DELAY_TIME);
-// sys0_64(SYS_TIME, &tf);
-// center = (tf - ti - 10);
-// if (10 > (tf-ti))
-// center = 0;
-// dt = 0;
-// unsigned long j = 0;
-// for(int i = 0; i < TEST_COUNT; i++) {
-// sys0_64(SYS_TIME, &ti);
-// delay(DELAY_TIME);
-// sys0_64(SYS_TIME, &tf);
-// dt += tf - ti;
-// if ((tf-ti-center) < TEST_BIN_COUNT)
-// bins[(tf-ti)-center]++;
-// else
-// j++;
-// }
-// for (int i = 0; i < TEST_BIN_COUNT; i++) {
-// draw_hex32(tidx, y+6+i, i);
-// draw_string(tidx+9, y+6+i, TEST_STR_CLR);
-// draw_u10(tidx+9, y+6+i, bins[i]);
-// bins[i] = 0;
-// }
-// draw_hex32(tidx, y+4, j);
-// draw_string(tidx, y+5, " ");
-// len = draw_u10(tidx, y+5, dt/TEST_COUNT);
-// draw_u10(tidx+len+1, y+5, dt%TEST_COUNT);
-// tidx += TEST_RESULT_WIDTH;
-// draw_hex32(0, y-1, nextpid);
-
- add_thread(qualitative_tests, 0, 4);
-}
-
-//static struct Mutex testm = {.addr = 0, .pid = 0};
-static struct Lock testm = {.pid = 0};
-
-void priority_inversion_test1(void);
-void priority_inversion_test2(void);
-void priority_inversion_test3(void);
-void priority_inversion_test4(void);
-
-void priority_inversion_test1(void)
-{
- draw_cletter(x++, y+2, 'S', 0xFF0000);
- // Try Lock
- draw_cletter(x++, y+2, 'T', 0xFF0000);
- lock(&testm);
- // Lock Acquired
- draw_cletter(x++, y+2, 'L', 0xFF0000);
- // Add Thread to Assist with Priority Inversion
- // Check
- // - Show that this thread gets temporarily
- // promoted
- add_thread(priority_inversion_test3, 0, 2);
- // Unlock
- draw_cletter(x++, y+2, 'U', 0xFF0000);
- unlock(&testm);
- draw_cletter(x++, y+2, 'F', 0xFF0000);
-}
-
-void priority_inversion_test2(void)
-{
- draw_cletter(x++, y+0, 'S', 0x0000FF);
- // Add Thread to Assist with Priority Inversion
- // Check
- // - Show that Thread 1 is Prepended To Queue
- add_thread(priority_inversion_test4, 0, 3);
- // Try Lock
- draw_cletter(x++, y+0, 'T', 0x0000FF);
- lock(&testm);
- // Lock Acquired
- draw_cletter(x++, y+0, 'L', 0x0000FF);
- // Unlock
- draw_cletter(x++, y+0, 'U', 0x0000FF);
- unlock(&testm);
- draw_cletter(x++, y+0, 'F', 0x0000FF);
-}
-
-void priority_inversion_test3(void)
-{
- draw_cletter(x++, y+1, 'S', 0x00FF00);
- // Add thread to Assist with Priority Inversion
- // Check
- // - Add high priority thread that will try
- // to lock the mutex
- add_thread(priority_inversion_test2, 0, 1);
- draw_cletter(x++, y+1, 'F', 0x00FF00);
-}
-
-void priority_inversion_test4(void)
-{
- draw_cletter(x++, y+2, 'S', 0xAFAF00);
- // Do nothing,
- // just show that this is executed last
- draw_cletter(x++, y+2, 'F', 0xAFAF00);
-}
-
-static unsigned long test_semaphore = 0;
-
-void semaphore_test1(void)
-{
- draw_cletter(x++, y+1, ' ', 0xFF0000);
- draw_cletter(x++, y+1, 'S', 0xFF0000);
- // Try to decrement semaphore
- draw_cletter(x++, y+1, 'T', 0xFF0000);
- sys1(SYS_SEMAPHORE_P, &test_semaphore);
- // Semaphore decremented
- draw_cletter(x++, y+1, 'P', 0xFF0000);
- draw_cletter(x++, y+1, 'V', 0xFF0000);
- sys1(SYS_SEMAPHORE_V, &test_semaphore);
- draw_cletter(x++, y+1, 'V', 0xFF0000);
- sys1(SYS_SEMAPHORE_V, &test_semaphore);
- draw_cletter(x++, y+1, 'V', 0xFF0000);
- sys1(SYS_SEMAPHORE_V, &test_semaphore);
- // Try to decrement semaphore
- draw_cletter(x++, y+1, 'T', 0xFF0000);
- sys1(SYS_SEMAPHORE_P, &test_semaphore);
- // Semaphore decremented
- draw_cletter(x++, y+1, 'P', 0xFF0000);
- // Try to decrement semaphore
- draw_cletter(x++, y+1, 'T', 0xFF0000);
- sys1(SYS_SEMAPHORE_P, &test_semaphore);
- // Semaphore decremented
- draw_cletter(x++, y+1, 'P', 0xFF0000);
- // Try to decrement semaphore
- draw_cletter(x++, y+1, 'T', 0xFF0000);
- sys1(SYS_SEMAPHORE_P, &test_semaphore);
- // Semaphore decremented
- draw_cletter(x++, y+1, 'P', 0xFF0000);
- // Try to decrement semaphore
- draw_cletter(x++, y+1, 'T', 0xFF0000);
- sys1(SYS_SEMAPHORE_P, &test_semaphore);
- // Semaphore decremented
- draw_cletter(x++, y+1, 'P', 0xFF0000);
- draw_cletter(x++, y+1, 'F', 0xFF0000);
-}
-
-void semaphore_test2(void)
-{
- draw_cletter(x++, y+2, 'S', 0xFF00);
- // Increment semaphore
- draw_cletter(x++, y+2, 'V', 0xFF00);
- sys1(SYS_SEMAPHORE_V, &test_semaphore);
- // Increment semaphore
- draw_cletter(x++, y+2, 'V', 0xFF00);
- sys1(SYS_SEMAPHORE_V, &test_semaphore);
- draw_cletter(x++, y+2, 'F', 0xFF00);
-}
-
-static struct Mutex* dead1 = 0;
-static struct Mutex* dead2 = 0;
-
-void deadlock_test2(void)
-{
- draw_cletter(x++, y+1, 'S', 0xFF0000);
- // Try Lock 1
- draw_cletter(x++, y+1, 'T', 0xFF0000);
- lock_mutex(dead1);
- // Lock 1 Acquired
- draw_cletter(x++, y+1, 'L', 0xFF0000);
- // Try Lock 2
- draw_cletter(x++, y+1, 't', 0xFF0000);
- lock_mutex(dead2);
- // Lock 2 Acquired
- draw_cletter(x++, y+1, 'l', 0xFF0000);
- // Unlock Locks
- draw_cletter(x++, y+1, 'u', 0xFF0000);
- unlock_mutex(dead2);
- draw_cletter(x++, y+1, 'U', 0xFF0000);
- unlock_mutex(dead1);
- draw_cletter(x++, y+1, 'F', 0xFF0000);
-}
-
-void deadlock_test1(void)
-{
- draw_cletter(x++, y+2, ' ', 0xFF00);
- draw_cletter(x++, y+2, 'S', 0xFF00);
- dead1 = create_mutex((void*)0xDEADBEEF);
- dead2 = create_mutex((void*)0x12345678);
- // Try Lock 2
- draw_cletter(x++, y+2, 't', 0xFF00);
- lock_mutex(dead2);
- // Lock 2 Acquired
- draw_cletter(x++, y+2, 'l', 0xFF00);
- // Create Higher priority thread to
- // check deadlock condition
- draw_cletter(x++, y+2, 'A', 0xFF00);
- add_thread(deadlock_test2, 0, 4);
- // Try Lock 1 - This would deadlock
- // if no mechanism is in place to
- // prevent it
- draw_cletter(x++, y+2, 'T', 0xFF00);
- lock_mutex(dead1);
- // Lock 1 Acquired - Deadlock condition
- // properly handled
- draw_cletter(x++, y+2, 'L', 0xFF00);
- // Unlock Locks
- draw_cletter(x++, y+2, 'u', 0xFF00);
- unlock_mutex(dead2);
- draw_cletter(x++, y+2, 'U', 0xFF00);
- unlock_mutex(dead1);
- delete_mutex(dead1);
- delete_mutex(dead2);
- draw_cletter(x++, y+2, 'F', 0xFF00);
-}
-
-void qualitative_tests(void)
-{
- draw_string(0, y+0, " ");
- draw_string(0, y+1, " ");
- draw_string(0, y+2, " ");
- draw_string(0, y+3, " ");
- x = 0;
- add_thread(atest, 0, 0);
- add_thread(priority_inversion_test1, 0, 3);
- add_thread(deadlock_test1, 0, 5);
- add_thread(semaphore_test1, 0, 6);
- add_thread(semaphore_test2, 0, 7);
- add_thread(time_status, 0, 8);
-}
diff --git a/src/usr/main.c b/src/usr/main.c
deleted file mode 100644
index 67b9c3a..0000000
--- a/src/usr/main.c
+++ /dev/null
@@ -1,25 +0,0 @@
-#include <graphics/lfb.h>
-#include <symbols.h>
-
-char* ulong_to_string(unsigned long value, char* data)
-{
- unsigned long t = value;
- unsigned long c;
- char* dptr = data + 9;
- for (int i = 0; i <= 10; i++) {
- c = t%10;
- *dptr = 0x30 + (c&0xF);
- t /= 10;
- if (t==0)
- break;
- dptr -= 1;
- }
- return dptr;
-}
-
-void main(void)
-{
- static char str[13];
- char* start = ulong_to_string(*(volatile unsigned long*)SYS_TIMER_CHI, str);
- draw_string(0, 10, start);
-}
diff --git a/src/util/lock.c b/src/util/lock.c
deleted file mode 100644
index c9fe654..0000000
--- a/src/util/lock.c
+++ /dev/null
@@ -1,20 +0,0 @@
-#include <cpu.h>
-#include <cpu/atomic/swap.h>
-#include <util/mutex.h>
-#include <util/lock.h>
-
-void lock(struct Lock* l)
-{
- unsigned long mode = getmode() & 0x1F;
- if (mode == 0x10) {
- sys1(SYS_LOCK, l);
- }
-}
-
-void unlock(struct Lock* l)
-{
- unsigned long mode = getmode() & 0x1F;
- if (mode == 0x10) {
- sys1(SYS_UNLOCK, l);
- }
-}
diff --git a/src/util/mutex.c b/src/util/mutex.c
deleted file mode 100644
index 8e85f8f..0000000
--- a/src/util/mutex.c
+++ /dev/null
@@ -1,110 +0,0 @@
-#include <cpu.h>
-#include <drivers/uart.h>
-#include <util/mutex.h>
-#include <util/lock.h>
-#include <globals.h>
-
-void mutex_init(void)
-{
- for (unsigned long m = 0; m < MAX_MUTEXS; m++) {
- mutexs[m].pid = 0;
- mutexs[m].addr = 0;
- mutex_entries[m].value = &mutexs[m];
- mutex_entries[m].entry_type = VALUE_ENTRY;
- mutex_entries[m].next = &mutex_entries[m+1];
- }
- // Initialize Free Mutexs
- mutex_manager.free.start.value = 0;
- mutex_manager.free.start.next = &mutex_entries[0];
- mutex_manager.free.start.entry_type = START_ENTRY;
- mutex_manager.free.end.value = 0;
- mutex_manager.free.end.next = &mutex_entries[MAX_MUTEXS-1];
- mutex_entries[MAX_MUTEXS-1].next = &mutex_manager.free.end;
- mutex_manager.free.end.entry_type = END_ENTRY;
- // Initialize In-use Mutexs
- mutex_manager.used.start.value = 0;
- mutex_manager.used.start.next = &mutex_manager.used.end;
- mutex_manager.used.start.entry_type = START_ENTRY;
- mutex_manager.used.end.value = 0;
- mutex_manager.used.end.next = &mutex_manager.used.start;
- mutex_manager.used.end.entry_type = END_ENTRY;
-}
-
-struct Mutex* create_mutex(void* addr)
-{
- struct Entry* e = pop_from_queue(&mutex_manager.free);
- if (e == 0)
- return 0;
- struct Mutex* m = e->value;
- m->pid = 0;
- m->addr = addr;
- push_to_queue(e, &mutex_manager.used);
- return e->value;
-}
-
-unsigned char delete_mutex(struct Mutex* m)
-{
- struct Entry* entry = find_value(m, &mutex_manager.used);
- if (entry == 0)
- return 1;
- // Remove it from the queue
- struct Entry* theentry = remove_next_from_queue(entry);
- // Add it to the free queue
- prepend_to_queue(theentry, &mutex_manager.free);
- return 0;
-}
-
-void uart_mutexes(void)
-{
- struct Entry* entry = mutex_manager.used.start.next;
- while (entry->entry_type == VALUE_ENTRY)
- {
- struct Mutex* m = entry->value;
- uart_hex((unsigned long)m);
- uart_char(' ');
- uart_hex(m->pid);
- uart_char(' ');
- uart_hexn((unsigned long)m->addr);
- entry = entry->next;
- }
- unsigned long count = 0;
- entry = mutex_manager.free.start.next;
- while (entry->entry_type == VALUE_ENTRY) {
- count++;
- entry = entry->next;
- }
- uart_hexn(count);
-}
-
-void lock_mutex(struct Mutex* m)
-{
- struct Thread* rthread = scheduler.rthread;
- unsigned long rpid = rthread->pid;
- unsigned long mode = getmode() & 0x1F;
- if (mode == 0x10) {
- // Find this mutex
- struct Entry* mentry = find_value(m, &mutex_manager.used);
- // If it is not a managed mutex, break away
- if (mentry == 0)
- return;
- struct Entry* entry = mutex_manager.used.start.next;
- // Ensure this thread locks all mutexs sequentially
- // To avoid a deadlock
- while (entry->entry_type == VALUE_ENTRY) {
- struct Mutex* vmutex = entry->value;
- // If this thread had locked it
- // Toggle the lock to prevent deadlock
- if (vmutex->pid == rpid) {
- sys1(SYS_UNLOCK, vmutex);
- sys1(SYS_LOCK, vmutex);
- }
- entry = entry->next;
- }
- sys1(SYS_LOCK, m);
- }
-}
-
-void unlock_mutex(struct Mutex* m)
-{
- unlock((struct Lock*)m);
-}
diff --git a/src/util/status.c b/src/util/status.c
deleted file mode 100644
index 456e89d..0000000
--- a/src/util/status.c
+++ /dev/null
@@ -1,133 +0,0 @@
-#include <cpu.h>
-#include <globals.h>
-#include <graphics/lfb.h>
-#include <symbols.h>
-#include <lib/strings.h>
-#include <lib/kmem.h>
-#include <sys/core.h>
-#include <sys/schedule.h>
-#include <util/mutex.h>
-#include <util/status.h>
-#include <util/time.h>
-
-void output_irq_status(void)
-{
- // Basic IRQ
- unsigned long ib_val = load32(IRQ_BASIC_ENABLE);
- // IRQ 1
- unsigned long i1_val = load32(IRQ_ENABLE1);
- // IRQ 2
- unsigned long i2_val = load32(IRQ_ENABLE2);
- // FIQ
- unsigned long f_val = load32(FIQ_CONTROL);
-
- // Check GPU Interrupt Routing
- unsigned long g_val = load32(GPU_INTERRUPTS_ROUTING);
- draw_cletter(0, 1, (g_val & 0b11) + 0x30, 0x1EA1A1);
- draw_cletter(1, 1, ((g_val >> 2) & 0b11) + 0x30, 0x1EA1A1);
-
- draw_chex32(4, 1, ib_val, 0x1EA1A1);
- draw_chex32(4+9, 1, i1_val, 0x1EA1A1);
- draw_chex32(4+9*2, 1, i2_val, 0x1EA1A1);
- draw_chex32(4+9*3, 1, f_val, 0x1EA1A1);
-
- // Check UART IRQ
- if (i2_val & (1<<25)) {
- draw_cstring(0, 2, "UART", 0x00FF00);
- } else if (f_val == 57) {
- draw_cstring(0, 2, "UART", 0xFFA500);
- } else {
- draw_cstring(0, 2, "UART", 0xFF0000);
- }
-
- // Check UART IRQ
- if (i1_val & (1<<0)) {
- draw_cstring(5, 2, "STIMERCMP", 0x00FF00);
- } else if (f_val == 1) {
- draw_cstring(5, 2, "STIMERCMP", 0xFFA500);
- } else {
- draw_cstring(5, 2, "STIMERCMP", 0xFF0000);
- }
-
- if (load32(CORE0_TIMER_IRQCNTL) & 0xF) {
- draw_cstring(4+9+2, 2, "LTIMER", 0x00FF00);
- } else if (load32(CORE0_TIMER_IRQCNTL) & 0xF0) {
- draw_cstring(4+9+2, 2, "LTIMER", 0xFFA500);
- } else {
- draw_cstring(4+9+2, 2, "LTIMER", 0xFF0000);
- }
-}
-
-void time_status(void)
-{
- // Report Sys Timer Stataus
- unsigned long systime;
- draw_string(0, 8, "Sys Timer Status");
- systime = *(volatile unsigned long*)SYS_TIMER_CS;
- draw_hex32(17, 8, systime);
- draw_string(17+8, 8, ":");
- unsigned long long tval = get_time();
- draw_hex32(17+8, 8, (tval >> 32));
- draw_hex32(17+8+8, 8, tval);
- systime = *(volatile unsigned long*)SYS_TIMER_C0;
- draw_hex32(19+14+8+1, 8, systime);
- draw_string(19+14+9+8, 8, "|");
- draw_string(19+14+18, 8, " ");
- draw_u10(19+14+18, 8, ((unsigned long)tval)/1000000);
-}
-
-void status(void)
-{
- // OS Info
- draw_cstring(7, 0, "v", 0x00FFFF);
- draw_cstring(0, 0, os_name, 0xFF0000);
- draw_cstring(8, 0, os_info_v, 0x00FFFF);
-
- // GPU IRQ Statuses
- output_irq_status();
-
- // Timer Status
- draw_cstring(0, 3, "TIMER", 0x00FF00);
- // Output the frequency
- draw_string(6, 3, "@");
- unsigned long frq = read_cntfrq()/1000;
- unsigned long fs_len = draw_u10(8, 3, frq) + 1;
- draw_string(8+fs_len, 3, "kHz");
- // Output the value
- unsigned long v = read_cntv_tval();
- unsigned long vs_len = draw_u10(8+fs_len+4, 3, v)+1;
- draw_string(8+fs_len+4 +vs_len, 3, " ");
- draw_letter(8+fs_len+4 +vs_len+1, 3, '|');
- draw_hex32(8+fs_len+7+vs_len, 3, v);
-
- // Video Status
- draw_cstring(0, 4, "VIDEO", 0x00FF00);
- unsigned long gw_len = draw_u10(6, 4, gwidth);
- unsigned long gh_len = draw_u10(6+gw_len+1, 4, gheight) + 1;
- draw_letter(6+gw_len, 4, 'x');
- if(gisrgb)
- draw_string(6+gw_len+gh_len + 1, 4, "RGB");
- else
- draw_string(6+gw_len+gh_len + 1, 4, "BGR");
-
- // Core Stacks
- draw_string(0, 5, "SVC IRQ FIQ User/SYS\n");
- unsigned long sp = (unsigned long)getsvcstack();
- draw_hex32(0, 6, sp);
- sp = (unsigned long)getirqstack();
- draw_hex32(9, 6, sp);
- sp = (unsigned long)getfiqstack();
- draw_hex32(9*2, 6, sp);
- sp = (unsigned long)getsysstack();
- draw_hex32(9*3, 6, sp);
-
- // Report Core that updated status
- unsigned long coren;
- asm volatile (
- "mrc p15, #0, %0, c0, c0, #5\n"
- "and %0, %0, #3" : "=r"(coren) :: "cc");
- draw_string(0, 7, "Status Updated by Core #");
- draw_hex32(24, 7, coren);
-
- time_status();
-}
diff --git a/src/util/time.c b/src/util/time.c
deleted file mode 100644
index abb9c8d..0000000
--- a/src/util/time.c
+++ /dev/null
@@ -1,76 +0,0 @@
-#include <symbols.h>
-#include <sys/core.h>
-
-// CCNT - Cycle Timer (Close to ns resolution)
-
-void routing_core0cntv_to_core0fiq(void)
-{
- store32(0x80, CORE0_TIMER_IRQCNTL);
-}
-
-void routing_core0cntv_to_core0irq(void)
-{
- store32(0x08, CORE0_TIMER_IRQCNTL);
-}
-
-unsigned long read_core0timer_pending(void)
-{
- unsigned long tmp;
- tmp = load32(CORE0_IRQ_SOURCE);
- return tmp;
-}
-
-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;
-}
-
-unsigned long long get_time(void)
-{
- union {
- unsigned long long tval;
- struct {
- unsigned long high;
- unsigned long low;
- } tvalb;
- } t;
- t.tvalb.low = *(unsigned long*)SYS_TIMER_CLO;
- t.tvalb.high = *(unsigned long*)SYS_TIMER_CHI;
- return t.tval;
-}
-
-void wait_msec(unsigned int n)
-{
- unsigned long start = *(volatile unsigned long*)SYS_TIMER_CHI;
- while (*(volatile unsigned long*)SYS_TIMER_CHI - start < n)
- asm volatile("nop");
-}