Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / u-boot / arch / arm / cpu / sa1100 / start.S
diff --git a/qemu/roms/u-boot/arch/arm/cpu/sa1100/start.S b/qemu/roms/u-boot/arch/arm/cpu/sa1100/start.S
new file mode 100644 (file)
index 0000000..bf80937
--- /dev/null
@@ -0,0 +1,349 @@
+/*
+ *  armboot - Startup Code for SA1100 CPU
+ *
+ *  Copyright (C) 1998 Dan Malek <dmalek@jlc.net>
+ *  Copyright (C) 1999 Magnus Damm <kieraypc01.p.y.kie.era.ericsson.se>
+ *  Copyright (C) 2000 Wolfgang Denk <wd@denx.de>
+ *  Copyright (c) 2001 Alex Züpke <azu@sysgo.de>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <asm-offsets.h>
+#include <config.h>
+#include <version.h>
+
+/*
+ *************************************************************************
+ *
+ * Jump vector table as in table 3.1 in [1]
+ *
+ *************************************************************************
+ */
+
+
+.globl _start
+_start:        b       reset
+       ldr     pc, _undefined_instruction
+       ldr     pc, _software_interrupt
+       ldr     pc, _prefetch_abort
+       ldr     pc, _data_abort
+       ldr     pc, _not_used
+       ldr     pc, _irq
+       ldr     pc, _fiq
+
+_undefined_instruction:        .word undefined_instruction
+_software_interrupt:   .word software_interrupt
+_prefetch_abort:       .word prefetch_abort
+_data_abort:           .word data_abort
+_not_used:             .word not_used
+_irq:                  .word irq
+_fiq:                  .word fiq
+
+       .balignl 16,0xdeadbeef
+
+
+/*
+ *************************************************************************
+ *
+ * Startup Code (reset vector)
+ *
+ * do important init only if we don't start from memory!
+ * relocate armboot to ram
+ * setup stack
+ * jump to second stage
+ *
+ *************************************************************************
+ */
+
+#ifdef CONFIG_USE_IRQ
+/* IRQ stack memory (calculated at run-time) */
+.globl IRQ_STACK_START
+IRQ_STACK_START:
+       .word   0x0badc0de
+
+/* IRQ stack memory (calculated at run-time) */
+.globl FIQ_STACK_START
+FIQ_STACK_START:
+       .word 0x0badc0de
+#endif
+
+/* IRQ stack memory (calculated at run-time) + 8 bytes */
+.globl IRQ_STACK_START_IN
+IRQ_STACK_START_IN:
+       .word   0x0badc0de
+
+/*
+ * the actual reset code
+ */
+
+reset:
+       /*
+        * set the cpu to SVC32 mode
+        */
+       mrs     r0,cpsr
+       bic     r0,r0,#0x1f
+       orr     r0,r0,#0xd3
+       msr     cpsr,r0
+
+       /*
+        * we do sys-critical inits only at reboot,
+        * not when booting from ram!
+        */
+#ifndef CONFIG_SKIP_LOWLEVEL_INIT
+       bl      cpu_init_crit
+#endif
+
+       bl      _main
+
+/*------------------------------------------------------------------------------*/
+
+       .globl  c_runtime_cpu_setup
+c_runtime_cpu_setup:
+
+       mov     pc, lr
+
+/*
+ *************************************************************************
+ *
+ * CPU_init_critical registers
+ *
+ * setup important registers
+ * setup memory timing
+ *
+ *************************************************************************
+ */
+
+
+/* Interrupt-Controller base address */
+IC_BASE:       .word   0x90050000
+#define ICMR   0x04
+
+
+/* Reset-Controller */
+RST_BASE:              .word   0x90030000
+#define RSRR   0x00
+#define RCSR   0x04
+
+
+/* PWR */
+PWR_BASE:              .word   0x90020000
+#define PSPR    0x08
+#define PPCR    0x14
+cpuspeed:              .word   CONFIG_SYS_CPUSPEED
+
+
+cpu_init_crit:
+       /*
+        * mask all IRQs
+        */
+       ldr     r0, IC_BASE
+       mov     r1, #0x00
+       str     r1, [r0, #ICMR]
+
+       /* set clock speed */
+       ldr     r0, PWR_BASE
+       ldr     r1, cpuspeed
+       str     r1, [r0, #PPCR]
+
+       /*
+        * before relocating, we have to setup RAM timing
+        * because memory timing is board-dependend, you will
+        * find a lowlevel_init.S in your board directory.
+        */
+       mov     ip,     lr
+       bl      lowlevel_init
+       mov     lr,     ip
+
+       /*
+        * disable MMU stuff and enable I-cache
+        */
+       mrc     p15,0,r0,c1,c0
+       bic     r0, r0, #0x00002000     @ clear bit 13 (X)
+       bic     r0, r0, #0x0000000f     @ clear bits 3-0 (WCAM)
+       orr     r0, r0, #0x00001000     @ set bit 12 (I) Icache
+       orr     r0, r0, #0x00000002     @ set bit 2 (A) Align
+       mcr     p15,0,r0,c1,c0
+
+       /*
+        * flush v4 I/D caches
+        */
+       mov     r0, #0
+       mcr     p15, 0, r0, c7, c7, 0   /* flush v3/v4 cache */
+       mcr     p15, 0, r0, c8, c7, 0   /* flush v4 TLB */
+
+       mov     pc, lr
+
+
+/*
+ *************************************************************************
+ *
+ * Interrupt handling
+ *
+ *************************************************************************
+ */
+
+@
+@ IRQ stack frame.
+@
+#define S_FRAME_SIZE   72
+
+#define S_OLD_R0       68
+#define S_PSR          64
+#define S_PC           60
+#define S_LR           56
+#define S_SP           52
+
+#define S_IP           48
+#define S_FP           44
+#define S_R10          40
+#define S_R9           36
+#define S_R8           32
+#define S_R7           28
+#define S_R6           24
+#define S_R5           20
+#define S_R4           16
+#define S_R3           12
+#define S_R2           8
+#define S_R1           4
+#define S_R0           0
+
+#define MODE_SVC 0x13
+#define I_BIT   0x80
+
+/*
+ * use bad_save_user_regs for abort/prefetch/undef/swi ...
+ * use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling
+ */
+
+       .macro  bad_save_user_regs
+       sub     sp, sp, #S_FRAME_SIZE
+       stmia   sp, {r0 - r12}                  @ Calling r0-r12
+       add     r8, sp, #S_PC
+
+       ldr     r2, IRQ_STACK_START_IN
+       ldmia   r2, {r2 - r4}                   @ get pc, cpsr, old_r0
+       add     r0, sp, #S_FRAME_SIZE           @ restore sp_SVC
+
+       add     r5, sp, #S_SP
+       mov     r1, lr
+       stmia   r5, {r0 - r4}                   @ save sp_SVC, lr_SVC, pc, cpsr, old_r
+       mov     r0, sp
+       .endm
+
+       .macro  irq_save_user_regs
+       sub     sp, sp, #S_FRAME_SIZE
+       stmia   sp, {r0 - r12}                  @ Calling r0-r12
+       add     r8, sp, #S_PC
+       stmdb   r8, {sp, lr}^                   @ Calling SP, LR
+       str     lr, [r8, #0]                    @ Save calling PC
+       mrs     r6, spsr
+       str     r6, [r8, #4]                    @ Save CPSR
+       str     r0, [r8, #8]                    @ Save OLD_R0
+       mov     r0, sp
+       .endm
+
+       .macro  irq_restore_user_regs
+       ldmia   sp, {r0 - lr}^                  @ Calling r0 - lr
+       mov     r0, r0
+       ldr     lr, [sp, #S_PC]                 @ Get PC
+       add     sp, sp, #S_FRAME_SIZE
+       subs    pc, lr, #4                      @ return & move spsr_svc into cpsr
+       .endm
+
+       .macro get_bad_stack
+       ldr     r13, IRQ_STACK_START_IN         @ setup our mode stack
+
+       str     lr, [r13]                       @ save caller lr / spsr
+       mrs     lr, spsr
+       str     lr, [r13, #4]
+
+       mov     r13, #MODE_SVC                  @ prepare SVC-Mode
+       msr     spsr_c, r13
+       mov     lr, pc
+       movs    pc, lr
+       .endm
+
+       .macro get_irq_stack                    @ setup IRQ stack
+       ldr     sp, IRQ_STACK_START
+       .endm
+
+       .macro get_fiq_stack                    @ setup FIQ stack
+       ldr     sp, FIQ_STACK_START
+       .endm
+
+/*
+ * exception handlers
+ */
+       .align  5
+undefined_instruction:
+       get_bad_stack
+       bad_save_user_regs
+       bl      do_undefined_instruction
+
+       .align  5
+software_interrupt:
+       get_bad_stack
+       bad_save_user_regs
+       bl      do_software_interrupt
+
+       .align  5
+prefetch_abort:
+       get_bad_stack
+       bad_save_user_regs
+       bl      do_prefetch_abort
+
+       .align  5
+data_abort:
+       get_bad_stack
+       bad_save_user_regs
+       bl      do_data_abort
+
+       .align  5
+not_used:
+       get_bad_stack
+       bad_save_user_regs
+       bl      do_not_used
+
+#ifdef CONFIG_USE_IRQ
+
+       .align  5
+irq:
+       get_irq_stack
+       irq_save_user_regs
+       bl      do_irq
+       irq_restore_user_regs
+
+       .align  5
+fiq:
+       get_fiq_stack
+       /* someone ought to write a more effiction fiq_save_user_regs */
+       irq_save_user_regs
+       bl      do_fiq
+       irq_restore_user_regs
+
+#else
+
+       .align  5
+irq:
+       get_bad_stack
+       bad_save_user_regs
+       bl      do_irq
+
+       .align  5
+fiq:
+       get_bad_stack
+       bad_save_user_regs
+       bl      do_fiq
+
+#endif
+
+       .align  5
+.globl reset_cpu
+reset_cpu:
+       ldr     r0, RST_BASE
+       mov     r1, #0x0                        @ set bit 3-0 ...
+       str     r1, [r0, #RCSR]                 @ ... to clear in RCSR
+       mov     r1, #0x1
+       str     r1, [r0, #RSRR]                 @ and perform reset
+       b       reset_cpu                       @ silly, but repeat endlessly