^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /* SPDX-License-Identifier: GPL-2.0-only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * ARC CPU startup Code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Vineetg: Dec 2007
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * -Check if we are running on Simulator or on real hardware
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * to skip certain things during boot on simulator
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/linkage.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <asm/asm-offsets.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <asm/entry.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <asm/arcregs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <asm/cache.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <asm/dsp-impl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <asm/irqflags.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) .macro CPU_EARLY_SETUP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) ; Setting up Vectror Table (in case exception happens in early boot
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) sr @_int_vec_base_lds, [AUX_INTR_VEC_BASE]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) ; Disable I-cache/D-cache if kernel so configured
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) lr r5, [ARC_REG_IC_BCR]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) breq r5, 0, 1f ; I$ doesn't exist
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) lr r5, [ARC_REG_IC_CTRL]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #ifdef CONFIG_ARC_HAS_ICACHE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) bclr r5, r5, 0 ; 0 - Enable, 1 is Disable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) bset r5, r5, 0 ; I$ exists, but is not used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) sr r5, [ARC_REG_IC_CTRL]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) lr r5, [ARC_REG_DC_BCR]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) breq r5, 0, 1f ; D$ doesn't exist
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) lr r5, [ARC_REG_DC_CTRL]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) bclr r5, r5, 6 ; Invalidate (discard w/o wback)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #ifdef CONFIG_ARC_HAS_DCACHE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) bclr r5, r5, 0 ; Enable (+Inv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) bset r5, r5, 0 ; Disable (+Inv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) sr r5, [ARC_REG_DC_CTRL]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #ifdef CONFIG_ISA_ARCV2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) ; Unaligned access is disabled at reset, so re-enable early as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) ; gcc 7.3.1 (ARC GNU 2018.03) onwards generates unaligned access
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) ; by default
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) lr r5, [status32]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #ifdef CONFIG_ARC_USE_UNALIGNED_MEM_ACCESS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) bset r5, r5, STATUS_AD_BIT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) ; Although disabled at reset, bootloader might have enabled it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) bclr r5, r5, STATUS_AD_BIT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) kflag r5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #ifdef CONFIG_ARC_LPB_DISABLE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) lr r5, [ARC_REG_LPB_BUILD]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) breq r5, 0, 1f ; LPB doesn't exist
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) mov r5, 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) sr r5, [ARC_REG_LPB_CTRL]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #endif /* CONFIG_ARC_LPB_DISABLE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) /* On HSDK, CCMs need to remapped super early */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #ifdef CONFIG_ARC_SOC_HSDK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) mov r6, 0x60000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) lr r5, [ARC_REG_ICCM_BUILD]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) breq r5, 0, 1f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) sr r6, [ARC_REG_AUX_ICCM]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) lr r5, [ARC_REG_DCCM_BUILD]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) breq r5, 0, 2f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) sr r6, [ARC_REG_AUX_DCCM]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) #endif /* CONFIG_ARC_SOC_HSDK */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) #endif /* CONFIG_ISA_ARCV2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) ; Config DSP_CTRL properly, so kernel may use integer multiply,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) ; multiply-accumulate, and divide operations
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) DSP_EARLY_INIT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) .endm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) .section .init.text, "ax",@progbits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) ;----------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) ; Default Reset Handler (jumped into from Reset vector)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) ; - Don't clobber r0,r1,r2 as they might have u-boot provided args
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) ; - Platforms can override this weak version if needed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) ;----------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) WEAK(res_service)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) j stext
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) END(res_service)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) ;----------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) ; Kernel Entry point
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) ;----------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) ENTRY(stext)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) CPU_EARLY_SETUP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) #ifdef CONFIG_SMP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) GET_CPU_ID r5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) cmp r5, 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) mov.nz r0, r5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) bz .Lmaster_proceed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) ; Non-Masters wait for Master to boot enough and bring them up
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) ; when they resume, tail-call to entry point
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) mov blink, @first_lines_of_secondary
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) j arc_platform_smp_wait_to_boot
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) .Lmaster_proceed:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) ; Clear BSS before updating any globals
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) ; XXX: use ZOL here
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) mov r5, __bss_start
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) sub r6, __bss_stop, r5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) lsr.f lp_count, r6, 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) lpnz 1f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) st.ab 0, [r5, 4]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) ; Uboot - kernel ABI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) ; r0 = [0] No uboot interaction, [1] cmdline in r2, [2] DTB in r2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) ; r1 = magic number (always zero as of now)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) ; r2 = pointer to uboot provided cmdline or external DTB in mem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) ; These are handled later in handle_uboot_args()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) st r0, [@uboot_tag]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) st r1, [@uboot_magic]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) st r2, [@uboot_arg]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) ; setup "current" tsk and optionally cache it in dedicated r25
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) mov r9, @init_task
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) SET_CURR_TASK_ON_CPU r9, r0 ; r9 = tsk, r0 = scratch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) ; setup stack (fp, sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) mov fp, 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) ; tsk->thread_info is really a PAGE, whose bottom hoists stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) GET_TSK_STACK_BASE r9, sp ; r9 = tsk, sp = stack base(output)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) j start_kernel ; "C" entry point
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) END(stext)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) #ifdef CONFIG_SMP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) ;----------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) ; First lines of code run by secondary before jumping to 'C'
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) ;----------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) .section .text, "ax",@progbits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) ENTRY(first_lines_of_secondary)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) ; setup per-cpu idle task as "current" on this CPU
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) ld r0, [@secondary_idle_tsk]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) SET_CURR_TASK_ON_CPU r0, r1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) ; setup stack (fp, sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) mov fp, 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) ; set it's stack base to tsk->thread_info bottom
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) GET_TSK_STACK_BASE r0, sp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) j start_kernel_secondary
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) END(first_lines_of_secondary)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) #endif