1*4882a593Smuzhiyun/* 2*4882a593Smuzhiyun * Copyright (C) 2013-2014 Synopsys, Inc. All rights reserved. 3*4882a593Smuzhiyun * 4*4882a593Smuzhiyun * SPDX-License-Identifier: GPL-2.0+ 5*4882a593Smuzhiyun */ 6*4882a593Smuzhiyun 7*4882a593Smuzhiyun#include <asm-offsets.h> 8*4882a593Smuzhiyun#include <config.h> 9*4882a593Smuzhiyun#include <linux/linkage.h> 10*4882a593Smuzhiyun#include <asm/arcregs.h> 11*4882a593Smuzhiyun 12*4882a593SmuzhiyunENTRY(_start) 13*4882a593Smuzhiyun; ARCompact devices are not supposed to be SMP so master/slave check 14*4882a593Smuzhiyun; makes no sense. 15*4882a593Smuzhiyun#ifdef CONFIG_ISA_ARCV2 16*4882a593Smuzhiyun ; Non-masters will be halted immediately, they might be kicked later 17*4882a593Smuzhiyun ; by platform code right before passing control to the Linux kernel 18*4882a593Smuzhiyun ; in bootm.c:boot_jump_linux(). 19*4882a593Smuzhiyun lr r5, [identity] 20*4882a593Smuzhiyun lsr r5, r5, 8 21*4882a593Smuzhiyun bmsk r5, r5, 7 22*4882a593Smuzhiyun cmp r5, 0 23*4882a593Smuzhiyun mov.nz r0, r5 24*4882a593Smuzhiyun bz .Lmaster_proceed 25*4882a593Smuzhiyun flag 1 26*4882a593Smuzhiyun nop 27*4882a593Smuzhiyun nop 28*4882a593Smuzhiyun nop 29*4882a593Smuzhiyun 30*4882a593Smuzhiyun.Lmaster_proceed: 31*4882a593Smuzhiyun#endif 32*4882a593Smuzhiyun 33*4882a593Smuzhiyun /* Setup interrupt vector base that matches "__text_start" */ 34*4882a593Smuzhiyun sr __ivt_start, [ARC_AUX_INTR_VEC_BASE] 35*4882a593Smuzhiyun 36*4882a593Smuzhiyun ; Disable/enable I-cache according to configuration 37*4882a593Smuzhiyun lr r5, [ARC_BCR_IC_BUILD] 38*4882a593Smuzhiyun breq r5, 0, 1f ; I$ doesn't exist 39*4882a593Smuzhiyun lr r5, [ARC_AUX_IC_CTRL] 40*4882a593Smuzhiyun#ifndef CONFIG_SYS_ICACHE_OFF 41*4882a593Smuzhiyun bclr r5, r5, 0 ; 0 - Enable, 1 is Disable 42*4882a593Smuzhiyun#else 43*4882a593Smuzhiyun bset r5, r5, 0 ; I$ exists, but is not used 44*4882a593Smuzhiyun#endif 45*4882a593Smuzhiyun sr r5, [ARC_AUX_IC_CTRL] 46*4882a593Smuzhiyun 47*4882a593Smuzhiyun1: 48*4882a593Smuzhiyun ; Disable/enable D-cache according to configuration 49*4882a593Smuzhiyun lr r5, [ARC_BCR_DC_BUILD] 50*4882a593Smuzhiyun breq r5, 0, 1f ; D$ doesn't exist 51*4882a593Smuzhiyun lr r5, [ARC_AUX_DC_CTRL] 52*4882a593Smuzhiyun bclr r5, r5, 6 ; Invalidate (discard w/o wback) 53*4882a593Smuzhiyun#ifndef CONFIG_SYS_DCACHE_OFF 54*4882a593Smuzhiyun bclr r5, r5, 0 ; Enable (+Inv) 55*4882a593Smuzhiyun#else 56*4882a593Smuzhiyun bset r5, r5, 0 ; Disable (+Inv) 57*4882a593Smuzhiyun#endif 58*4882a593Smuzhiyun sr r5, [ARC_AUX_DC_CTRL] 59*4882a593Smuzhiyun 60*4882a593Smuzhiyun1: 61*4882a593Smuzhiyun#ifdef CONFIG_ISA_ARCV2 62*4882a593Smuzhiyun ; Disable System-Level Cache (SLC) 63*4882a593Smuzhiyun lr r5, [ARC_BCR_SLC] 64*4882a593Smuzhiyun breq r5, 0, 1f ; SLC doesn't exist 65*4882a593Smuzhiyun lr r5, [ARC_AUX_SLC_CTRL] 66*4882a593Smuzhiyun bclr r5, r5, 6 ; Invalidate (discard w/o wback) 67*4882a593Smuzhiyun bclr r5, r5, 0 ; Enable (+Inv) 68*4882a593Smuzhiyun sr r5, [ARC_AUX_SLC_CTRL] 69*4882a593Smuzhiyun 70*4882a593Smuzhiyun1: 71*4882a593Smuzhiyun#endif 72*4882a593Smuzhiyun 73*4882a593Smuzhiyun /* Establish C runtime stack and frame */ 74*4882a593Smuzhiyun mov %sp, CONFIG_SYS_INIT_SP_ADDR 75*4882a593Smuzhiyun mov %fp, %sp 76*4882a593Smuzhiyun 77*4882a593Smuzhiyun /* Allocate reserved area from current top of stack */ 78*4882a593Smuzhiyun mov %r0, %sp 79*4882a593Smuzhiyun bl board_init_f_alloc_reserve 80*4882a593Smuzhiyun /* Set stack below reserved area, adjust frame pointer accordingly */ 81*4882a593Smuzhiyun mov %sp, %r0 82*4882a593Smuzhiyun mov %fp, %sp 83*4882a593Smuzhiyun 84*4882a593Smuzhiyun /* Initialize reserved area - note: r0 already contains address */ 85*4882a593Smuzhiyun bl board_init_f_init_reserve 86*4882a593Smuzhiyun 87*4882a593Smuzhiyun /* Zero the one and only argument of "board_init_f" */ 88*4882a593Smuzhiyun mov_s %r0, 0 89*4882a593Smuzhiyun j board_init_f 90*4882a593SmuzhiyunENDPROC(_start) 91*4882a593Smuzhiyun 92*4882a593Smuzhiyun/* 93*4882a593Smuzhiyun * void board_init_f_r_trampoline(stack-pointer address) 94*4882a593Smuzhiyun * 95*4882a593Smuzhiyun * This "function" does not return, instead it continues in RAM 96*4882a593Smuzhiyun * after relocating the monitor code. 97*4882a593Smuzhiyun * 98*4882a593Smuzhiyun * r0 = new stack-pointer 99*4882a593Smuzhiyun */ 100*4882a593SmuzhiyunENTRY(board_init_f_r_trampoline) 101*4882a593Smuzhiyun /* Set up the stack- and frame-pointers */ 102*4882a593Smuzhiyun mov %sp, %r0 103*4882a593Smuzhiyun mov %fp, %sp 104*4882a593Smuzhiyun 105*4882a593Smuzhiyun /* Update position of intterupt vector table */ 106*4882a593Smuzhiyun lr %r0, [ARC_AUX_INTR_VEC_BASE] 107*4882a593Smuzhiyun ld %r1, [%r25, GD_RELOC_OFF] 108*4882a593Smuzhiyun add %r0, %r0, %r1 109*4882a593Smuzhiyun sr %r0, [ARC_AUX_INTR_VEC_BASE] 110*4882a593Smuzhiyun 111*4882a593Smuzhiyun /* Re-enter U-Boot by calling board_init_f_r */ 112*4882a593Smuzhiyun j board_init_f_r 113*4882a593SmuzhiyunENDPROC(board_init_f_r_trampoline) 114