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/mipsregs.h> 21 !! 25 #include <asm/stackframe.h> 22 ; Setting up Vectror Table (in case ex !! 26 23 sr @_int_vec_base_lds, [AUX_INTR_ !! 27 #include <kernel-entry-init.h> 24 !! 28 25 ; Disable I-cache/D-cache if kernel so !! 29 /* 26 lr r5, [ARC_REG_IC_BCR] !! 30 * For the moment disable interrupts, mark the kernel mode and 27 breq r5, 0, 1f ; I$ d !! 31 * set ST0_KX so that the CPU does not spit fire when using 28 lr r5, [ARC_REG_IC_CTRL] !! 32 * 64-bit addresses. A full initialization of the CPU's status 29 #ifdef CONFIG_ARC_HAS_ICACHE !! 33 * register is done later in per_cpu_trap_init(). 30 bclr r5, r5, 0 ; 0 - !! 34 */ >> 35 .macro setup_c0_status set clr >> 36 .set push >> 37 mfc0 t0, CP0_STATUS >> 38 or t0, ST0_CU0|\set|0x1f|\clr >> 39 xor t0, 0x1f|\clr >> 40 mtc0 t0, CP0_STATUS >> 41 .set noreorder >> 42 sll zero,3 # ehb >> 43 .set pop >> 44 .endm >> 45 >> 46 .macro setup_c0_status_pri >> 47 #ifdef CONFIG_64BIT >> 48 setup_c0_status ST0_KX 0 31 #else 49 #else 32 bset r5, r5, 0 ; I$ e !! 50 setup_c0_status 0 0 33 #endif 51 #endif 34 sr r5, [ARC_REG_IC_CTRL] !! 52 .endm 35 53 36 1: !! 54 .macro setup_c0_status_sec 37 lr r5, [ARC_REG_DC_BCR] !! 55 #ifdef CONFIG_64BIT 38 breq r5, 0, 1f ; D$ d !! 56 setup_c0_status ST0_KX ST0_BEV 39 lr r5, [ARC_REG_DC_CTRL] << 40 bclr r5, r5, 6 ; Inva << 41 #ifdef CONFIG_ARC_HAS_DCACHE << 42 bclr r5, r5, 0 ; Enab << 43 #else 57 #else 44 bset r5, r5, 0 ; Disa !! 58 setup_c0_status 0 ST0_BEV 45 #endif 59 #endif 46 sr r5, [ARC_REG_DC_CTRL] !! 60 .endm 47 << 48 1: << 49 61 50 #ifdef CONFIG_ISA_ARCV2 !! 62 #ifndef CONFIG_NO_EXCEPT_FILL 51 ; Unaligned access is disabled at rese !! 63 /* 52 ; gcc 7.3.1 (ARC GNU 2018.03) onwards !! 64 * Reserved space for exception handlers. 53 ; by default !! 65 * Necessary for machines which link their kernels at KSEG0. 54 lr r5, [status32] !! 66 */ 55 #ifdef CONFIG_ARC_USE_UNALIGNED_MEM_ACCESS !! 67 .fill 0x400 56 bset r5, r5, STATUS_AD_BIT << 57 #else << 58 ; Although disabled at reset, bootload << 59 bclr r5, r5, STATUS_AD_BIT << 60 #endif 68 #endif 61 kflag r5 << 62 69 63 #ifdef CONFIG_ARC_LPB_DISABLE !! 70 EXPORT(_stext) 64 lr r5, [ARC_REG_LPB_BUILD] << 65 breq r5, 0, 1f ; LPB << 66 mov r5, 1 << 67 sr r5, [ARC_REG_LPB_CTRL] << 68 1: << 69 #endif /* CONFIG_ARC_LPB_DISABLE */ << 70 71 71 /* On HSDK, CCMs need to remapped supe !! 72 #ifdef CONFIG_BOOT_RAW 72 #ifdef CONFIG_ARC_SOC_HSDK !! 73 /* 73 mov r6, 0x60000000 !! 74 * Give us a fighting chance of running if execution beings at the 74 lr r5, [ARC_REG_ICCM_BUILD] !! 75 * kernel load address. This is needed because this platform does 75 breq r5, 0, 1f !! 76 * not have a ELF loader yet. 76 sr r6, [ARC_REG_AUX_ICCM] !! 77 */ 77 1: !! 78 FEXPORT(__kernel_entry) 78 lr r5, [ARC_REG_DCCM_BUILD] !! 79 j kernel_entry 79 breq r5, 0, 2f !! 80 #endif 80 sr r6, [ARC_REG_AUX_DCCM] << 81 2: << 82 #endif /* CONFIG_ARC_SOC_HSDK */ << 83 << 84 #endif /* CONFIG_ISA_ARCV2 */ << 85 << 86 ; Config DSP_CTRL properly, so kernel << 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 81 107 CPU_EARLY_SETUP !! 82 __REF 108 83 109 #ifdef CONFIG_SMP !! 84 NESTED(kernel_entry, 16, sp) # kernel entry point 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 85 132 ; Uboot - kernel ABI !! 86 kernel_entry_setup # cpu specific setup 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 87 145 ; setup stack (fp, sp) !! 88 setup_c0_status_pri 146 mov fp, 0 << 147 89 148 ; tsk->thread_info is really a PAGE, w !! 90 /* We might not get launched at the address the kernel is linked to, 149 GET_TSK_STACK_BASE r9, sp ; r9 = !! 91 so we jump there. */ >> 92 PTR_LA t0, 0f >> 93 jr t0 >> 94 0: 150 95 151 j start_kernel ; "C" entry po !! 96 #ifdef CONFIG_USE_OF 152 END(stext) !! 97 #ifdef CONFIG_MIPS_RAW_APPENDED_DTB >> 98 PTR_LA t2, __appended_dtb 153 99 154 #ifdef CONFIG_SMP !! 100 #ifdef CONFIG_CPU_BIG_ENDIAN 155 ;--------------------------------------------- !! 101 li t1, 0xd00dfeed 156 ; First lines of code run by secondary bef !! 102 #else 157 ;--------------------------------------------- !! 103 li t1, 0xedfe0dd0 158 .section .text, "ax",@progbits !! 104 #endif 159 ENTRY(first_lines_of_secondary) !! 105 lw t0, (t2) 160 !! 106 beq t0, t1, dtb_found 161 ; setup per-cpu idle task as "current" !! 107 #endif 162 ld r0, [@secondary_idle_tsk] !! 108 li t1, -2 163 SET_CURR_TASK_ON_CPU r0, r1 !! 109 move t2, a1 >> 110 beq a0, t1, dtb_found 164 111 165 ; setup stack (fp, sp) !! 112 li t2, 0 166 mov fp, 0 !! 113 dtb_found: >> 114 #endif >> 115 PTR_LA t0, __bss_start # clear .bss >> 116 LONG_S zero, (t0) >> 117 PTR_LA t1, __bss_stop - LONGSIZE >> 118 1: >> 119 PTR_ADDIU t0, LONGSIZE >> 120 LONG_S zero, (t0) >> 121 bne t0, t1, 1b >> 122 >> 123 LONG_S a0, fw_arg0 # firmware arguments >> 124 LONG_S a1, fw_arg1 >> 125 LONG_S a2, fw_arg2 >> 126 LONG_S a3, fw_arg3 167 127 168 ; set its stack base to tsk->thread_in !! 128 #ifdef CONFIG_USE_OF 169 GET_TSK_STACK_BASE r0, sp !! 129 LONG_S t2, fw_passed_dtb >> 130 #endif 170 131 171 j start_kernel_secondary !! 132 MTC0 zero, CP0_CONTEXT # clear context register 172 END(first_lines_of_secondary) !! 133 PTR_LA $28, init_thread_union >> 134 /* Set the SP after an empty pt_regs. */ >> 135 PTR_LI sp, _THREAD_SIZE - 32 - PT_SIZE >> 136 PTR_ADDU sp, $28 >> 137 back_to_back_c0_hazard >> 138 set_saved_sp sp, t0, t1 >> 139 PTR_SUBU sp, 4 * SZREG # init stack pointer >> 140 >> 141 #ifdef CONFIG_RELOCATABLE >> 142 /* Copy kernel and apply the relocations */ >> 143 jal relocate_kernel >> 144 >> 145 /* Repoint the sp into the new kernel image */ >> 146 PTR_LI sp, _THREAD_SIZE - 32 - PT_SIZE >> 147 PTR_ADDU sp, $28 >> 148 set_saved_sp sp, t0, t1 >> 149 PTR_SUBU sp, 4 * SZREG # init stack pointer >> 150 >> 151 /* >> 152 * relocate_kernel returns the entry point either >> 153 * in the relocated kernel or the original if for >> 154 * some reason relocation failed - jump there now >> 155 * with instruction hazard barrier because of the >> 156 * newly sync'd icache. >> 157 */ >> 158 jr.hb v0 >> 159 #else >> 160 j start_kernel 173 #endif 161 #endif >> 162 END(kernel_entry) >> 163 >> 164 #ifdef CONFIG_SMP >> 165 /* >> 166 * SMP slave cpus entry point. Board specific code for bootstrap calls this >> 167 * function after setting up the stack and gp registers. >> 168 */ >> 169 NESTED(smp_bootstrap, 16, sp) >> 170 smp_slave_setup >> 171 setup_c0_status_sec >> 172 j start_secondary >> 173 END(smp_bootstrap) >> 174 #endif /* CONFIG_SMP */
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.