.section .text .set tpl_booted_flag, 0 .set tpl_info_struct, 8 .set tpl_pgd_low, 16 .set tpl_pgd_high, 24 .set tpl_hhdm_offset, 32 .set tpl_temp_stack, 40 .global smp_trampoline_start .extern loongarch_spinup .extern loongarch_smp_passed_info smp_trampoline_start: // Load trampoline state and switch to the kernel page tables. la.local $t0, loongarch_smp_passed_info la.local $a0, 1f ld.d $a1, $t0, tpl_temp_stack ld.d $a2, $t0, tpl_pgd_low ld.d $a3, $t0, tpl_pgd_high b loongarch_spinup 1: // Relocate the MP info pointer to the higher-half direct map. la.local $t0, loongarch_smp_passed_info ld.d $t1, $t0, tpl_info_struct ld.d $t2, $t0, tpl_hhdm_offset add.d $t1, $t1, $t2 move $a0, $t1 // Tell the BSP that this AP reached the parking loop. li.d $t3, 1 st.d $t3, $t0, tpl_booted_flag dbar 0 2: // Wait until the kernel sets goto_address. ld.d $t8, $t1, 24 dbar 0 beqz $t8, 2b // Load the kernel-provided stack (reserved field). ld.d $sp, $t1, 16 // Save entry point in $t0 (matching BSP convention). move $t0, $t8 // Zero non-essential registers. move $ra, $zero move $tp, $zero move $a1, $zero move $a2, $zero move $a3, $zero move $a4, $zero move $a5, $zero move $a6, $zero move $a7, $zero move $t1, $zero move $t2, $zero move $t3, $zero move $t4, $zero move $t5, $zero move $t6, $zero move $t7, $zero move $t8, $zero move $r21, $zero move $fp, $zero move $s0, $zero move $s1, $zero move $s2, $zero move $s3, $zero move $s4, $zero move $s5, $zero move $s6, $zero move $s7, $zero move $s8, $zero jirl $zero, $t0, 0 .section .note.GNU-stack,"",%progbits