>> 1 /* SPDX-License-Identifier: GPL-2.0 */ 1 /* 2 /* 2 * arch/xtensa/kernel/head.S !! 3 * arch/alpha/kernel/head.S 3 * 4 * 4 * Xtensa Processor startup code. !! 5 * initial boot stuff.. At this point, the bootloader has already 5 * !! 6 * switched into OSF/1 PAL-code, and loaded us at the correct address 6 * This file is subject to the terms and condi !! 7 * (START_ADDR). So there isn't much left for us to do: just set up 7 * License. See the file "COPYING" in the mai !! 8 * the kernel global pointer and jump to the kernel entry-point. 8 * for more details. << 9 * << 10 * Copyright (C) 2001 - 2008 Tensilica Inc. << 11 * << 12 * Chris Zankel <chris@zankel.net> << 13 * Marc Gauthier <marc@tensilica.com, marc@alum << 14 * Joe Taylor <joe@tensilica.com, joetylr@yahoo << 15 * Kevin Chea << 16 */ 9 */ 17 10 18 #include <asm/asmmacro.h> << 19 #include <asm/processor.h> << 20 #include <asm/page.h> << 21 #include <asm/cacheasm.h> << 22 #include <asm/initialize_mmu.h> << 23 #include <asm/mxregs.h> << 24 << 25 #include <linux/init.h> 11 #include <linux/init.h> 26 #include <linux/linkage.h> !! 12 #include <asm/asm-offsets.h> 27 !! 13 #include <asm/pal.h> 28 /* !! 14 #include <asm/setup.h> 29 * This module contains the entry code for ker !! 15 30 * minimal setup needed to call the generic C !! 16 __HEAD 31 * !! 17 .globl _stext 32 * Prerequisites: !! 18 .set noreorder 33 * !! 19 .globl __start 34 * - The kernel image has been loaded to the a !! 20 .ent __start 35 * compiled to. !! 21 _stext: 36 * - a2 contains either 0 or a pointer to a li !! 22 __start: 37 * (see setup.c for more details) !! 23 .prologue 0 38 * !! 24 br $27,1f 39 */ !! 25 1: ldgp $29,0($27) 40 !! 26 /* We need to get current_task_info loaded up... */ 41 /* !! 27 lda $8,init_thread_union 42 * _start !! 28 /* ... and find our stack ... */ 43 * !! 29 lda $30,0x4000 - SIZEOF_PT_REGS($8) 44 * The bootloader passes a pointer to a list !! 30 /* ... and then we can start the kernel. */ 45 */ !! 31 jsr $26,start_kernel 46 !! 32 call_pal PAL_halt 47 /* The first bytes of the kernel image !! 33 .end __start 48 * manually allocate and define the li << 49 * instruction. << 50 */ << 51 << 52 __HEAD << 53 .begin no-absolute-literals << 54 << 55 ENTRY(_start) << 56 << 57 /* Preserve the pointer to the boot pa << 58 wsr a2, excsave1 << 59 _j _SetupOCD << 60 << 61 .align 4 << 62 .literal_position << 63 _SetupOCD: << 64 /* << 65 * Initialize WB, WS, and clear PS.EXC << 66 * Set Interrupt Level just below XCHA << 67 * xt-gdb to single step via DEBUG exc << 68 * by ocd. << 69 */ << 70 #if XCHAL_HAVE_WINDOWED << 71 movi a1, 1 << 72 movi a0, 0 << 73 wsr a1, windowstart << 74 wsr a0, windowbase << 75 rsync << 76 #endif << 77 << 78 movi a1, LOCKLEVEL << 79 wsr a1, ps << 80 rsync << 81 << 82 .global _SetupMMU << 83 _SetupMMU: << 84 Offset = _SetupMMU - _start << 85 << 86 #ifdef CONFIG_INITIALIZE_XTENSA_MMU_INSIDE_VML << 87 initialize_mmu << 88 #if defined(CONFIG_MMU) && XCHAL_HAVE_PTP_MMU << 89 rsr a2, excsave1 << 90 movi a3, XCHAL_KSEG_PADDR << 91 bltu a2, a3, 1f << 92 sub a2, a2, a3 << 93 movi a3, XCHAL_KSEG_SIZE << 94 bgeu a2, a3, 1f << 95 movi a3, XCHAL_KSEG_CACHED_VADDR << 96 add a2, a2, a3 << 97 wsr a2, excsave1 << 98 1: << 99 #endif << 100 #endif << 101 << 102 movi a0, _startup << 103 jx a0 << 104 << 105 ENDPROC(_start) << 106 .end no-absolute-literals << 107 << 108 __REF << 109 .literal_position << 110 << 111 ENTRY(_startup) << 112 << 113 /* Set a0 to 0 for the remaining initi << 114 << 115 movi a0, 0 << 116 << 117 #if XCHAL_HAVE_VECBASE << 118 movi a2, VECBASE_VADDR << 119 wsr a2, vecbase << 120 #endif << 121 << 122 /* Clear debugging registers. */ << 123 << 124 #if XCHAL_HAVE_DEBUG << 125 #if XCHAL_NUM_IBREAK > 0 << 126 wsr a0, ibreakenable << 127 #endif << 128 wsr a0, icount << 129 movi a1, 15 << 130 wsr a0, icountlevel << 131 << 132 .set _index, 0 << 133 .rept XCHAL_NUM_DBREAK << 134 wsr a0, SREG_DBREAKC + _index << 135 .set _index, _index + 1 << 136 .endr << 137 #endif << 138 << 139 /* Clear CCOUNT (not really necessary, << 140 << 141 wsr a0, ccount # not really n << 142 << 143 /* Disable zero-loops. */ << 144 << 145 #if XCHAL_HAVE_LOOPS << 146 wsr a0, lcount << 147 #endif << 148 << 149 /* Disable all timers. */ << 150 << 151 .set _index, 0 << 152 .rept XCHAL_NUM_TIMERS << 153 wsr a0, SREG_CCOMPARE + _index << 154 .set _index, _index + 1 << 155 .endr << 156 << 157 /* Interrupt initialization. */ << 158 << 159 movi a2, XCHAL_INTTYPE_MASK_SOFTWAR << 160 wsr a0, intenable << 161 wsr a2, intclear << 162 << 163 /* Disable coprocessors. */ << 164 << 165 #if XCHAL_HAVE_CP << 166 wsr a0, cpenable << 167 #endif << 168 << 169 /* Initialize the caches. << 170 * a2, a3 are just working registers << 171 */ << 172 << 173 #if XCHAL_DCACHE_LINE_LOCKABLE << 174 ___unlock_dcache_all a2 a3 << 175 #endif << 176 << 177 #if XCHAL_ICACHE_LINE_LOCKABLE << 178 ___unlock_icache_all a2 a3 << 179 #endif << 180 << 181 ___invalidate_dcache_all a2 a3 << 182 ___invalidate_icache_all a2 a3 << 183 << 184 isync << 185 << 186 initialize_cacheattr << 187 << 188 #ifdef CONFIG_HAVE_SMP << 189 movi a2, CCON # MX External << 190 movi a3, 1 << 191 wer a3, a2 << 192 #endif << 193 << 194 /* Setup stack and enable window excep << 195 << 196 movi a1, start_info << 197 l32i a1, a1, 0 << 198 << 199 /* Disable interrupts. */ << 200 /* Enable window exceptions if kernel << 201 movi a2, KERNEL_PS_WOE_MASK | LOCKL << 202 wsr a2, ps << 203 rsync << 204 34 205 #ifdef CONFIG_SMP 35 #ifdef CONFIG_SMP 206 /* !! 36 .align 3 207 * Notice that we assume with SMP that !! 37 .globl __smp_callin 208 * supported by the cores. !! 38 .ent __smp_callin 209 */ !! 39 /* On entry here from SRM console, the HWPCB of the per-cpu 210 rsr a2, prid !! 40 slot for this processor has been loaded. We've arranged 211 bnez a2, .Lboot_secondary !! 41 for the UNIQUE value for this process to contain the PCBB 212 !! 42 of the target idle task. */ 213 #endif /* CONFIG_SMP */ !! 43 __smp_callin: 214 !! 44 .prologue 1 215 /* Unpack data sections !! 45 ldgp $29,0($27) # First order of business, load the GP. 216 * !! 46 217 * The linker script used to build the !! 47 call_pal PAL_rduniq # Grab the target PCBB. 218 * creates a table located at __boot_r !! 48 mov $0,$16 # Install it. 219 * that contains the information what !! 49 call_pal PAL_swpctx 220 * << 221 * Uses a2-a7. << 222 */ << 223 << 224 movi a2, __boot_reloc_table_start << 225 movi a3, __boot_reloc_table_end << 226 << 227 1: beq a2, a3, 3f # no more entr << 228 l32i a4, a2, 0 # start destin << 229 l32i a5, a2, 4 # end destinat << 230 l32i a6, a2, 8 # start source << 231 addi a2, a2, 12 # next entry << 232 beq a4, a5, 1b # skip, empty << 233 beq a4, a6, 1b # skip, source << 234 << 235 2: l32i a7, a6, 0 # load word << 236 addi a6, a6, 4 << 237 s32i a7, a4, 0 # store word << 238 addi a4, a4, 4 << 239 bltu a4, a5, 2b << 240 j 1b << 241 << 242 3: << 243 /* All code and initialized data segme << 244 * Now clear the BSS segment. << 245 */ << 246 << 247 movi a2, __bss_start # start of BSS << 248 movi a3, __bss_stop # end of BSS << 249 << 250 __loopt a2, a3, a4, 2 << 251 s32i a0, a2, 0 << 252 __endla a2, a3, 4 << 253 << 254 #if XCHAL_DCACHE_IS_WRITEBACK << 255 << 256 /* After unpacking, flush the writebac << 257 * instructions/data are available. << 258 */ << 259 << 260 ___flush_dcache_all a2 a3 << 261 #endif << 262 memw << 263 isync << 264 ___invalidate_icache_all a2 a3 << 265 isync << 266 << 267 #ifdef CONFIG_XIP_KERNEL << 268 /* Setup bootstrap CPU stack in XIP ke << 269 << 270 movi a1, start_info << 271 l32i a1, a1, 0 << 272 #endif << 273 << 274 movi abi_arg0, 0 << 275 xsr abi_arg0, excsave1 << 276 << 277 /* init_arch kick-starts the linux ker << 278 << 279 abi_call init_arch << 280 abi_call start_kernel << 281 << 282 should_never_return: << 283 j should_never_return << 284 50 285 #ifdef CONFIG_SMP !! 51 lda $8,0x3fff # Find "current". 286 .Lboot_secondary: !! 52 bic $30,$8,$8 287 << 288 movi a2, cpu_start_ccount << 289 1: << 290 memw << 291 l32i a3, a2, 0 << 292 beqi a3, 0, 1b << 293 movi a3, 0 << 294 s32i a3, a2, 0 << 295 1: << 296 memw << 297 l32i a3, a2, 0 << 298 beqi a3, 0, 1b << 299 wsr a3, ccount << 300 movi a3, 0 << 301 s32i a3, a2, 0 << 302 memw << 303 << 304 movi abi_arg0, 0 << 305 wsr abi_arg0, excsave1 << 306 << 307 abi_call secondary_start_kernel << 308 j should_never_return << 309 << 310 #endif /* CONFIG_SMP */ << 311 << 312 ENDPROC(_startup) << 313 << 314 #ifdef CONFIG_HOTPLUG_CPU << 315 << 316 ENTRY(cpu_restart) << 317 << 318 #if XCHAL_DCACHE_IS_WRITEBACK << 319 ___flush_invalidate_dcache_all a2 a3 << 320 #else << 321 ___invalidate_dcache_all a2 a3 << 322 #endif << 323 memw << 324 movi a2, CCON # MX External << 325 movi a3, 0 << 326 wer a3, a2 << 327 extw << 328 << 329 rsr a0, prid << 330 neg a2, a0 << 331 movi a3, cpu_start_id << 332 memw << 333 s32i a2, a3, 0 << 334 #if XCHAL_DCACHE_IS_WRITEBACK << 335 dhwbi a3, 0 << 336 #endif << 337 1: << 338 memw << 339 l32i a2, a3, 0 << 340 dhi a3, 0 << 341 bne a2, a0, 1b << 342 << 343 /* << 344 * Initialize WB, WS, and clear PS.EXC << 345 * Set Interrupt Level just below XCHA << 346 * xt-gdb to single step via DEBUG exc << 347 * by ocd. << 348 */ << 349 movi a1, 1 << 350 movi a0, 0 << 351 wsr a1, windowstart << 352 wsr a0, windowbase << 353 rsync << 354 << 355 movi a1, LOCKLEVEL << 356 wsr a1, ps << 357 rsync << 358 << 359 j _startup << 360 << 361 ENDPROC(cpu_restart) << 362 << 363 #endif /* CONFIG_HOTPLUG_CPU */ << 364 << 365 /* << 366 * DATA section << 367 */ << 368 << 369 __REFDATA << 370 .align 4 << 371 ENTRY(start_info) << 372 .long init_thread_union + KERNEL_STA << 373 << 374 /* << 375 * BSS section << 376 */ << 377 53 378 __PAGE_ALIGNED_BSS !! 54 jsr $26,smp_callin 379 #ifdef CONFIG_MMU !! 55 call_pal PAL_halt 380 ENTRY(swapper_pg_dir) !! 56 .end __smp_callin 381 .fill PAGE_SIZE, 1, 0 !! 57 #endif /* CONFIG_SMP */ 382 END(swapper_pg_dir) !! 58 383 #endif !! 59 # 384 ENTRY(empty_zero_page) !! 60 # The following two functions are needed for supporting SRM PALcode 385 .fill PAGE_SIZE, 1, 0 !! 61 # on the PC164 (at least), since that PALcode manages the interrupt 386 END(empty_zero_page) !! 62 # masking, and we cannot duplicate the effort without causing problems >> 63 # >> 64 >> 65 .align 3 >> 66 .globl cserve_ena >> 67 .ent cserve_ena >> 68 cserve_ena: >> 69 .prologue 0 >> 70 bis $16,$16,$17 >> 71 lda $16,52($31) >> 72 call_pal PAL_cserve >> 73 ret ($26) >> 74 .end cserve_ena >> 75 >> 76 .align 3 >> 77 .globl cserve_dis >> 78 .ent cserve_dis >> 79 cserve_dis: >> 80 .prologue 0 >> 81 bis $16,$16,$17 >> 82 lda $16,53($31) >> 83 call_pal PAL_cserve >> 84 ret ($26) >> 85 .end cserve_dis >> 86 >> 87 # >> 88 # It is handy, on occasion, to make halt actually just loop. >> 89 # Putting it here means we dont have to recompile the whole >> 90 # kernel. >> 91 # >> 92 >> 93 .align 3 >> 94 .globl halt >> 95 .ent halt >> 96 halt: >> 97 .prologue 0 >> 98 call_pal PAL_halt >> 99 .end halt
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.