1 //
2 // processor_state.c - processor state management routines
3 //
4
5 // Copyright (c) 2005-2010 Tensilica Inc.
6 //
7 // Permission is hereby granted, free of charge, to any person obtaining
8 // a copy of this software and associated documentation files (the
9 // "Software"), to deal in the Software without restriction, including
10 // without limitation the rights to use, copy, modify, merge, publish,
11 // distribute, sublicense, and/or sell copies of the Software, and to
12 // permit persons to whom the Software is furnished to do so, subject to
13 // the following conditions:
14 //
15 // The above copyright notice and this permission notice shall be included
16 // in all copies or substantial portions of the Software.
17 //
18 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
21 // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
22 // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25
26 #include <xtensa/hal.h>
27 #include <xtensa/config/core.h>
28
29
30 //----------------------------------------------------------------------
31
32 #if defined(__SPLIT__extra_size)
33 // space for "extra" (user special registers and non-coprocessor TIE) state:
34 const unsigned int Xthal_extra_size = XCHAL_NCP_SA_SIZE;
35
36 #elif defined(__SPLIT__extra_align)
37 const unsigned int Xthal_extra_align = XCHAL_NCP_SA_ALIGN;
38
39 #elif defined(__SPLIT__cpregs_size)
40 // space for state of TIE coprocessors:
41 const unsigned int Xthal_cpregs_size[8] =
42 {
43 XCHAL_CP0_SA_SIZE,
44 XCHAL_CP1_SA_SIZE,
45 XCHAL_CP2_SA_SIZE,
46 XCHAL_CP3_SA_SIZE,
47 XCHAL_CP4_SA_SIZE,
48 XCHAL_CP5_SA_SIZE,
49 XCHAL_CP6_SA_SIZE,
50 XCHAL_CP7_SA_SIZE
51 };
52
53 #elif defined(__SPLIT__cpregs_align)
54 const unsigned int Xthal_cpregs_align[8] =
55 {
56 XCHAL_CP0_SA_ALIGN,
57 XCHAL_CP1_SA_ALIGN,
58 XCHAL_CP2_SA_ALIGN,
59 XCHAL_CP3_SA_ALIGN,
60 XCHAL_CP4_SA_ALIGN,
61 XCHAL_CP5_SA_ALIGN,
62 XCHAL_CP6_SA_ALIGN,
63 XCHAL_CP7_SA_ALIGN
64 };
65
66 #elif defined(__SPLIT__cp_names)
67 const char * const Xthal_cp_names[8] =
68 {
69 XCHAL_CP0_NAME,
70 XCHAL_CP1_NAME,
71 XCHAL_CP2_NAME,
72 XCHAL_CP3_NAME,
73 XCHAL_CP4_NAME,
74 XCHAL_CP5_NAME,
75 XCHAL_CP6_NAME,
76 XCHAL_CP7_NAME
77 };
78
79 #elif defined(__SPLIT__all_extra_size)
80 // total save area size (extra + all coprocessors + min 16-byte alignment everywhere)
81 const unsigned int Xthal_all_extra_size = XCHAL_TOTAL_SA_SIZE;
82
83 #elif defined(__SPLIT__all_extra_align)
84 // maximum required alignment for the total save area (this might be useful):
85 const unsigned int Xthal_all_extra_align = XCHAL_TOTAL_SA_ALIGN;
86
87 #elif defined(__SPLIT__num_coprocessors)
88 // number of coprocessors starting contiguously from zero
89 // (same as Xthal_cp_max, but included for Tornado2):
90 const unsigned int Xthal_num_coprocessors = XCHAL_CP_MAX;
91
92 #elif defined(__SPLIT__cp_num)
93 // actual number of coprocessors:
94 const unsigned char Xthal_cp_num = XCHAL_CP_NUM;
95
96 #elif defined(__SPLIT__cp_max)
97 // index of highest numbered coprocessor, plus one:
98 const unsigned char Xthal_cp_max = XCHAL_CP_MAX;
99
100 // index of highest allowed coprocessor number, per cfg, plus one:
101 //const unsigned char Xthal_cp_maxcfg = XCHAL_CP_MAXCFG;
102
103 #elif defined(__SPLIT__cp_mask)
104 // bitmask of which coprocessors are present:
105 const unsigned int Xthal_cp_mask = XCHAL_CP_MASK;
106
107 #elif defined(__SPLIT__cp_id_mappings)
108 // Coprocessor ID from its name
109
110 # ifdef XCHAL_CP0_IDENT
111 const unsigned char XCJOIN(Xthal_cp_id_,XCHAL_CP0_IDENT) = 0;
112 # endif
113 # ifdef XCHAL_CP1_IDENT
114 const unsigned char XCJOIN(Xthal_cp_id_,XCHAL_CP1_IDENT) = 1;
115 # endif
116 # ifdef XCHAL_CP2_IDENT
117 const unsigned char XCJOIN(Xthal_cp_id_,XCHAL_CP2_IDENT) = 2;
118 # endif
119 # ifdef XCHAL_CP3_IDENT
120 const unsigned char XCJOIN(Xthal_cp_id_,XCHAL_CP3_IDENT) = 3;
121 # endif
122 # ifdef XCHAL_CP4_IDENT
123 const unsigned char XCJOIN(Xthal_cp_id_,XCHAL_CP4_IDENT) = 4;
124 # endif
125 # ifdef XCHAL_CP5_IDENT
126 const unsigned char XCJOIN(Xthal_cp_id_,XCHAL_CP5_IDENT) = 5;
127 # endif
128 # ifdef XCHAL_CP6_IDENT
129 const unsigned char XCJOIN(Xthal_cp_id_,XCHAL_CP6_IDENT) = 6;
130 # endif
131 # ifdef XCHAL_CP7_IDENT
132 const unsigned char XCJOIN(Xthal_cp_id_,XCHAL_CP7_IDENT) = 7;
133 # endif
134
135 #elif defined(__SPLIT__cp_mask_mappings)
136 // Coprocessor "mask" (1 << ID) from its name
137
138 # ifdef XCHAL_CP0_IDENT
139 const unsigned int XCJOIN(Xthal_cp_mask_,XCHAL_CP0_IDENT) = (1 << 0);
140 # endif
141 # ifdef XCHAL_CP1_IDENT
142 const unsigned int XCJOIN(Xthal_cp_mask_,XCHAL_CP1_IDENT) = (1 << 1);
143 # endif
144 # ifdef XCHAL_CP2_IDENT
145 const unsigned int XCJOIN(Xthal_cp_mask_,XCHAL_CP2_IDENT) = (1 << 2);
146 # endif
147 # ifdef XCHAL_CP3_IDENT
148 const unsigned int XCJOIN(Xthal_cp_mask_,XCHAL_CP3_IDENT) = (1 << 3);
149 # endif
150 # ifdef XCHAL_CP4_IDENT
151 const unsigned int XCJOIN(Xthal_cp_mask_,XCHAL_CP4_IDENT) = (1 << 4);
152 # endif
153 # ifdef XCHAL_CP5_IDENT
154 const unsigned int XCJOIN(Xthal_cp_mask_,XCHAL_CP5_IDENT) = (1 << 5);
155 # endif
156 # ifdef XCHAL_CP6_IDENT
157 const unsigned int XCJOIN(Xthal_cp_mask_,XCHAL_CP6_IDENT) = (1 << 6);
158 # endif
159 # ifdef XCHAL_CP7_IDENT
160 const unsigned int XCJOIN(Xthal_cp_mask_,XCHAL_CP7_IDENT) = (1 << 7);
161 # endif
162
163 //----------------------------------------------------------------------
164
165 #elif defined(__SPLIT__init_mem_extra)
166 // CMS: I have made the assumptions that 0's are safe initial
167 // values. That may be wrong at some point.
168 //
169 // initialize the extra processor
170 void
xthal_init_mem_extra(void * address)171 xthal_init_mem_extra(void *address)
172 /* not clear that it is safe to call memcpy and also not clear
173 that performance is important. */
174 {
175 unsigned int *ptr;
176 unsigned int *end;
177
178 ptr = (unsigned int *)address;
179 end = (unsigned int *)((int)address + XCHAL_NCP_SA_SIZE);
180 while( ptr < end )
181 {
182 *ptr++ = 0;
183 }
184 }
185
186 #elif defined(__SPLIT__init_mem_cp)
187 // initialize the TIE coprocessor
188 void
xthal_init_mem_cp(void * address,int cp)189 xthal_init_mem_cp(void *address, int cp)
190 {
191 unsigned int *ptr;
192 unsigned int *end;
193
194 if( cp <= 7 )
195 {
196 end = (unsigned int *)((int)address + Xthal_cpregs_size[cp]);
197 ptr = (unsigned int *)address;
198 while( ptr < end )
199 {
200 *ptr++ = 0;
201 }
202 }
203 }
204
205 #endif /*splitting*/
206
207
208 /* Nothing implemented below this point. */
209 /************************************************************************/
210
211 // save all extra+cp processor state (NOT IMPLEMENTED)
212 /*void xthal_save_all_extra(void *base)
213 {
214 xthal_save_extra(base);
215 ... here we need to iterate over configured coprocessor register files ...
216 // xthal_save_cpregs(base+XCHAL_NCP_SA_SIZE, 0);
217 }*/
218
219 // restore all extra+cp processor state (NOT IMPLEMENTED)
220 /*void xthal_restore_all_extra(void *base)
221 {
222 xthal_restore_extra(base);
223 ... here we need to iterate over configured coprocessor register files ...
224 // xthal_restore_cpregs(base+XCHAL_NCP_SA_SIZE, 0);
225 }*/
226
227
228 // initialize the extra processor (NOT IMPLEMENTED)
229 /*void xthal_init_extra()
230 {
231 }*/
232
233 // initialize the TIE coprocessor (NOT IMPLEMENTED)
234 /*void xthal_init_cp(int cp)
235 {
236 }*/
237
238
239 #if 0
240
241 /* read extra state register (NOT IMPLEMENTED) */
242 int xthal_read_extra(void *base, unsigned reg, unsigned *value)
243 {
244 if (reg&0x1000) {
245 switch(reg) {
246 #if XCHAL_HAVE_MAC16
247 case 16:
248 *value = ((unsigned *)base)[0];
249 return reg;
250 case 17:
251 *value = ((unsigned *)base)[1];
252 return reg;
253 case 32:
254 *value = ((unsigned *)base)[2];
255 return reg;
256 case 33:
257 *value = ((unsigned *)base)[3];
258 return reg;
259 case 34:
260 *value = ((unsigned *)base)[4];
261 return reg;
262 case 35:
263 *value = ((unsigned *)base)[5];
264 return reg;
265 #endif /* XCHAL_HAVE_MAC16 */
266 }
267 }
268 return -1;
269 }
270
271 /* write extra state register (NOT IMPLEMENTED) */
272 int xthal_write_extra(void *base, unsigned reg, unsigned value)
273 {
274 if (reg&0x1000) {
275 switch(reg) {
276 #if XCHAL_HAVE_MAC16
277 case 16:
278 ((unsigned *)base)[0] = value;
279 return reg;
280 case 17:
281 ((unsigned *)base)[1] = value;
282 return reg;
283 case 32:
284 ((unsigned *)base)[2] = value;
285 return reg;
286 case 33:
287 ((unsigned *)base)[3] = value;
288 return reg;
289 case 34:
290 ((unsigned *)base)[4] = value;
291 return reg;
292 case 35:
293 ((unsigned *)base)[5] = value;
294 return reg;
295 #endif /* XCHAL_HAVE_MAC16 */
296 }
297 }
298 return -1;
299 }
300
301 #endif /*0*/
302
303
304 /* read TIE coprocessor register (NOT IMPLEMENTED) */
305 /*int xthal_read_cpreg(void *base, int cp, unsigned reg, unsigned *value)
306 {
307 return -1;
308 }*/
309
310 /* write TIE coproessor register (NOT IMPLEMENTED) */
311 /*int xthal_write_cpreg(void *base, int cp, unsigned reg, unsigned value)
312 {
313 return -1;
314 }*/
315
316 /* return coprocessor number based on register (NOT IMPLEMENTED) */
317 /*int xthal_which_cp(unsigned reg)
318 {
319 return -1;
320 }*/
321
322