*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
*/
-
#include <config.h>
#include <version.h>
-
+#include <asm/hardware.h>
/*
*************************************************************************
.globl _start
-_start: b reset
+_start: b reset
ldr pc, _undefined_instruction
ldr pc, _software_interrupt
ldr pc, _prefetch_abort
ldr pc, _data_abort
+#ifdef CONFIG_LPC2292
+ .word 0xB4405F76 /* 2's complement of the checksum of the vectors */
+#else
ldr pc, _not_used
+#endif
ldr pc, _irq
ldr pc, _fiq
-_undefined_instruction: .word undefined_instruction
+_undefined_instruction: .word undefined_instruction
_software_interrupt: .word software_interrupt
_prefetch_abort: .word prefetch_abort
_data_abort: .word data_abort
*
* Startup Code (reset vector)
*
- * do important init only if we don't start from memory!
+ * do important init only if we don't start from RAM!
* relocate armboot to ram
* setup stack
* jump to second stage
*************************************************************************
*/
-/*
- * CFG_MEM_END is in the board dependent config-file (configs/config_BOARD.h)
- */
_TEXT_BASE:
.word TEXT_BASE
.word _start
/*
- * Note: _armboot_end_data and _armboot_end are defined
- * by the (board-dependent) linker script.
- * _armboot_end_data is the first usable FLASH address after armboot
+ * These are defined in the board-specific linker script.
*/
-.globl _armboot_end_data
-_armboot_end_data:
- .word armboot_end_data
-.globl _armboot_end
-_armboot_end:
- .word armboot_end
+.globl _bss_start
+_bss_start:
+ .word __bss_start
-/*
- * _armboot_real_end is the first usable RAM address behind armboot
- * and the various stacks
- */
-.globl _armboot_real_end
-_armboot_real_end:
- .word 0x0badc0de
+.globl _bss_end
+_bss_end:
+ .word _end
#ifdef CONFIG_USE_IRQ
/* IRQ stack memory (calculated at run-time) */
* we do sys-critical inits only at reboot,
* not when booting from ram!
*/
-#ifdef CONFIG_INIT_CRITICAL
+#ifndef CONFIG_SKIP_LOWLEVEL_INIT
bl cpu_init_crit
#endif
-relocate:
- /*
- * relocate armboot to RAM
- */
- adr r0, _start /* r0 <- current position of code */
+#ifdef CONFIG_LPC2292
+ bl lowlevel_init
+#endif
+
+#ifndef CONFIG_SKIP_RELOCATE_UBOOT
+relocate: /* relocate U-Boot to RAM */
+ adr r0, _start /* r0 <- current position of code */
+ ldr r1, _TEXT_BASE /* test if we run from flash or RAM */
+ cmp r0, r1 /* don't reloc during debug */
+ beq stack_setup
+
+#if TEXT_BASE
+#ifndef CONFIG_LPC2292 /* already done in lowlevel_init */
+ ldr r2, =0x0 /* Relocate the exception vectors */
+ cmp r1, r2 /* and associated data to address */
+ ldmneia r0!, {r3-r10} /* 0x0. Do nothing if TEXT_BASE is */
+ stmneia r2!, {r3-r10} /* 0x0. Copy the first 15 words. */
+ ldmneia r0, {r3-r9}
+ stmneia r2, {r3-r9}
+ adrne r0, _start /* restore r0 */
+#endif /* !CONFIG_LPC2292 */
+#endif
+
ldr r2, _armboot_start
- ldr r3, _armboot_end
- sub r2, r3, r2 /* r2 <- size of armboot */
- ldr r1, _TEXT_BASE /* r1 <- destination address */
- add r2, r0, r2 /* r2 <- source end address */
+ ldr r3, _bss_start
+ sub r2, r3, r2 /* r2 <- size of armboot */
+ add r2, r0, r2 /* r2 <- source end address */
- /*
- * r0 = source address
- * r1 = target address
- * r2 = source end address
- */
copy_loop:
- ldmia r0!, {r3-r10}
- stmia r1!, {r3-r10}
- cmp r0, r2
+ ldmia r0!, {r3-r10} /* copy from source address [r0] */
+ stmia r1!, {r3-r10} /* copy to target address [r1] */
+ cmp r0, r2 /* until source end addreee [r2] */
ble copy_loop
- /* set up the stack */
- ldr r0, _armboot_end
- add r0, r0, #CONFIG_STACKSIZE
- sub sp, r0, #12 /* leave 3 words for abort-stack */
+#endif /* CONFIG_SKIP_RELOCATE_UBOOT */
- ldr pc, _start_armboot
+ /* Set up the stack */
+stack_setup:
+ ldr r0, _TEXT_BASE /* upper 128 KiB: relocated uboot */
+ sub r0, r0, #CONFIG_SYS_MALLOC_LEN /* malloc area */
+ sub r0, r0, #CONFIG_SYS_GBL_DATA_SIZE /* bdinfo */
+#ifdef CONFIG_USE_IRQ
+ sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)
+#endif
+ sub sp, r0, #12 /* leave 3 words for abort-stack */
-_start_armboot: .word start_armboot
+clear_bss:
+ ldr r0, _bss_start /* find start of bss segment */
+ ldr r1, _bss_end /* stop here */
+ mov r2, #0x00000000 /* clear */
+clbss_l:str r2, [r0] /* clear loop... */
+ add r0, r0, #4
+ cmp r0, r1
+ ble clbss_l
+
+ ldr pc, _start_armboot
+
+_start_armboot: .word start_armboot
/*
*************************************************************************
*************************************************************************
*/
+#if defined(CONFIG_IMPA7) || defined(CONFIG_EP7312) || defined(CONFIG_ARMADILLO)
/* Interupt-Controller base addresses */
INTMR1: .word 0x80000280 @ 32 bit size
#define CLKCTL_49 0x4 /* 49.152 MHz */
#define CLKCTL_73 0x6 /* 73.728 MHz */
+#elif defined(CONFIG_LPC2292)
+PLLCFG_ADR: .word PLLCFG
+PLLFEED_ADR: .word PLLFEED
+PLLCON_ADR: .word PLLCON
+PLLSTAT_ADR: .word PLLSTAT
+VPBDIV_ADR: .word VPBDIV
+MEMMAP_ADR: .word MEMMAP
+
+#endif
+
cpu_init_crit:
+#if defined(CONFIG_IMPA7) || defined(CONFIG_EP7312) || defined(CONFIG_ARMADILLO)
+
/*
* mask all IRQs by clearing all bits in the INTMRs
*/
bic r0, r0, #0x0000008f @ clear bits 7, 3:0 (B--- WCAM)
orr r0, r0, #0x00000002 @ set bit 2 (A) Align
mcr p15,0,r0,c1,c0
+#elif defined(CONFIG_NETARM)
+ /*
+ * prior to software reset : need to set pin PORTC4 to be *HRESET
+ */
+ ldr r0, =NETARM_GEN_MODULE_BASE
+ ldr r1, =(NETARM_GEN_PORT_MODE(0x10) | \
+ NETARM_GEN_PORT_DIR(0x10))
+ str r1, [r0, #+NETARM_GEN_PORTC]
+ /*
+ * software reset : see HW Ref. Guide 8.2.4 : Software Service register
+ * for an explanation of this process
+ */
+ ldr r0, =NETARM_GEN_MODULE_BASE
+ ldr r1, =NETARM_GEN_SW_SVC_RESETA
+ str r1, [r0, #+NETARM_GEN_SOFTWARE_SERVICE]
+ ldr r1, =NETARM_GEN_SW_SVC_RESETB
+ str r1, [r0, #+NETARM_GEN_SOFTWARE_SERVICE]
+ ldr r1, =NETARM_GEN_SW_SVC_RESETA
+ str r1, [r0, #+NETARM_GEN_SOFTWARE_SERVICE]
+ ldr r1, =NETARM_GEN_SW_SVC_RESETB
+ str r1, [r0, #+NETARM_GEN_SOFTWARE_SERVICE]
+ /*
+ * setup PLL and System Config
+ */
+ ldr r0, =NETARM_GEN_MODULE_BASE
+
+ ldr r1, =( NETARM_GEN_SYS_CFG_LENDIAN | \
+ NETARM_GEN_SYS_CFG_BUSFULL | \
+ NETARM_GEN_SYS_CFG_USER_EN | \
+ NETARM_GEN_SYS_CFG_ALIGN_ABORT | \
+ NETARM_GEN_SYS_CFG_BUSARB_INT | \
+ NETARM_GEN_SYS_CFG_BUSMON_EN )
+
+ str r1, [r0, #+NETARM_GEN_SYSTEM_CONTROL]
+
+#ifndef CONFIG_NETARM_PLL_BYPASS
+ ldr r1, =( NETARM_GEN_PLL_CTL_PLLCNT(NETARM_PLL_COUNT_VAL) | \
+ NETARM_GEN_PLL_CTL_POLTST_DEF | \
+ NETARM_GEN_PLL_CTL_INDIV(1) | \
+ NETARM_GEN_PLL_CTL_ICP_DEF | \
+ NETARM_GEN_PLL_CTL_OUTDIV(2) )
+ str r1, [r0, #+NETARM_GEN_PLL_CONTROL]
+#endif
+
+ /*
+ * mask all IRQs by clearing all bits in the INTMRs
+ */
+ mov r1, #0
+ ldr r0, =NETARM_GEN_MODULE_BASE
+ str r1, [r0, #+NETARM_GEN_INTR_ENABLE]
+
+#elif defined(CONFIG_S3C4510B)
+
+ /*
+ * Mask off all IRQ sources
+ */
+ ldr r1, =REG_INTMASK
+ ldr r0, =0x3FFFFF
+ str r0, [r1]
+
+ /*
+ * Disable Cache
+ */
+ ldr r0, =REG_SYSCFG
+ ldr r1, =0x83ffffa0 /* cache-disabled */
+ str r1, [r0]
+
+#elif defined(CONFIG_INTEGRATOR) && defined(CONFIG_ARCH_INTEGRATOR)
+ /* No specific initialisation for IntegratorAP/CM720T as yet */
+#elif defined(CONFIG_LPC2292)
+ /* Set-up PLL */
+ mov r3, #0xAA
+ mov r4, #0x55
+ /* First disconnect and disable the PLL */
+ ldr r0, PLLCON_ADR
+ mov r1, #0x00
+ str r1, [r0]
+ ldr r0, PLLFEED_ADR /* start feed sequence */
+ str r3, [r0]
+ str r4, [r0] /* feed sequence done */
+ /* Set new M and P values */
+ ldr r0, PLLCFG_ADR
+ mov r1, #0x23 /* M=4 and P=2 */
+ str r1, [r0]
+ ldr r0, PLLFEED_ADR /* start feed sequence */
+ str r3, [r0]
+ str r4, [r0] /* feed sequence done */
+ /* Then enable the PLL */
+ ldr r0, PLLCON_ADR
+ mov r1, #0x01 /* PLL enable bit */
+ str r1, [r0]
+ ldr r0, PLLFEED_ADR /* start feed sequence */
+ str r3, [r0]
+ str r4, [r0] /* feed sequence done */
+ /* Wait for the lock */
+ ldr r0, PLLSTAT_ADR
+ mov r1, #0x400 /* lock bit */
+lock_loop:
+ ldr r2, [r0]
+ and r2, r1, r2
+ cmp r2, #0
+ beq lock_loop
+ /* And finally connect the PLL */
+ ldr r0, PLLCON_ADR
+ mov r1, #0x03 /* PLL enable bit and connect bit */
+ str r1, [r0]
+ ldr r0, PLLFEED_ADR /* start feed sequence */
+ str r3, [r0]
+ str r4, [r0] /* feed sequence done */
+ /* Set-up VPBDIV register */
+ ldr r0, VPBDIV_ADR
+ mov r1, #0x01 /* VPB clock is same as process clock */
+ str r1, [r0]
+#else
+#error No cpu_init_crit() defined for current CPU type
+#endif
#ifdef CONFIG_ARM7_REVD
/* set clock speed */
str r1, [r0]
#endif
+#ifndef CONFIG_LPC2292
+ mov ip, lr
/*
* before relocating, we have to setup RAM timing
- * because memory timing is board-dependend, you will
- * find a memsetup.S in your board directory.
+ * because memory timing is board-dependent, you will
+ * find a lowlevel_init.S in your board directory.
*/
- mov ip, lr
- bl memsetup
+ bl lowlevel_init
mov lr, ip
+#endif
mov pc, lr
-
-
/*
*************************************************************************
*
.macro bad_save_user_regs
sub sp, sp, #S_FRAME_SIZE
stmia sp, {r0 - r12} @ Calling r0-r12
- add r8, sp, #S_PC
+ add r8, sp, #S_PC
- ldr r2, _armboot_end
- add r2, r2, #CONFIG_STACKSIZE
- sub r2, r2, #8
- ldmia r2, {r2 - r4} @ get pc, cpsr, old_r0
+ ldr r2, _armboot_start
+ sub r2, r2, #(CONFIG_STACKSIZE+CONFIG_SYS_MALLOC_LEN)
+ sub r2, r2, #(CONFIG_SYS_GBL_DATA_SIZE+8) @ set base 2 words into abort stack
+ 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
+ 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
+ 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
.endm
.macro get_bad_stack
- ldr r13, _armboot_end @ setup our mode stack
- add r13, r13, #CONFIG_STACKSIZE @ resides at top of normal stack
- sub r13, r13, #8
+ ldr r13, _armboot_start @ setup our mode stack
+ sub r13, r13, #(CONFIG_STACKSIZE+CONFIG_SYS_MALLOC_LEN)
+ sub r13, r13, #(CONFIG_SYS_GBL_DATA_SIZE+8) @ reserved a couple spots in abort stack
str lr, [r13] @ save caller lr / spsr
mrs lr, spsr
- str lr, [r13, #4]
+ str lr, [r13, #4]
mov r13, #MODE_SVC @ prepare SVC-Mode
msr spsr_c, r13
/*
* exception handlers
*/
- .align 5
+ .align 5
undefined_instruction:
get_bad_stack
bad_save_user_regs
- bl do_undefined_instruction
+ bl do_undefined_instruction
.align 5
software_interrupt:
get_bad_stack
bad_save_user_regs
- bl do_software_interrupt
+ bl do_software_interrupt
.align 5
prefetch_abort:
get_bad_stack
bad_save_user_regs
- bl do_prefetch_abort
+ bl do_prefetch_abort
.align 5
data_abort:
get_bad_stack
bad_save_user_regs
- bl do_data_abort
+ bl do_data_abort
.align 5
not_used:
get_bad_stack
bad_save_user_regs
- bl do_not_used
+ bl do_not_used
#ifdef CONFIG_USE_IRQ
irq:
get_irq_stack
irq_save_user_regs
- bl do_irq
+ bl do_irq
irq_restore_user_regs
.align 5
get_fiq_stack
/* someone ought to write a more effiction fiq_save_user_regs */
irq_save_user_regs
- bl do_fiq
+ bl do_fiq
irq_restore_user_regs
#else
irq:
get_bad_stack
bad_save_user_regs
- bl do_irq
+ bl do_irq
.align 5
fiq:
get_bad_stack
bad_save_user_regs
- bl do_fiq
+ bl do_fiq
#endif
+#if defined(CONFIG_IMPA7) || defined(CONFIG_EP7312) || defined(CONFIG_ARMADILLO)
.align 5
.globl reset_cpu
reset_cpu:
- mov ip, #0
- mcr p15, 0, ip, c7, c7, 0 @ invalidate cache
- mcr p15, 0, ip, c8, c7, 0 @ flush TLB (v4)
- mrc p15, 0, ip, c1, c0, 0 @ get ctrl register
- bic ip, ip, #0x000f @ ............wcam
- bic ip, ip, #0x2100 @ ..v....s........
- mcr p15, 0, ip, c1, c0, 0 @ ctrl register
- mov pc, r0
+ mov ip, #0
+ mcr p15, 0, ip, c7, c7, 0 @ invalidate cache
+ mcr p15, 0, ip, c8, c7, 0 @ flush TLB (v4)
+ mrc p15, 0, ip, c1, c0, 0 @ get ctrl register
+ bic ip, ip, #0x000f @ ............wcam
+ bic ip, ip, #0x2100 @ ..v....s........
+ mcr p15, 0, ip, c1, c0, 0 @ ctrl register
+ mov pc, r0
+#elif defined(CONFIG_NETARM)
+ .align 5
+.globl reset_cpu
+reset_cpu:
+ ldr r1, =NETARM_MEM_MODULE_BASE
+ ldr r0, [r1, #+NETARM_MEM_CS0_BASE_ADDR]
+ ldr r1, =0xFFFFF000
+ and r0, r1, r0
+ ldr r1, =(relocate-TEXT_BASE)
+ add r0, r1, r0
+ ldr r4, =NETARM_GEN_MODULE_BASE
+ ldr r1, =NETARM_GEN_SW_SVC_RESETA
+ str r1, [r4, #+NETARM_GEN_SOFTWARE_SERVICE]
+ ldr r1, =NETARM_GEN_SW_SVC_RESETB
+ str r1, [r4, #+NETARM_GEN_SOFTWARE_SERVICE]
+ ldr r1, =NETARM_GEN_SW_SVC_RESETA
+ str r1, [r4, #+NETARM_GEN_SOFTWARE_SERVICE]
+ ldr r1, =NETARM_GEN_SW_SVC_RESETB
+ str r1, [r4, #+NETARM_GEN_SOFTWARE_SERVICE]
+ mov pc, r0
+#elif defined(CONFIG_S3C4510B)
+/* Nothing done here as reseting the CPU is board specific, depending
+ * on external peripherals such as watchdog timers, etc. */
+#elif defined(CONFIG_INTEGRATOR) && defined(CONFIG_ARCH_INTEGRATOR)
+ /* No specific reset actions for IntegratorAP/CM720T as yet */
+#elif defined(CONFIG_LPC2292)
+ .align 5
+.globl reset_cpu
+reset_cpu:
+ mov pc, r0
+#else
+#error No reset_cpu() defined for current CPU type
+#endif