Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / u-boot / arch / arm / cpu / arm1136 / start.S
diff --git a/qemu/roms/u-boot/arch/arm/cpu/arm1136/start.S b/qemu/roms/u-boot/arch/arm/cpu/arm1136/start.S
new file mode 100644 (file)
index 0000000..3e2358e
--- /dev/null
@@ -0,0 +1,346 @@
+/*
+ *  armboot - Startup Code for OMP2420/ARM1136 CPU-core
+ *
+ *  Copyright (c) 2004 Texas Instruments <r-woodruff2@ti.com>
+ *
+ *  Copyright (c) 2001 Marius Gröger <mag@sysgo.de>
+ *  Copyright (c) 2002 Alex Züpke <azu@sysgo.de>
+ *  Copyright (c) 2002 Gary Jennejohn <garyj@denx.de>
+ *  Copyright (c) 2003 Richard Woodruff <r-woodruff2@ti.com>
+ *  Copyright (c) 2003 Kshitij <kshitij@ti.com>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <asm-offsets.h>
+#include <config.h>
+#include <version.h>
+.globl _start
+_start: b      reset
+#ifdef CONFIG_SPL_BUILD
+       ldr     pc, _hang
+       ldr     pc, _hang
+       ldr     pc, _hang
+       ldr     pc, _hang
+       ldr     pc, _hang
+       ldr     pc, _hang
+       ldr     pc, _hang
+
+_hang:
+       .word   do_hang
+       .word   0x12345678
+       .word   0x12345678
+       .word   0x12345678
+       .word   0x12345678
+       .word   0x12345678
+       .word   0x12345678
+       .word   0x12345678      /* now 16*4=64 */
+#else
+       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
+_pad:                  .word 0x12345678 /* now 16*4=64 */
+#endif /* CONFIG_SPL_BUILD */
+.global _end_vect
+_end_vect:
+
+       .balignl 16,0xdeadbeef
+/*
+ *************************************************************************
+ *
+ * Startup Code (reset vector)
+ *
+ * do important init only if we don't start from memory!
+ * setup Memory and board specific bits prior to relocation.
+ * relocate armboot to ram
+ * setup stack
+ *
+ *************************************************************************
+ */
+
+#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
+
+       /* the mask ROM code should have PLL and others stable */
+#ifndef CONFIG_SKIP_LOWLEVEL_INIT
+       bl  cpu_init_crit
+#endif
+
+       bl      _main
+
+/*------------------------------------------------------------------------------*/
+
+       .globl  c_runtime_cpu_setup
+c_runtime_cpu_setup:
+
+       bx      lr
+
+/*
+ *************************************************************************
+ *
+ * CPU_init_critical registers
+ *
+ * setup important registers
+ * setup memory timing
+ *
+ *************************************************************************
+ */
+#ifndef CONFIG_SKIP_LOWLEVEL_INIT
+cpu_init_crit:
+       /*
+        * flush v4 I/D caches
+        */
+       mov     r0, #0
+       mcr     p15, 0, r0, c7, c7, 0   /* Invalidate I+D+BTB caches */
+       mcr     p15, 0, r0, c8, c7, 0   /* Invalidate Unified TLB */
+
+       /*
+        * disable MMU stuff and caches
+        */
+       mrc     p15, 0, r0, c1, c0, 0
+       bic     r0, r0, #0x00002300     @ clear bits 13, 9:8 (--V- --RS)
+       bic     r0, r0, #0x00000087     @ clear bits 7, 2:0 (B--- -CAM)
+       orr     r0, r0, #0x00000002     @ set bit 2 (A) Align
+       orr     r0, r0, #0x00001000     @ set bit 12 (I) I-Cache
+       mcr     p15, 0, r0, c1, c0, 0
+
+       /*
+        * Jump to board specific initialization... The Mask ROM will have already initialized
+        * basic memory.  Go here to bump up clock rate and handle wake up conditions.
+        */
+       mov     ip, lr          /* persevere link reg across call */
+       bl      lowlevel_init   /* go setup pll,mux,memory */
+       mov     lr, ip          /* restore link */
+       mov     pc, lr          /* back to my caller */
+#endif /* CONFIG_SKIP_LOWLEVEL_INIT */
+
+#ifndef CONFIG_SPL_BUILD
+/*
+ *************************************************************************
+ *
+ * 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           @ carve out a frame on current user stack
+       stmia   sp, {r0 - r12}                  @ Save user registers (now in svc mode) r0-r12
+
+       ldr     r2, IRQ_STACK_START_IN          @ set base 2 words into abort stack
+       ldmia   r2, {r2 - r3}                   @ get values for "aborted" pc and cpsr (into parm regs)
+       add     r0, sp, #S_FRAME_SIZE           @ grab pointer to old stack
+
+       add     r5, sp, #S_SP
+       mov     r1, lr
+       stmia   r5, {r0 - r3}                   @ save sp_SVC, lr_SVC, pc, cpsr
+       mov     r0, sp                          @ save current stack into r0 (param register)
+       .endm
+
+       .macro  irq_save_user_regs
+       sub     sp, sp, #S_FRAME_SIZE
+       stmia   sp, {r0 - r12}                  @ Calling r0-r12
+       add     r8, sp, #S_PC                   @ !!!! R8 NEEDS to be saved !!!! a reserved stack spot would be good.
+       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 (enter in banked mode)
+
+       str     lr, [r13]                       @ save caller lr in position 0 of saved stack
+       mrs     lr, spsr                        @ get the spsr
+       str     lr, [r13, #4]                   @ save spsr in position 1 of saved stack
+
+       mov     r13, #MODE_SVC                  @ prepare SVC-Mode
+       @ msr   spsr_c, r13
+       msr     spsr, r13                       @ switch modes, make sure moves will execute
+       mov     lr, pc                          @ capture return pc
+       movs    pc, lr                          @ jump to next instruction & switch modes.
+       .endm
+
+       .macro get_bad_stack_swi
+       sub     r13, r13, #4                    @ space on current stack for scratch reg.
+       str     r0, [r13]                       @ save R0's value.
+       ldr     r0, IRQ_STACK_START_IN          @ get data regions start
+       str     lr, [r0]                        @ save caller lr in position 0 of saved stack
+       mrs     lr, spsr                        @ get the spsr
+       str     lr, [r0, #4]                    @ save spsr in position 1 of saved stack
+       ldr     lr, [r0]                        @ restore lr
+       ldr     r0, [r13]                       @ restore r0
+       add     r13, r13, #4                    @ pop stack entry
+       .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
+#endif /* CONFIG_SPL_BUILD */
+
+/*
+ * exception handlers
+ */
+#ifdef CONFIG_SPL_BUILD
+       .align  5
+do_hang:
+       bl      hang                            /* hang and never return */
+#else  /* !CONFIG_SPL_BUILD */
+       .align  5
+undefined_instruction:
+       get_bad_stack
+       bad_save_user_regs
+       bl      do_undefined_instruction
+
+       .align  5
+software_interrupt:
+       get_bad_stack_swi
+       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
+.global arm1136_cache_flush
+arm1136_cache_flush:
+#if !defined(CONFIG_SYS_ICACHE_OFF)
+               mcr     p15, 0, r1, c7, c5, 0   @ invalidate I cache
+#endif
+#if !defined(CONFIG_SYS_DCACHE_OFF)
+               mcr     p15, 0, r1, c7, c14, 0  @ invalidate D cache
+#endif
+               mov     pc, lr                  @ back to caller
+#endif /* CONFIG_SPL_BUILD */