overlay_os_asm.h 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. // overlay_os_asm.h -- Overlay manager assembly macros for OS use.
  2. // $Id$
  3. // Copyright (c) 2013 Tensilica Inc.
  4. //
  5. // Permission is hereby granted, free of charge, to any person obtaining
  6. // a copy of this software and associated documentation files (the
  7. // "Software"), to deal in the Software without restriction, including
  8. // without limitation the rights to use, copy, modify, merge, publish,
  9. // distribute, sublicense, and/or sell copies of the Software, and to
  10. // permit persons to whom the Software is furnished to do so, subject to
  11. // the following conditions:
  12. //
  13. // The above copyright notice and this permission notice shall be included
  14. // in all copies or substantial portions of the Software.
  15. //
  16. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  17. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  18. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  19. // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  20. // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  21. // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  22. // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  23. #ifndef OVERLAY_OS_ASM_H
  24. #define OVERLAY_OS_ASM_H
  25. // The macros in here are intended to be used by RTOS task switch code
  26. // to check overlay status. Such code is usually in assembly and cannot
  27. // call C code without penalty. For C code usage, it is best to use the
  28. // corresponding C functions from the library.
  29. // Inline assembly version of xt_overlay_get_state(). The arguments are
  30. // three AR registers (a0-a15):
  31. //
  32. // "pcreg" - should contain the outgoing task's PC, i.e. the point at
  33. // which the task got interrupted. The return value is also
  34. // returned in this register.
  35. // "sr1/2" - Scratch registers. These must be distinct from "pcreg".
  36. //
  37. // The return value is a 32-bit result that should be saved with the
  38. // task context and passed as-is to xt_overlay_check_map.
  39. .macro _xt_overlay_get_state pcreg sr1 sr2
  40. movi \sr1, _mapping_id
  41. movi \sr2, _ovly_id
  42. l16si \sr1, \sr1, 0
  43. l16ui \sr2, \sr2, 0
  44. slli \sr1, \sr1, 16
  45. or \pcreg, \sr1, \sr2
  46. .endm
  47. // Inline assembly version of xt_overlay_check_map(). It requires 5 AR
  48. // registers (a0-a15) as arguments.
  49. //
  50. // "pcreg" - should contain the interrupted task's PC, i.e. the point
  51. // at which the task got interrupted. This will be adjusted
  52. // if required.
  53. // "psreg" - should contain the interrupted task's PS. This will be
  54. // adjusted if required.
  55. // "ovreg" - should contain the overlay state on entry. Contents may
  56. // be clobbered.
  57. // "spreg" - should contain the tasks stack pointer on entry.
  58. // "sr1" - Scratch register. Must be distinct from any of the above.
  59. //
  60. // The return values are "pcreg" and "psreg" and these must be used
  61. // to update the task's PC and PS.
  62. // Note that this macro may store data below the "spreg" pointer. If
  63. // it does, then it will also disable interrupts via the PS, so that
  64. // the task resumes with all interrupts disabled (to avoid corrupting
  65. // this data).
  66. //
  67. // (SP - 24) Overlay ID to restore
  68. // (SP - 28) Task PC
  69. // (SP - 32) Task PS
  70. .macro _xt_overlay_check_map pcreg psreg ovreg spreg sr1
  71. // There are four cases to deal with:
  72. //
  73. // _ovly_id = -1, _mapping_id = -1
  74. // No overlay is mapped or mapping, nothing to do.
  75. //
  76. // _ovly_id >= 0, _mapping_id = -1
  77. // An overlay was mapped, check PC to see if we need a restore.
  78. //
  79. // _ovly_id = -1, _mapping_id >= 0
  80. // An overlay is being mapped. Either it belongs to this task, which
  81. // implies that the PC is in the mapping function, or it does not
  82. // belong to this task. Either way there is nothing to do.
  83. //
  84. // _ovly_id >= 0, _mapping_id >= 0
  85. // Illegal, cannot happen by design. Don't need to handle this.
  86. //
  87. // So, the logic is to check _ovly_id first. If this is >= 0, then
  88. // we check the task PC. If the PC is in the regions of interest then
  89. // we'll patch the return PC to invoke xt_overlay_restore.
  90. .L1:
  91. extui \sr1, \ovreg, 0, 16 // Extract _ovly_id
  92. bbsi.l \sr1, 15, .Lno // If -1 then we're done
  93. mov \ovreg, \sr1 // Restore this one
  94. // Next check the PC to see if it falls within the ranges of interest.
  95. .L2:
  96. movi \sr1, _overlay_vma // Is PC < VMA range ?
  97. bltu \pcreg, \sr1, .L3
  98. movi \sr1, _overlay_vma_end // Is PC > VMA range ?
  99. bgeu \pcreg, \sr1, .L3
  100. j .L4 // PC is in VMA range
  101. .L3:
  102. movi \sr1, _overlay_call_stubs_start // Is PC < call stubs range ?
  103. bltu \pcreg, \sr1, .Lno
  104. movi \sr1, _overlay_call_stubs_end // Is PC > call stubs range ?
  105. bgeu \pcreg, \sr1, .Lno
  106. // If we get here then a restore is needed. Save the overlay ID, PC and PS.
  107. // Return modified PC and PS so that xt_overlay_restore() will execute in
  108. // the context of the task when resumed. Note that the OS resumption code
  109. // may expect PS.EXCM to be set so we leave it as is in the return value.
  110. .L4:
  111. s32e \ovreg, \spreg, -24 // Save overlay ID
  112. s32e \pcreg, \spreg, -28 // Save task PC
  113. s32e \psreg, \spreg, -32 // Save task PS
  114. movi \pcreg, xt_overlay_restore // Adjust resumption PC
  115. movi \sr1, 15
  116. or \psreg, \psreg, \sr1 // Set intlevel to highest
  117. .Lno:
  118. .endm
  119. #endif // OVERLAY_OS_ASM_H