16260fb04SPeter Tyser/* 26260fb04SPeter Tyser * (C) Copyright 2007 Michal Simek 36260fb04SPeter Tyser * (C) Copyright 2004 Atmark Techno, Inc. 46260fb04SPeter Tyser * 56260fb04SPeter Tyser * Michal SIMEK <monstr@monstr.eu> 66260fb04SPeter Tyser * Yasushi SHOJI <yashi@atmark-techno.com> 76260fb04SPeter Tyser * 81a459660SWolfgang Denk * SPDX-License-Identifier: GPL-2.0+ 96260fb04SPeter Tyser */ 106260fb04SPeter Tyser 1125ddd1fbSWolfgang Denk#include <asm-offsets.h> 126260fb04SPeter Tyser#include <config.h> 136260fb04SPeter Tyser 146260fb04SPeter Tyser .text 156260fb04SPeter Tyser .global _start 166260fb04SPeter Tyser_start: 1786c1b2a8SMichal Simek /* 1886c1b2a8SMichal Simek * reserve registers: 1986c1b2a8SMichal Simek * r10: Stores little/big endian offset for vectors 2086c1b2a8SMichal Simek * r2: Stores imm opcode 2186c1b2a8SMichal Simek * r3: Stores brai opcode 2286c1b2a8SMichal Simek */ 2386c1b2a8SMichal Simek 246260fb04SPeter Tyser mts rmsr, r0 /* disable cache */ 25*9d242745SMichal Simek 26*9d242745SMichal Simek#if defined(CONFIG_SPL_BUILD) 27*9d242745SMichal Simek addi r1, r0, CONFIG_SPL_STACK_ADDR 28*9d242745SMichal Simek addi r1, r1, -4 /* Decrement SP to top of memory */ 29*9d242745SMichal Simek#else 306260fb04SPeter Tyser addi r1, r0, CONFIG_SYS_INIT_SP_OFFSET 316260fb04SPeter Tyser addi r1, r1, -4 /* Decrement SP to top of memory */ 32b98cba09SMichal Simek 33b98cba09SMichal Simek /* Find-out if u-boot is running on BIG/LITTLE endian platform 34b98cba09SMichal Simek * There are some steps which is necessary to keep in mind: 35b98cba09SMichal Simek * 1. Setup offset value to r6 36b98cba09SMichal Simek * 2. Store word offset value to address 0x0 37b98cba09SMichal Simek * 3. Load just byte from address 0x0 38b98cba09SMichal Simek * 4a) LITTLE endian - r10 contains 0x2 because it is the smallest 39b98cba09SMichal Simek * value that's why is on address 0x0 40b98cba09SMichal Simek * 4b) BIG endian - r10 contains 0x0 because 0x2 offset is on addr 0x3 41b98cba09SMichal Simek */ 42b98cba09SMichal Simek addik r6, r0, 0x2 /* BIG/LITTLE endian offset */ 43f3090fceSMichal Simek lwi r7, r0, 0x28 44f3090fceSMichal Simek swi r6, r0, 0x28 /* used first unused MB vector */ 45f3090fceSMichal Simek lbui r10, r0, 0x28 /* used first unused MB vector */ 46f3090fceSMichal Simek swi r7, r0, 0x28 47b98cba09SMichal Simek 486260fb04SPeter Tyser /* add opcode instruction for 32bit jump - 2 instruction imm & brai */ 4986c1b2a8SMichal Simek addi r2, r0, 0xb0000000 /* hex b000 opcode imm */ 5086c1b2a8SMichal Simek addi r3, r0, 0xb8080000 /* hew b808 opcode brai */ 516260fb04SPeter Tyser 526260fb04SPeter Tyser#ifdef CONFIG_SYS_RESET_ADDRESS 536260fb04SPeter Tyser /* reset address */ 5486c1b2a8SMichal Simek swi r2, r0, 0x0 /* reset address - imm opcode */ 5586c1b2a8SMichal Simek swi r3, r0, 0x4 /* reset address - brai opcode */ 5686c1b2a8SMichal Simek 576260fb04SPeter Tyser addik r6, r0, CONFIG_SYS_RESET_ADDRESS 586260fb04SPeter Tyser sw r6, r1, r0 595562bcc2SMichal Simek lhu r7, r1, r10 605562bcc2SMichal Simek rsubi r8, r10, 0x2 615562bcc2SMichal Simek sh r7, r0, r8 625562bcc2SMichal Simek rsubi r8, r10, 0x6 635562bcc2SMichal Simek sh r6, r0, r8 646260fb04SPeter Tyser#endif 656260fb04SPeter Tyser 666260fb04SPeter Tyser#ifdef CONFIG_SYS_USR_EXCEP 676260fb04SPeter Tyser /* user_vector_exception */ 6886c1b2a8SMichal Simek swi r2, r0, 0x8 /* user vector exception - imm opcode */ 6986c1b2a8SMichal Simek swi r3, r0, 0xC /* user vector exception - brai opcode */ 7086c1b2a8SMichal Simek 716260fb04SPeter Tyser addik r6, r0, _exception_handler 726260fb04SPeter Tyser sw r6, r1, r0 73b98cba09SMichal Simek /* 74b98cba09SMichal Simek * BIG ENDIAN memory map for user exception 75b98cba09SMichal Simek * 0x8: 0xB000XXXX 76b98cba09SMichal Simek * 0xC: 0xB808XXXX 77b98cba09SMichal Simek * 78b98cba09SMichal Simek * then it is necessary to count address for storing the most significant 79b98cba09SMichal Simek * 16bits from _exception_handler address and copy it to 80b98cba09SMichal Simek * 0xa address. Big endian use offset in r10=0 that's why is it just 81b98cba09SMichal Simek * 0xa address. The same is done for the least significant 16 bits 82b98cba09SMichal Simek * for 0xe address. 83b98cba09SMichal Simek * 84b98cba09SMichal Simek * LITTLE ENDIAN memory map for user exception 85b98cba09SMichal Simek * 0x8: 0xXXXX00B0 86b98cba09SMichal Simek * 0xC: 0xXXXX08B8 87b98cba09SMichal Simek * 88b98cba09SMichal Simek * Offset is for little endian setup to 0x2. rsubi instruction decrease 89b98cba09SMichal Simek * address value to ensure that points to proper place which is 90b98cba09SMichal Simek * 0x8 for the most significant 16 bits and 91b98cba09SMichal Simek * 0xC for the least significant 16 bits 92b98cba09SMichal Simek */ 93b98cba09SMichal Simek lhu r7, r1, r10 94b98cba09SMichal Simek rsubi r8, r10, 0xa 95b98cba09SMichal Simek sh r7, r0, r8 96b98cba09SMichal Simek rsubi r8, r10, 0xe 97b98cba09SMichal Simek sh r6, r0, r8 986260fb04SPeter Tyser#endif 996260fb04SPeter Tyser 1006260fb04SPeter Tyser /* interrupt_handler */ 10186c1b2a8SMichal Simek swi r2, r0, 0x10 /* interrupt - imm opcode */ 10286c1b2a8SMichal Simek swi r3, r0, 0x14 /* interrupt - brai opcode */ 10386c1b2a8SMichal Simek 1046260fb04SPeter Tyser addik r6, r0, _interrupt_handler 1056260fb04SPeter Tyser sw r6, r1, r0 106b98cba09SMichal Simek lhu r7, r1, r10 107b98cba09SMichal Simek rsubi r8, r10, 0x12 108b98cba09SMichal Simek sh r7, r0, r8 109b98cba09SMichal Simek rsubi r8, r10, 0x16 110b98cba09SMichal Simek sh r6, r0, r8 1116260fb04SPeter Tyser 1126260fb04SPeter Tyser /* hardware exception */ 11386c1b2a8SMichal Simek swi r2, r0, 0x20 /* hardware exception - imm opcode */ 11486c1b2a8SMichal Simek swi r3, r0, 0x24 /* hardware exception - brai opcode */ 11586c1b2a8SMichal Simek 1166260fb04SPeter Tyser addik r6, r0, _hw_exception_handler 1176260fb04SPeter Tyser sw r6, r1, r0 118b98cba09SMichal Simek lhu r7, r1, r10 119b98cba09SMichal Simek rsubi r8, r10, 0x22 120b98cba09SMichal Simek sh r7, r0, r8 121b98cba09SMichal Simek rsubi r8, r10, 0x26 122b98cba09SMichal Simek sh r6, r0, r8 123*9d242745SMichal Simek#endif /* BUILD_SPL */ 1246260fb04SPeter Tyser 1255811830fSMichal Simek /* Flush cache before enable cache */ 1265811830fSMichal Simek addik r5, r0, 0 1275811830fSMichal Simek addik r6, r0, XILINX_DCACHE_BYTE_SIZE 1285811830fSMichal Simekflush: bralid r15, flush_cache 1295811830fSMichal Simek nop 1305811830fSMichal Simek 1316260fb04SPeter Tyser /* enable instruction and data cache */ 1326260fb04SPeter Tyser mfs r12, rmsr 1336260fb04SPeter Tyser ori r12, r12, 0xa0 1346260fb04SPeter Tyser mts rmsr, r12 1356260fb04SPeter Tyser 1366260fb04SPeter Tyserclear_bss: 1376260fb04SPeter Tyser /* clear BSS segments */ 1386260fb04SPeter Tyser addi r5, r0, __bss_start 1396260fb04SPeter Tyser addi r4, r0, __bss_end 1406260fb04SPeter Tyser cmp r6, r5, r4 1416260fb04SPeter Tyser beqi r6, 3f 1426260fb04SPeter Tyser2: 1436260fb04SPeter Tyser swi r0, r5, 0 /* write zero to loc */ 1446260fb04SPeter Tyser addi r5, r5, 4 /* increment to next loc */ 1456260fb04SPeter Tyser cmp r6, r5, r4 /* check if we have reach the end */ 1466260fb04SPeter Tyser bnei r6, 2b 1476260fb04SPeter Tyser3: /* jumping to board_init */ 148*9d242745SMichal Simek#ifndef CONFIG_SPL_BUILD 1492380b8f5SMichal Simek brai board_init_f 150*9d242745SMichal Simek#else 151*9d242745SMichal Simek brai board_init_r 152*9d242745SMichal Simek#endif 1536260fb04SPeter Tyser1: bri 1b 1546260fb04SPeter Tyser 155*9d242745SMichal Simek#ifndef CONFIG_SPL_BUILD 1566260fb04SPeter Tyser/* 1576260fb04SPeter Tyser * Read 16bit little endian 1586260fb04SPeter Tyser */ 1596260fb04SPeter Tyser .text 1606260fb04SPeter Tyser .global in16 1616260fb04SPeter Tyser .ent in16 1626260fb04SPeter Tyser .align 2 1636260fb04SPeter Tyserin16: lhu r3, r0, r5 1646260fb04SPeter Tyser bslli r4, r3, 8 1656260fb04SPeter Tyser bsrli r3, r3, 8 1666260fb04SPeter Tyser andi r4, r4, 0xffff 1676260fb04SPeter Tyser or r3, r3, r4 1686260fb04SPeter Tyser rtsd r15, 8 1696260fb04SPeter Tyser sext16 r3, r3 1706260fb04SPeter Tyser .end in16 1716260fb04SPeter Tyser 1726260fb04SPeter Tyser/* 1736260fb04SPeter Tyser * Write 16bit little endian 1746260fb04SPeter Tyser * first parameter(r5) - address, second(r6) - short value 1756260fb04SPeter Tyser */ 1766260fb04SPeter Tyser .text 1776260fb04SPeter Tyser .global out16 1786260fb04SPeter Tyser .ent out16 1796260fb04SPeter Tyser .align 2 1806260fb04SPeter Tyserout16: bslli r3, r6, 8 1816260fb04SPeter Tyser bsrli r6, r6, 8 1826260fb04SPeter Tyser andi r3, r3, 0xffff 1836260fb04SPeter Tyser or r3, r3, r6 1846260fb04SPeter Tyser sh r3, r0, r5 1856260fb04SPeter Tyser rtsd r15, 8 1866260fb04SPeter Tyser or r0, r0, r0 1876260fb04SPeter Tyser .end out16 188*9d242745SMichal Simek#endif 189