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 6 * !! 7 * Written by Ralf Baechle and Andreas Busse 7 * Vineetg: Dec 2007 !! 8 * Copyright (C) 1994 - 99, 2003, 06 Ralf Baechle 8 * -Check if we are running on Simulator or o !! 9 * Copyright (C) 1996 Paul M. Antoine 9 * to skip certain things during boot on !! 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. >> 13 * Kevin Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com >> 14 * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. 10 */ 15 */ >> 16 #include <linux/init.h> >> 17 #include <linux/threads.h> 11 18 12 #include <linux/linkage.h> !! 19 #include <asm/addrspace.h> 13 #include <asm/asm-offsets.h> !! 20 #include <asm/asm.h> 14 #include <asm/entry.h> !! 21 #include <asm/asmmacro.h> 15 #include <asm/arcregs.h> << 16 #include <asm/cache.h> << 17 #include <asm/dsp-impl.h> << 18 #include <asm/irqflags.h> 22 #include <asm/irqflags.h> 19 !! 23 #include <asm/regdef.h> 20 .macro CPU_EARLY_SETUP !! 24 #include <asm/pgtable-bits.h> 21 !! 25 #include <asm/mipsregs.h> 22 ; Setting up Vectror Table (in case ex !! 26 #include <asm/stackframe.h> 23 sr @_int_vec_base_lds, [AUX_INTR_ !! 27 24 !! 28 #include <kernel-entry-init.h> 25 ; Disable I-cache/D-cache if kernel so !! 29 26 lr r5, [ARC_REG_IC_BCR] !! 30 /* 27 breq r5, 0, 1f ; I$ d !! 31 * inputs are the text nasid in t1, data nasid in t2. 28 lr r5, [ARC_REG_IC_CTRL] !! 32 */ 29 #ifdef CONFIG_ARC_HAS_ICACHE !! 33 .macro MAPPED_KERNEL_SETUP_TLB 30 bclr r5, r5, 0 ; 0 - !! 34 #ifdef CONFIG_MAPPED_KERNEL >> 35 /* >> 36 * This needs to read the nasid - assume 0 for now. >> 37 * Drop in 0xffffffffc0000000 in tlbhi, 0+VG in tlblo_0, >> 38 * 0+DVG in tlblo_1. >> 39 */ >> 40 dli t0, 0xffffffffc0000000 >> 41 dmtc0 t0, CP0_ENTRYHI >> 42 li t0, 0x1c000 # Offset of text into node memory >> 43 dsll t1, NASID_SHFT # Shift text nasid into place >> 44 dsll t2, NASID_SHFT # Same for data nasid >> 45 or t1, t1, t0 # Physical load address of kernel text >> 46 or t2, t2, t0 # Physical load address of kernel data >> 47 dsrl t1, 12 # 4K pfn >> 48 dsrl t2, 12 # 4K pfn >> 49 dsll t1, 6 # Get pfn into place >> 50 dsll t2, 6 # Get pfn into place >> 51 li t0, ((_PAGE_GLOBAL|_PAGE_VALID| _CACHE_CACHABLE_COW) >> 6) >> 52 or t0, t0, t1 >> 53 mtc0 t0, CP0_ENTRYLO0 # physaddr, VG, cach exlwr >> 54 li t0, ((_PAGE_GLOBAL|_PAGE_VALID| _PAGE_DIRTY|_CACHE_CACHABLE_COW) >> 6) >> 55 or t0, t0, t2 >> 56 mtc0 t0, CP0_ENTRYLO1 # physaddr, DVG, cach exlwr >> 57 li t0, 0x1ffe000 # MAPPED_KERN_TLBMASK, TLBPGMASK_16M >> 58 mtc0 t0, CP0_PAGEMASK >> 59 li t0, 0 # KMAP_INX >> 60 mtc0 t0, CP0_INDEX >> 61 li t0, 1 >> 62 mtc0 t0, CP0_WIRED >> 63 tlbwi 31 #else 64 #else 32 bset r5, r5, 0 ; I$ e !! 65 mtc0 zero, CP0_WIRED 33 #endif 66 #endif 34 sr r5, [ARC_REG_IC_CTRL] !! 67 .endm 35 68 36 1: !! 69 /* 37 lr r5, [ARC_REG_DC_BCR] !! 70 * For the moment disable interrupts, mark the kernel mode and 38 breq r5, 0, 1f ; D$ d !! 71 * set ST0_KX so that the CPU does not spit fire when using 39 lr r5, [ARC_REG_DC_CTRL] !! 72 * 64-bit addresses. A full initialization of the CPU's status 40 bclr r5, r5, 6 ; Inva !! 73 * register is done later in per_cpu_trap_init(). 41 #ifdef CONFIG_ARC_HAS_DCACHE !! 74 */ 42 bclr r5, r5, 0 ; Enab !! 75 .macro setup_c0_status set clr >> 76 .set push >> 77 #ifdef CONFIG_MIPS_MT_SMTC >> 78 /* >> 79 * For SMTC, we need to set privilege and disable interrupts only for >> 80 * the current TC, using the TCStatus register. >> 81 */ >> 82 mfc0 t0, CP0_TCSTATUS >> 83 /* Fortunately CU 0 is in the same place in both registers */ >> 84 /* Set TCU0, TMX, TKSU (for later inversion) and IXMT */ >> 85 li t1, ST0_CU0 | 0x08001c00 >> 86 or t0, t1 >> 87 /* Clear TKSU, leave IXMT */ >> 88 xori t0, 0x00001800 >> 89 mtc0 t0, CP0_TCSTATUS >> 90 _ehb >> 91 /* We need to leave the global IE bit set, but clear EXL...*/ >> 92 mfc0 t0, CP0_STATUS >> 93 or t0, ST0_CU0 | ST0_EXL | ST0_ERL | \set | \clr >> 94 xor t0, ST0_EXL | ST0_ERL | \clr >> 95 mtc0 t0, CP0_STATUS 43 #else 96 #else 44 bset r5, r5, 0 ; Disa !! 97 mfc0 t0, CP0_STATUS >> 98 or t0, ST0_CU0|\set|0x1f|\clr >> 99 xor t0, 0x1f|\clr >> 100 mtc0 t0, CP0_STATUS >> 101 .set noreorder >> 102 sll zero,3 # ehb 45 #endif 103 #endif 46 sr r5, [ARC_REG_DC_CTRL] !! 104 .set pop >> 105 .endm 47 106 48 1: !! 107 .macro setup_c0_status_pri >> 108 #ifdef CONFIG_64BIT >> 109 setup_c0_status ST0_KX 0 >> 110 #else >> 111 setup_c0_status 0 0 >> 112 #endif >> 113 .endm 49 114 50 #ifdef CONFIG_ISA_ARCV2 !! 115 .macro setup_c0_status_sec 51 ; Unaligned access is disabled at rese !! 116 #ifdef CONFIG_64BIT 52 ; gcc 7.3.1 (ARC GNU 2018.03) onwards !! 117 setup_c0_status ST0_KX ST0_BEV 53 ; by default << 54 lr r5, [status32] << 55 #ifdef CONFIG_ARC_USE_UNALIGNED_MEM_ACCESS << 56 bset r5, r5, STATUS_AD_BIT << 57 #else 118 #else 58 ; Although disabled at reset, bootload !! 119 setup_c0_status 0 ST0_BEV 59 bclr r5, r5, STATUS_AD_BIT << 60 #endif 120 #endif 61 kflag r5 !! 121 .endm 62 122 63 #ifdef CONFIG_ARC_LPB_DISABLE !! 123 #ifndef CONFIG_NO_EXCEPT_FILL 64 lr r5, [ARC_REG_LPB_BUILD] !! 124 /* 65 breq r5, 0, 1f ; LPB !! 125 * Reserved space for exception handlers. 66 mov r5, 1 !! 126 * Necessary for machines which link their kernels at KSEG0. 67 sr r5, [ARC_REG_LPB_CTRL] !! 127 */ 68 1: !! 128 .fill 0x400 69 #endif /* CONFIG_ARC_LPB_DISABLE */ !! 129 #endif 70 130 71 /* On HSDK, CCMs need to remapped supe !! 131 EXPORT(_stext) 72 #ifdef CONFIG_ARC_SOC_HSDK << 73 mov r6, 0x60000000 << 74 lr r5, [ARC_REG_ICCM_BUILD] << 75 breq r5, 0, 1f << 76 sr r6, [ARC_REG_AUX_ICCM] << 77 1: << 78 lr r5, [ARC_REG_DCCM_BUILD] << 79 breq r5, 0, 2f << 80 sr r6, [ARC_REG_AUX_DCCM] << 81 2: << 82 #endif /* CONFIG_ARC_SOC_HSDK */ << 83 132 84 #endif /* CONFIG_ISA_ARCV2 */ !! 133 #ifdef CONFIG_BOOT_RAW >> 134 /* >> 135 * Give us a fighting chance of running if execution beings at the >> 136 * kernel load address. This is needed because this platform does >> 137 * not have a ELF loader yet. >> 138 */ >> 139 FEXPORT(__kernel_entry) >> 140 j kernel_entry >> 141 #endif 85 142 86 ; Config DSP_CTRL properly, so kernel !! 143 __REF 87 ; multiply-accumulate, and divide oper << 88 DSP_EARLY_INIT << 89 .endm << 90 << 91 .section .init.text, "ax",@progbits << 92 << 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 144 107 CPU_EARLY_SETUP !! 145 NESTED(kernel_entry, 16, sp) # kernel entry point 108 146 109 #ifdef CONFIG_SMP !! 147 kernel_entry_setup # cpu specific setup 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 << 120 .Lmaster_proceed: << 121 #endif << 122 << 123 ; Clear BSS before updating any global << 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 148 132 ; Uboot - kernel ABI !! 149 setup_c0_status_pri 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 150 145 ; setup stack (fp, sp) !! 151 /* We might not get launched at the address the kernel is linked to, 146 mov fp, 0 !! 152 so we jump there. */ >> 153 PTR_LA t0, 0f >> 154 jr t0 >> 155 0: >> 156 >> 157 #ifdef CONFIG_MIPS_MT_SMTC >> 158 /* >> 159 * In SMTC kernel, "CLI" is thread-specific, in TCStatus. >> 160 * We still need to enable interrupts globally in Status, >> 161 * and clear EXL/ERL. >> 162 * >> 163 * TCContext is used to track interrupt levels under >> 164 * service in SMTC kernel. Clear for boot TC before >> 165 * allowing any interrupts. >> 166 */ >> 167 mtc0 zero, CP0_TCCONTEXT >> 168 >> 169 mfc0 t0, CP0_STATUS >> 170 ori t0, t0, 0xff1f >> 171 xori t0, t0, 0x001e >> 172 mtc0 t0, CP0_STATUS >> 173 #endif /* CONFIG_MIPS_MT_SMTC */ >> 174 >> 175 PTR_LA t0, __bss_start # clear .bss >> 176 LONG_S zero, (t0) >> 177 PTR_LA t1, __bss_stop - LONGSIZE >> 178 1: >> 179 PTR_ADDIU t0, LONGSIZE >> 180 LONG_S zero, (t0) >> 181 bne t0, t1, 1b >> 182 >> 183 LONG_S a0, fw_arg0 # firmware arguments >> 184 LONG_S a1, fw_arg1 >> 185 LONG_S a2, fw_arg2 >> 186 LONG_S a3, fw_arg3 >> 187 >> 188 MTC0 zero, CP0_CONTEXT # clear context register >> 189 PTR_LA $28, init_thread_union >> 190 /* Set the SP after an empty pt_regs. */ >> 191 PTR_LI sp, _THREAD_SIZE - 32 - PT_SIZE >> 192 PTR_ADDU sp, $28 >> 193 back_to_back_c0_hazard >> 194 set_saved_sp sp, t0, t1 >> 195 PTR_SUBU sp, 4 * SZREG # init stack pointer 147 196 148 ; tsk->thread_info is really a PAGE, w !! 197 j start_kernel 149 GET_TSK_STACK_BASE r9, sp ; r9 = !! 198 END(kernel_entry) 150 199 151 j start_kernel ; "C" entry po !! 200 __CPUINIT 152 END(stext) << 153 201 154 #ifdef CONFIG_SMP 202 #ifdef CONFIG_SMP 155 ;--------------------------------------------- !! 203 /* 156 ; First lines of code run by secondary bef !! 204 * SMP slave cpus entry point. Board specific code for bootstrap calls this 157 ;--------------------------------------------- !! 205 * function after setting up the stack and gp registers. 158 .section .text, "ax",@progbits !! 206 */ 159 ENTRY(first_lines_of_secondary) !! 207 NESTED(smp_bootstrap, 16, sp) 160 !! 208 #ifdef CONFIG_MIPS_MT_SMTC 161 ; setup per-cpu idle task as "current" !! 209 /* 162 ld r0, [@secondary_idle_tsk] !! 210 * Read-modify-writes of Status must be atomic, and this 163 SET_CURR_TASK_ON_CPU r0, r1 !! 211 * is one case where CLI is invoked without EXL being 164 !! 212 * necessarily set. The CLI and setup_c0_status will 165 ; setup stack (fp, sp) !! 213 * in fact be redundant for all but the first TC of 166 mov fp, 0 !! 214 * each VPE being booted. 167 !! 215 */ 168 ; set its stack base to tsk->thread_in !! 216 DMT 10 # dmt t2 /* t0, t1 are used by CLI and setup_c0_status() */ 169 GET_TSK_STACK_BASE r0, sp !! 217 jal mips_ihb >> 218 #endif /* CONFIG_MIPS_MT_SMTC */ >> 219 setup_c0_status_sec >> 220 smp_slave_setup >> 221 #ifdef CONFIG_MIPS_MT_SMTC >> 222 andi t2, t2, VPECONTROL_TE >> 223 beqz t2, 2f >> 224 EMT # emt >> 225 2: >> 226 #endif /* CONFIG_MIPS_MT_SMTC */ >> 227 j start_secondary >> 228 END(smp_bootstrap) >> 229 #endif /* CONFIG_SMP */ 170 230 171 j start_kernel_secondary !! 231 __FINIT 172 END(first_lines_of_secondary) << 173 #endif <<
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.