genex.S 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. /*
  3. * Copyright (C) 2020-2022 Loongson Technology Corporation Limited
  4. *
  5. * Derived from MIPS:
  6. * Copyright (C) 1994 - 2000, 2001, 2003 Ralf Baechle
  7. * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
  8. * Copyright (C) 2002, 2007 Maciej W. Rozycki
  9. * Copyright (C) 2001, 2012 MIPS Technologies, Inc. All rights reserved.
  10. */
  11. #include <asm/asm.h>
  12. #include <asm/asmmacro.h>
  13. #include <asm/loongarch.h>
  14. #include <asm/regdef.h>
  15. #include <asm/fpregdef.h>
  16. #include <asm/stackframe.h>
  17. #include <asm/thread_info.h>
  18. .section .cpuidle.text, "ax"
  19. .align 5
  20. SYM_FUNC_START(__arch_cpu_idle)
  21. /* start of idle interrupt region */
  22. ori t0, zero, CSR_CRMD_IE
  23. /* idle instruction needs irq enabled */
  24. csrxchg t0, t0, LOONGARCH_CSR_CRMD
  25. /*
  26. * If an interrupt lands here; between enabling interrupts above and
  27. * going idle on the next instruction, we must *NOT* go idle since the
  28. * interrupt could have set TIF_NEED_RESCHED or caused an timer to need
  29. * reprogramming. Fall through -- see handle_vint() below -- and have
  30. * the idle loop take care of things.
  31. */
  32. idle 0
  33. /* end of idle interrupt region */
  34. idle_exit:
  35. jr ra
  36. SYM_FUNC_END(__arch_cpu_idle)
  37. .previous
  38. SYM_CODE_START(handle_vint)
  39. UNWIND_HINT_UNDEFINED
  40. BACKUP_T0T1
  41. SAVE_ALL
  42. la_abs t1, idle_exit
  43. LONG_L t0, sp, PT_ERA
  44. /* 3 instructions idle interrupt region */
  45. ori t0, t0, 0b1100
  46. bne t0, t1, 1f
  47. LONG_S t0, sp, PT_ERA
  48. 1: move a0, sp
  49. move a1, sp
  50. la_abs t0, do_vint
  51. jirl ra, t0, 0
  52. RESTORE_ALL_AND_RET
  53. SYM_CODE_END(handle_vint)
  54. SYM_CODE_START(except_vec_cex)
  55. UNWIND_HINT_UNDEFINED
  56. b cache_parity_error
  57. SYM_CODE_END(except_vec_cex)
  58. .macro build_prep_badv
  59. csrrd t0, LOONGARCH_CSR_BADV
  60. PTR_S t0, sp, PT_BVADDR
  61. .endm
  62. .macro build_prep_fcsr
  63. movfcsr2gr a1, fcsr0
  64. .endm
  65. .macro build_prep_none
  66. .endm
  67. .macro BUILD_HANDLER exception handler prep
  68. .align 5
  69. SYM_CODE_START(handle_\exception)
  70. UNWIND_HINT_UNDEFINED
  71. 666:
  72. BACKUP_T0T1
  73. SAVE_ALL
  74. build_prep_\prep
  75. move a0, sp
  76. la_abs t0, do_\handler
  77. jirl ra, t0, 0
  78. 668:
  79. RESTORE_ALL_AND_RET
  80. SYM_CODE_END(handle_\exception)
  81. .pushsection ".data", "aw", %progbits
  82. SYM_DATA(unwind_hint_\exception, .word 668b - 666b)
  83. .popsection
  84. .endm
  85. BUILD_HANDLER ade ade badv
  86. BUILD_HANDLER ale ale badv
  87. BUILD_HANDLER bce bce none
  88. BUILD_HANDLER bp bp none
  89. BUILD_HANDLER fpe fpe fcsr
  90. BUILD_HANDLER fpu fpu none
  91. BUILD_HANDLER lsx lsx none
  92. BUILD_HANDLER lasx lasx none
  93. BUILD_HANDLER lbt lbt none
  94. BUILD_HANDLER ri ri none
  95. BUILD_HANDLER watch watch none
  96. BUILD_HANDLER reserved reserved none /* others */
  97. SYM_CODE_START(handle_sys)
  98. UNWIND_HINT_UNDEFINED
  99. la_abs t0, handle_syscall
  100. jr t0
  101. SYM_CODE_END(handle_sys)