1628c3bb4SHuacai Chen/* SPDX-License-Identifier: GPL-2.0 */ 2628c3bb4SHuacai Chen/* 3628c3bb4SHuacai Chen * Copyright (C) 2020-2022 Loongson Technology Corporation Limited 4628c3bb4SHuacai Chen */ 5628c3bb4SHuacai Chen#include <linux/init.h> 6628c3bb4SHuacai Chen#include <linux/threads.h> 7628c3bb4SHuacai Chen 8628c3bb4SHuacai Chen#include <asm/addrspace.h> 9628c3bb4SHuacai Chen#include <asm/asm.h> 10628c3bb4SHuacai Chen#include <asm/asmmacro.h> 112d2c3952SYouling Tang#include <asm/bug.h> 12628c3bb4SHuacai Chen#include <asm/regdef.h> 13628c3bb4SHuacai Chen#include <asm/loongarch.h> 14628c3bb4SHuacai Chen#include <asm/stackframe.h> 15628c3bb4SHuacai Chen 16ead384d9SHuacai Chen#ifdef CONFIG_EFI_STUB 17ead384d9SHuacai Chen 18ead384d9SHuacai Chen#include "efi-header.S" 19ead384d9SHuacai Chen 20ead384d9SHuacai Chen __HEAD 21ead384d9SHuacai Chen 22ead384d9SHuacai Chen_head: 23ead384d9SHuacai Chen .word MZ_MAGIC /* "MZ", MS-DOS header */ 244a03b2acSYouling Tang .org 0x8 25*988a03e3SJiaxun Yang .dword _kernel_entry /* Kernel entry point (physical address) */ 26414cefc7SWANG Rui .dword _kernel_asize /* Kernel image effective size */ 273f89765dSYouling Tang .quad PHYS_LINK_KADDR /* Kernel image load offset from start of RAM */ 2829636a5cSArd Biesheuvel .org 0x38 /* 0x20 ~ 0x37 reserved */ 2929636a5cSArd Biesheuvel .long LINUX_PE_MAGIC 30ead384d9SHuacai Chen .long pe_header - _head /* Offset to the PE header */ 31ead384d9SHuacai Chen 32ead384d9SHuacai Chenpe_header: 33ead384d9SHuacai Chen __EFI_PE_HEADER 34ead384d9SHuacai Chen 35414cefc7SWANG RuiSYM_DATA(kernel_asize, .long _kernel_asize); 36414cefc7SWANG RuiSYM_DATA(kernel_fsize, .long _kernel_fsize); 37ead384d9SHuacai Chen 38ead384d9SHuacai Chen#endif 39ead384d9SHuacai Chen 40628c3bb4SHuacai Chen __REF 41628c3bb4SHuacai Chen 422938431eSHuacai Chen .align 12 432938431eSHuacai Chen 44628c3bb4SHuacai ChenSYM_CODE_START(kernel_entry) # kernel entry point 45628c3bb4SHuacai Chen 46628c3bb4SHuacai Chen /* Config direct window and set PG */ 47628c3bb4SHuacai Chen li.d t0, CSR_DMW0_INIT # UC, PLV0, 0x8000 xxxx xxxx xxxx 48628c3bb4SHuacai Chen csrwr t0, LOONGARCH_CSR_DMWIN0 49628c3bb4SHuacai Chen li.d t0, CSR_DMW1_INIT # CA, PLV0, 0x9000 xxxx xxxx xxxx 50628c3bb4SHuacai Chen csrwr t0, LOONGARCH_CSR_DMWIN1 51ab2579d7SHuacai Chen 528cbd5ebfSYouling Tang JUMP_VIRT_ADDR t0, t1 538cbd5ebfSYouling Tang 54628c3bb4SHuacai Chen /* Enable PG */ 55628c3bb4SHuacai Chen li.w t0, 0xb0 # PLV=0, IE=0, PG=1 56628c3bb4SHuacai Chen csrwr t0, LOONGARCH_CSR_CRMD 57628c3bb4SHuacai Chen li.w t0, 0x04 # PLV=0, PIE=1, PWE=0 58628c3bb4SHuacai Chen csrwr t0, LOONGARCH_CSR_PRMD 59628c3bb4SHuacai Chen li.w t0, 0x00 # FPE=0, SXE=0, ASXE=0, BTE=0 60628c3bb4SHuacai Chen csrwr t0, LOONGARCH_CSR_EUEN 61628c3bb4SHuacai Chen 6211cd8a64SXi Ruoyao la.pcrel t0, __bss_start # clear .bss 63628c3bb4SHuacai Chen st.d zero, t0, 0 6411cd8a64SXi Ruoyao la.pcrel t1, __bss_stop - LONGSIZE 65628c3bb4SHuacai Chen1: 66628c3bb4SHuacai Chen addi.d t0, t0, LONGSIZE 67628c3bb4SHuacai Chen st.d zero, t0, 0 68628c3bb4SHuacai Chen bne t0, t1, 1b 69628c3bb4SHuacai Chen 7011cd8a64SXi Ruoyao la.pcrel t0, fw_arg0 71628c3bb4SHuacai Chen st.d a0, t0, 0 # firmware arguments 7211cd8a64SXi Ruoyao la.pcrel t0, fw_arg1 73628c3bb4SHuacai Chen st.d a1, t0, 0 7411cd8a64SXi Ruoyao la.pcrel t0, fw_arg2 7540cd01a9SArd Biesheuvel st.d a2, t0, 0 76628c3bb4SHuacai Chen 77628c3bb4SHuacai Chen /* KSave3 used for percpu base, initialized as 0 */ 78628c3bb4SHuacai Chen csrwr zero, PERCPU_BASE_KS 79628c3bb4SHuacai Chen /* GPR21 used for percpu base (runtime), initialized as 0 */ 8057ce5d3eSWANG Xuerui move u0, zero 81628c3bb4SHuacai Chen 8211cd8a64SXi Ruoyao la.pcrel tp, init_thread_union 83628c3bb4SHuacai Chen /* Set the SP after an empty pt_regs. */ 84b40fa75eSJinyang He PTR_LI sp, (_THREAD_SIZE - PT_SIZE) 85628c3bb4SHuacai Chen PTR_ADD sp, sp, tp 86628c3bb4SHuacai Chen set_saved_sp sp, t0, t1 87628c3bb4SHuacai Chen 88d8da19fbSYouling Tang#ifdef CONFIG_RELOCATABLE 89e5f02b51SYouling Tang 90d8da19fbSYouling Tang bl relocate_kernel 91e5f02b51SYouling Tang 92e5f02b51SYouling Tang#ifdef CONFIG_RANDOMIZE_BASE 93e5f02b51SYouling Tang /* Repoint the sp into the new kernel */ 94e5f02b51SYouling Tang PTR_LI sp, (_THREAD_SIZE - PT_SIZE) 95e5f02b51SYouling Tang PTR_ADD sp, sp, tp 96e5f02b51SYouling Tang set_saved_sp sp, t0, t1 97e5f02b51SYouling Tang 989fbcc076SQing Zhang /* Jump to the new kernel: new_pc = current_pc + random_offset */ 999fbcc076SQing Zhang pcaddi t0, 0 1009fbcc076SQing Zhang add.d t0, t0, a0 1019fbcc076SQing Zhang jirl zero, t0, 0xc 1029fbcc076SQing Zhang#endif /* CONFIG_RANDOMIZE_BASE */ 103e5f02b51SYouling Tang 1049fbcc076SQing Zhang#endif /* CONFIG_RELOCATABLE */ 105d8da19fbSYouling Tang 1065aa4ac64SQing Zhang#ifdef CONFIG_KASAN 1075aa4ac64SQing Zhang bl kasan_early_init 1085aa4ac64SQing Zhang#endif 1095aa4ac64SQing Zhang 110628c3bb4SHuacai Chen bl start_kernel 1112d2c3952SYouling Tang ASM_BUG() 112628c3bb4SHuacai Chen 113628c3bb4SHuacai ChenSYM_CODE_END(kernel_entry) 114628c3bb4SHuacai Chen 11546859ac8SHuacai Chen#ifdef CONFIG_SMP 11646859ac8SHuacai Chen 11746859ac8SHuacai Chen/* 11846859ac8SHuacai Chen * SMP slave cpus entry point. Board specific code for bootstrap calls this 11946859ac8SHuacai Chen * function after setting up the stack and tp registers. 12046859ac8SHuacai Chen */ 12146859ac8SHuacai ChenSYM_CODE_START(smpboot_entry) 12246859ac8SHuacai Chen li.d t0, CSR_DMW0_INIT # UC, PLV0 12346859ac8SHuacai Chen csrwr t0, LOONGARCH_CSR_DMWIN0 12446859ac8SHuacai Chen li.d t0, CSR_DMW1_INIT # CA, PLV0 12546859ac8SHuacai Chen csrwr t0, LOONGARCH_CSR_DMWIN1 126ab2579d7SHuacai Chen 1278cbd5ebfSYouling Tang JUMP_VIRT_ADDR t0, t1 1288cbd5ebfSYouling Tang 129ab2579d7SHuacai Chen /* Enable PG */ 13046859ac8SHuacai Chen li.w t0, 0xb0 # PLV=0, IE=0, PG=1 13146859ac8SHuacai Chen csrwr t0, LOONGARCH_CSR_CRMD 13246859ac8SHuacai Chen li.w t0, 0x04 # PLV=0, PIE=1, PWE=0 13346859ac8SHuacai Chen csrwr t0, LOONGARCH_CSR_PRMD 13446859ac8SHuacai Chen li.w t0, 0x00 # FPE=0, SXE=0, ASXE=0, BTE=0 13546859ac8SHuacai Chen csrwr t0, LOONGARCH_CSR_EUEN 13646859ac8SHuacai Chen 137f733f119SXi Ruoyao la.pcrel t0, cpuboot_data 13846859ac8SHuacai Chen ld.d sp, t0, CPU_BOOT_STACK 13946859ac8SHuacai Chen ld.d tp, t0, CPU_BOOT_TINFO 14046859ac8SHuacai Chen 14146859ac8SHuacai Chen bl start_secondary 1422d2c3952SYouling Tang ASM_BUG() 1432d2c3952SYouling Tang 14446859ac8SHuacai ChenSYM_CODE_END(smpboot_entry) 14546859ac8SHuacai Chen 14646859ac8SHuacai Chen#endif /* CONFIG_SMP */ 14746859ac8SHuacai Chen 148628c3bb4SHuacai ChenSYM_ENTRY(kernel_entry_end, SYM_L_GLOBAL, SYM_A_NONE) 149