183d290c5STom Rini/* SPDX-License-Identifier: GPL-2.0+ */ 2907208c4SChristophe Leroy/* 3907208c4SChristophe Leroy * Copyright (C) 1998 Dan Malek <dmalek@jlc.net> 4907208c4SChristophe Leroy * Copyright (C) 1999 Magnus Damm <kieraypc01.p.y.kie.era.ericsson.se> 5907208c4SChristophe Leroy * Copyright (C) 2000,2001,2002 Wolfgang Denk <wd@denx.de> 6907208c4SChristophe Leroy */ 7907208c4SChristophe Leroy 8907208c4SChristophe Leroy/* U-Boot - Startup Code for PowerPC based Embedded Boards 9907208c4SChristophe Leroy * 10907208c4SChristophe Leroy * 11907208c4SChristophe Leroy * The processor starts at 0x00000100 and the code is executed 12907208c4SChristophe Leroy * from flash. The code is organized to be at an other address 13907208c4SChristophe Leroy * in memory, but as long we don't jump around before relocating, 14907208c4SChristophe Leroy * board_init lies at a quite high address and when the cpu has 15907208c4SChristophe Leroy * jumped there, everything is ok. 16907208c4SChristophe Leroy * This works because the cpu gives the FLASH (CS0) the whole 17907208c4SChristophe Leroy * address space at startup, and board_init lies as a echo of 18907208c4SChristophe Leroy * the flash somewhere up there in the memory map. 19907208c4SChristophe Leroy * 20907208c4SChristophe Leroy * board_init will change CS0 to be positioned at the correct 21907208c4SChristophe Leroy * address and (s)dram will be positioned at address 0 22907208c4SChristophe Leroy */ 23907208c4SChristophe Leroy#include <asm-offsets.h> 24907208c4SChristophe Leroy#include <config.h> 25907208c4SChristophe Leroy#include <mpc8xx.h> 26907208c4SChristophe Leroy#include <version.h> 27907208c4SChristophe Leroy 28907208c4SChristophe Leroy#include <ppc_asm.tmpl> 29907208c4SChristophe Leroy#include <ppc_defs.h> 30907208c4SChristophe Leroy 31907208c4SChristophe Leroy#include <asm/cache.h> 32907208c4SChristophe Leroy#include <asm/mmu.h> 33907208c4SChristophe Leroy#include <asm/u-boot.h> 34907208c4SChristophe Leroy 35907208c4SChristophe Leroy/* We don't want the MMU yet. 36907208c4SChristophe Leroy*/ 37907208c4SChristophe Leroy#undef MSR_KERNEL 38907208c4SChristophe Leroy#define MSR_KERNEL ( MSR_ME | MSR_RI ) /* Machine Check and Recoverable Interr. */ 39907208c4SChristophe Leroy 40907208c4SChristophe Leroy/* 41907208c4SChristophe Leroy * Set up GOT: Global Offset Table 42907208c4SChristophe Leroy * 43907208c4SChristophe Leroy * Use r12 to access the GOT 44907208c4SChristophe Leroy */ 45907208c4SChristophe Leroy START_GOT 46907208c4SChristophe Leroy GOT_ENTRY(_GOT2_TABLE_) 47907208c4SChristophe Leroy GOT_ENTRY(_FIXUP_TABLE_) 48907208c4SChristophe Leroy 49907208c4SChristophe Leroy GOT_ENTRY(_start) 50907208c4SChristophe Leroy GOT_ENTRY(_start_of_vectors) 51907208c4SChristophe Leroy GOT_ENTRY(_end_of_vectors) 52907208c4SChristophe Leroy GOT_ENTRY(transfer_to_handler) 53907208c4SChristophe Leroy 54907208c4SChristophe Leroy GOT_ENTRY(__init_end) 55907208c4SChristophe Leroy GOT_ENTRY(__bss_end) 56907208c4SChristophe Leroy GOT_ENTRY(__bss_start) 57907208c4SChristophe Leroy END_GOT 58907208c4SChristophe Leroy 59907208c4SChristophe Leroy/* 60907208c4SChristophe Leroy * r3 - 1st arg to board_init(): IMMP pointer 61907208c4SChristophe Leroy * r4 - 2nd arg to board_init(): boot flag 62907208c4SChristophe Leroy */ 63907208c4SChristophe Leroy .text 64907208c4SChristophe Leroy .long 0x27051956 /* U-Boot Magic Number */ 65907208c4SChristophe Leroy .globl version_string 66907208c4SChristophe Leroyversion_string: 67907208c4SChristophe Leroy .ascii U_BOOT_VERSION_STRING, "\0" 68907208c4SChristophe Leroy 69907208c4SChristophe Leroy . = EXC_OFF_SYS_RESET 70907208c4SChristophe Leroy .globl _start 71907208c4SChristophe Leroy_start: 72907208c4SChristophe Leroy lis r3, CONFIG_SYS_IMMR@h /* position IMMR */ 73907208c4SChristophe Leroy mtspr 638, r3 74907208c4SChristophe Leroy 75907208c4SChristophe Leroy /* Initialize machine status; enable machine check interrupt */ 76907208c4SChristophe Leroy /*----------------------------------------------------------------------*/ 77907208c4SChristophe Leroy li r3, MSR_KERNEL /* Set ME, RI flags */ 78907208c4SChristophe Leroy mtmsr r3 79907208c4SChristophe Leroy mtspr SRR1, r3 /* Make SRR1 match MSR */ 80907208c4SChristophe Leroy 81907208c4SChristophe Leroy mfspr r3, ICR /* clear Interrupt Cause Register */ 82907208c4SChristophe Leroy 83907208c4SChristophe Leroy /* Initialize debug port registers */ 84907208c4SChristophe Leroy /*----------------------------------------------------------------------*/ 85907208c4SChristophe Leroy xor r0, r0, r0 /* Clear R0 */ 86907208c4SChristophe Leroy mtspr LCTRL1, r0 /* Initialize debug port regs */ 87907208c4SChristophe Leroy mtspr LCTRL2, r0 88907208c4SChristophe Leroy mtspr COUNTA, r0 89907208c4SChristophe Leroy mtspr COUNTB, r0 90907208c4SChristophe Leroy 91907208c4SChristophe Leroy /* Reset the caches */ 92907208c4SChristophe Leroy /*----------------------------------------------------------------------*/ 93907208c4SChristophe Leroy 94907208c4SChristophe Leroy mfspr r3, IC_CST /* Clear error bits */ 95907208c4SChristophe Leroy mfspr r3, DC_CST 96907208c4SChristophe Leroy 97907208c4SChristophe Leroy lis r3, IDC_UNALL@h /* Unlock all */ 98907208c4SChristophe Leroy mtspr IC_CST, r3 99907208c4SChristophe Leroy mtspr DC_CST, r3 100907208c4SChristophe Leroy 101907208c4SChristophe Leroy lis r3, IDC_INVALL@h /* Invalidate all */ 102907208c4SChristophe Leroy mtspr IC_CST, r3 103907208c4SChristophe Leroy mtspr DC_CST, r3 104907208c4SChristophe Leroy 105907208c4SChristophe Leroy lis r3, IDC_DISABLE@h /* Disable data cache */ 106907208c4SChristophe Leroy mtspr DC_CST, r3 107907208c4SChristophe Leroy 108907208c4SChristophe Leroy lis r3, IDC_ENABLE@h /* Enable instruction cache */ 109907208c4SChristophe Leroy mtspr IC_CST, r3 110907208c4SChristophe Leroy 111907208c4SChristophe Leroy /* invalidate all tlb's */ 112907208c4SChristophe Leroy /*----------------------------------------------------------------------*/ 113907208c4SChristophe Leroy 114907208c4SChristophe Leroy tlbia 115907208c4SChristophe Leroy isync 116907208c4SChristophe Leroy 117907208c4SChristophe Leroy /* 118907208c4SChristophe Leroy * Calculate absolute address in FLASH and jump there 119907208c4SChristophe Leroy *----------------------------------------------------------------------*/ 120907208c4SChristophe Leroy 121907208c4SChristophe Leroy lis r3, CONFIG_SYS_MONITOR_BASE@h 122907208c4SChristophe Leroy ori r3, r3, CONFIG_SYS_MONITOR_BASE@l 123907208c4SChristophe Leroy addi r3, r3, in_flash - _start + EXC_OFF_SYS_RESET 124907208c4SChristophe Leroy mtlr r3 125907208c4SChristophe Leroy blr 126907208c4SChristophe Leroy 127907208c4SChristophe Leroyin_flash: 128907208c4SChristophe Leroy 129907208c4SChristophe Leroy /* initialize some SPRs that are hard to access from C */ 130907208c4SChristophe Leroy /*----------------------------------------------------------------------*/ 131907208c4SChristophe Leroy 132907208c4SChristophe Leroy /* 133907208c4SChristophe Leroy * Disable serialized ifetch and show cycles 134907208c4SChristophe Leroy * (i.e. set processor to normal mode). 135907208c4SChristophe Leroy * This is also a silicon bug workaround, see errata 136907208c4SChristophe Leroy */ 137907208c4SChristophe Leroy 138907208c4SChristophe Leroy li r2, 0x0007 139907208c4SChristophe Leroy mtspr ICTRL, r2 140907208c4SChristophe Leroy 141907208c4SChristophe Leroy /* Set up debug mode entry */ 142907208c4SChristophe Leroy 143907208c4SChristophe Leroy lis r2, CONFIG_SYS_DER@h 144907208c4SChristophe Leroy ori r2, r2, CONFIG_SYS_DER@l 145907208c4SChristophe Leroy mtspr DER, r2 146907208c4SChristophe Leroy 147*71c743c5SChristophe Leroy /* set up the stack on top of internal DPRAM */ 148872807b1SChristophe Leroy lis r3, (CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_RAM_SIZE)@h 149872807b1SChristophe Leroy ori r3, r3, (CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_RAM_SIZE)@l 150*71c743c5SChristophe Leroy stw r0, -4(r3) 151*71c743c5SChristophe Leroy stw r0, -8(r3) 152872807b1SChristophe Leroy addi r1, r3, -8 153872807b1SChristophe Leroy 154872807b1SChristophe Leroy bl board_init_f_alloc_reserve 155872807b1SChristophe Leroy addi r1, r3, -8 156872807b1SChristophe Leroy 157872807b1SChristophe Leroy /* Zeroise the CPM dpram */ 158872807b1SChristophe Leroy lis r4, CONFIG_SYS_IMMR@h 159872807b1SChristophe Leroy ori r4, r4, (0x2000 - 4) 160872807b1SChristophe Leroy li r0, (0x2000 / 4) 161872807b1SChristophe Leroy mtctr r0 162872807b1SChristophe Leroy li r0, 0 163872807b1SChristophe Leroy1: stwu r0, 4(r4) 164872807b1SChristophe Leroy bdnz 1b 165872807b1SChristophe Leroy 166872807b1SChristophe Leroy bl board_init_f_init_reserve 167872807b1SChristophe Leroy 168907208c4SChristophe Leroy /* let the C-code set up the rest */ 169907208c4SChristophe Leroy /* */ 170907208c4SChristophe Leroy /* Be careful to keep code relocatable ! */ 171907208c4SChristophe Leroy /*----------------------------------------------------------------------*/ 172907208c4SChristophe Leroy 173907208c4SChristophe Leroy GET_GOT /* initialize GOT access */ 174907208c4SChristophe Leroy 175872807b1SChristophe Leroy lis r3, CONFIG_SYS_IMMR@h 176907208c4SChristophe Leroy bl cpu_init_f /* run low-level CPU init code (from Flash) */ 177907208c4SChristophe Leroy 178907208c4SChristophe Leroy bl board_init_f /* run 1st part of board init code (from Flash) */ 179907208c4SChristophe Leroy 180907208c4SChristophe Leroy /* NOTREACHED - board_init_f() does not return */ 181907208c4SChristophe Leroy 182907208c4SChristophe Leroy 183907208c4SChristophe Leroy .globl _start_of_vectors 184907208c4SChristophe Leroy_start_of_vectors: 185907208c4SChristophe Leroy 186907208c4SChristophe Leroy/* Machine check */ 187907208c4SChristophe Leroy STD_EXCEPTION(0x200, MachineCheck, MachineCheckException) 188907208c4SChristophe Leroy 189907208c4SChristophe Leroy/* Data Storage exception. "Never" generated on the 860. */ 190907208c4SChristophe Leroy STD_EXCEPTION(0x300, DataStorage, UnknownException) 191907208c4SChristophe Leroy 192907208c4SChristophe Leroy/* Instruction Storage exception. "Never" generated on the 860. */ 193907208c4SChristophe Leroy STD_EXCEPTION(0x400, InstStorage, UnknownException) 194907208c4SChristophe Leroy 195907208c4SChristophe Leroy/* External Interrupt exception. */ 196907208c4SChristophe Leroy STD_EXCEPTION(0x500, ExtInterrupt, external_interrupt) 197907208c4SChristophe Leroy 198907208c4SChristophe Leroy/* Alignment exception. */ 199907208c4SChristophe Leroy . = 0x600 200907208c4SChristophe LeroyAlignment: 201907208c4SChristophe Leroy EXCEPTION_PROLOG(SRR0, SRR1) 202907208c4SChristophe Leroy mfspr r4,DAR 203907208c4SChristophe Leroy stw r4,_DAR(r21) 204907208c4SChristophe Leroy mfspr r5,DSISR 205907208c4SChristophe Leroy stw r5,_DSISR(r21) 206907208c4SChristophe Leroy addi r3,r1,STACK_FRAME_OVERHEAD 207907208c4SChristophe Leroy EXC_XFER_TEMPLATE(Alignment, AlignmentException, MSR_KERNEL, COPY_EE) 208907208c4SChristophe Leroy 209907208c4SChristophe Leroy/* Program check exception */ 210907208c4SChristophe Leroy . = 0x700 211907208c4SChristophe LeroyProgramCheck: 212907208c4SChristophe Leroy EXCEPTION_PROLOG(SRR0, SRR1) 213907208c4SChristophe Leroy addi r3,r1,STACK_FRAME_OVERHEAD 214907208c4SChristophe Leroy EXC_XFER_TEMPLATE(ProgramCheck, ProgramCheckException, 215907208c4SChristophe Leroy MSR_KERNEL, COPY_EE) 216907208c4SChristophe Leroy 217907208c4SChristophe Leroy /* No FPU on MPC8xx. This exception is not supposed to happen. 218907208c4SChristophe Leroy */ 219907208c4SChristophe Leroy STD_EXCEPTION(0x800, FPUnavailable, UnknownException) 220907208c4SChristophe Leroy 221907208c4SChristophe Leroy /* I guess we could implement decrementer, and may have 222907208c4SChristophe Leroy * to someday for timekeeping. 223907208c4SChristophe Leroy */ 224907208c4SChristophe Leroy STD_EXCEPTION(0x900, Decrementer, timer_interrupt) 225907208c4SChristophe Leroy STD_EXCEPTION(0xa00, Trap_0a, UnknownException) 226907208c4SChristophe Leroy STD_EXCEPTION(0xb00, Trap_0b, UnknownException) 227907208c4SChristophe Leroy STD_EXCEPTION(0xc00, SystemCall, UnknownException) 228907208c4SChristophe Leroy STD_EXCEPTION(0xd00, SingleStep, UnknownException) 229907208c4SChristophe Leroy 230907208c4SChristophe Leroy STD_EXCEPTION(0xe00, Trap_0e, UnknownException) 231907208c4SChristophe Leroy STD_EXCEPTION(0xf00, Trap_0f, UnknownException) 232907208c4SChristophe Leroy 233907208c4SChristophe Leroy /* On the MPC8xx, this is a software emulation interrupt. It occurs 234907208c4SChristophe Leroy * for all unimplemented and illegal instructions. 235907208c4SChristophe Leroy */ 236907208c4SChristophe Leroy STD_EXCEPTION(0x1000, SoftEmu, SoftEmuException) 237907208c4SChristophe Leroy 238907208c4SChristophe Leroy STD_EXCEPTION(0x1100, InstructionTLBMiss, UnknownException) 239907208c4SChristophe Leroy STD_EXCEPTION(0x1200, DataTLBMiss, UnknownException) 240907208c4SChristophe Leroy STD_EXCEPTION(0x1300, InstructionTLBError, UnknownException) 241907208c4SChristophe Leroy STD_EXCEPTION(0x1400, DataTLBError, UnknownException) 242907208c4SChristophe Leroy 243907208c4SChristophe Leroy STD_EXCEPTION(0x1500, Reserved5, UnknownException) 244907208c4SChristophe Leroy STD_EXCEPTION(0x1600, Reserved6, UnknownException) 245907208c4SChristophe Leroy STD_EXCEPTION(0x1700, Reserved7, UnknownException) 246907208c4SChristophe Leroy STD_EXCEPTION(0x1800, Reserved8, UnknownException) 247907208c4SChristophe Leroy STD_EXCEPTION(0x1900, Reserved9, UnknownException) 248907208c4SChristophe Leroy STD_EXCEPTION(0x1a00, ReservedA, UnknownException) 249907208c4SChristophe Leroy STD_EXCEPTION(0x1b00, ReservedB, UnknownException) 250907208c4SChristophe Leroy 251907208c4SChristophe Leroy STD_EXCEPTION(0x1c00, DataBreakpoint, UnknownException) 252907208c4SChristophe Leroy STD_EXCEPTION(0x1d00, InstructionBreakpoint, DebugException) 253907208c4SChristophe Leroy STD_EXCEPTION(0x1e00, PeripheralBreakpoint, UnknownException) 254907208c4SChristophe Leroy STD_EXCEPTION(0x1f00, DevPortBreakpoint, UnknownException) 255907208c4SChristophe Leroy 256907208c4SChristophe Leroy 257907208c4SChristophe Leroy .globl _end_of_vectors 258907208c4SChristophe Leroy_end_of_vectors: 259907208c4SChristophe Leroy 260907208c4SChristophe Leroy 261907208c4SChristophe Leroy . = 0x2000 262907208c4SChristophe Leroy 263907208c4SChristophe Leroy/* 264907208c4SChristophe Leroy * This code finishes saving the registers to the exception frame 265907208c4SChristophe Leroy * and jumps to the appropriate handler for the exception. 266907208c4SChristophe Leroy * Register r21 is pointer into trap frame, r1 has new stack pointer. 267907208c4SChristophe Leroy */ 268907208c4SChristophe Leroy .globl transfer_to_handler 269907208c4SChristophe Leroytransfer_to_handler: 270907208c4SChristophe Leroy stw r22,_NIP(r21) 271907208c4SChristophe Leroy lis r22,MSR_POW@h 272907208c4SChristophe Leroy andc r23,r23,r22 273907208c4SChristophe Leroy stw r23,_MSR(r21) 274907208c4SChristophe Leroy SAVE_GPR(7, r21) 275907208c4SChristophe Leroy SAVE_4GPRS(8, r21) 276907208c4SChristophe Leroy SAVE_8GPRS(12, r21) 277907208c4SChristophe Leroy SAVE_8GPRS(24, r21) 278907208c4SChristophe Leroy mflr r23 279907208c4SChristophe Leroy andi. r24,r23,0x3f00 /* get vector offset */ 280907208c4SChristophe Leroy stw r24,TRAP(r21) 281907208c4SChristophe Leroy li r22,0 282907208c4SChristophe Leroy stw r22,RESULT(r21) 283907208c4SChristophe Leroy mtspr SPRG2,r22 /* r1 is now kernel sp */ 284907208c4SChristophe Leroy lwz r24,0(r23) /* virtual address of handler */ 285907208c4SChristophe Leroy lwz r23,4(r23) /* where to go when done */ 286907208c4SChristophe Leroy mtspr SRR0,r24 287907208c4SChristophe Leroy mtspr SRR1,r20 288907208c4SChristophe Leroy mtlr r23 289907208c4SChristophe Leroy SYNC 290907208c4SChristophe Leroy rfi /* jump to handler, enable MMU */ 291907208c4SChristophe Leroy 292907208c4SChristophe Leroyint_return: 293907208c4SChristophe Leroy mfmsr r28 /* Disable interrupts */ 294907208c4SChristophe Leroy li r4,0 295907208c4SChristophe Leroy ori r4,r4,MSR_EE 296907208c4SChristophe Leroy andc r28,r28,r4 297907208c4SChristophe Leroy SYNC /* Some chip revs need this... */ 298907208c4SChristophe Leroy mtmsr r28 299907208c4SChristophe Leroy SYNC 300907208c4SChristophe Leroy lwz r2,_CTR(r1) 301907208c4SChristophe Leroy lwz r0,_LINK(r1) 302907208c4SChristophe Leroy mtctr r2 303907208c4SChristophe Leroy mtlr r0 304907208c4SChristophe Leroy lwz r2,_XER(r1) 305907208c4SChristophe Leroy lwz r0,_CCR(r1) 306907208c4SChristophe Leroy mtspr XER,r2 307907208c4SChristophe Leroy mtcrf 0xFF,r0 308907208c4SChristophe Leroy REST_10GPRS(3, r1) 309907208c4SChristophe Leroy REST_10GPRS(13, r1) 310907208c4SChristophe Leroy REST_8GPRS(23, r1) 311907208c4SChristophe Leroy REST_GPR(31, r1) 312907208c4SChristophe Leroy lwz r2,_NIP(r1) /* Restore environment */ 313907208c4SChristophe Leroy lwz r0,_MSR(r1) 314907208c4SChristophe Leroy mtspr SRR0,r2 315907208c4SChristophe Leroy mtspr SRR1,r0 316907208c4SChristophe Leroy lwz r0,GPR0(r1) 317907208c4SChristophe Leroy lwz r2,GPR2(r1) 318907208c4SChristophe Leroy lwz r1,GPR1(r1) 319907208c4SChristophe Leroy SYNC 320907208c4SChristophe Leroy rfi 321907208c4SChristophe Leroy 322907208c4SChristophe Leroy/*------------------------------------------------------------------------------*/ 323907208c4SChristophe Leroy 324907208c4SChristophe Leroy/* 325907208c4SChristophe Leroy * void relocate_code (addr_sp, gd, addr_moni) 326907208c4SChristophe Leroy * 327907208c4SChristophe Leroy * This "function" does not return, instead it continues in RAM 328907208c4SChristophe Leroy * after relocating the monitor code. 329907208c4SChristophe Leroy * 330907208c4SChristophe Leroy * r3 = dest 331907208c4SChristophe Leroy * r4 = src 332907208c4SChristophe Leroy * r5 = length in bytes 333907208c4SChristophe Leroy * r6 = cachelinesize 334907208c4SChristophe Leroy */ 335907208c4SChristophe Leroy .globl relocate_code 336907208c4SChristophe Leroyrelocate_code: 337907208c4SChristophe Leroy mr r1, r3 /* Set new stack pointer */ 338907208c4SChristophe Leroy mr r9, r4 /* Save copy of Global Data pointer */ 339907208c4SChristophe Leroy mr r10, r5 /* Save copy of Destination Address */ 340907208c4SChristophe Leroy 341907208c4SChristophe Leroy GET_GOT 342907208c4SChristophe Leroy mr r3, r5 /* Destination Address */ 343907208c4SChristophe Leroy lis r4, CONFIG_SYS_MONITOR_BASE@h /* Source Address */ 344907208c4SChristophe Leroy ori r4, r4, CONFIG_SYS_MONITOR_BASE@l 345907208c4SChristophe Leroy lwz r5, GOT(__init_end) 346907208c4SChristophe Leroy sub r5, r5, r4 347907208c4SChristophe Leroy li r6, CONFIG_SYS_CACHELINE_SIZE /* Cache Line Size */ 348907208c4SChristophe Leroy 349907208c4SChristophe Leroy /* 350907208c4SChristophe Leroy * Fix GOT pointer: 351907208c4SChristophe Leroy * 352907208c4SChristophe Leroy * New GOT-PTR = (old GOT-PTR - CONFIG_SYS_MONITOR_BASE) + Destination Address 353907208c4SChristophe Leroy * 354907208c4SChristophe Leroy * Offset: 355907208c4SChristophe Leroy */ 356907208c4SChristophe Leroy sub r15, r10, r4 357907208c4SChristophe Leroy 358907208c4SChristophe Leroy /* First our own GOT */ 359907208c4SChristophe Leroy add r12, r12, r15 360907208c4SChristophe Leroy /* then the one used by the C code */ 361907208c4SChristophe Leroy add r30, r30, r15 362907208c4SChristophe Leroy 363907208c4SChristophe Leroy /* 364907208c4SChristophe Leroy * Now relocate code 365907208c4SChristophe Leroy */ 366907208c4SChristophe Leroy 367907208c4SChristophe Leroy cmplw cr1,r3,r4 368907208c4SChristophe Leroy addi r0,r5,3 369907208c4SChristophe Leroy srwi. r0,r0,2 370907208c4SChristophe Leroy beq cr1,4f /* In place copy is not necessary */ 371907208c4SChristophe Leroy beq 7f /* Protect against 0 count */ 372907208c4SChristophe Leroy mtctr r0 373907208c4SChristophe Leroy bge cr1,2f 374907208c4SChristophe Leroy 375907208c4SChristophe Leroy la r8,-4(r4) 376907208c4SChristophe Leroy la r7,-4(r3) 377907208c4SChristophe Leroy1: lwzu r0,4(r8) 378907208c4SChristophe Leroy stwu r0,4(r7) 379907208c4SChristophe Leroy bdnz 1b 380907208c4SChristophe Leroy b 4f 381907208c4SChristophe Leroy 382907208c4SChristophe Leroy2: slwi r0,r0,2 383907208c4SChristophe Leroy add r8,r4,r0 384907208c4SChristophe Leroy add r7,r3,r0 385907208c4SChristophe Leroy3: lwzu r0,-4(r8) 386907208c4SChristophe Leroy stwu r0,-4(r7) 387907208c4SChristophe Leroy bdnz 3b 388907208c4SChristophe Leroy 389907208c4SChristophe Leroy/* 390907208c4SChristophe Leroy * Now flush the cache: note that we must start from a cache aligned 391907208c4SChristophe Leroy * address. Otherwise we might miss one cache line. 392907208c4SChristophe Leroy */ 393907208c4SChristophe Leroy4: cmpwi r6,0 394907208c4SChristophe Leroy add r5,r3,r5 395907208c4SChristophe Leroy beq 7f /* Always flush prefetch queue in any case */ 396907208c4SChristophe Leroy subi r0,r6,1 397907208c4SChristophe Leroy andc r3,r3,r0 398907208c4SChristophe Leroy mr r4,r3 399907208c4SChristophe Leroy5: dcbst 0,r4 400907208c4SChristophe Leroy add r4,r4,r6 401907208c4SChristophe Leroy cmplw r4,r5 402907208c4SChristophe Leroy blt 5b 403907208c4SChristophe Leroy sync /* Wait for all dcbst to complete on bus */ 404907208c4SChristophe Leroy mr r4,r3 405907208c4SChristophe Leroy6: icbi 0,r4 406907208c4SChristophe Leroy add r4,r4,r6 407907208c4SChristophe Leroy cmplw r4,r5 408907208c4SChristophe Leroy blt 6b 409907208c4SChristophe Leroy7: sync /* Wait for all icbi to complete on bus */ 410907208c4SChristophe Leroy isync 411907208c4SChristophe Leroy 412907208c4SChristophe Leroy/* 413907208c4SChristophe Leroy * We are done. Do not return, instead branch to second part of board 414907208c4SChristophe Leroy * initialization, now running from RAM. 415907208c4SChristophe Leroy */ 416907208c4SChristophe Leroy 417907208c4SChristophe Leroy addi r0, r10, in_ram - _start + EXC_OFF_SYS_RESET 418907208c4SChristophe Leroy mtlr r0 419907208c4SChristophe Leroy blr 420907208c4SChristophe Leroy 421907208c4SChristophe Leroyin_ram: 422907208c4SChristophe Leroy 423907208c4SChristophe Leroy /* 424907208c4SChristophe Leroy * Relocation Function, r12 point to got2+0x8000 425907208c4SChristophe Leroy * 426907208c4SChristophe Leroy * Adjust got2 pointers, no need to check for 0, this code 427907208c4SChristophe Leroy * already puts a few entries in the table. 428907208c4SChristophe Leroy */ 429907208c4SChristophe Leroy li r0,__got2_entries@sectoff@l 430907208c4SChristophe Leroy la r3,GOT(_GOT2_TABLE_) 431907208c4SChristophe Leroy lwz r11,GOT(_GOT2_TABLE_) 432907208c4SChristophe Leroy mtctr r0 433907208c4SChristophe Leroy sub r11,r3,r11 434907208c4SChristophe Leroy addi r3,r3,-4 435907208c4SChristophe Leroy1: lwzu r0,4(r3) 436907208c4SChristophe Leroy cmpwi r0,0 437907208c4SChristophe Leroy beq- 2f 438907208c4SChristophe Leroy add r0,r0,r11 439907208c4SChristophe Leroy stw r0,0(r3) 440907208c4SChristophe Leroy2: bdnz 1b 441907208c4SChristophe Leroy 442907208c4SChristophe Leroy /* 443907208c4SChristophe Leroy * Now adjust the fixups and the pointers to the fixups 444907208c4SChristophe Leroy * in case we need to move ourselves again. 445907208c4SChristophe Leroy */ 446907208c4SChristophe Leroy li r0,__fixup_entries@sectoff@l 447907208c4SChristophe Leroy lwz r3,GOT(_FIXUP_TABLE_) 448907208c4SChristophe Leroy cmpwi r0,0 449907208c4SChristophe Leroy mtctr r0 450907208c4SChristophe Leroy addi r3,r3,-4 451907208c4SChristophe Leroy beq 4f 452907208c4SChristophe Leroy3: lwzu r4,4(r3) 453907208c4SChristophe Leroy lwzux r0,r4,r11 454907208c4SChristophe Leroy cmpwi r0,0 455907208c4SChristophe Leroy add r0,r0,r11 456907208c4SChristophe Leroy stw r4,0(r3) 457907208c4SChristophe Leroy beq- 5f 458907208c4SChristophe Leroy stw r0,0(r4) 459907208c4SChristophe Leroy5: bdnz 3b 460907208c4SChristophe Leroy4: 461907208c4SChristophe Leroyclear_bss: 462907208c4SChristophe Leroy /* 463907208c4SChristophe Leroy * Now clear BSS segment 464907208c4SChristophe Leroy */ 465907208c4SChristophe Leroy lwz r3,GOT(__bss_start) 466907208c4SChristophe Leroy lwz r4,GOT(__bss_end) 467907208c4SChristophe Leroy 468907208c4SChristophe Leroy cmplw 0, r3, r4 469907208c4SChristophe Leroy beq 6f 470907208c4SChristophe Leroy 471907208c4SChristophe Leroy li r0, 0 472907208c4SChristophe Leroy5: 473907208c4SChristophe Leroy stw r0, 0(r3) 474907208c4SChristophe Leroy addi r3, r3, 4 475907208c4SChristophe Leroy cmplw 0, r3, r4 476907208c4SChristophe Leroy bne 5b 477907208c4SChristophe Leroy6: 478907208c4SChristophe Leroy 479907208c4SChristophe Leroy mr r3, r9 /* Global Data pointer */ 480907208c4SChristophe Leroy mr r4, r10 /* Destination Address */ 481907208c4SChristophe Leroy bl board_init_r 482907208c4SChristophe Leroy 483907208c4SChristophe Leroy /* 484907208c4SChristophe Leroy * Copy exception vector code to low memory 485907208c4SChristophe Leroy * 486907208c4SChristophe Leroy * r3: dest_addr 487907208c4SChristophe Leroy * r7: source address, r8: end address, r9: target address 488907208c4SChristophe Leroy */ 489907208c4SChristophe Leroy .globl trap_init 490907208c4SChristophe Leroytrap_init: 491907208c4SChristophe Leroy mflr r4 /* save link register */ 492907208c4SChristophe Leroy GET_GOT 493907208c4SChristophe Leroy lwz r7, GOT(_start) 494907208c4SChristophe Leroy lwz r8, GOT(_end_of_vectors) 495907208c4SChristophe Leroy 496907208c4SChristophe Leroy li r9, 0x100 /* reset vector always at 0x100 */ 497907208c4SChristophe Leroy 498907208c4SChristophe Leroy cmplw 0, r7, r8 499907208c4SChristophe Leroy bgelr /* return if r7>=r8 - just in case */ 500907208c4SChristophe Leroy1: 501907208c4SChristophe Leroy lwz r0, 0(r7) 502907208c4SChristophe Leroy stw r0, 0(r9) 503907208c4SChristophe Leroy addi r7, r7, 4 504907208c4SChristophe Leroy addi r9, r9, 4 505907208c4SChristophe Leroy cmplw 0, r7, r8 506907208c4SChristophe Leroy bne 1b 507907208c4SChristophe Leroy 508907208c4SChristophe Leroy /* 509907208c4SChristophe Leroy * relocate `hdlr' and `int_return' entries 510907208c4SChristophe Leroy */ 511907208c4SChristophe Leroy li r7, .L_MachineCheck - _start + EXC_OFF_SYS_RESET 512907208c4SChristophe Leroy li r8, Alignment - _start + EXC_OFF_SYS_RESET 513907208c4SChristophe Leroy2: 514907208c4SChristophe Leroy bl trap_reloc 515907208c4SChristophe Leroy addi r7, r7, 0x100 /* next exception vector */ 516907208c4SChristophe Leroy cmplw 0, r7, r8 517907208c4SChristophe Leroy blt 2b 518907208c4SChristophe Leroy 519907208c4SChristophe Leroy li r7, .L_Alignment - _start + EXC_OFF_SYS_RESET 520907208c4SChristophe Leroy bl trap_reloc 521907208c4SChristophe Leroy 522907208c4SChristophe Leroy li r7, .L_ProgramCheck - _start + EXC_OFF_SYS_RESET 523907208c4SChristophe Leroy bl trap_reloc 524907208c4SChristophe Leroy 525907208c4SChristophe Leroy li r7, .L_FPUnavailable - _start + EXC_OFF_SYS_RESET 526907208c4SChristophe Leroy li r8, SystemCall - _start + EXC_OFF_SYS_RESET 527907208c4SChristophe Leroy3: 528907208c4SChristophe Leroy bl trap_reloc 529907208c4SChristophe Leroy addi r7, r7, 0x100 /* next exception vector */ 530907208c4SChristophe Leroy cmplw 0, r7, r8 531907208c4SChristophe Leroy blt 3b 532907208c4SChristophe Leroy 533907208c4SChristophe Leroy li r7, .L_SingleStep - _start + EXC_OFF_SYS_RESET 534907208c4SChristophe Leroy li r8, _end_of_vectors - _start + EXC_OFF_SYS_RESET 535907208c4SChristophe Leroy4: 536907208c4SChristophe Leroy bl trap_reloc 537907208c4SChristophe Leroy addi r7, r7, 0x100 /* next exception vector */ 538907208c4SChristophe Leroy cmplw 0, r7, r8 539907208c4SChristophe Leroy blt 4b 540907208c4SChristophe Leroy 541907208c4SChristophe Leroy mtlr r4 /* restore link register */ 542907208c4SChristophe Leroy blr 543