1 // overlay.h -- Overlay manager header file 2 // $Id$ 3 4 // Copyright (c) 2013 Tensilica Inc. 5 // 6 // Permission is hereby granted, free of charge, to any person obtaining 7 // a copy of this software and associated documentation files (the 8 // "Software"), to deal in the Software without restriction, including 9 // without limitation the rights to use, copy, modify, merge, publish, 10 // distribute, sublicense, and/or sell copies of the Software, and to 11 // permit persons to whom the Software is furnished to do so, subject to 12 // the following conditions: 13 // 14 // The above copyright notice and this permission notice shall be included 15 // in all copies or substantial portions of the Software. 16 // 17 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20 // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 21 // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 22 // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 23 // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 25 26 #ifndef OVERLAY_H 27 #define OVERLAY_H 28 29 30 #include <xtensa/xtruntime.h> 31 32 33 #ifdef __cplusplus 34 extern "C" { 35 #endif 36 37 38 // Overlays not supported for CALL0 ABI 39 #if defined (__XTENSA_CALL0_ABI__) 40 #undef XT_DISABLE_OVERLAYS 41 #define XT_DISABLE_OVERLAYS 1 42 #endif 43 44 // Define this to turn off overlay support 45 #ifdef XT_DISABLE_OVERLAYS 46 47 #define OVERLAY(n) 48 #define DECLARE_OVERLAY(n) 49 50 #define xt_overlay_map(ov_id) 51 #define xt_overlay_map_async(ov_id) 0 52 #define xt_overlay_map_in_progress() 0 53 #define xt_overlay_get_id() 0 54 #define xt_overlay_get_state(pc) 0 55 #define xt_overlay_check_map(pc,ps,ovstate,sp) 0 56 57 #else 58 59 // Shorthand for convenience and portability. 60 #define OVERLAY(n) __attribute__((overlay(n))) 61 62 // Structure of the overlay table required by gdb and the overlay 63 // manager. Should not be accessed by user code unless overriding 64 // the load process. 65 struct ovly_table { 66 void * vma; // The overlay's mapped address. 67 unsigned int size; // The size of the overlay, in bytes. 68 void * lma; // The overlay's load address. 69 unsigned int mapped; // Non-zero if overlay is currently mapped; zero otherwise. 70 }; 71 72 // Constructed by the linker. Required for gdb and for the overlay 73 // manager. Should not be accessed by user code unless overriding 74 // the load process. 75 extern struct ovly_table _ovly_table[]; 76 77 // Functions. 78 void xt_overlay_map(int ov_id); 79 int xt_overlay_map_async(int ov_id); 80 int xt_overlay_map_in_progress(void); 81 unsigned int xt_overlay_get_state(unsigned int pc); 82 unsigned int xt_overlay_check_map(unsigned int * pc, unsigned int * ps, 83 unsigned int ovstate, unsigned int sp); 84 int xt_overlay_start_map(void * dst, void * src, unsigned int len, int ov_id); 85 int xt_overlay_is_mapping(int ov_id); 86 void xt_overlay_fatal_error(int ov_id); 87 88 89 // Returns the current overlay ID. If no overlay is mapped or an overlay 90 // is in the middle of being mapped, returns -1. Inlined to avoid calling 91 // out of overlay (wastes cycles, can end up reading wrong ID on interrupt 92 // activity). 93 // 94 static inline int __attribute__((always_inline)) xt_overlay_get_id(void) 95 { 96 extern short _mapping_id; 97 extern short _ovly_id; 98 99 int ret; 100 unsigned int flags = XTOS_SET_INTLEVEL(15); 101 102 if (_mapping_id >= 0) { 103 ret = -1; 104 } 105 else { 106 ret = _ovly_id; 107 } 108 109 XTOS_RESTORE_INTLEVEL(flags); 110 return ret; 111 } 112 113 114 // The following macros are used to declare numbered overlays and generate 115 // the corresponding call stubs. Use as follows: 116 // 117 // DECLARE_OVERLAY(n) 118 // 119 // See documentation for more details. 120 121 //#include <xtensa/config/core-isa.h> 122 123 // At this time overlays are not supported without windowing. 124 #if defined(__XTENSA_WINDOWED_ABI__) 125 126 #define xstr(x) str(x) 127 #define str(x) #x 128 129 // At entry, register a8 holds the return address and a9 holds the target 130 // function address. This stub saves a8 on the stack at (SP - 20) which 131 // is the only location that is safe for us to use. Then it allocates 32 132 // bytes on the stack for working storage, loads the overlay number into 133 // a8, and jumps to the common handler. The common handler will make sure 134 // that the called function is loaded into memory before calling it. 135 // NOTE: we are using the stack area normally reserved for nested functions. 136 // This means nested functions cannot be used when overlays are in use. 137 138 #define CALL_IN(num) \ 139 asm(".section .gnu.linkonce.t.overlay.call." xstr(num) ".text, \"ax\"\n" \ 140 ".global _overlay_call_in_" xstr(num) "_\n" \ 141 ".align 4\n" \ 142 "_overlay_call_in_" xstr(num) "_:\n" \ 143 "s32e a8, a1, -20\n" \ 144 "addi a8, a1, -32\n" \ 145 "movsp a1, a8\n" \ 146 "movi a8, " xstr(num) "\n" \ 147 "j _overlay_call_in_common\n" \ 148 ".size _overlay_call_in_" xstr(num) "_, . - _overlay_call_in_" xstr(num) "_\n"); 149 150 // The call-out stub first calls the target function, then loads the overlay 151 // number into register a14 and jumps to the common handler. The handler will 152 // make sure that the caller function is present in memory before returning. 153 // Note that registers a10-a13 may contain return values so must be preserved. 154 // 155 // Because we came here via a call4, the return address is in a4, and the top 156 // 2 bits are set to the window increment. We'll restore the top 2 bits of 157 // the return address from the called function's address, assuming that both 158 // are in the same 1 GB segment. For now this is always true. 159 160 #define CALL_OUT(num) \ 161 asm(".section .gnu.linkonce.t.overlay.call." xstr(num) ".text, \"ax\"\n" \ 162 ".global _overlay_call_out_" xstr(num) "_\n" \ 163 ".align 4\n" \ 164 "_overlay_call_out_" xstr(num) "_:\n" \ 165 "slli a4, a4, 2\n" \ 166 "srli a4, a4, 2\n" \ 167 "extui a8, a9, 30, 2\n" \ 168 "slli a8, a8, 30\n" \ 169 "or a4, a4, a8\n" \ 170 "callx8 a9\n" \ 171 "movi a14, " xstr(num) "\n" \ 172 "j _overlay_call_out_common\n" \ 173 ".size _overlay_call_out_" xstr(num) "_, . - _overlay_call_out_" xstr(num) "_\n"); 174 175 // Generate a call-in and a call-out stub for each overlay. 176 177 #define DECLARE_OVERLAY(num) \ 178 CALL_IN(num) \ 179 CALL_OUT(num) 180 181 #endif // defined(__XTENSA_WINDOWED_ABI__) 182 183 #endif // XT_DISABLE_OVERLAYS 184 185 #ifdef __cplusplus 186 } 187 #endif 188 189 #endif // OVERLAY_H 190 191