aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/boot.S135
-rw-r--r--src/irq.S0
-rw-r--r--src/kernel.S24
-rw-r--r--src/uart.S46
4 files changed, 205 insertions, 0 deletions
diff --git a/src/boot.S b/src/boot.S
new file mode 100644
index 0000000..f0caebc
--- /dev/null
+++ b/src/boot.S
@@ -0,0 +1,135 @@
+// To keep this in the first portion of the binary.
+.section ".text.boot"
+
+// Make _start global.
+.globl _start
+
+_start:
+reset:
+ // disable core0,1,2.
+ mrc p15, #0, r1, c0, c0, #5
+ and r1, r1, #3
+ cmp r1, #0
+ bne io_halt
+
+ // set vector address.
+ ldr r0, =vector
+ mcR P15, 0, r0, c12, c0, 0
+
+ // save cpsr.
+ mrs r0, cpsr
+
+ // setup sp in IRQ mode.
+ bic r1, r0, #0x1f
+ orr r1, r1, #0x12
+ msr cpsr_c,r1
+ mov sp,#0x4000
+
+ // restore cpsr.
+ msr cpsr_c, r0
+
+ // setup the stack in SVC mode.
+ mov sp, #0x8000
+
+ // 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}
+
+ // If we are still below bss_end, loop.
+2:
+ cmp r4, r9
+ blo 1b
+
+ // Call kernel_main
+ ldr r3, =kernel_main
+ blx r3
+
+irq:
+ push {r0,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,r12,lr}
+ bl a_irq_handler
+ pop {r0,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,r12,lr}
+ subs pc, lr, #4
+
+.globl io_halt
+io_halt:
+ wfi
+ b io_halt
+
+.globl enable_irq
+enable_irq:
+ cpsie i
+ bx lr
+
+.globl disable_irq
+disable_irq:
+ cpsid i
+ bx lr
+
+.align 5
+vector:
+ ldr pc, reset_handler
+ ldr pc, undefined_handler
+ ldr pc, swi_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 io_halt
+swi_handler: .word io_halt
+prefetch_handler: .word io_halt
+data_handler: .word io_halt
+unused_handler: .word io_halt
+irq_handler: .word irq
+fiq_handler: .word io_halt
+
+.global a_irq_handler
+a_irq_handler:
+ push {lr}
+ bl disable_irq
+ // r2 = CORE0_INTERRUPT_SOURCE
+ // if r2 & 0b100000000
+ mov r2, #0x40000000
+ ldr r3, [r2, #0x60]
+ tst r3, #256
+ beq a_irq_handler.exit
+ // r2 = IRQ_PEND2
+ // r2 & 1 << 25
+ mov r2, #0xB208
+ movt r2, #0x3F00
+ ldr r3, [r2]
+ tst r3, #0x2000000
+ beq a_irq_handler.exit
+ mov r2, #0x1040
+ movt r2, #0x3F20
+ ldr r3, [r2]
+ tst r3, #16
+ beq a_irq_handler.exit
+ mov r2, #0x1000
+ movt r2, #0x3F20
+ ldrb r0, [r2]
+ push {r0}
+ bl enable_irq
+ pop {r0}
+ bl uart_char
+ ldr r0, =amsg
+ bl uart_string
+ pop {pc}
+a_irq_handler.exit:
+ bl enable_irq
+ pop {pc}
+
+.section ".data"
+amsg:
+ .asciz " a_irq_handler\n"
diff --git a/src/irq.S b/src/irq.S
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/irq.S
diff --git a/src/kernel.S b/src/kernel.S
new file mode 100644
index 0000000..02894a6
--- /dev/null
+++ b/src/kernel.S
@@ -0,0 +1,24 @@
+.section ".text.kernel"
+
+.globl kernel_main
+kernel_main:
+ push {lr}
+ bl uart_init
+ bl enable_irq
+ ldr r0, =os_info
+ bl uart_string
+ mov r0, #0x00
+kernel_main.a:
+ cmp r0, #0x100
+ beq kernel_main.loop
+ bl uart_char
+ add r0, #1
+ b kernel_main.a
+kernel_main.loop:
+ bl io_halt
+ b kernel_main.loop
+ pop {lr}
+
+.section ".data"
+os_info:
+ .asciz "Sergey Bilovytskyy's Real Time Operating System\n Version 0.0a\n Interrupt 01: uart rx interrupt\n Exit : Ctrl-A x\n Monitor : Ctrl-A c\n\n"
diff --git a/src/uart.S b/src/uart.S
new file mode 100644
index 0000000..bd98bac
--- /dev/null
+++ b/src/uart.S
@@ -0,0 +1,46 @@
+.section ".text"
+
+.globl uart_init
+uart_init:
+ //*UART0_IMSC = 1 << 4;
+ mov r2, #0x1038
+ movt r2, #0x3F20
+ mov r3, #0b10000
+ str r3, [r2]
+ //*IRQ_ENABLE2 = 1 << 25;
+ mov r2, #0xB214
+ movt r2, #0x3F00
+ mov r3, #0
+ movt r3, #0b1000000000
+ str r3, [r2]
+ //*GPU_INTERRUPTS_ROUTING = 0x00;
+ mov r2, #0x000C
+ movt r2, #0x4000
+ eor r3, r3
+ str r3, [r2]
+ bx lr
+
+.globl uart_char
+uart_char:
+ mov r2, #0x1000
+ movt r2, #0x3f20
+uart_char.loop:
+ ldr r3, [r2, #24]
+ tst r3, #0b100000
+ bne uart_char.loop
+ 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}
+uart_string.loop:
+ bl uart_char
+ ldrb r0, [r4, #1]!
+ cmp r0, #0
+ bne uart_string.loop
+ pop {r4, pc}