Statistics
| Branch: | Revision:

root / target-alpha / helper.c @ 57c83dac

History | View | Annotate | Download (12.2 kB)

1 4c9649a9 j_mayer
/*
2 4c9649a9 j_mayer
 *  Alpha emulation cpu helpers for qemu.
3 5fafdf24 ths
 *
4 4c9649a9 j_mayer
 *  Copyright (c) 2007 Jocelyn Mayer
5 4c9649a9 j_mayer
 *
6 4c9649a9 j_mayer
 * This library is free software; you can redistribute it and/or
7 4c9649a9 j_mayer
 * modify it under the terms of the GNU Lesser General Public
8 4c9649a9 j_mayer
 * License as published by the Free Software Foundation; either
9 4c9649a9 j_mayer
 * version 2 of the License, or (at your option) any later version.
10 4c9649a9 j_mayer
 *
11 4c9649a9 j_mayer
 * This library is distributed in the hope that it will be useful,
12 4c9649a9 j_mayer
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 4c9649a9 j_mayer
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 4c9649a9 j_mayer
 * Lesser General Public License for more details.
15 4c9649a9 j_mayer
 *
16 4c9649a9 j_mayer
 * You should have received a copy of the GNU Lesser General Public
17 8167ee88 Blue Swirl
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18 4c9649a9 j_mayer
 */
19 4c9649a9 j_mayer
20 4c9649a9 j_mayer
#include <stdint.h>
21 4c9649a9 j_mayer
#include <stdlib.h>
22 4c9649a9 j_mayer
#include <stdio.h>
23 4c9649a9 j_mayer
24 4c9649a9 j_mayer
#include "cpu.h"
25 ba0e276d Richard Henderson
#include "softfloat.h"
26 ba0e276d Richard Henderson
27 ba0e276d Richard Henderson
uint64_t cpu_alpha_load_fpcr (CPUState *env)
28 ba0e276d Richard Henderson
{
29 8443effb Richard Henderson
    uint64_t r = 0;
30 8443effb Richard Henderson
    uint8_t t;
31 8443effb Richard Henderson
32 8443effb Richard Henderson
    t = env->fpcr_exc_status;
33 8443effb Richard Henderson
    if (t) {
34 8443effb Richard Henderson
        r = FPCR_SUM;
35 8443effb Richard Henderson
        if (t & float_flag_invalid) {
36 8443effb Richard Henderson
            r |= FPCR_INV;
37 8443effb Richard Henderson
        }
38 8443effb Richard Henderson
        if (t & float_flag_divbyzero) {
39 8443effb Richard Henderson
            r |= FPCR_DZE;
40 8443effb Richard Henderson
        }
41 8443effb Richard Henderson
        if (t & float_flag_overflow) {
42 8443effb Richard Henderson
            r |= FPCR_OVF;
43 8443effb Richard Henderson
        }
44 8443effb Richard Henderson
        if (t & float_flag_underflow) {
45 8443effb Richard Henderson
            r |= FPCR_UNF;
46 8443effb Richard Henderson
        }
47 8443effb Richard Henderson
        if (t & float_flag_inexact) {
48 8443effb Richard Henderson
            r |= FPCR_INE;
49 8443effb Richard Henderson
        }
50 8443effb Richard Henderson
    }
51 8443effb Richard Henderson
52 8443effb Richard Henderson
    t = env->fpcr_exc_mask;
53 8443effb Richard Henderson
    if (t & float_flag_invalid) {
54 8443effb Richard Henderson
        r |= FPCR_INVD;
55 8443effb Richard Henderson
    }
56 8443effb Richard Henderson
    if (t & float_flag_divbyzero) {
57 8443effb Richard Henderson
        r |= FPCR_DZED;
58 8443effb Richard Henderson
    }
59 8443effb Richard Henderson
    if (t & float_flag_overflow) {
60 8443effb Richard Henderson
        r |= FPCR_OVFD;
61 8443effb Richard Henderson
    }
62 8443effb Richard Henderson
    if (t & float_flag_underflow) {
63 8443effb Richard Henderson
        r |= FPCR_UNFD;
64 8443effb Richard Henderson
    }
65 8443effb Richard Henderson
    if (t & float_flag_inexact) {
66 8443effb Richard Henderson
        r |= FPCR_INED;
67 8443effb Richard Henderson
    }
68 8443effb Richard Henderson
69 8443effb Richard Henderson
    switch (env->fpcr_dyn_round) {
70 ba0e276d Richard Henderson
    case float_round_nearest_even:
71 8443effb Richard Henderson
        r |= FPCR_DYN_NORMAL;
72 ba0e276d Richard Henderson
        break;
73 ba0e276d Richard Henderson
    case float_round_down:
74 8443effb Richard Henderson
        r |= FPCR_DYN_MINUS;
75 ba0e276d Richard Henderson
        break;
76 ba0e276d Richard Henderson
    case float_round_up:
77 8443effb Richard Henderson
        r |= FPCR_DYN_PLUS;
78 ba0e276d Richard Henderson
        break;
79 ba0e276d Richard Henderson
    case float_round_to_zero:
80 8443effb Richard Henderson
        r |= FPCR_DYN_CHOPPED;
81 ba0e276d Richard Henderson
        break;
82 ba0e276d Richard Henderson
    }
83 8443effb Richard Henderson
84 8443effb Richard Henderson
    if (env->fpcr_dnz) {
85 8443effb Richard Henderson
        r |= FPCR_DNZ;
86 8443effb Richard Henderson
    }
87 8443effb Richard Henderson
    if (env->fpcr_dnod) {
88 8443effb Richard Henderson
        r |= FPCR_DNOD;
89 8443effb Richard Henderson
    }
90 8443effb Richard Henderson
    if (env->fpcr_undz) {
91 8443effb Richard Henderson
        r |= FPCR_UNDZ;
92 8443effb Richard Henderson
    }
93 8443effb Richard Henderson
94 8443effb Richard Henderson
    return r;
95 ba0e276d Richard Henderson
}
96 ba0e276d Richard Henderson
97 ba0e276d Richard Henderson
void cpu_alpha_store_fpcr (CPUState *env, uint64_t val)
98 ba0e276d Richard Henderson
{
99 8443effb Richard Henderson
    uint8_t t;
100 8443effb Richard Henderson
101 8443effb Richard Henderson
    t = 0;
102 8443effb Richard Henderson
    if (val & FPCR_INV) {
103 8443effb Richard Henderson
        t |= float_flag_invalid;
104 8443effb Richard Henderson
    }
105 8443effb Richard Henderson
    if (val & FPCR_DZE) {
106 8443effb Richard Henderson
        t |= float_flag_divbyzero;
107 8443effb Richard Henderson
    }
108 8443effb Richard Henderson
    if (val & FPCR_OVF) {
109 8443effb Richard Henderson
        t |= float_flag_overflow;
110 8443effb Richard Henderson
    }
111 8443effb Richard Henderson
    if (val & FPCR_UNF) {
112 8443effb Richard Henderson
        t |= float_flag_underflow;
113 8443effb Richard Henderson
    }
114 8443effb Richard Henderson
    if (val & FPCR_INE) {
115 8443effb Richard Henderson
        t |= float_flag_inexact;
116 8443effb Richard Henderson
    }
117 8443effb Richard Henderson
    env->fpcr_exc_status = t;
118 8443effb Richard Henderson
119 8443effb Richard Henderson
    t = 0;
120 8443effb Richard Henderson
    if (val & FPCR_INVD) {
121 8443effb Richard Henderson
        t |= float_flag_invalid;
122 8443effb Richard Henderson
    }
123 8443effb Richard Henderson
    if (val & FPCR_DZED) {
124 8443effb Richard Henderson
        t |= float_flag_divbyzero;
125 8443effb Richard Henderson
    }
126 8443effb Richard Henderson
    if (val & FPCR_OVFD) {
127 8443effb Richard Henderson
        t |= float_flag_overflow;
128 8443effb Richard Henderson
    }
129 8443effb Richard Henderson
    if (val & FPCR_UNFD) {
130 8443effb Richard Henderson
        t |= float_flag_underflow;
131 8443effb Richard Henderson
    }
132 8443effb Richard Henderson
    if (val & FPCR_INED) {
133 8443effb Richard Henderson
        t |= float_flag_inexact;
134 8443effb Richard Henderson
    }
135 8443effb Richard Henderson
    env->fpcr_exc_mask = t;
136 8443effb Richard Henderson
137 8443effb Richard Henderson
    switch (val & FPCR_DYN_MASK) {
138 8443effb Richard Henderson
    case FPCR_DYN_CHOPPED:
139 8443effb Richard Henderson
        t = float_round_to_zero;
140 ba0e276d Richard Henderson
        break;
141 8443effb Richard Henderson
    case FPCR_DYN_MINUS:
142 8443effb Richard Henderson
        t = float_round_down;
143 ba0e276d Richard Henderson
        break;
144 8443effb Richard Henderson
    case FPCR_DYN_NORMAL:
145 8443effb Richard Henderson
        t = float_round_nearest_even;
146 ba0e276d Richard Henderson
        break;
147 8443effb Richard Henderson
    case FPCR_DYN_PLUS:
148 8443effb Richard Henderson
        t = float_round_up;
149 ba0e276d Richard Henderson
        break;
150 ba0e276d Richard Henderson
    }
151 8443effb Richard Henderson
    env->fpcr_dyn_round = t;
152 8443effb Richard Henderson
153 8443effb Richard Henderson
    env->fpcr_flush_to_zero
154 8443effb Richard Henderson
      = (val & (FPCR_UNDZ|FPCR_UNFD)) == (FPCR_UNDZ|FPCR_UNFD);
155 8443effb Richard Henderson
156 8443effb Richard Henderson
    env->fpcr_dnz = (val & FPCR_DNZ) != 0;
157 8443effb Richard Henderson
    env->fpcr_dnod = (val & FPCR_DNOD) != 0;
158 8443effb Richard Henderson
    env->fpcr_undz = (val & FPCR_UNDZ) != 0;
159 ba0e276d Richard Henderson
}
160 4c9649a9 j_mayer
161 5fafdf24 ths
#if defined(CONFIG_USER_ONLY)
162 4c9649a9 j_mayer
int cpu_alpha_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
163 97b348e7 Blue Swirl
                                int mmu_idx)
164 4c9649a9 j_mayer
{
165 07b6c13b Richard Henderson
    env->exception_index = EXCP_MMFAULT;
166 129d8aa5 Richard Henderson
    env->trap_arg0 = address;
167 4c9649a9 j_mayer
    return 1;
168 4c9649a9 j_mayer
}
169 4c9649a9 j_mayer
#else
170 21d2beaa Richard Henderson
void swap_shadow_regs(CPUState *env)
171 21d2beaa Richard Henderson
{
172 21d2beaa Richard Henderson
    uint64_t i0, i1, i2, i3, i4, i5, i6, i7;
173 21d2beaa Richard Henderson
174 21d2beaa Richard Henderson
    i0 = env->ir[8];
175 21d2beaa Richard Henderson
    i1 = env->ir[9];
176 21d2beaa Richard Henderson
    i2 = env->ir[10];
177 21d2beaa Richard Henderson
    i3 = env->ir[11];
178 21d2beaa Richard Henderson
    i4 = env->ir[12];
179 21d2beaa Richard Henderson
    i5 = env->ir[13];
180 21d2beaa Richard Henderson
    i6 = env->ir[14];
181 21d2beaa Richard Henderson
    i7 = env->ir[25];
182 21d2beaa Richard Henderson
183 21d2beaa Richard Henderson
    env->ir[8]  = env->shadow[0];
184 21d2beaa Richard Henderson
    env->ir[9]  = env->shadow[1];
185 21d2beaa Richard Henderson
    env->ir[10] = env->shadow[2];
186 21d2beaa Richard Henderson
    env->ir[11] = env->shadow[3];
187 21d2beaa Richard Henderson
    env->ir[12] = env->shadow[4];
188 21d2beaa Richard Henderson
    env->ir[13] = env->shadow[5];
189 21d2beaa Richard Henderson
    env->ir[14] = env->shadow[6];
190 21d2beaa Richard Henderson
    env->ir[25] = env->shadow[7];
191 21d2beaa Richard Henderson
192 21d2beaa Richard Henderson
    env->shadow[0] = i0;
193 21d2beaa Richard Henderson
    env->shadow[1] = i1;
194 21d2beaa Richard Henderson
    env->shadow[2] = i2;
195 21d2beaa Richard Henderson
    env->shadow[3] = i3;
196 21d2beaa Richard Henderson
    env->shadow[4] = i4;
197 21d2beaa Richard Henderson
    env->shadow[5] = i5;
198 21d2beaa Richard Henderson
    env->shadow[6] = i6;
199 21d2beaa Richard Henderson
    env->shadow[7] = i7;
200 21d2beaa Richard Henderson
}
201 21d2beaa Richard Henderson
202 a3b9af16 Richard Henderson
/* Returns the OSF/1 entMM failure indication, or -1 on success.  */
203 a3b9af16 Richard Henderson
static int get_physical_address(CPUState *env, target_ulong addr,
204 a3b9af16 Richard Henderson
                                int prot_need, int mmu_idx,
205 a3b9af16 Richard Henderson
                                target_ulong *pphys, int *pprot)
206 4c9649a9 j_mayer
{
207 a3b9af16 Richard Henderson
    target_long saddr = addr;
208 a3b9af16 Richard Henderson
    target_ulong phys = 0;
209 a3b9af16 Richard Henderson
    target_ulong L1pte, L2pte, L3pte;
210 a3b9af16 Richard Henderson
    target_ulong pt, index;
211 a3b9af16 Richard Henderson
    int prot = 0;
212 a3b9af16 Richard Henderson
    int ret = MM_K_ACV;
213 a3b9af16 Richard Henderson
214 a3b9af16 Richard Henderson
    /* Ensure that the virtual address is properly sign-extended from
215 a3b9af16 Richard Henderson
       the last implemented virtual address bit.  */
216 a3b9af16 Richard Henderson
    if (saddr >> TARGET_VIRT_ADDR_SPACE_BITS != saddr >> 63) {
217 a3b9af16 Richard Henderson
        goto exit;
218 a3b9af16 Richard Henderson
    }
219 a3b9af16 Richard Henderson
220 a3b9af16 Richard Henderson
    /* Translate the superpage.  */
221 a3b9af16 Richard Henderson
    /* ??? When we do more than emulate Unix PALcode, we'll need to
222 fa6e0a63 Richard Henderson
       determine which KSEG is actually active.  */
223 fa6e0a63 Richard Henderson
    if (saddr < 0 && ((saddr >> 41) & 3) == 2) {
224 fa6e0a63 Richard Henderson
        /* User-space cannot access KSEG addresses.  */
225 a3b9af16 Richard Henderson
        if (mmu_idx != MMU_KERNEL_IDX) {
226 a3b9af16 Richard Henderson
            goto exit;
227 a3b9af16 Richard Henderson
        }
228 a3b9af16 Richard Henderson
229 fa6e0a63 Richard Henderson
        /* For the benefit of the Typhoon chipset, move bit 40 to bit 43.
230 fa6e0a63 Richard Henderson
           We would not do this if the 48-bit KSEG is enabled.  */
231 a3b9af16 Richard Henderson
        phys = saddr & ((1ull << 40) - 1);
232 fa6e0a63 Richard Henderson
        phys |= (saddr & (1ull << 40)) << 3;
233 fa6e0a63 Richard Henderson
234 a3b9af16 Richard Henderson
        prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
235 a3b9af16 Richard Henderson
        ret = -1;
236 a3b9af16 Richard Henderson
        goto exit;
237 a3b9af16 Richard Henderson
    }
238 a3b9af16 Richard Henderson
239 a3b9af16 Richard Henderson
    /* Interpret the page table exactly like PALcode does.  */
240 a3b9af16 Richard Henderson
241 a3b9af16 Richard Henderson
    pt = env->ptbr;
242 a3b9af16 Richard Henderson
243 a3b9af16 Richard Henderson
    /* L1 page table read.  */
244 a3b9af16 Richard Henderson
    index = (addr >> (TARGET_PAGE_BITS + 20)) & 0x3ff;
245 a3b9af16 Richard Henderson
    L1pte = ldq_phys(pt + index*8);
246 a3b9af16 Richard Henderson
247 a3b9af16 Richard Henderson
    if (unlikely((L1pte & PTE_VALID) == 0)) {
248 a3b9af16 Richard Henderson
        ret = MM_K_TNV;
249 a3b9af16 Richard Henderson
        goto exit;
250 a3b9af16 Richard Henderson
    }
251 a3b9af16 Richard Henderson
    if (unlikely((L1pte & PTE_KRE) == 0)) {
252 a3b9af16 Richard Henderson
        goto exit;
253 a3b9af16 Richard Henderson
    }
254 a3b9af16 Richard Henderson
    pt = L1pte >> 32 << TARGET_PAGE_BITS;
255 a3b9af16 Richard Henderson
256 a3b9af16 Richard Henderson
    /* L2 page table read.  */
257 a3b9af16 Richard Henderson
    index = (addr >> (TARGET_PAGE_BITS + 10)) & 0x3ff;
258 a3b9af16 Richard Henderson
    L2pte = ldq_phys(pt + index*8);
259 a3b9af16 Richard Henderson
260 a3b9af16 Richard Henderson
    if (unlikely((L2pte & PTE_VALID) == 0)) {
261 a3b9af16 Richard Henderson
        ret = MM_K_TNV;
262 a3b9af16 Richard Henderson
        goto exit;
263 a3b9af16 Richard Henderson
    }
264 a3b9af16 Richard Henderson
    if (unlikely((L2pte & PTE_KRE) == 0)) {
265 a3b9af16 Richard Henderson
        goto exit;
266 a3b9af16 Richard Henderson
    }
267 a3b9af16 Richard Henderson
    pt = L2pte >> 32 << TARGET_PAGE_BITS;
268 a3b9af16 Richard Henderson
269 a3b9af16 Richard Henderson
    /* L3 page table read.  */
270 a3b9af16 Richard Henderson
    index = (addr >> TARGET_PAGE_BITS) & 0x3ff;
271 a3b9af16 Richard Henderson
    L3pte = ldq_phys(pt + index*8);
272 a3b9af16 Richard Henderson
273 a3b9af16 Richard Henderson
    phys = L3pte >> 32 << TARGET_PAGE_BITS;
274 a3b9af16 Richard Henderson
    if (unlikely((L3pte & PTE_VALID) == 0)) {
275 a3b9af16 Richard Henderson
        ret = MM_K_TNV;
276 a3b9af16 Richard Henderson
        goto exit;
277 a3b9af16 Richard Henderson
    }
278 a3b9af16 Richard Henderson
279 a3b9af16 Richard Henderson
#if PAGE_READ != 1 || PAGE_WRITE != 2 || PAGE_EXEC != 4
280 a3b9af16 Richard Henderson
# error page bits out of date
281 a3b9af16 Richard Henderson
#endif
282 a3b9af16 Richard Henderson
283 a3b9af16 Richard Henderson
    /* Check access violations.  */
284 a3b9af16 Richard Henderson
    if (L3pte & (PTE_KRE << mmu_idx)) {
285 a3b9af16 Richard Henderson
        prot |= PAGE_READ | PAGE_EXEC;
286 a3b9af16 Richard Henderson
    }
287 a3b9af16 Richard Henderson
    if (L3pte & (PTE_KWE << mmu_idx)) {
288 a3b9af16 Richard Henderson
        prot |= PAGE_WRITE;
289 a3b9af16 Richard Henderson
    }
290 a3b9af16 Richard Henderson
    if (unlikely((prot & prot_need) == 0 && prot_need)) {
291 a3b9af16 Richard Henderson
        goto exit;
292 a3b9af16 Richard Henderson
    }
293 a3b9af16 Richard Henderson
294 a3b9af16 Richard Henderson
    /* Check fault-on-operation violations.  */
295 a3b9af16 Richard Henderson
    prot &= ~(L3pte >> 1);
296 a3b9af16 Richard Henderson
    ret = -1;
297 a3b9af16 Richard Henderson
    if (unlikely((prot & prot_need) == 0)) {
298 a3b9af16 Richard Henderson
        ret = (prot_need & PAGE_EXEC ? MM_K_FOE :
299 a3b9af16 Richard Henderson
               prot_need & PAGE_WRITE ? MM_K_FOW :
300 a3b9af16 Richard Henderson
               prot_need & PAGE_READ ? MM_K_FOR : -1);
301 a3b9af16 Richard Henderson
    }
302 a3b9af16 Richard Henderson
303 a3b9af16 Richard Henderson
 exit:
304 a3b9af16 Richard Henderson
    *pphys = phys;
305 a3b9af16 Richard Henderson
    *pprot = prot;
306 a3b9af16 Richard Henderson
    return ret;
307 4c9649a9 j_mayer
}
308 4c9649a9 j_mayer
309 a3b9af16 Richard Henderson
target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
310 4c9649a9 j_mayer
{
311 a3b9af16 Richard Henderson
    target_ulong phys;
312 a3b9af16 Richard Henderson
    int prot, fail;
313 a3b9af16 Richard Henderson
314 a3b9af16 Richard Henderson
    fail = get_physical_address(env, addr, 0, 0, &phys, &prot);
315 a3b9af16 Richard Henderson
    return (fail >= 0 ? -1 : phys);
316 a3b9af16 Richard Henderson
}
317 a3b9af16 Richard Henderson
318 a3b9af16 Richard Henderson
int cpu_alpha_handle_mmu_fault(CPUState *env, target_ulong addr, int rw,
319 97b348e7 Blue Swirl
                               int mmu_idx)
320 a3b9af16 Richard Henderson
{
321 a3b9af16 Richard Henderson
    target_ulong phys;
322 a3b9af16 Richard Henderson
    int prot, fail;
323 a3b9af16 Richard Henderson
324 a3b9af16 Richard Henderson
    fail = get_physical_address(env, addr, 1 << rw, mmu_idx, &phys, &prot);
325 a3b9af16 Richard Henderson
    if (unlikely(fail >= 0)) {
326 a3b9af16 Richard Henderson
        env->exception_index = EXCP_MMFAULT;
327 a3b9af16 Richard Henderson
        env->trap_arg0 = addr;
328 a3b9af16 Richard Henderson
        env->trap_arg1 = fail;
329 a3b9af16 Richard Henderson
        env->trap_arg2 = (rw == 2 ? -1 : rw);
330 a3b9af16 Richard Henderson
        return 1;
331 a3b9af16 Richard Henderson
    }
332 a3b9af16 Richard Henderson
333 a3b9af16 Richard Henderson
    tlb_set_page(env, addr & TARGET_PAGE_MASK, phys & TARGET_PAGE_MASK,
334 a3b9af16 Richard Henderson
                 prot, mmu_idx, TARGET_PAGE_SIZE);
335 129d8aa5 Richard Henderson
    return 0;
336 4c9649a9 j_mayer
}
337 3a6fa678 Richard Henderson
#endif /* USER_ONLY */
338 4c9649a9 j_mayer
339 4c9649a9 j_mayer
void do_interrupt (CPUState *env)
340 4c9649a9 j_mayer
{
341 3a6fa678 Richard Henderson
    int i = env->exception_index;
342 3a6fa678 Richard Henderson
343 3a6fa678 Richard Henderson
    if (qemu_loglevel_mask(CPU_LOG_INT)) {
344 3a6fa678 Richard Henderson
        static int count;
345 3a6fa678 Richard Henderson
        const char *name = "<unknown>";
346 3a6fa678 Richard Henderson
347 3a6fa678 Richard Henderson
        switch (i) {
348 3a6fa678 Richard Henderson
        case EXCP_RESET:
349 3a6fa678 Richard Henderson
            name = "reset";
350 3a6fa678 Richard Henderson
            break;
351 3a6fa678 Richard Henderson
        case EXCP_MCHK:
352 3a6fa678 Richard Henderson
            name = "mchk";
353 3a6fa678 Richard Henderson
            break;
354 3a6fa678 Richard Henderson
        case EXCP_SMP_INTERRUPT:
355 3a6fa678 Richard Henderson
            name = "smp_interrupt";
356 3a6fa678 Richard Henderson
            break;
357 3a6fa678 Richard Henderson
        case EXCP_CLK_INTERRUPT:
358 3a6fa678 Richard Henderson
            name = "clk_interrupt";
359 3a6fa678 Richard Henderson
            break;
360 3a6fa678 Richard Henderson
        case EXCP_DEV_INTERRUPT:
361 3a6fa678 Richard Henderson
            name = "dev_interrupt";
362 3a6fa678 Richard Henderson
            break;
363 3a6fa678 Richard Henderson
        case EXCP_MMFAULT:
364 3a6fa678 Richard Henderson
            name = "mmfault";
365 3a6fa678 Richard Henderson
            break;
366 3a6fa678 Richard Henderson
        case EXCP_UNALIGN:
367 3a6fa678 Richard Henderson
            name = "unalign";
368 3a6fa678 Richard Henderson
            break;
369 3a6fa678 Richard Henderson
        case EXCP_OPCDEC:
370 3a6fa678 Richard Henderson
            name = "opcdec";
371 3a6fa678 Richard Henderson
            break;
372 3a6fa678 Richard Henderson
        case EXCP_ARITH:
373 3a6fa678 Richard Henderson
            name = "arith";
374 3a6fa678 Richard Henderson
            break;
375 3a6fa678 Richard Henderson
        case EXCP_FEN:
376 3a6fa678 Richard Henderson
            name = "fen";
377 3a6fa678 Richard Henderson
            break;
378 3a6fa678 Richard Henderson
        case EXCP_CALL_PAL:
379 3a6fa678 Richard Henderson
            name = "call_pal";
380 3a6fa678 Richard Henderson
            break;
381 3a6fa678 Richard Henderson
        case EXCP_STL_C:
382 3a6fa678 Richard Henderson
            name = "stl_c";
383 3a6fa678 Richard Henderson
            break;
384 3a6fa678 Richard Henderson
        case EXCP_STQ_C:
385 3a6fa678 Richard Henderson
            name = "stq_c";
386 3a6fa678 Richard Henderson
            break;
387 3a6fa678 Richard Henderson
        }
388 3a6fa678 Richard Henderson
        qemu_log("INT %6d: %s(%#x) pc=%016" PRIx64 " sp=%016" PRIx64 "\n",
389 3a6fa678 Richard Henderson
                 ++count, name, env->error_code, env->pc, env->ir[IR_SP]);
390 3a6fa678 Richard Henderson
    }
391 3a6fa678 Richard Henderson
392 3a6fa678 Richard Henderson
    env->exception_index = -1;
393 3a6fa678 Richard Henderson
394 3a6fa678 Richard Henderson
#if !defined(CONFIG_USER_ONLY)
395 3a6fa678 Richard Henderson
    switch (i) {
396 3a6fa678 Richard Henderson
    case EXCP_RESET:
397 3a6fa678 Richard Henderson
        i = 0x0000;
398 3a6fa678 Richard Henderson
        break;
399 3a6fa678 Richard Henderson
    case EXCP_MCHK:
400 3a6fa678 Richard Henderson
        i = 0x0080;
401 3a6fa678 Richard Henderson
        break;
402 3a6fa678 Richard Henderson
    case EXCP_SMP_INTERRUPT:
403 3a6fa678 Richard Henderson
        i = 0x0100;
404 3a6fa678 Richard Henderson
        break;
405 3a6fa678 Richard Henderson
    case EXCP_CLK_INTERRUPT:
406 3a6fa678 Richard Henderson
        i = 0x0180;
407 3a6fa678 Richard Henderson
        break;
408 3a6fa678 Richard Henderson
    case EXCP_DEV_INTERRUPT:
409 3a6fa678 Richard Henderson
        i = 0x0200;
410 3a6fa678 Richard Henderson
        break;
411 3a6fa678 Richard Henderson
    case EXCP_MMFAULT:
412 3a6fa678 Richard Henderson
        i = 0x0280;
413 3a6fa678 Richard Henderson
        break;
414 3a6fa678 Richard Henderson
    case EXCP_UNALIGN:
415 3a6fa678 Richard Henderson
        i = 0x0300;
416 3a6fa678 Richard Henderson
        break;
417 3a6fa678 Richard Henderson
    case EXCP_OPCDEC:
418 3a6fa678 Richard Henderson
        i = 0x0380;
419 3a6fa678 Richard Henderson
        break;
420 3a6fa678 Richard Henderson
    case EXCP_ARITH:
421 3a6fa678 Richard Henderson
        i = 0x0400;
422 3a6fa678 Richard Henderson
        break;
423 3a6fa678 Richard Henderson
    case EXCP_FEN:
424 3a6fa678 Richard Henderson
        i = 0x0480;
425 3a6fa678 Richard Henderson
        break;
426 3a6fa678 Richard Henderson
    case EXCP_CALL_PAL:
427 3a6fa678 Richard Henderson
        i = env->error_code;
428 3a6fa678 Richard Henderson
        /* There are 64 entry points for both privileged and unprivileged,
429 3a6fa678 Richard Henderson
           with bit 0x80 indicating unprivileged.  Each entry point gets
430 3a6fa678 Richard Henderson
           64 bytes to do its job.  */
431 3a6fa678 Richard Henderson
        if (i & 0x80) {
432 3a6fa678 Richard Henderson
            i = 0x2000 + (i - 0x80) * 64;
433 3a6fa678 Richard Henderson
        } else {
434 3a6fa678 Richard Henderson
            i = 0x1000 + i * 64;
435 3a6fa678 Richard Henderson
        }
436 3a6fa678 Richard Henderson
        break;
437 3a6fa678 Richard Henderson
    default:
438 3a6fa678 Richard Henderson
        cpu_abort(env, "Unhandled CPU exception");
439 3a6fa678 Richard Henderson
    }
440 3a6fa678 Richard Henderson
441 3a6fa678 Richard Henderson
    /* Remember where the exception happened.  Emulate real hardware in
442 3a6fa678 Richard Henderson
       that the low bit of the PC indicates PALmode.  */
443 3a6fa678 Richard Henderson
    env->exc_addr = env->pc | env->pal_mode;
444 3a6fa678 Richard Henderson
445 3a6fa678 Richard Henderson
    /* Continue execution at the PALcode entry point.  */
446 3a6fa678 Richard Henderson
    env->pc = env->palbr + i;
447 3a6fa678 Richard Henderson
448 3a6fa678 Richard Henderson
    /* Switch to PALmode.  */
449 21d2beaa Richard Henderson
    if (!env->pal_mode) {
450 21d2beaa Richard Henderson
        env->pal_mode = 1;
451 21d2beaa Richard Henderson
        swap_shadow_regs(env);
452 21d2beaa Richard Henderson
    }
453 3a6fa678 Richard Henderson
#endif /* !USER_ONLY */
454 4c9649a9 j_mayer
}
455 4c9649a9 j_mayer
456 9a78eead Stefan Weil
void cpu_dump_state (CPUState *env, FILE *f, fprintf_function cpu_fprintf,
457 4c9649a9 j_mayer
                     int flags)
458 4c9649a9 j_mayer
{
459 b55266b5 blueswir1
    static const char *linux_reg_names[] = {
460 4c9649a9 j_mayer
        "v0 ", "t0 ", "t1 ", "t2 ", "t3 ", "t4 ", "t5 ", "t6 ",
461 4c9649a9 j_mayer
        "t7 ", "s0 ", "s1 ", "s2 ", "s3 ", "s4 ", "s5 ", "fp ",
462 4c9649a9 j_mayer
        "a0 ", "a1 ", "a2 ", "a3 ", "a4 ", "a5 ", "t8 ", "t9 ",
463 4c9649a9 j_mayer
        "t10", "t11", "ra ", "t12", "at ", "gp ", "sp ", "zero",
464 4c9649a9 j_mayer
    };
465 4c9649a9 j_mayer
    int i;
466 4c9649a9 j_mayer
467 129d8aa5 Richard Henderson
    cpu_fprintf(f, "     PC  " TARGET_FMT_lx "      PS  %02x\n",
468 4c9649a9 j_mayer
                env->pc, env->ps);
469 4c9649a9 j_mayer
    for (i = 0; i < 31; i++) {
470 4c9649a9 j_mayer
        cpu_fprintf(f, "IR%02d %s " TARGET_FMT_lx " ", i,
471 4c9649a9 j_mayer
                    linux_reg_names[i], env->ir[i]);
472 4c9649a9 j_mayer
        if ((i % 3) == 2)
473 4c9649a9 j_mayer
            cpu_fprintf(f, "\n");
474 4c9649a9 j_mayer
    }
475 6910b8f6 Richard Henderson
476 6910b8f6 Richard Henderson
    cpu_fprintf(f, "lock_a   " TARGET_FMT_lx " lock_v   " TARGET_FMT_lx "\n",
477 6910b8f6 Richard Henderson
                env->lock_addr, env->lock_value);
478 6910b8f6 Richard Henderson
479 4c9649a9 j_mayer
    for (i = 0; i < 31; i++) {
480 4c9649a9 j_mayer
        cpu_fprintf(f, "FIR%02d    " TARGET_FMT_lx " ", i,
481 4c9649a9 j_mayer
                    *((uint64_t *)(&env->fir[i])));
482 4c9649a9 j_mayer
        if ((i % 3) == 2)
483 4c9649a9 j_mayer
            cpu_fprintf(f, "\n");
484 4c9649a9 j_mayer
    }
485 6910b8f6 Richard Henderson
    cpu_fprintf(f, "\n");
486 4c9649a9 j_mayer
}