/* SPDX-License-Identifier: GPL-2.0-or-later */ /* TOC (Transfer of Control) handler. */ .level 1.1 #include #include #include #include .text .import toc_intr,code .import toc_lock,data .align 16 ENTRY_CFI(toc_handler) /* * synchronize CPUs and obtain offset * for stack setup. */ load32 PA(toc_lock),%r1 0: ldcw,co 0(%r1),%r2 cmpib,= 0,%r2,0b nop addi 1,%r2,%r4 stw %r4,0(%r1) addi -1,%r2,%r4 load32 PA(toc_stack),%sp /* * deposit CPU number into stack address, * so every CPU will have its own stack. */ SHLREG %r4,14,%r4 add %r4,%sp,%sp /* * setup pt_regs on stack and save the * floating point registers. PIM_TOC doesn't * save fp registers, so we're doing it here. */ copy %sp,%arg0 ldo PT_SZ_ALGN(%sp), %sp /* clear pt_regs */ copy %arg0,%r1 0: cmpb,<<,n %r1,%sp,0b stw,ma %r0,4(%r1) ldo PT_FR0(%arg0),%r25 save_fp %r25 /* go virtual */ load32 PA(swapper_pg_dir),%r4 mtctl %r4,%cr24 mtctl %r4,%cr25 /* Clear sr4-sr7 */ mtsp %r0, %sr4 mtsp %r0, %sr5 mtsp %r0, %sr6 mtsp %r0, %sr7 tovirt_r1 %sp tovirt_r1 %arg0 virt_map loadgp #ifdef CONFIG_64BIT ldo -16(%sp),%r29 #endif load32 toc_intr,%r1 be 0(%sr7,%r1) nop ENDPROC_CFI(toc_handler) /* * keep this checksum here, as it is part of the toc_handler * spanned by toc_handler_size (all words in toc_handler are * added in PDC and the sum must equal to zero. */ SYM_DATA(toc_handler_csum, .long 0) SYM_DATA(toc_handler_size, .long . - toc_handler) __PAGE_ALIGNED_BSS .align 64 SYM_DATA(toc_stack, .block 16384*NR_CPUS)