1 /* SPDX-License-Identifier: GPL-2.0-only */ << 2 /* 1 /* 3 * ARC CPU startup Code !! 2 * This file is subject to the terms and conditions of the GNU General Public >> 3 * License. See the file "COPYING" in the main directory of this archive >> 4 * for more details. 4 * 5 * 5 * Copyright (C) 2004, 2007-2010, 2011-2012 Sy !! 6 * Copyright (C) 1994, 1995 Waldorf Electronics >> 7 * Written by Ralf Baechle and Andreas Busse >> 8 * Copyright (C) 1995 - 1999 Ralf Baechle >> 9 * Copyright (C) 1996 Paul M. Antoine >> 10 * Modified for DECStation and hence R3000 support by Paul M. Antoine >> 11 * Further modifications by David S. Miller and Harald Koerfgen >> 12 * Copyright (C) 1999 Silicon Graphics, Inc. 6 * 13 * 7 * Vineetg: Dec 2007 !! 14 * Kevin Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com 8 * -Check if we are running on Simulator or o !! 15 * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. 9 * to skip certain things during boot on << 10 */ 16 */ 11 !! 17 #include <linux/config.h> 12 #include <linux/linkage.h> !! 18 #include <linux/init.h> 13 #include <asm/asm-offsets.h> !! 19 #include <linux/threads.h> 14 #include <asm/entry.h> !! 20 15 #include <asm/arcregs.h> !! 21 #include <asm/asm.h> 16 #include <asm/cache.h> !! 22 #include <asm/current.h> 17 #include <asm/dsp-impl.h> !! 23 #include <asm/offset.h> 18 #include <asm/irqflags.h> !! 24 #include <asm/pgtable-bits.h> 19 !! 25 #include <asm/processor.h> 20 .macro CPU_EARLY_SETUP !! 26 #include <asm/regdef.h> 21 !! 27 #include <asm/cachectl.h> 22 ; Setting up Vectror Table (in case ex !! 28 #include <asm/mipsregs.h> 23 sr @_int_vec_base_lds, [AUX_INTR_ !! 29 #include <asm/stackframe.h> 24 !! 30 25 ; Disable I-cache/D-cache if kernel so !! 31 .text 26 lr r5, [ARC_REG_IC_BCR] !! 32 /* 27 breq r5, 0, 1f ; I$ d !! 33 * Reserved space for exception handlers. 28 lr r5, [ARC_REG_IC_CTRL] !! 34 * Necessary for machines which link their kernels at KSEG0. 29 #ifdef CONFIG_ARC_HAS_ICACHE !! 35 */ 30 bclr r5, r5, 0 ; 0 - !! 36 .fill 0x400 31 #else !! 37 32 bset r5, r5, 0 ; I$ e !! 38 /* The following two symbols are used for kernel profiling. */ 33 #endif !! 39 EXPORT(stext) 34 sr r5, [ARC_REG_IC_CTRL] !! 40 EXPORT(_stext) 35 !! 41 36 1: !! 42 __INIT 37 lr r5, [ARC_REG_DC_BCR] !! 43 38 breq r5, 0, 1f ; D$ d !! 44 /* Cache Error */ 39 lr r5, [ARC_REG_DC_CTRL] !! 45 LEAF(except_vec2_generic) 40 bclr r5, r5, 6 ; Inva !! 46 .set noreorder 41 #ifdef CONFIG_ARC_HAS_DCACHE !! 47 .set noat 42 bclr r5, r5, 0 ; Enab !! 48 .set mips0 43 #else !! 49 /* 44 bset r5, r5, 0 ; Disa !! 50 * This is a very bad place to be. Our cache error 45 #endif !! 51 * detection has triggered. If we have write-back data 46 sr r5, [ARC_REG_DC_CTRL] !! 52 * in the cache, we may not be able to recover. As a 47 !! 53 * first-order desperate measure, turn off KSEG0 cacheing. 48 1: !! 54 */ 49 !! 55 mfc0 k0,CP0_CONFIG 50 #ifdef CONFIG_ISA_ARCV2 !! 56 li k1,~CONF_CM_CMASK 51 ; Unaligned access is disabled at rese !! 57 and k0,k0,k1 52 ; gcc 7.3.1 (ARC GNU 2018.03) onwards !! 58 ori k0,k0,CONF_CM_UNCACHED 53 ; by default !! 59 mtc0 k0,CP0_CONFIG 54 lr r5, [status32] !! 60 /* Give it a few cycles to sink in... */ 55 #ifdef CONFIG_ARC_USE_UNALIGNED_MEM_ACCESS !! 61 nop 56 bset r5, r5, STATUS_AD_BIT !! 62 nop 57 #else !! 63 nop 58 ; Although disabled at reset, bootload !! 64 59 bclr r5, r5, STATUS_AD_BIT !! 65 j cache_parity_error 60 #endif !! 66 nop 61 kflag r5 !! 67 END(except_vec2_generic) 62 !! 68 63 #ifdef CONFIG_ARC_LPB_DISABLE !! 69 .set at 64 lr r5, [ARC_REG_LPB_BUILD] !! 70 65 breq r5, 0, 1f ; LPB !! 71 /* 66 mov r5, 1 !! 72 * Special interrupt vector for embedded MIPS. This is a 67 sr r5, [ARC_REG_LPB_CTRL] !! 73 * dedicated interrupt vector which reduces interrupt processing 68 1: !! 74 * overhead. The jump instruction will be inserted here at 69 #endif /* CONFIG_ARC_LPB_DISABLE */ !! 75 * initialization time. This handler may only be 8 bytes in 70 !! 76 * size! 71 /* On HSDK, CCMs need to remapped supe !! 77 */ 72 #ifdef CONFIG_ARC_SOC_HSDK !! 78 NESTED(except_vec4, 0, sp) 73 mov r6, 0x60000000 !! 79 1: j 1b /* Dummy, will be replaced */ 74 lr r5, [ARC_REG_ICCM_BUILD] !! 80 nop 75 breq r5, 0, 1f !! 81 END(except_vec4) 76 sr r6, [ARC_REG_AUX_ICCM] !! 82 >> 83 /* >> 84 * EJTAG debug exception handler. >> 85 * The EJTAG debug exception entry point is 0xbfc00480, which >> 86 * normally is in the boot PROM, so the boot PROM must do a >> 87 * unconditional jump to this vector. >> 88 */ >> 89 NESTED(except_vec_ejtag_debug, 0, sp) >> 90 j ejtag_debug_handler >> 91 nop >> 92 END(except_vec_ejtag_debug) >> 93 >> 94 __FINIT >> 95 >> 96 /* >> 97 * EJTAG debug exception handler. >> 98 */ >> 99 NESTED(ejtag_debug_handler, PT_SIZE, sp) >> 100 .set noat >> 101 .set noreorder >> 102 mtc0 k0, CP0_DESAVE >> 103 mfc0 k0, CP0_DEBUG >> 104 >> 105 sll k0, k0, 30 # Check for SDBBP. >> 106 bgez k0, ejtag_return >> 107 >> 108 la k0, ejtag_debug_buffer >> 109 sw k1, 0(k0) >> 110 SAVE_ALL >> 111 jal ejtag_exception_handler >> 112 move a0, sp >> 113 RESTORE_ALL >> 114 la k0, ejtag_debug_buffer >> 115 lw k1, 0(k0) >> 116 >> 117 ejtag_return: >> 118 mfc0 k0, CP0_DESAVE >> 119 .set mips32 >> 120 deret >> 121 .set mips0 >> 122 nop >> 123 .set at >> 124 END(ejtag_debug_handler) >> 125 >> 126 __INIT >> 127 >> 128 /* >> 129 * NMI debug exception handler for MIPS reference boards. >> 130 * The NMI debug exception entry point is 0xbfc00000, which >> 131 * normally is in the boot PROM, so the boot PROM must do a >> 132 * unconditional jump to this vector. >> 133 */ >> 134 NESTED(except_vec_nmi, 0, sp) >> 135 j nmi_handler >> 136 nop >> 137 END(except_vec_nmi) >> 138 >> 139 __FINIT >> 140 >> 141 NESTED(nmi_handler, PT_SIZE, sp) >> 142 .set noat >> 143 .set noreorder >> 144 .set mips3 >> 145 SAVE_ALL >> 146 jal nmi_exception_handler >> 147 move a0, sp >> 148 RESTORE_ALL >> 149 eret >> 150 .set at >> 151 .set mips0 >> 152 END(nmi_handler) >> 153 >> 154 __INIT >> 155 >> 156 /* >> 157 * Kernel entry point >> 158 */ >> 159 NESTED(kernel_entry, 16, sp) >> 160 .set noreorder >> 161 >> 162 /* >> 163 * The firmware/bootloader passes argc/argp/envp >> 164 * to us as arguments. But clear bss first because >> 165 * the romvec and other important info is stored there >> 166 * by prom_init(). >> 167 */ >> 168 la t0, _edata >> 169 sw zero, (t0) >> 170 la t1, (_end - 4) 77 1: 171 1: 78 lr r5, [ARC_REG_DCCM_BUILD] !! 172 addiu t0, 4 79 breq r5, 0, 2f !! 173 bne t0, t1, 1b 80 sr r6, [ARC_REG_AUX_DCCM] !! 174 sw zero, (t0) 81 2: !! 175 82 #endif /* CONFIG_ARC_SOC_HSDK */ !! 176 /* 83 !! 177 * Stack for kernel and init, current variable 84 #endif /* CONFIG_ISA_ARCV2 */ !! 178 */ 85 !! 179 la $28, init_task_union 86 ; Config DSP_CTRL properly, so kernel !! 180 addiu t0, $28, KERNEL_STACK_SIZE-32 87 ; multiply-accumulate, and divide oper !! 181 subu sp, t0, 4*SZREG 88 DSP_EARLY_INIT !! 182 sw t0, kernelsp 89 .endm !! 183 90 !! 184 jal init_arch 91 .section .init.text, "ax",@progbits !! 185 nop 92 !! 186 END(kernel_entry) 93 ;--------------------------------------------- << 94 ; Default Reset Handler (jumped into from Rese << 95 ; - Don't clobber r0,r1,r2 as they might have << 96 ; - Platforms can override this weak version i << 97 ;--------------------------------------------- << 98 WEAK(res_service) << 99 j stext << 100 END(res_service) << 101 << 102 ;--------------------------------------------- << 103 ; Kernel Entry point << 104 ;--------------------------------------------- << 105 ENTRY(stext) << 106 187 107 CPU_EARLY_SETUP << 108 188 109 #ifdef CONFIG_SMP 189 #ifdef CONFIG_SMP 110 GET_CPU_ID r5 << 111 cmp r5, 0 << 112 mov.nz r0, r5 << 113 bz .Lmaster_proceed << 114 << 115 ; Non-Masters wait for Master to boot << 116 ; when they resume, tail-call to entry << 117 mov blink, @first_lines_of_seconda << 118 j arc_platform_smp_wait_to_boot << 119 190 120 .Lmaster_proceed: !! 191 /* >> 192 * SMP slave cpus entry point. Board specific code for bootstrap calls this >> 193 * function after setting up the stack and gp registers. >> 194 */ >> 195 LEAF(smp_bootstrap) >> 196 .set push >> 197 .set noreorder >> 198 mtc0 zero, CP0_WIRED >> 199 CLI >> 200 mfc0 t0, CP0_STATUS >> 201 li t1, ~(ST0_CU1|ST0_CU2|ST0_CU3|ST0_KX|ST0_SX|ST0_UX) >> 202 and t0, t1 >> 203 or t0, (ST0_CU0); >> 204 jal start_secondary >> 205 mtc0 t0, CP0_STATUS >> 206 .set pop >> 207 END(smp_bootstrap) 121 #endif 208 #endif 122 209 123 ; Clear BSS before updating any global !! 210 __FINIT 124 ; XXX: use ZOL here << 125 mov r5, __bss_start << 126 sub r6, __bss_stop, r5 << 127 lsr.f lp_count, r6, 2 << 128 lpnz 1f << 129 st.ab 0, [r5, 4] << 130 1: << 131 << 132 ; Uboot - kernel ABI << 133 ; r0 = [0] No uboot interaction, [1 << 134 ; r1 = magic number (always zero as << 135 ; r2 = pointer to uboot provided cm << 136 ; These are handled later in handle_ub << 137 st r0, [@uboot_tag] << 138 st r1, [@uboot_magic] << 139 st r2, [@uboot_arg] << 140 << 141 ; setup "current" tsk and optionally c << 142 mov r9, @init_task << 143 SET_CURR_TASK_ON_CPU r9, r0 ; r9 = << 144 << 145 ; setup stack (fp, sp) << 146 mov fp, 0 << 147 << 148 ; tsk->thread_info is really a PAGE, w << 149 GET_TSK_STACK_BASE r9, sp ; r9 = << 150 211 151 j start_kernel ; "C" entry po !! 212 /* 152 END(stext) !! 213 * This buffer is reserved for the use of the EJTAG debug 153 !! 214 * handler. 154 #ifdef CONFIG_SMP !! 215 */ 155 ;--------------------------------------------- !! 216 .data 156 ; First lines of code run by secondary bef !! 217 EXPORT(ejtag_debug_buffer) 157 ;--------------------------------------------- !! 218 .fill 4 158 .section .text, "ax",@progbits !! 219 159 ENTRY(first_lines_of_secondary) !! 220 .comm kernelsp, NR_CPUS * 8, 8 160 !! 221 .comm pgd_current, NR_CPUS * 8, 8 161 ; setup per-cpu idle task as "current" !! 222 162 ld r0, [@secondary_idle_tsk] !! 223 .macro page name, order=0 163 SET_CURR_TASK_ON_CPU r0, r1 !! 224 .globl \name 164 !! 225 \name: .size \name, (_PAGE_SIZE << \order) 165 ; setup stack (fp, sp) !! 226 .org . + (_PAGE_SIZE << \order) 166 mov fp, 0 !! 227 .type \name, @object 167 !! 228 .endm 168 ; set its stack base to tsk->thread_in !! 229 169 GET_TSK_STACK_BASE r0, sp !! 230 .data 170 !! 231 .align 12 171 j start_kernel_secondary !! 232 172 END(first_lines_of_secondary) !! 233 page swapper_pg_dir, _PGD_ORDER 173 #endif !! 234 page empty_bad_page, 0 >> 235 page empty_bad_page_table, 0 >> 236 page invalid_pte_table, 0
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.