toc_asm.S 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. /* SPDX-License-Identifier: GPL-2.0-or-later */
  2. /* TOC (Transfer of Control) handler. */
  3. .level 1.1
  4. #include <asm/assembly.h>
  5. #include <linux/threads.h>
  6. #include <linux/linkage.h>
  7. .text
  8. .import toc_intr,code
  9. .import toc_stack,data
  10. .align 16
  11. ENTRY_CFI(toc_handler)
  12. load32 PA(toc_stack),%sp
  13. #ifdef CONFIG_SMP
  14. /* get per-cpu toc_stack address. */
  15. mfctl %cr30, %r1
  16. tophys %r1,%r2 /* task_struct */
  17. LDREG TASK_TI_CPU(%r2),%r4 /* cpu */
  18. load32 PA(__per_cpu_offset),%r1
  19. LDREGX %r4(%r1),%r4
  20. add %r4,%sp,%sp
  21. #endif
  22. /*
  23. * setup pt_regs on stack and save the
  24. * floating point registers. PIM_TOC doesn't
  25. * save fp registers, so we're doing it here.
  26. */
  27. copy %sp,%arg0
  28. ldo PT_SZ_ALGN(%sp), %sp
  29. /* clear pt_regs */
  30. copy %arg0,%r1
  31. 0: cmpb,<<,n %r1,%sp,0b
  32. stw,ma %r0,4(%r1)
  33. ldo PT_FR0(%arg0),%r25
  34. save_fp %r25
  35. /* go virtual */
  36. load32 PA(swapper_pg_dir),%r4
  37. mtctl %r4,%cr24
  38. mtctl %r4,%cr25
  39. /* Clear sr4-sr7 */
  40. mtsp %r0, %sr4
  41. mtsp %r0, %sr5
  42. mtsp %r0, %sr6
  43. mtsp %r0, %sr7
  44. tovirt_r1 %sp
  45. tovirt_r1 %arg0
  46. virt_map
  47. loadgp
  48. #ifdef CONFIG_64BIT
  49. ldo -16(%sp),%r29
  50. #endif
  51. load32 toc_intr,%r1
  52. be 0(%sr7,%r1)
  53. nop
  54. ENDPROC_CFI(toc_handler)
  55. /*
  56. * keep this checksum here, as it is part of the toc_handler
  57. * spanned by toc_handler_size (all words in toc_handler are
  58. * added in PDC and the sum must equal to zero.
  59. */
  60. SYM_DATA(toc_handler_csum, .long 0)
  61. SYM_DATA(toc_handler_size, .long . - toc_handler)