1*4882a593Smuzhiyun/* 2*4882a593Smuzhiyun * armboot - Startup Code for ARM920 CPU-core 3*4882a593Smuzhiyun * 4*4882a593Smuzhiyun * Copyright (c) 2001 Marius Gröger <mag@sysgo.de> 5*4882a593Smuzhiyun * Copyright (c) 2002 Alex Züpke <azu@sysgo.de> 6*4882a593Smuzhiyun * Copyright (c) 2002 Gary Jennejohn <garyj@denx.de> 7*4882a593Smuzhiyun * 8*4882a593Smuzhiyun * SPDX-License-Identifier: GPL-2.0+ 9*4882a593Smuzhiyun */ 10*4882a593Smuzhiyun 11*4882a593Smuzhiyun#include <asm-offsets.h> 12*4882a593Smuzhiyun#include <common.h> 13*4882a593Smuzhiyun#include <config.h> 14*4882a593Smuzhiyun 15*4882a593Smuzhiyun/* 16*4882a593Smuzhiyun ************************************************************************* 17*4882a593Smuzhiyun * 18*4882a593Smuzhiyun * Startup Code (called from the ARM reset exception vector) 19*4882a593Smuzhiyun * 20*4882a593Smuzhiyun * do important init only if we don't start from memory! 21*4882a593Smuzhiyun * relocate armboot to ram 22*4882a593Smuzhiyun * setup stack 23*4882a593Smuzhiyun * jump to second stage 24*4882a593Smuzhiyun * 25*4882a593Smuzhiyun ************************************************************************* 26*4882a593Smuzhiyun */ 27*4882a593Smuzhiyun 28*4882a593Smuzhiyun .globl reset 29*4882a593Smuzhiyun 30*4882a593Smuzhiyunreset: 31*4882a593Smuzhiyun /* 32*4882a593Smuzhiyun * set the cpu to SVC32 mode 33*4882a593Smuzhiyun */ 34*4882a593Smuzhiyun mrs r0, cpsr 35*4882a593Smuzhiyun bic r0, r0, #0x1f 36*4882a593Smuzhiyun orr r0, r0, #0xd3 37*4882a593Smuzhiyun msr cpsr, r0 38*4882a593Smuzhiyun 39*4882a593Smuzhiyun#if defined(CONFIG_AT91RM9200DK) || defined(CONFIG_AT91RM9200EK) 40*4882a593Smuzhiyun /* 41*4882a593Smuzhiyun * relocate exception table 42*4882a593Smuzhiyun */ 43*4882a593Smuzhiyun ldr r0, =_start 44*4882a593Smuzhiyun ldr r1, =0x0 45*4882a593Smuzhiyun mov r2, #16 46*4882a593Smuzhiyuncopyex: 47*4882a593Smuzhiyun subs r2, r2, #1 48*4882a593Smuzhiyun ldr r3, [r0], #4 49*4882a593Smuzhiyun str r3, [r1], #4 50*4882a593Smuzhiyun bne copyex 51*4882a593Smuzhiyun#endif 52*4882a593Smuzhiyun 53*4882a593Smuzhiyun /* 54*4882a593Smuzhiyun * we do sys-critical inits only at reboot, 55*4882a593Smuzhiyun * not when booting from ram! 56*4882a593Smuzhiyun */ 57*4882a593Smuzhiyun#ifndef CONFIG_SKIP_LOWLEVEL_INIT 58*4882a593Smuzhiyun bl cpu_init_crit 59*4882a593Smuzhiyun#endif 60*4882a593Smuzhiyun 61*4882a593Smuzhiyun bl _main 62*4882a593Smuzhiyun 63*4882a593Smuzhiyun/*------------------------------------------------------------------------------*/ 64*4882a593Smuzhiyun 65*4882a593Smuzhiyun .globl c_runtime_cpu_setup 66*4882a593Smuzhiyunc_runtime_cpu_setup: 67*4882a593Smuzhiyun 68*4882a593Smuzhiyun mov pc, lr 69*4882a593Smuzhiyun 70*4882a593Smuzhiyun/* 71*4882a593Smuzhiyun ************************************************************************* 72*4882a593Smuzhiyun * 73*4882a593Smuzhiyun * CPU_init_critical registers 74*4882a593Smuzhiyun * 75*4882a593Smuzhiyun * setup important registers 76*4882a593Smuzhiyun * setup memory timing 77*4882a593Smuzhiyun * 78*4882a593Smuzhiyun ************************************************************************* 79*4882a593Smuzhiyun */ 80*4882a593Smuzhiyun 81*4882a593Smuzhiyun 82*4882a593Smuzhiyun#ifndef CONFIG_SKIP_LOWLEVEL_INIT 83*4882a593Smuzhiyuncpu_init_crit: 84*4882a593Smuzhiyun /* 85*4882a593Smuzhiyun * flush v4 I/D caches 86*4882a593Smuzhiyun */ 87*4882a593Smuzhiyun mov r0, #0 88*4882a593Smuzhiyun mcr p15, 0, r0, c7, c7, 0 /* flush v3/v4 cache */ 89*4882a593Smuzhiyun mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */ 90*4882a593Smuzhiyun 91*4882a593Smuzhiyun /* 92*4882a593Smuzhiyun * disable MMU stuff and caches 93*4882a593Smuzhiyun */ 94*4882a593Smuzhiyun mrc p15, 0, r0, c1, c0, 0 95*4882a593Smuzhiyun bic r0, r0, #0x00002300 @ clear bits 13, 9:8 (--V- --RS) 96*4882a593Smuzhiyun bic r0, r0, #0x00000087 @ clear bits 7, 2:0 (B--- -CAM) 97*4882a593Smuzhiyun orr r0, r0, #0x00000002 @ set bit 1 (A) Align 98*4882a593Smuzhiyun orr r0, r0, #0x00001000 @ set bit 12 (I) I-Cache 99*4882a593Smuzhiyun mcr p15, 0, r0, c1, c0, 0 100*4882a593Smuzhiyun 101*4882a593Smuzhiyun#ifndef CONFIG_SKIP_LOWLEVEL_INIT_ONLY 102*4882a593Smuzhiyun /* 103*4882a593Smuzhiyun * before relocating, we have to setup RAM timing 104*4882a593Smuzhiyun * because memory timing is board-dependend, you will 105*4882a593Smuzhiyun * find a lowlevel_init.S in your board directory. 106*4882a593Smuzhiyun */ 107*4882a593Smuzhiyun mov ip, lr 108*4882a593Smuzhiyun 109*4882a593Smuzhiyun bl lowlevel_init 110*4882a593Smuzhiyun mov lr, ip 111*4882a593Smuzhiyun#endif 112*4882a593Smuzhiyun mov pc, lr 113*4882a593Smuzhiyun#endif /* CONFIG_SKIP_LOWLEVEL_INIT */ 114