overlay.h 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. // overlay.h -- Overlay manager header file
  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_H
  24. #define OVERLAY_H
  25. #include <xtensa/xtruntime.h>
  26. #ifdef __cplusplus
  27. extern "C" {
  28. #endif
  29. // Define this to turn off overlay support
  30. #ifdef XT_DISABLE_OVERLAYS
  31. #define OVERLAY(n)
  32. #define DECLARE_OVERLAY(n)
  33. #define xt_overlay_map(ov_id)
  34. #define xt_overlay_map_async(ov_id) 0
  35. #define xt_overlay_map_in_progress() 0
  36. #define xt_overlay_get_id() 0
  37. #define xt_overlay_get_state(pc) 0
  38. #define xt_overlay_check_map(pc,ps,ovstate,sp) 0
  39. #else
  40. // Shorthand for convenience and portability.
  41. #define OVERLAY(n) __attribute__((overlay(n)))
  42. // Structure of the overlay table required by gdb and the overlay
  43. // manager. Should not be accessed by user code unless overriding
  44. // the load process.
  45. struct ovly_table {
  46. void * vma; // The overlay's mapped address.
  47. unsigned int size; // The size of the overlay, in bytes.
  48. void * lma; // The overlay's load address.
  49. unsigned int mapped; // Non-zero if overlay is currently mapped; zero otherwise.
  50. };
  51. // Constructed by the linker. Required for gdb and for the overlay
  52. // manager. Should not be accessed by user code unless overriding
  53. // the load process.
  54. extern struct ovly_table _ovly_table[];
  55. // Functions.
  56. void xt_overlay_map(int ov_id);
  57. int xt_overlay_map_async(int ov_id);
  58. int xt_overlay_map_in_progress(void);
  59. unsigned int xt_overlay_get_state(unsigned int pc);
  60. unsigned int xt_overlay_check_map(unsigned int * pc, unsigned int * ps,
  61. unsigned int ovstate, unsigned int sp);
  62. int xt_overlay_start_map(void * dst, void * src, unsigned int len, int ov_id);
  63. int xt_overlay_is_mapping(int ov_id);
  64. void xt_overlay_fatal_error(int ov_id);
  65. // Returns the current overlay ID. If no overlay is mapped or an overlay
  66. // is in the middle of being mapped, returns -1. Inlined to avoid calling
  67. // out of overlay (wastes cycles, can end up reading wrong ID on interrupt
  68. // activity).
  69. //
  70. static inline int xt_overlay_get_id(void)
  71. {
  72. #pragma always_inline
  73. extern short _mapping_id;
  74. extern short _ovly_id;
  75. int ret;
  76. unsigned int flags = XTOS_SET_INTLEVEL(15);
  77. if (_mapping_id >= 0) {
  78. ret = -1;
  79. }
  80. else {
  81. ret = _ovly_id;
  82. }
  83. XTOS_RESTORE_INTLEVEL(flags);
  84. return ret;
  85. }
  86. // The following macros are used to declare numbered overlays and generate
  87. // the corresponding call stubs. Use as follows:
  88. //
  89. // DECLARE_OVERLAY(n)
  90. //
  91. // See documentation for more details.
  92. //#include <xtensa/config/core-isa.h>
  93. // At this time overlays are not supported without windowing.
  94. #if defined(__XTENSA_WINDOWED_ABI__)
  95. #define xstr(x) str(x)
  96. #define str(x) #x
  97. // At entry, register a8 holds the return address and a9 holds the target
  98. // function address. This stub saves a8 on the stack at (SP - 20) which
  99. // is the only location that is safe for us to use. Then it allocates 32
  100. // bytes on the stack for working storage, loads the overlay number into
  101. // a8, and jumps to the common handler. The common handler will make sure
  102. // that the called function is loaded into memory before calling it.
  103. // NOTE: we are using the stack area normally reserved for nested functions.
  104. // This means nested functions cannot be used when overlays are in use.
  105. #define CALL_IN(num) \
  106. asm(".section .gnu.linkonce.t.overlay.call." xstr(num) ".text, \"ax\"\n" \
  107. ".global _overlay_call_in_" xstr(num) "_\n" \
  108. ".align 4\n" \
  109. "_overlay_call_in_" xstr(num) "_:\n" \
  110. "s32e a8, a1, -20\n" \
  111. "addi a8, a1, -32\n" \
  112. "movsp a1, a8\n" \
  113. "movi a8, " xstr(num) "\n" \
  114. "j _overlay_call_in_common\n" \
  115. ".size _overlay_call_in_" xstr(num) "_, . - _overlay_call_in_" xstr(num) "_\n");
  116. // The call-out stub first calls the target function, then loads the overlay
  117. // number into register a14 and jumps to the common handler. The handler will
  118. // make sure that the caller function is present in memory before returning.
  119. // Note that registers a10-a13 may contain return values so must be preserved.
  120. //
  121. // Because we came here via a call4, the return address is in a4, and the top
  122. // 2 bits are set to the window increment. We'll restore the top 2 bits of
  123. // the return address from the called function's address, assuming that both
  124. // are in the same 1 GB segment. For now this is always true.
  125. #define CALL_OUT(num) \
  126. asm(".section .gnu.linkonce.t.overlay.call." xstr(num) ".text, \"ax\"\n" \
  127. ".global _overlay_call_out_" xstr(num) "_\n" \
  128. ".align 4\n" \
  129. "_overlay_call_out_" xstr(num) "_:\n" \
  130. "slli a4, a4, 2\n" \
  131. "srli a4, a4, 2\n" \
  132. "extui a8, a9, 30, 2\n" \
  133. "slli a8, a8, 30\n" \
  134. "or a4, a4, a8\n" \
  135. "callx8 a9\n" \
  136. "movi a14, " xstr(num) "\n" \
  137. "j _overlay_call_out_common\n" \
  138. ".size _overlay_call_out_" xstr(num) "_, . - _overlay_call_out_" xstr(num) "_\n");
  139. // Generate a call-in and a call-out stub for each overlay.
  140. #define DECLARE_OVERLAY(num) \
  141. CALL_IN(num) \
  142. CALL_OUT(num)
  143. #endif // defined(__XTENSA_WINDOWED_ABI__)
  144. #endif // XT_DISABLE_OVERLAYS
  145. #ifdef __cplusplus
  146. }
  147. #endif
  148. #endif // OVERLAY_H