diff options
Diffstat (limited to 'src/target/firmware/board/common/compal_ramload_start.S')
-rw-r--r-- | src/target/firmware/board/common/compal_ramload_start.S | 257 |
1 files changed, 257 insertions, 0 deletions
diff --git a/src/target/firmware/board/common/compal_ramload_start.S b/src/target/firmware/board/common/compal_ramload_start.S new file mode 100644 index 00000000..4f6fadef --- /dev/null +++ b/src/target/firmware/board/common/compal_ramload_start.S @@ -0,0 +1,257 @@ + +#define BA_UART_MODEM 0xFFFF5800 + +# + +.macro senduart, rd, rx + strb \rd, [\rx, #0] +.endm + +.macro busyuart, rd, rx +1001: + @busy waiting until THR is empty + ldrb \rd, [\rx, #5] @ read LSR register + mov \rd, \rd, lsr #6 + tst \rd, #1 + beq 1001b +.endm + +.macro loadsp, rd + ldr \rd, =BA_UART_MODEM +.endm + + + .EQU ARM_MODE_FIQ, 0x11 + .EQU ARM_MODE_IRQ, 0x12 + .EQU ARM_MODE_SVC, 0x13 + + .EQU I_BIT, 0x80 + .EQU F_BIT, 0x40 + +#define TOP_OF_RAM 0x083fff0 +#define FIQ_STACK_SIZE 1024 +#define IRQ_STACK_SIZE 1024 + +.section .text._start +.globl _start +_start: + @ clear bss section + .global __bss_start + .global __bss_end + mov r0, #0 + ldr r1, =__bss_start + ldr r2, =__bss_end +2: cmp r1, r2 + strlo r0, [r1], #4 + blo 2b + + ldr r0, =TOP_OF_RAM + /* initialize FIQ stack */ + msr CPSR_c, #ARM_MODE_FIQ | I_BIT | F_BIT + mov r13, r0 + sub r0, r0, #FIQ_STACK_SIZE + + /* initialize IRQ stack */ + msr CPSR_c, #ARM_MODE_IRQ | I_BIT | F_BIT + mov r13, r0 + sub r0, r0, #IRQ_STACK_SIZE + + /* initialize supervisor stack */ + msr CPSR_c, #ARM_MODE_SVC | I_BIT | F_BIT + mov r13, r0 + + @ set backlight to moderate level + bl pwl_init + mov r0, #50 + bl pwl_set_level + + @ldr r0, =string + @bl puts_asm + + @ some memory dumps + @ldr r0, =0xfffef000 + @bl memdump + @ldr r0, =0xfffffe00 + @bl memdump + + ldr pc, _jump_main + + @ endless loop at end of program +_end: b _end + b _start + +_jump_main: .word main + +string: .word 0x6c6c6548 + .word 0x6f57206f + .word 0x00646c72 + +foo: .word 0xee4c9f63 +bar: .word 0x639f4cee + + .align 2 + .type phexbuf, #object +phexbuf: .space 12 + .size phexubf, . - phexbuf + +.globl phex +phex: adr r3, phexbuf + mov r2, #0 + strb r2, [r3, r1] +1: subs r1, r1, #1 + movmi r0, r3 + bmi puts_asm + and r2, r0, #15 + mov r0, r0, lsr #4 + cmp r2, #10 + addge r2, r2, #7 + add r2, r2, #'0' + strb r2, [r3, r1] + b 1b + +puts_asm: loadsp r3 +1: ldrb r2, [r0], #1 + teq r2, #0 + moveq pc, lr +2: senduart r2, r3 + busyuart r1, r3 + teq r2, #'\n' + moveq r2, #'\r' + beq 2b + teq r0, #0 + bne 1b + mov pc, lr +.globl putchar_asm +putchar_asm: + mov r2, r0 + mov r0, #0 + loadsp r3 + b 2b + +memdump: mov r12, r0 + mov r10, lr + mov r11, #0 +2: mov r0, r11, lsl #2 + add r0, r0, r12 + mov r1, #8 + bl phex + mov r0, #':' + bl putchar_asm +1: mov r0, #' ' + bl putchar_asm + ldr r0, [r12, r11, lsl #2] + mov r1, #8 + bl phex + and r0, r11, #7 + teq r0, #3 + moveq r0, #' ' + bleq putchar_asm + and r0, r11, #7 + add r11, r11, #1 + teq r0, #7 + bne 1b + mov r0, #'\n' + bl putchar_asm + cmp r11, #64 + blt 2b + mov pc, r10 + + +#define ASIC_CONF_REG 0xfffef008 +#define BA_PWL 0xfffe8000 + +pwl_init: ldr r1, =ASIC_CONF_REG + ldr r2, [r1] + orr r2, r2, #0x10 @ set light output to PWL + str r2, [r1] + ldr r1, =BA_PWL + mov r0, #1 + strb r0, [r1, #1] @ enable clock of PWL unut + mov pc, lr + +pwl_set_level: ldr r1, =BA_PWL + strb r0, [r1] + mov pc, lr + +handle_abort: + @ print the PC we would jump back to... + sub lr, lr, #4 @ we assume to be ARM32 + + mov r0, lr + mov r1, #8 + bl phex + + @ print abort message + mov r0, #'A' + bl putchar_asm + mov r0, #'B' + bl putchar_asm + mov r0, #'O' + bl putchar_asm + mov r0, #'R' + bl putchar_asm + mov r0, #'T' + bl putchar_asm +0: @ dead + b 0b + +irq_entry: + /* Adjust and save LR_irq in IRQ stack */ + sub lr, lr, #4 + stmfd sp!, {lr} + + /* Save SPSR for nested interrupt */ + mrs r14, SPSR + stmfd sp!, {r14} + + /* Call the interrupt handler C function */ + stmfd sp!, {r0-r4, r12} + bl irq + ldmfd sp!, {r0-r4, r12} + + /* Restore SPSR_irq from IRQ stack */ + ldmia sp!, {r14} + msr SPSR_cxsf, r14 + + /* Restore adjusted LR_irq from IRQ stack directly in the PC */ + ldmia sp!, {pc}^ + +fiq_entry: + /* Adjust and save LR_irq in IRQ stack */ + sub lr, lr, #4 + stmfd sp!, {lr} + + /* Save SPSR for nested interrupt */ + mrs r14, SPSR + stmfd sp!, {r14} + + /* Call the interrupt handler C function */ + stmfd sp!, {r0-r4, r12} + bl fiq + ldmfd sp!, {r0-r4, r12} + + /* Restore SPSR_irq from IRQ stack */ + ldmia sp!, {r14} + msr SPSR_cxsf, r14 + + /* Restore adjusted LR_irq from IRQ stack directly in the PC */ + ldmia sp!, {pc}^ + +/* Exception Vectors like they are needed for the exception vector + indirection of the internal boot ROM. The following section must be liked + to appear at 0x80'001c */ +.section .text.exceptions +_undef_instr: + b handle_abort +_sw_interr: + b _sw_interr +_prefetch_abort: + b handle_abort +_data_abort: + b handle_abort +_reserved: + b _reserved +_irq: + b irq_entry +_fiq: + b fiq_entry |