1*4882a593Smuzhiyun/* 2*4882a593Smuzhiyun * (C) Copyright 2015 Angelo Dureghello <angelo@sysam.it> 3*4882a593Smuzhiyun * Based on code from Bernhard Kuhn <bkuhn@metrowerks.com> 4*4882a593Smuzhiyun * 5*4882a593Smuzhiyun * SPDX-License-Identifier: GPL-2.0+ 6*4882a593Smuzhiyun */ 7*4882a593Smuzhiyun 8*4882a593Smuzhiyun#include <asm-offsets.h> 9*4882a593Smuzhiyun#include <config.h> 10*4882a593Smuzhiyun#include "version.h" 11*4882a593Smuzhiyun#include <asm/cache.h> 12*4882a593Smuzhiyun 13*4882a593Smuzhiyun#define _START _start 14*4882a593Smuzhiyun#define _FAULT _fault 15*4882a593Smuzhiyun 16*4882a593Smuzhiyun 17*4882a593Smuzhiyun.macro SAVE_ALL 18*4882a593Smuzhiyun move.w #0x2700,%sr; /* disable intrs */ 19*4882a593Smuzhiyun subl #60,%sp; /* space for 15 regs */ 20*4882a593Smuzhiyun moveml %d0-%d7/%a0-%a6,%sp@ 21*4882a593Smuzhiyun.endm 22*4882a593Smuzhiyun 23*4882a593Smuzhiyun.macro RESTORE_ALL 24*4882a593Smuzhiyun moveml %sp@,%d0-%d7/%a0-%a6; 25*4882a593Smuzhiyun addl #60,%sp; /* space for 15 regs */ 26*4882a593Smuzhiyun rte 27*4882a593Smuzhiyun.endm 28*4882a593Smuzhiyun 29*4882a593Smuzhiyun/* If we come from a pre-loader we don't need an initial exception 30*4882a593Smuzhiyun * table. 31*4882a593Smuzhiyun */ 32*4882a593Smuzhiyun#if !defined(CONFIG_MONITOR_IS_IN_RAM) 33*4882a593Smuzhiyun 34*4882a593Smuzhiyun.text 35*4882a593Smuzhiyun 36*4882a593Smuzhiyun/* 37*4882a593Smuzhiyun * Vector table. This is used for initial platform startup. 38*4882a593Smuzhiyun * These vectors are to catch any un-intended traps. 39*4882a593Smuzhiyun */ 40*4882a593Smuzhiyun_vectors: 41*4882a593Smuzhiyun/* Flash offset is 0 until we setup CS0 */ 42*4882a593Smuzhiyun.long 0x00000000 43*4882a593Smuzhiyun#if defined(CONFIG_M5307) && \ 44*4882a593Smuzhiyun (CONFIG_SYS_TEXT_BASE == CONFIG_SYS_INT_FLASH_BASE) 45*4882a593Smuzhiyun.long _start - CONFIG_SYS_TEXT_BASE 46*4882a593Smuzhiyun#else 47*4882a593Smuzhiyun.long _START 48*4882a593Smuzhiyun#endif 49*4882a593Smuzhiyun 50*4882a593Smuzhiyun.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT 51*4882a593Smuzhiyun.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT 52*4882a593Smuzhiyun.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT 53*4882a593Smuzhiyun.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT 54*4882a593Smuzhiyun.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT 55*4882a593Smuzhiyun.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT 56*4882a593Smuzhiyun.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT 57*4882a593Smuzhiyun.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT 58*4882a593Smuzhiyun 59*4882a593Smuzhiyun.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT 60*4882a593Smuzhiyun.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT 61*4882a593Smuzhiyun.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT 62*4882a593Smuzhiyun.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT 63*4882a593Smuzhiyun.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT 64*4882a593Smuzhiyun.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT 65*4882a593Smuzhiyun.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT 66*4882a593Smuzhiyun.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT 67*4882a593Smuzhiyun 68*4882a593Smuzhiyun.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT 69*4882a593Smuzhiyun.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT 70*4882a593Smuzhiyun.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT 71*4882a593Smuzhiyun.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT 72*4882a593Smuzhiyun.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT 73*4882a593Smuzhiyun.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT 74*4882a593Smuzhiyun.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT 75*4882a593Smuzhiyun.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT 76*4882a593Smuzhiyun 77*4882a593Smuzhiyun.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT 78*4882a593Smuzhiyun.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT 79*4882a593Smuzhiyun.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT 80*4882a593Smuzhiyun.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT 81*4882a593Smuzhiyun.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT 82*4882a593Smuzhiyun.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT 83*4882a593Smuzhiyun.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT 84*4882a593Smuzhiyun.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT 85*4882a593Smuzhiyun 86*4882a593Smuzhiyun#endif 87*4882a593Smuzhiyun 88*4882a593Smuzhiyun.text 89*4882a593Smuzhiyun 90*4882a593Smuzhiyun.globl _start 91*4882a593Smuzhiyun_start: 92*4882a593Smuzhiyun nop 93*4882a593Smuzhiyun nop 94*4882a593Smuzhiyun move.w #0x2700,%sr 95*4882a593Smuzhiyun 96*4882a593Smuzhiyun /* set MBAR address + valid flag */ 97*4882a593Smuzhiyun move.l #(CONFIG_SYS_MBAR + 1), %d0 98*4882a593Smuzhiyun move.c %d0, %MBAR 99*4882a593Smuzhiyun 100*4882a593Smuzhiyun move.l #(CONFIG_SYS_INIT_RAM_ADDR + 1), %d0 101*4882a593Smuzhiyun move.c %d0, %RAMBAR 102*4882a593Smuzhiyun 103*4882a593Smuzhiyun /* DS 4.8.2 (Cache Organization) invalidate and disable cache */ 104*4882a593Smuzhiyun move.l #CF_CACR_CINVA, %d0 105*4882a593Smuzhiyun movec %d0, %CACR 106*4882a593Smuzhiyun move.l #0, %d0 107*4882a593Smuzhiyun movec %d0, %ACR0 108*4882a593Smuzhiyun movec %d0, %ACR1 109*4882a593Smuzhiyun 110*4882a593Smuzhiyun /* 111*4882a593Smuzhiyun * if we come from a pre-loader we have no exception table and 112*4882a593Smuzhiyun * therefore no VBR to set 113*4882a593Smuzhiyun */ 114*4882a593Smuzhiyun#if !defined(CONFIG_MONITOR_IS_IN_RAM) 115*4882a593Smuzhiyun move.l #CONFIG_SYS_FLASH_BASE, %d0 116*4882a593Smuzhiyun movec %d0, %VBR 117*4882a593Smuzhiyun#endif 118*4882a593Smuzhiyun 119*4882a593Smuzhiyun /* initialize general use internal ram */ 120*4882a593Smuzhiyun move.l #0, %d0 121*4882a593Smuzhiyun move.l #(ICACHE_STATUS), %a1 /* icache */ 122*4882a593Smuzhiyun move.l #(DCACHE_STATUS), %a2 /* dcache */ 123*4882a593Smuzhiyun move.l %d0, (%a1) 124*4882a593Smuzhiyun move.l %d0, (%a2) 125*4882a593Smuzhiyun 126*4882a593Smuzhiyun /* put relocation table address to a5 */ 127*4882a593Smuzhiyun move.l #__got_start, %a5 128*4882a593Smuzhiyun 129*4882a593Smuzhiyun /* setup stack initially on top of internal static ram */ 130*4882a593Smuzhiyun move.l #(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_RAM_SIZE), %sp 131*4882a593Smuzhiyun 132*4882a593Smuzhiyun /* 133*4882a593Smuzhiyun * if configured, malloc_f arena will be reserved first, 134*4882a593Smuzhiyun * then (and always) gd struct space will be reserved 135*4882a593Smuzhiyun */ 136*4882a593Smuzhiyun move.l %sp, -(%sp) 137*4882a593Smuzhiyun bsr board_init_f_alloc_reserve 138*4882a593Smuzhiyun 139*4882a593Smuzhiyun /* update stack and frame-pointers */ 140*4882a593Smuzhiyun move.l %d0, %sp 141*4882a593Smuzhiyun move.l %sp, %fp 142*4882a593Smuzhiyun 143*4882a593Smuzhiyun /* initialize reserved area */ 144*4882a593Smuzhiyun move.l %d0, -(%sp) 145*4882a593Smuzhiyun bsr board_init_f_init_reserve 146*4882a593Smuzhiyun 147*4882a593Smuzhiyun /* run low-level CPU init code (from flash) */ 148*4882a593Smuzhiyun bsr cpu_init_f 149*4882a593Smuzhiyun 150*4882a593Smuzhiyun /* run low-level board init code (from flash) */ 151*4882a593Smuzhiyun clr.l %sp@- 152*4882a593Smuzhiyun bsr board_init_f 153*4882a593Smuzhiyun 154*4882a593Smuzhiyun /* board_init_f() does not return */ 155*4882a593Smuzhiyun 156*4882a593Smuzhiyun/******************************************************************************/ 157*4882a593Smuzhiyun 158*4882a593Smuzhiyun/* 159*4882a593Smuzhiyun * void relocate_code (addr_sp, gd, addr_moni) 160*4882a593Smuzhiyun * 161*4882a593Smuzhiyun * This "function" does not return, instead it continues in RAM 162*4882a593Smuzhiyun * after relocating the monitor code. 163*4882a593Smuzhiyun * 164*4882a593Smuzhiyun */ 165*4882a593Smuzhiyun.globl relocate_code 166*4882a593Smuzhiyunrelocate_code: 167*4882a593Smuzhiyun link.w %a6,#0 168*4882a593Smuzhiyun move.l 8(%a6), %sp /* set new stack pointer */ 169*4882a593Smuzhiyun move.l 12(%a6), %d0 /* Save copy of Global Data pointer */ 170*4882a593Smuzhiyun move.l 16(%a6), %a0 /* Save copy of Destination Address */ 171*4882a593Smuzhiyun 172*4882a593Smuzhiyun move.l #CONFIG_SYS_MONITOR_BASE, %a1 173*4882a593Smuzhiyun move.l #__init_end, %a2 174*4882a593Smuzhiyun move.l %a0, %a3 175*4882a593Smuzhiyun /* copy the code to RAM */ 176*4882a593Smuzhiyun1: 177*4882a593Smuzhiyun move.l (%a1)+, (%a3)+ 178*4882a593Smuzhiyun cmp.l %a1,%a2 179*4882a593Smuzhiyun bgt.s 1b 180*4882a593Smuzhiyun 181*4882a593Smuzhiyun/* 182*4882a593Smuzhiyun * We are done. Do not return, instead branch to second part of board 183*4882a593Smuzhiyun * initialization, now running from RAM. 184*4882a593Smuzhiyun */ 185*4882a593Smuzhiyun move.l %a0, %a1 186*4882a593Smuzhiyun add.l #(in_ram - CONFIG_SYS_MONITOR_BASE), %a1 187*4882a593Smuzhiyun jmp (%a1) 188*4882a593Smuzhiyun 189*4882a593Smuzhiyunin_ram: 190*4882a593Smuzhiyun 191*4882a593Smuzhiyunclear_bss: 192*4882a593Smuzhiyun /* 193*4882a593Smuzhiyun * Now clear BSS segment 194*4882a593Smuzhiyun */ 195*4882a593Smuzhiyun move.l %a0, %a1 196*4882a593Smuzhiyun add.l #(_sbss - CONFIG_SYS_MONITOR_BASE), %a1 197*4882a593Smuzhiyun move.l %a0, %d1 198*4882a593Smuzhiyun add.l #(_ebss - CONFIG_SYS_MONITOR_BASE), %d1 199*4882a593Smuzhiyun6: 200*4882a593Smuzhiyun clr.l (%a1)+ 201*4882a593Smuzhiyun cmp.l %a1,%d1 202*4882a593Smuzhiyun bgt.s 6b 203*4882a593Smuzhiyun 204*4882a593Smuzhiyun /* 205*4882a593Smuzhiyun * fix got table in RAM 206*4882a593Smuzhiyun */ 207*4882a593Smuzhiyun move.l %a0, %a1 208*4882a593Smuzhiyun add.l #(__got_start - CONFIG_SYS_MONITOR_BASE), %a1 209*4882a593Smuzhiyun 210*4882a593Smuzhiyun /* fix got pointer register a5 */ 211*4882a593Smuzhiyun move.l %a1,%a5 212*4882a593Smuzhiyun 213*4882a593Smuzhiyun move.l %a0, %a2 214*4882a593Smuzhiyun add.l #(__got_end - CONFIG_SYS_MONITOR_BASE), %a2 215*4882a593Smuzhiyun 216*4882a593Smuzhiyun7: 217*4882a593Smuzhiyun move.l (%a1),%d1 218*4882a593Smuzhiyun sub.l #_start, %d1 219*4882a593Smuzhiyun add.l %a0,%d1 220*4882a593Smuzhiyun move.l %d1,(%a1)+ 221*4882a593Smuzhiyun cmp.l %a2, %a1 222*4882a593Smuzhiyun bne 7b 223*4882a593Smuzhiyun 224*4882a593Smuzhiyun /* calculate relative jump to board_init_r in ram */ 225*4882a593Smuzhiyun move.l %a0, %a1 226*4882a593Smuzhiyun add.l #(board_init_r - CONFIG_SYS_MONITOR_BASE), %a1 227*4882a593Smuzhiyun 228*4882a593Smuzhiyun /* set parameters for board_init_r */ 229*4882a593Smuzhiyun move.l %a0,-(%sp) /* dest_addr */ 230*4882a593Smuzhiyun move.l %d0,-(%sp) /* gd */ 231*4882a593Smuzhiyun#if defined(DEBUG) && (CONFIG_SYS_TEXT_BASE!=CONFIG_SYS_INT_FLASH_BASE) && \ 232*4882a593Smuzhiyun defined(CONFIG_SYS_HALT_BEFOR_RAM_JUMP) 233*4882a593Smuzhiyun halt 234*4882a593Smuzhiyun#endif 235*4882a593Smuzhiyun jsr (%a1) 236*4882a593Smuzhiyun 237*4882a593Smuzhiyun/******************************************************************************/ 238*4882a593Smuzhiyun 239*4882a593Smuzhiyun/* exception code */ 240*4882a593Smuzhiyun.globl _fault 241*4882a593Smuzhiyun_fault: 242*4882a593Smuzhiyun bra _fault 243*4882a593Smuzhiyun 244*4882a593Smuzhiyun.globl _exc_handler 245*4882a593Smuzhiyun_exc_handler: 246*4882a593Smuzhiyun SAVE_ALL 247*4882a593Smuzhiyun movel %sp,%sp@- 248*4882a593Smuzhiyun bsr exc_handler 249*4882a593Smuzhiyun addql #4,%sp 250*4882a593Smuzhiyun RESTORE_ALL 251*4882a593Smuzhiyun 252*4882a593Smuzhiyun.globl _int_handler 253*4882a593Smuzhiyun_int_handler: 254*4882a593Smuzhiyun SAVE_ALL 255*4882a593Smuzhiyun movel %sp,%sp@- 256*4882a593Smuzhiyun bsr int_handler 257*4882a593Smuzhiyun addql #4,%sp 258*4882a593Smuzhiyun RESTORE_ALL 259*4882a593Smuzhiyun 260*4882a593Smuzhiyun/******************************************************************************/ 261*4882a593Smuzhiyun 262*4882a593Smuzhiyun.globl version_string 263*4882a593Smuzhiyunversion_string: 264*4882a593Smuzhiyun.ascii U_BOOT_VERSION 265*4882a593Smuzhiyun.ascii " (", U_BOOT_DATE, " - ", U_BOOT_TIME, ")" 266*4882a593Smuzhiyun.ascii CONFIG_IDENT_STRING, "\0" 267*4882a593Smuzhiyun.align 4 268