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, 95, 96, 97, 98, 99, 2003 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 */ 11 !! 16 #include <linux/config.h> 12 #include <linux/linkage.h> !! 17 #include <linux/init.h> 13 #include <asm/asm-offsets.h> !! 18 #include <linux/threads.h> 14 #include <asm/entry.h> !! 19 15 #include <asm/arcregs.h> !! 20 #include <asm/asm.h> 16 #include <asm/cache.h> !! 21 #include <asm/regdef.h> 17 #include <asm/dsp-impl.h> !! 22 #include <asm/page.h> 18 #include <asm/irqflags.h> !! 23 #include <asm/processor.h> 19 !! 24 #include <asm/mipsregs.h> 20 .macro CPU_EARLY_SETUP !! 25 #include <asm/stackframe.h> 21 !! 26 #ifdef CONFIG_SGI_IP27 22 ; Setting up Vectror Table (in case ex !! 27 #include <asm/sn/addrs.h> 23 sr @_int_vec_base_lds, [AUX_INTR_ !! 28 #include <asm/sn/sn0/hubni.h> 24 !! 29 #include <asm/sn/klkernvars.h> 25 ; Disable I-cache/D-cache if kernel so << 26 lr r5, [ARC_REG_IC_BCR] << 27 breq r5, 0, 1f ; I$ d << 28 lr r5, [ARC_REG_IC_CTRL] << 29 #ifdef CONFIG_ARC_HAS_ICACHE << 30 bclr r5, r5, 0 ; 0 - << 31 #else << 32 bset r5, r5, 0 ; I$ e << 33 #endif 30 #endif 34 sr r5, [ARC_REG_IC_CTRL] << 35 31 36 1: !! 32 .macro ARC64_TWIDDLE_PC 37 lr r5, [ARC_REG_DC_BCR] !! 33 #if defined(CONFIG_ARC64) || defined(CONFIG_MAPPED_KERNEL) 38 breq r5, 0, 1f ; D$ d !! 34 /* We get launched at a XKPHYS address but the kernel is linked to 39 lr r5, [ARC_REG_DC_CTRL] !! 35 run at a KSEG0 address, so jump there. */ 40 bclr r5, r5, 6 ; Inva !! 36 PTR_LA t0, \@f 41 #ifdef CONFIG_ARC_HAS_DCACHE !! 37 jr t0 42 bclr r5, r5, 0 ; Enab !! 38 \@: 43 #else << 44 bset r5, r5, 0 ; Disa << 45 #endif 39 #endif 46 sr r5, [ARC_REG_DC_CTRL] !! 40 .endm 47 << 48 1: << 49 41 50 #ifdef CONFIG_ISA_ARCV2 !! 42 #ifdef CONFIG_SGI_IP27 51 ; Unaligned access is disabled at rese !! 43 /* 52 ; gcc 7.3.1 (ARC GNU 2018.03) onwards !! 44 * outputs the local nasid into res. IP27 stuff. 53 ; by default !! 45 */ 54 lr r5, [status32] !! 46 .macro GET_NASID_ASM res 55 #ifdef CONFIG_ARC_USE_UNALIGNED_MEM_ACCESS !! 47 dli \res, LOCAL_HUB_ADDR(NI_STATUS_REV_ID) 56 bset r5, r5, STATUS_AD_BIT !! 48 ld \res, (\res) >> 49 and \res, NSRI_NODEID_MASK >> 50 dsrl \res, NSRI_NODEID_SHFT >> 51 .endm >> 52 #endif /* CONFIG_SGI_IP27 */ >> 53 >> 54 /* >> 55 * inputs are the text nasid in t1, data nasid in t2. >> 56 */ >> 57 .macro MAPPED_KERNEL_SETUP_TLB >> 58 #ifdef CONFIG_MAPPED_KERNEL >> 59 /* >> 60 * This needs to read the nasid - assume 0 for now. >> 61 * Drop in 0xffffffffc0000000 in tlbhi, 0+VG in tlblo_0, >> 62 * 0+DVG in tlblo_1. >> 63 */ >> 64 dli t0, 0xffffffffc0000000 >> 65 dmtc0 t0, CP0_ENTRYHI >> 66 li t0, 0x1c000 # Offset of text into node memory >> 67 dsll t1, NASID_SHFT # Shift text nasid into place >> 68 dsll t2, NASID_SHFT # Same for data nasid >> 69 or t1, t1, t0 # Physical load address of kernel text >> 70 or t2, t2, t0 # Physical load address of kernel data >> 71 dsrl t1, 12 # 4K pfn >> 72 dsrl t2, 12 # 4K pfn >> 73 dsll t1, 6 # Get pfn into place >> 74 dsll t2, 6 # Get pfn into place >> 75 li t0, ((_PAGE_GLOBAL|_PAGE_VALID| _CACHE_CACHABLE_COW) >> 6) >> 76 or t0, t0, t1 >> 77 mtc0 t0, CP0_ENTRYLO0 # physaddr, VG, cach exlwr >> 78 li t0, ((_PAGE_GLOBAL|_PAGE_VALID| _PAGE_DIRTY|_CACHE_CACHABLE_COW) >> 6) >> 79 or t0, t0, t2 >> 80 mtc0 t0, CP0_ENTRYLO1 # physaddr, DVG, cach exlwr >> 81 li t0, 0x1ffe000 # MAPPED_KERN_TLBMASK, TLBPGMASK_16M >> 82 mtc0 t0, CP0_PAGEMASK >> 83 li t0, 0 # KMAP_INX >> 84 mtc0 t0, CP0_INDEX >> 85 li t0, 1 >> 86 mtc0 t0, CP0_WIRED >> 87 tlbwi 57 #else 88 #else 58 ; Although disabled at reset, bootload !! 89 mtc0 zero, CP0_WIRED 59 bclr r5, r5, STATUS_AD_BIT << 60 #endif 90 #endif 61 kflag r5 !! 91 .endm 62 << 63 #ifdef CONFIG_ARC_LPB_DISABLE << 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 92 71 /* On HSDK, CCMs need to remapped supe !! 93 /* 72 #ifdef CONFIG_ARC_SOC_HSDK !! 94 * Reserved space for exception handlers. 73 mov r6, 0x60000000 !! 95 * Necessary for machines which link their kernels at KSEG0. 74 lr r5, [ARC_REG_ICCM_BUILD] !! 96 */ 75 breq r5, 0, 1f !! 97 .fill 0x400 76 sr r6, [ARC_REG_AUX_ICCM] !! 98 >> 99 EXPORT(stext) # used for profiling >> 100 EXPORT(_stext) >> 101 >> 102 __INIT >> 103 >> 104 NESTED(kernel_entry, 16, sp) # kernel entry point >> 105 #ifdef CONFIG_SGI_IP27 >> 106 GET_NASID_ASM t1 >> 107 move t2, t1 # text and data are here >> 108 MAPPED_KERNEL_SETUP_TLB >> 109 #endif /* IP27 */ >> 110 >> 111 ARC64_TWIDDLE_PC >> 112 >> 113 CLI # disable interrupts >> 114 >> 115 PTR_LA $28, init_thread_union >> 116 PTR_ADDIU sp, $28, _THREAD_SIZE - 32 >> 117 set_saved_sp sp, t0, t1 >> 118 PTR_SUBU sp, 4 * SZREG # init stack pointer >> 119 >> 120 /* >> 121 * The firmware/bootloader passes argc/argp/envp >> 122 * to us as arguments. But clear bss first because >> 123 * the romvec and other important info is stored there >> 124 * by prom_init(). >> 125 */ >> 126 PTR_LA t0, __bss_start >> 127 LONG_S zero, (t0) >> 128 PTR_LA t1, __bss_stop - LONGSIZE 77 1: 129 1: 78 lr r5, [ARC_REG_DCCM_BUILD] !! 130 PTR_ADDIU t0, LONGSIZE 79 breq r5, 0, 2f !! 131 LONG_S zero, (t0) 80 sr r6, [ARC_REG_AUX_DCCM] !! 132 bne t0, t1, 1b 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 133 107 CPU_EARLY_SETUP !! 134 jal init_arch >> 135 END(kernel_entry) 108 136 109 #ifdef CONFIG_SMP 137 #ifdef CONFIG_SMP 110 GET_CPU_ID r5 !! 138 /* 111 cmp r5, 0 !! 139 * SMP slave cpus entry point. Board specific code for bootstrap calls this 112 mov.nz r0, r5 !! 140 * function after setting up the stack and gp registers. 113 bz .Lmaster_proceed !! 141 */ 114 !! 142 NESTED(smp_bootstrap, 16, sp) 115 ; Non-Masters wait for Master to boot !! 143 #ifdef CONFIG_SGI_IP27 116 ; when they resume, tail-call to entry !! 144 GET_NASID_ASM t1 117 mov blink, @first_lines_of_seconda !! 145 li t0, KLDIR_OFFSET + (KLI_KERN_VARS * KLDIR_ENT_SIZE) + \ 118 j arc_platform_smp_wait_to_boot !! 146 KLDIR_OFF_POINTER + K0BASE 119 !! 147 dsll t1, NASID_SHFT 120 .Lmaster_proceed: !! 148 or t0, t0, t1 >> 149 ld t0, 0(t0) # t0 points to kern_vars struct >> 150 lh t1, KV_RO_NASID_OFFSET(t0) >> 151 lh t2, KV_RW_NASID_OFFSET(t0) >> 152 MAPPED_KERNEL_SETUP_TLB >> 153 ARC64_TWIDDLE_PC >> 154 #endif /* CONFIG_SGI_IP27 */ >> 155 >> 156 CLI >> 157 >> 158 #ifdef CONFIG_MIPS64 >> 159 /* >> 160 * For the moment set ST0_KU so the CPU will not spit fire when >> 161 * executing 64-bit instructions. The full initialization of the >> 162 * CPU's status register is done later in per_cpu_trap_init(). >> 163 */ >> 164 mfc0 t0, CP0_STATUS >> 165 or t0, ST0_KX >> 166 mtc0 t0, CP0_STATUS 121 #endif 167 #endif 122 !! 168 jal start_secondary 123 ; Clear BSS before updating any global !! 169 END(smp_bootstrap) 124 ; XXX: use ZOL here !! 170 #endif /* CONFIG_SMP */ 125 mov r5, __bss_start !! 171 126 sub r6, __bss_stop, r5 !! 172 __FINIT 127 lsr.f lp_count, r6, 2 !! 173 128 lpnz 1f !! 174 .comm kernelsp, NR_CPUS * 8, 8 129 st.ab 0, [r5, 4] !! 175 .comm pgd_current, NR_CPUS * 8, 8 130 1: !! 176 131 !! 177 .macro page name, order=0 132 ; Uboot - kernel ABI !! 178 .globl \name 133 ; r0 = [0] No uboot interaction, [1 !! 179 \name: .size \name, (_PAGE_SIZE << \order) 134 ; r1 = magic number (always zero as !! 180 .org . + (_PAGE_SIZE << \order) 135 ; r2 = pointer to uboot provided cm !! 181 .type \name, @object 136 ; These are handled later in handle_ub !! 182 .endm 137 st r0, [@uboot_tag] !! 183 138 st r1, [@uboot_magic] !! 184 .data 139 st r2, [@uboot_arg] !! 185 .align PAGE_SHIFT 140 !! 186 141 ; setup "current" tsk and optionally c !! 187 #ifdef CONFIG_MIPS32 142 mov r9, @init_task !! 188 /* 143 SET_CURR_TASK_ON_CPU r9, r0 ; r9 = !! 189 * Here we only have a two-level pagetable structure ... 144 !! 190 */ 145 ; setup stack (fp, sp) !! 191 page swapper_pg_dir, _PGD_ORDER 146 mov fp, 0 !! 192 page invalid_pte_table, _PTE_ORDER 147 !! 193 #endif 148 ; tsk->thread_info is really a PAGE, w !! 194 #ifdef CONFIG_MIPS64 149 GET_TSK_STACK_BASE r9, sp ; r9 = !! 195 /* 150 !! 196 * ... but on 64-bit we've got three-level pagetables with a 151 j start_kernel ; "C" entry po !! 197 * slightly different layout ... 152 END(stext) !! 198 */ 153 !! 199 page swapper_pg_dir, _PGD_ORDER 154 #ifdef CONFIG_SMP !! 200 page invalid_pmd_table, _PMD_ORDER 155 ;--------------------------------------------- !! 201 page invalid_pte_table, _PTE_ORDER 156 ; First lines of code run by secondary bef !! 202 157 ;--------------------------------------------- !! 203 /* 158 .section .text, "ax",@progbits !! 204 * 64-bit kernel mappings are really screwed up ... 159 ENTRY(first_lines_of_secondary) !! 205 */ 160 !! 206 page kptbl, _PGD_ORDER 161 ; setup per-cpu idle task as "current" !! 207 .globl ekptbl 162 ld r0, [@secondary_idle_tsk] !! 208 page kpmdtbl, 0 163 SET_CURR_TASK_ON_CPU r0, r1 !! 209 ekptbl: 164 << 165 ; setup stack (fp, sp) << 166 mov fp, 0 << 167 << 168 ; set its stack base to tsk->thread_in << 169 GET_TSK_STACK_BASE r0, sp << 170 << 171 j start_kernel_secondary << 172 END(first_lines_of_secondary) << 173 #endif 210 #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.