Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 | /* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2013-2014 Synopsys, Inc. All rights reserved. */ #include <asm-offsets.h> #include <config.h> #include <linux/linkage.h> #include <asm/arcregs.h> #include <system-constants.h> ENTRY(_start) /* Setup interrupt vector base that matches "__text_start" */ sr __ivt_start, [ARC_AUX_INTR_VEC_BASE] ; Disable/enable I-cache according to configuration lr r5, [ARC_BCR_IC_BUILD] breq r5, 0, 1f ; I$ doesn't exist lr r5, [ARC_AUX_IC_CTRL] #if !CONFIG_IS_ENABLED(SYS_ICACHE_OFF) bclr r5, r5, 0 ; 0 - Enable, 1 is Disable #else bset r5, r5, 0 ; I$ exists, but is not used #endif sr r5, [ARC_AUX_IC_CTRL] mov r5, 1 sr r5, [ARC_AUX_IC_IVIC] ; As per ARC HS databook (see chapter 5.3.3.2) ; it is required to add 3 NOPs after each write to IC_IVIC. nop nop nop 1: ; Disable/enable D-cache according to configuration lr r5, [ARC_BCR_DC_BUILD] breq r5, 0, 1f ; D$ doesn't exist lr r5, [ARC_AUX_DC_CTRL] bclr r5, r5, 6 ; Invalidate (discard w/o wback) #if !CONFIG_IS_ENABLED(SYS_DCACHE_OFF) bclr r5, r5, 0 ; Enable (+Inv) #else bset r5, r5, 0 ; Disable (+Inv) #endif sr r5, [ARC_AUX_DC_CTRL] mov r5, 1 sr r5, [ARC_AUX_DC_IVDC] 1: #ifdef CONFIG_ISA_ARCV2 ; Disable System-Level Cache (SLC) lr r5, [ARC_BCR_SLC] breq r5, 0, 1f ; SLC doesn't exist lr r5, [ARC_AUX_SLC_CTRL] bclr r5, r5, 6 ; Invalidate (discard w/o wback) bclr r5, r5, 0 ; Enable (+Inv) sr r5, [ARC_AUX_SLC_CTRL] 1: #endif #ifdef CONFIG_ISA_ARCV2 ; In case of DSP extension presence in HW some instructions ; (related to integer multiply, multiply-accumulate, and divide ; operation) executes on this DSP execution unit. So their ; execution will depend on dsp configuration register (DSP_CTRL) ; As we want these instructions to execute the same way regardless ; of DSP presence we need to set DSP_CTRL properly. lr r5, [ARC_AUX_DSP_BUILD] bmsk r5, r5, 7 breq r5, 0, 1f mov r5, 0 sr r5, [ARC_AUX_DSP_CTRL] 1: #endif #ifdef __ARC_UNALIGNED__ /* * Enable handling of unaligned access in the CPU as by default * this HW feature is disabled while GCC starting from 8.1.0 * unconditionally uses it for ARC HS cores. */ flag 1 << STATUS_AD_BIT #endif /* Establish C runtime stack and frame */ mov %sp, SYS_INIT_SP_ADDR mov %fp, %sp /* Allocate reserved area from current top of stack */ mov %r0, %sp bl board_init_f_alloc_reserve /* Set stack below reserved area, adjust frame pointer accordingly */ mov %sp, %r0 mov %fp, %sp /* Initialize reserved area - note: r0 already contains address */ bl board_init_f_init_reserve #ifdef CONFIG_DEBUG_UART /* Earliest point to set up early debug uart */ bl debug_uart_init #endif /* Zero the one and only argument of "board_init_f" */ mov_s %r0, 0 bl board_init_f /* We only get here if relocation is disabled by GD_FLG_SKIP_RELOC */ /* Make sure we don't lose GD overwritten by zero new GD */ mov %r0, %r25 mov %r1, 0 bl board_init_r ENDPROC(_start) /* * void board_init_f_r_trampoline(stack-pointer address) * * This "function" does not return, instead it continues in RAM * after relocating the monitor code. * * r0 = new stack-pointer */ ENTRY(board_init_f_r_trampoline) /* Set up the stack- and frame-pointers */ mov %sp, %r0 mov %fp, %sp /* Update position of intterupt vector table */ lr %r0, [ARC_AUX_INTR_VEC_BASE] ld %r1, [%r25, GD_RELOC_OFF] add %r0, %r0, %r1 sr %r0, [ARC_AUX_INTR_VEC_BASE] /* Re-enter U-Boot by calling board_init_f_r */ j board_init_f_r ENDPROC(board_init_f_r_trampoline) |