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