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 // space for "extra" (user special registers and non-coprocessor TIE) state:
33 const unsigned int Xthal_extra_size = XCHAL_NCP_SA_SIZE;
34
35 const unsigned int Xthal_extra_align = XCHAL_NCP_SA_ALIGN;
36
37 // space for state of TIE coprocessors:
38 const unsigned int Xthal_cpregs_size[8] =
39 {
40 XCHAL_CP0_SA_SIZE,
41 XCHAL_CP1_SA_SIZE,
42 XCHAL_CP2_SA_SIZE,
43 XCHAL_CP3_SA_SIZE,
44 XCHAL_CP4_SA_SIZE,
45 XCHAL_CP5_SA_SIZE,
46 XCHAL_CP6_SA_SIZE,
47 XCHAL_CP7_SA_SIZE
48 };
49
50 const unsigned int Xthal_cpregs_align[8] =
51 {
52 XCHAL_CP0_SA_ALIGN,
53 XCHAL_CP1_SA_ALIGN,
54 XCHAL_CP2_SA_ALIGN,
55 XCHAL_CP3_SA_ALIGN,
56 XCHAL_CP4_SA_ALIGN,
57 XCHAL_CP5_SA_ALIGN,
58 XCHAL_CP6_SA_ALIGN,
59 XCHAL_CP7_SA_ALIGN
60 };
61
62 const char * const Xthal_cp_names[8] =
63 {
64 XCHAL_CP0_NAME,
65 XCHAL_CP1_NAME,
66 XCHAL_CP2_NAME,
67 XCHAL_CP3_NAME,
68 XCHAL_CP4_NAME,
69 XCHAL_CP5_NAME,
70 XCHAL_CP6_NAME,
71 XCHAL_CP7_NAME
72 };
73
74 // total save area size (extra + all coprocessors + min 16-byte alignment everywhere)
75 const unsigned int Xthal_all_extra_size = XCHAL_TOTAL_SA_SIZE;
76
77 // maximum required alignment for the total save area (this might be useful):
78 const unsigned int Xthal_all_extra_align = XCHAL_TOTAL_SA_ALIGN;
79
80 // number of coprocessors starting contiguously from zero
81 // (same as Xthal_cp_max, but included for Tornado2):
82 const unsigned int Xthal_num_coprocessors = XCHAL_CP_MAX;
83
84 // actual number of coprocessors:
85 const unsigned char Xthal_cp_num = XCHAL_CP_NUM;
86
87 // index of highest numbered coprocessor, plus one:
88 const unsigned char Xthal_cp_max = XCHAL_CP_MAX;
89
90 // index of highest allowed coprocessor number, per cfg, plus one:
91 //const unsigned char Xthal_cp_maxcfg = XCHAL_CP_MAXCFG;
92
93 // bitmask of which coprocessors are present:
94 const unsigned int Xthal_cp_mask = XCHAL_CP_MASK;
95
96 // Coprocessor ID from its name
97
98 # ifdef XCHAL_CP0_IDENT
99 const unsigned char XCJOIN(Xthal_cp_id_,XCHAL_CP0_IDENT) = 0;
100 # endif
101 # ifdef XCHAL_CP1_IDENT
102 const unsigned char XCJOIN(Xthal_cp_id_,XCHAL_CP1_IDENT) = 1;
103 # endif
104 # ifdef XCHAL_CP2_IDENT
105 const unsigned char XCJOIN(Xthal_cp_id_,XCHAL_CP2_IDENT) = 2;
106 # endif
107 # ifdef XCHAL_CP3_IDENT
108 const unsigned char XCJOIN(Xthal_cp_id_,XCHAL_CP3_IDENT) = 3;
109 # endif
110 # ifdef XCHAL_CP4_IDENT
111 const unsigned char XCJOIN(Xthal_cp_id_,XCHAL_CP4_IDENT) = 4;
112 # endif
113 # ifdef XCHAL_CP5_IDENT
114 const unsigned char XCJOIN(Xthal_cp_id_,XCHAL_CP5_IDENT) = 5;
115 # endif
116 # ifdef XCHAL_CP6_IDENT
117 const unsigned char XCJOIN(Xthal_cp_id_,XCHAL_CP6_IDENT) = 6;
118 # endif
119 # ifdef XCHAL_CP7_IDENT
120 const unsigned char XCJOIN(Xthal_cp_id_,XCHAL_CP7_IDENT) = 7;
121 # endif
122
123 // Coprocessor "mask" (1 << ID) from its name
124
125 # ifdef XCHAL_CP0_IDENT
126 const unsigned int XCJOIN(Xthal_cp_mask_,XCHAL_CP0_IDENT) = (1 << 0);
127 # endif
128 # ifdef XCHAL_CP1_IDENT
129 const unsigned int XCJOIN(Xthal_cp_mask_,XCHAL_CP1_IDENT) = (1 << 1);
130 # endif
131 # ifdef XCHAL_CP2_IDENT
132 const unsigned int XCJOIN(Xthal_cp_mask_,XCHAL_CP2_IDENT) = (1 << 2);
133 # endif
134 # ifdef XCHAL_CP3_IDENT
135 const unsigned int XCJOIN(Xthal_cp_mask_,XCHAL_CP3_IDENT) = (1 << 3);
136 # endif
137 # ifdef XCHAL_CP4_IDENT
138 const unsigned int XCJOIN(Xthal_cp_mask_,XCHAL_CP4_IDENT) = (1 << 4);
139 # endif
140 # ifdef XCHAL_CP5_IDENT
141 const unsigned int XCJOIN(Xthal_cp_mask_,XCHAL_CP5_IDENT) = (1 << 5);
142 # endif
143 # ifdef XCHAL_CP6_IDENT
144 const unsigned int XCJOIN(Xthal_cp_mask_,XCHAL_CP6_IDENT) = (1 << 6);
145 # endif
146 # ifdef XCHAL_CP7_IDENT
147 const unsigned int XCJOIN(Xthal_cp_mask_,XCHAL_CP7_IDENT) = (1 << 7);
148 # endif
149
150 //----------------------------------------------------------------------
151
152 // CMS: I have made the assumptions that 0's are safe initial
153 // values. That may be wrong at some point.
154 //
155 // initialize the extra processor
156 void
xthal_init_mem_extra(void * address)157 xthal_init_mem_extra(void *address)
158 /* not clear that it is safe to call memcpy and also not clear
159 that performance is important. */
160 {
161 unsigned int *ptr;
162 unsigned int *end;
163
164 ptr = (unsigned int *)address;
165 end = (unsigned int *)((int)address + XCHAL_NCP_SA_SIZE);
166 while( ptr < end )
167 {
168 *ptr++ = 0;
169 }
170 }
171
172 // initialize the TIE coprocessor
173 void
xthal_init_mem_cp(void * address,int cp)174 xthal_init_mem_cp(void *address, int cp)
175 {
176 unsigned int *ptr;
177 unsigned int *end;
178
179 if( cp <= 7 )
180 {
181 end = (unsigned int *)((int)address + Xthal_cpregs_size[cp]);
182 ptr = (unsigned int *)address;
183 while( ptr < end )
184 {
185 *ptr++ = 0;
186 }
187 }
188 }
189
190
191
192 /* Nothing implemented below this point. */
193 /************************************************************************/
194
195 // save all extra+cp processor state (NOT IMPLEMENTED)
196 /*void xthal_save_all_extra(void *base)
197 {
198 xthal_save_extra(base);
199 ... here we need to iterate over configured coprocessor register files ...
200 // xthal_save_cpregs(base+XCHAL_NCP_SA_SIZE, 0);
201 }*/
202
203 // restore all extra+cp processor state (NOT IMPLEMENTED)
204 /*void xthal_restore_all_extra(void *base)
205 {
206 xthal_restore_extra(base);
207 ... here we need to iterate over configured coprocessor register files ...
208 // xthal_restore_cpregs(base+XCHAL_NCP_SA_SIZE, 0);
209 }*/
210
211
212 // initialize the extra processor (NOT IMPLEMENTED)
213 /*void xthal_init_extra()
214 {
215 }*/
216
217 // initialize the TIE coprocessor (NOT IMPLEMENTED)
218 /*void xthal_init_cp(int cp)
219 {
220 }*/
221
222
223 #if 0
224
225 /* read extra state register (NOT IMPLEMENTED) */
226 int xthal_read_extra(void *base, unsigned reg, unsigned *value)
227 {
228 if (reg&0x1000) {
229 switch(reg) {
230 #if XCHAL_HAVE_MAC16
231 case 16:
232 *value = ((unsigned *)base)[0];
233 return reg;
234 case 17:
235 *value = ((unsigned *)base)[1];
236 return reg;
237 case 32:
238 *value = ((unsigned *)base)[2];
239 return reg;
240 case 33:
241 *value = ((unsigned *)base)[3];
242 return reg;
243 case 34:
244 *value = ((unsigned *)base)[4];
245 return reg;
246 case 35:
247 *value = ((unsigned *)base)[5];
248 return reg;
249 #endif /* XCHAL_HAVE_MAC16 */
250 }
251 }
252 return -1;
253 }
254
255 /* write extra state register (NOT IMPLEMENTED) */
256 int xthal_write_extra(void *base, unsigned reg, unsigned value)
257 {
258 if (reg&0x1000) {
259 switch(reg) {
260 #if XCHAL_HAVE_MAC16
261 case 16:
262 ((unsigned *)base)[0] = value;
263 return reg;
264 case 17:
265 ((unsigned *)base)[1] = value;
266 return reg;
267 case 32:
268 ((unsigned *)base)[2] = value;
269 return reg;
270 case 33:
271 ((unsigned *)base)[3] = value;
272 return reg;
273 case 34:
274 ((unsigned *)base)[4] = value;
275 return reg;
276 case 35:
277 ((unsigned *)base)[5] = value;
278 return reg;
279 #endif /* XCHAL_HAVE_MAC16 */
280 }
281 }
282 return -1;
283 }
284
285 #endif /*0*/
286
287
288 /* read TIE coprocessor register (NOT IMPLEMENTED) */
289 /*int xthal_read_cpreg(void *base, int cp, unsigned reg, unsigned *value)
290 {
291 return -1;
292 }*/
293
294 /* write TIE coproessor register (NOT IMPLEMENTED) */
295 /*int xthal_write_cpreg(void *base, int cp, unsigned reg, unsigned value)
296 {
297 return -1;
298 }*/
299
300 /* return coprocessor number based on register (NOT IMPLEMENTED) */
301 /*int xthal_which_cp(unsigned reg)
302 {
303 return -1;
304 }*/
305
306