port_asm.S 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. /*
  2. * FreeRTOS Kernel V10.4.6
  3. * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
  4. *
  5. * SPDX-License-Identifier: MIT
  6. *
  7. * Permission is hereby granted, free of charge, to any person obtaining a copy of
  8. * this software and associated documentation files (the "Software"), to deal in
  9. * the Software without restriction, including without limitation the rights to
  10. * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
  11. * the Software, and to permit persons to whom the Software is furnished to do so,
  12. * subject to the following conditions:
  13. *
  14. * The above copyright notice and this permission notice shall be included in all
  15. * copies or substantial portions of the Software.
  16. *
  17. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  18. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
  19. * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
  20. * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
  21. * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  22. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  23. *
  24. * https://www.FreeRTOS.org
  25. * https://github.com/FreeRTOS
  26. *
  27. */
  28. .extern vTaskSwitchContext
  29. .set noat
  30. # Exported to start the first task.
  31. .globl restore_sp_from_pxCurrentTCB
  32. # Entry point for exceptions.
  33. .section .exceptions.entry, "xa"
  34. # Save the entire context of a task.
  35. save_context:
  36. addi ea, ea, -4 # Point to the next instruction.
  37. addi sp, sp, -116 # Create space on the stack.
  38. stw ra, 0(sp)
  39. # Leave a gap for muldiv 0
  40. stw at, 8(sp)
  41. stw r2, 12(sp)
  42. stw r3, 16(sp)
  43. stw r4, 20(sp)
  44. stw r5, 24(sp)
  45. stw r6, 28(sp)
  46. stw r7, 32(sp)
  47. stw r8, 36(sp)
  48. stw r9, 40(sp)
  49. stw r10, 44(sp)
  50. stw r11, 48(sp)
  51. stw r12, 52(sp)
  52. stw r13, 56(sp)
  53. stw r14, 60(sp)
  54. stw r15, 64(sp)
  55. rdctl r5, estatus # Save the eStatus
  56. stw r5, 68(sp)
  57. stw ea, 72(sp) # Save the PC
  58. stw r16, 76(sp) # Save the remaining registers
  59. stw r17, 80(sp)
  60. stw r18, 84(sp)
  61. stw r19, 88(sp)
  62. stw r20, 92(sp)
  63. stw r21, 96(sp)
  64. stw r22, 100(sp)
  65. stw r23, 104(sp)
  66. stw gp, 108(sp)
  67. stw fp, 112(sp)
  68. save_sp_to_pxCurrentTCB:
  69. movia et, pxCurrentTCB # Load the address of the pxCurrentTCB pointer
  70. ldw et, (et) # Load the value of the pxCurrentTCB pointer
  71. stw sp, (et) # Store the stack pointer into the top of the TCB
  72. .section .exceptions.irqtest, "xa"
  73. hw_irq_test:
  74. /*
  75. * Test to see if the exception was a software exception or caused
  76. * by an external interrupt, and vector accordingly.
  77. */
  78. rdctl r4, ipending # Load the Pending Interrupts indication
  79. rdctl r5, estatus # Load the eStatus (enabled interrupts).
  80. andi r2, r5, 1 # Are interrupts enabled globally.
  81. beq r2, zero, soft_exceptions # Interrupts are not enabled.
  82. beq r4, zero, soft_exceptions # There are no interrupts triggered.
  83. .section .exceptions.irqhandler, "xa"
  84. hw_irq_handler:
  85. call alt_irq_handler # Call the alt_irq_handler to deliver to the registered interrupt handler.
  86. .section .exceptions.irqreturn, "xa"
  87. restore_sp_from_pxCurrentTCB:
  88. movia et, pxCurrentTCB # Load the address of the pxCurrentTCB pointer
  89. ldw et, (et) # Load the value of the pxCurrentTCB pointer
  90. ldw sp, (et) # Load the stack pointer with the top value of the TCB
  91. restore_context:
  92. ldw ra, 0(sp) # Restore the registers.
  93. # Leave a gap for muldiv 0.
  94. ldw at, 8(sp)
  95. ldw r2, 12(sp)
  96. ldw r3, 16(sp)
  97. ldw r4, 20(sp)
  98. ldw r5, 24(sp)
  99. ldw r6, 28(sp)
  100. ldw r7, 32(sp)
  101. ldw r8, 36(sp)
  102. ldw r9, 40(sp)
  103. ldw r10, 44(sp)
  104. ldw r11, 48(sp)
  105. ldw r12, 52(sp)
  106. ldw r13, 56(sp)
  107. ldw r14, 60(sp)
  108. ldw r15, 64(sp)
  109. ldw et, 68(sp) # Load the eStatus
  110. wrctl estatus, et # Write the eStatus
  111. ldw ea, 72(sp) # Load the Program Counter
  112. ldw r16, 76(sp)
  113. ldw r17, 80(sp)
  114. ldw r18, 84(sp)
  115. ldw r19, 88(sp)
  116. ldw r20, 92(sp)
  117. ldw r21, 96(sp)
  118. ldw r22, 100(sp)
  119. ldw r23, 104(sp)
  120. ldw gp, 108(sp)
  121. ldw fp, 112(sp)
  122. addi sp, sp, 116 # Release stack space
  123. eret # Return to address ea, loading eStatus into Status.
  124. .section .exceptions.soft, "xa"
  125. soft_exceptions:
  126. ldw et, 0(ea) # Load the instruction where the interrupt occured.
  127. movhi at, %hi(0x003B683A) # Load the registers with the trap instruction code
  128. ori at, at, %lo(0x003B683A)
  129. cmpne et, et, at # Compare the trap instruction code to the last excuted instruction
  130. beq et, r0, call_scheduler # its a trap so switchcontext
  131. break # This is an un-implemented instruction or muldiv problem.
  132. br restore_context # its something else
  133. call_scheduler:
  134. addi ea, ea, 4 # A trap was called, increment the program counter so it is not called again.
  135. stw ea, 72(sp) # Save the new program counter to the context.
  136. call vTaskSwitchContext # Pick the next context.
  137. br restore_sp_from_pxCurrentTCB # Switch in the task context and restore.