1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21#include <stdint.h>
22#include <stdlib.h>
23#include <stdio.h>
24
25#include "cpu.h"
26#include "exec-all.h"
27
28#if defined(CONFIG_USER_ONLY)
29
30int cpu_alpha_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
31 int mmu_idx, int is_softmmu)
32{
33 if (rw == 2)
34 env->exception_index = EXCP_ITB_MISS;
35 else
36 env->exception_index = EXCP_DFAULT;
37 env->ipr[IPR_EXC_ADDR] = address;
38
39 return 1;
40}
41
42target_phys_addr_t cpu_get_phys_page_debug (CPUState *env, target_ulong addr)
43{
44 return addr;
45}
46
47void do_interrupt (CPUState *env)
48{
49 env->exception_index = -1;
50}
51
52#else
53
54target_phys_addr_t cpu_get_phys_page_debug (CPUState *env, target_ulong addr)
55{
56 return -1;
57}
58
59int cpu_alpha_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
60 int mmu_idx, int is_softmmu)
61{
62 uint32_t opc;
63
64 if (rw == 2) {
65
66 env->exception_index = EXCP_ITB_MISS;
67 } else {
68 if (env->ipr[IPR_EXC_ADDR] & 1)
69 env->exception_index = EXCP_DTB_MISS_PAL;
70 else
71 env->exception_index = EXCP_DTB_MISS_NATIVE;
72 opc = (ldl_code(env->pc) >> 21) << 4;
73 if (rw) {
74 opc |= 0x9;
75 } else {
76 opc |= 0x4;
77 }
78 env->ipr[IPR_MM_STAT] = opc;
79 }
80
81 return 1;
82}
83
84int cpu_alpha_mfpr (CPUState *env, int iprn, uint64_t *valp)
85{
86 uint64_t hwpcb;
87 int ret = 0;
88
89 hwpcb = env->ipr[IPR_PCBB];
90 switch (iprn) {
91 case IPR_ASN:
92 if (env->features & FEATURE_ASN)
93 *valp = env->ipr[IPR_ASN];
94 else
95 *valp = 0;
96 break;
97 case IPR_ASTEN:
98 *valp = ((int64_t)(env->ipr[IPR_ASTEN] << 60)) >> 60;
99 break;
100 case IPR_ASTSR:
101 *valp = ((int64_t)(env->ipr[IPR_ASTSR] << 60)) >> 60;
102 break;
103 case IPR_DATFX:
104
105 ret = -1;
106 break;
107 case IPR_ESP:
108 if (env->features & FEATURE_SPS)
109 *valp = env->ipr[IPR_ESP];
110 else
111 *valp = ldq_raw(hwpcb + 8);
112 break;
113 case IPR_FEN:
114 *valp = ((int64_t)(env->ipr[IPR_FEN] << 63)) >> 63;
115 break;
116 case IPR_IPIR:
117
118 ret = -1;
119 break;
120 case IPR_IPL:
121 *valp = ((int64_t)(env->ipr[IPR_IPL] << 59)) >> 59;
122 break;
123 case IPR_KSP:
124 if (!(env->ipr[IPR_EXC_ADDR] & 1)) {
125 ret = -1;
126 } else {
127 if (env->features & FEATURE_SPS)
128 *valp = env->ipr[IPR_KSP];
129 else
130 *valp = ldq_raw(hwpcb + 0);
131 }
132 break;
133 case IPR_MCES:
134 *valp = ((int64_t)(env->ipr[IPR_MCES] << 59)) >> 59;
135 break;
136 case IPR_PERFMON:
137
138 *valp = 0;
139 break;
140 case IPR_PCBB:
141 *valp = ((int64_t)env->ipr[IPR_PCBB] << 16) >> 16;
142 break;
143 case IPR_PRBR:
144 *valp = env->ipr[IPR_PRBR];
145 break;
146 case IPR_PTBR:
147 *valp = env->ipr[IPR_PTBR];
148 break;
149 case IPR_SCBB:
150 *valp = (int64_t)((int32_t)env->ipr[IPR_SCBB]);
151 break;
152 case IPR_SIRR:
153
154 ret = -1;
155 break;
156 case IPR_SISR:
157 *valp = (int64_t)((int16_t)env->ipr[IPR_SISR]);
158 case IPR_SSP:
159 if (env->features & FEATURE_SPS)
160 *valp = env->ipr[IPR_SSP];
161 else
162 *valp = ldq_raw(hwpcb + 16);
163 break;
164 case IPR_SYSPTBR:
165 if (env->features & FEATURE_VIRBND)
166 *valp = env->ipr[IPR_SYSPTBR];
167 else
168 ret = -1;
169 break;
170 case IPR_TBCHK:
171 if ((env->features & FEATURE_TBCHK)) {
172
173 *valp = 0;
174 ret = -1;
175 } else {
176 ret = -1;
177 }
178 break;
179 case IPR_TBIA:
180
181 ret = -1;
182 break;
183 case IPR_TBIAP:
184
185 ret = -1;
186 break;
187 case IPR_TBIS:
188
189 ret = -1;
190 break;
191 case IPR_TBISD:
192
193 ret = -1;
194 break;
195 case IPR_TBISI:
196
197 ret = -1;
198 break;
199 case IPR_USP:
200 if (env->features & FEATURE_SPS)
201 *valp = env->ipr[IPR_USP];
202 else
203 *valp = ldq_raw(hwpcb + 24);
204 break;
205 case IPR_VIRBND:
206 if (env->features & FEATURE_VIRBND)
207 *valp = env->ipr[IPR_VIRBND];
208 else
209 ret = -1;
210 break;
211 case IPR_VPTB:
212 *valp = env->ipr[IPR_VPTB];
213 break;
214 case IPR_WHAMI:
215 *valp = env->ipr[IPR_WHAMI];
216 break;
217 default:
218
219 ret = -1;
220 break;
221 }
222
223 return ret;
224}
225
226int cpu_alpha_mtpr (CPUState *env, int iprn, uint64_t val, uint64_t *oldvalp)
227{
228 uint64_t hwpcb, tmp64;
229 uint8_t tmp8;
230 int ret = 0;
231
232 hwpcb = env->ipr[IPR_PCBB];
233 switch (iprn) {
234 case IPR_ASN:
235
236 ret = -1;
237 break;
238 case IPR_ASTEN:
239 tmp8 = ((int8_t)(env->ipr[IPR_ASTEN] << 4)) >> 4;
240 *oldvalp = tmp8;
241 tmp8 &= val & 0xF;
242 tmp8 |= (val >> 4) & 0xF;
243 env->ipr[IPR_ASTEN] &= ~0xF;
244 env->ipr[IPR_ASTEN] |= tmp8;
245 ret = 1;
246 break;
247 case IPR_ASTSR:
248 tmp8 = ((int8_t)(env->ipr[IPR_ASTSR] << 4)) >> 4;
249 *oldvalp = tmp8;
250 tmp8 &= val & 0xF;
251 tmp8 |= (val >> 4) & 0xF;
252 env->ipr[IPR_ASTSR] &= ~0xF;
253 env->ipr[IPR_ASTSR] |= tmp8;
254 ret = 1;
255 case IPR_DATFX:
256 env->ipr[IPR_DATFX] &= ~0x1;
257 env->ipr[IPR_DATFX] |= val & 1;
258 tmp64 = ldq_raw(hwpcb + 56);
259 tmp64 &= ~0x8000000000000000ULL;
260 tmp64 |= (val & 1) << 63;
261 stq_raw(hwpcb + 56, tmp64);
262 break;
263 case IPR_ESP:
264 if (env->features & FEATURE_SPS)
265 env->ipr[IPR_ESP] = val;
266 else
267 stq_raw(hwpcb + 8, val);
268 break;
269 case IPR_FEN:
270 env->ipr[IPR_FEN] = val & 1;
271 tmp64 = ldq_raw(hwpcb + 56);
272 tmp64 &= ~1;
273 tmp64 |= val & 1;
274 stq_raw(hwpcb + 56, tmp64);
275 break;
276 case IPR_IPIR:
277
278 break;
279 case IPR_IPL:
280 *oldvalp = ((int64_t)(env->ipr[IPR_IPL] << 59)) >> 59;
281 env->ipr[IPR_IPL] &= ~0x1F;
282 env->ipr[IPR_IPL] |= val & 0x1F;
283
284 ret = 1;
285 break;
286 case IPR_KSP:
287 if (!(env->ipr[IPR_EXC_ADDR] & 1)) {
288 ret = -1;
289 } else {
290 if (env->features & FEATURE_SPS)
291 env->ipr[IPR_KSP] = val;
292 else
293 stq_raw(hwpcb + 0, val);
294 }
295 break;
296 case IPR_MCES:
297 env->ipr[IPR_MCES] &= ~((val & 0x7) | 0x18);
298 env->ipr[IPR_MCES] |= val & 0x18;
299 break;
300 case IPR_PERFMON:
301
302 *oldvalp = 0;
303 ret = 1;
304 break;
305 case IPR_PCBB:
306
307 ret = -1;
308 break;
309 case IPR_PRBR:
310 env->ipr[IPR_PRBR] = val;
311 break;
312 case IPR_PTBR:
313
314 ret = -1;
315 break;
316 case IPR_SCBB:
317 env->ipr[IPR_SCBB] = (uint32_t)val;
318 break;
319 case IPR_SIRR:
320 if (val & 0xF) {
321 env->ipr[IPR_SISR] |= 1 << (val & 0xF);
322
323 }
324 break;
325 case IPR_SISR:
326
327 ret = -1;
328 break;
329 case IPR_SSP:
330 if (env->features & FEATURE_SPS)
331 env->ipr[IPR_SSP] = val;
332 else
333 stq_raw(hwpcb + 16, val);
334 break;
335 case IPR_SYSPTBR:
336 if (env->features & FEATURE_VIRBND)
337 env->ipr[IPR_SYSPTBR] = val;
338 else
339 ret = -1;
340 case IPR_TBCHK:
341
342 ret = -1;
343 break;
344 case IPR_TBIA:
345 tlb_flush(env, 1);
346 break;
347 case IPR_TBIAP:
348 tlb_flush(env, 1);
349 break;
350 case IPR_TBIS:
351 tlb_flush_page(env, val);
352 break;
353 case IPR_TBISD:
354 tlb_flush_page(env, val);
355 break;
356 case IPR_TBISI:
357 tlb_flush_page(env, val);
358 break;
359 case IPR_USP:
360 if (env->features & FEATURE_SPS)
361 env->ipr[IPR_USP] = val;
362 else
363 stq_raw(hwpcb + 24, val);
364 break;
365 case IPR_VIRBND:
366 if (env->features & FEATURE_VIRBND)
367 env->ipr[IPR_VIRBND] = val;
368 else
369 ret = -1;
370 break;
371 case IPR_VPTB:
372 env->ipr[IPR_VPTB] = val;
373 break;
374 case IPR_WHAMI:
375
376 ret = -1;
377 break;
378 default:
379
380 ret = -1;
381 break;
382 }
383
384 return ret;
385}
386
387void do_interrupt (CPUState *env)
388{
389 int excp;
390
391 env->ipr[IPR_EXC_ADDR] = env->pc | 1;
392 excp = env->exception_index;
393 env->exception_index = 0;
394 env->error_code = 0;
395
396 if (env->ipr[IPR_PAL_BASE] != -1ULL) {
397
398 env->pc = env->ipr[IPR_PAL_BASE] + excp;
399 } else {
400
401 call_pal(env);
402
403 env->pc = env->ipr[IPR_EXC_ADDR] & ~7;
404 env->ipr[IPR_EXC_ADDR] = env->ipr[IPR_EXC_ADDR] & 1;
405
406 }
407}
408#endif
409
410void cpu_dump_state (CPUState *env, FILE *f,
411 int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
412 int flags)
413{
414 static const char *linux_reg_names[] = {
415 "v0 ", "t0 ", "t1 ", "t2 ", "t3 ", "t4 ", "t5 ", "t6 ",
416 "t7 ", "s0 ", "s1 ", "s2 ", "s3 ", "s4 ", "s5 ", "fp ",
417 "a0 ", "a1 ", "a2 ", "a3 ", "a4 ", "a5 ", "t8 ", "t9 ",
418 "t10", "t11", "ra ", "t12", "at ", "gp ", "sp ", "zero",
419 };
420 int i;
421
422 cpu_fprintf(f, " PC " TARGET_FMT_lx " PS " TARGET_FMT_lx "\n",
423 env->pc, env->ps);
424 for (i = 0; i < 31; i++) {
425 cpu_fprintf(f, "IR%02d %s " TARGET_FMT_lx " ", i,
426 linux_reg_names[i], env->ir[i]);
427 if ((i % 3) == 2)
428 cpu_fprintf(f, "\n");
429 }
430 cpu_fprintf(f, "\n");
431 for (i = 0; i < 31; i++) {
432 cpu_fprintf(f, "FIR%02d " TARGET_FMT_lx " ", i,
433 *((uint64_t *)(&env->fir[i])));
434 if ((i % 3) == 2)
435 cpu_fprintf(f, "\n");
436 }
437 cpu_fprintf(f, "\nlock " TARGET_FMT_lx "\n", env->lock);
438}
439