Statistics
| Branch: | Revision:

root / target-alpha / helper.c @ 2c50e26e

History | View | Annotate | Download (13.8 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 4c9649a9 j_mayer
#include "exec-all.h"
26 ba0e276d Richard Henderson
#include "softfloat.h"
27 ba0e276d Richard Henderson
28 ba0e276d Richard Henderson
uint64_t cpu_alpha_load_fpcr (CPUState *env)
29 ba0e276d Richard Henderson
{
30 8443effb Richard Henderson
    uint64_t r = 0;
31 8443effb Richard Henderson
    uint8_t t;
32 8443effb Richard Henderson
33 8443effb Richard Henderson
    t = env->fpcr_exc_status;
34 8443effb Richard Henderson
    if (t) {
35 8443effb Richard Henderson
        r = FPCR_SUM;
36 8443effb Richard Henderson
        if (t & float_flag_invalid) {
37 8443effb Richard Henderson
            r |= FPCR_INV;
38 8443effb Richard Henderson
        }
39 8443effb Richard Henderson
        if (t & float_flag_divbyzero) {
40 8443effb Richard Henderson
            r |= FPCR_DZE;
41 8443effb Richard Henderson
        }
42 8443effb Richard Henderson
        if (t & float_flag_overflow) {
43 8443effb Richard Henderson
            r |= FPCR_OVF;
44 8443effb Richard Henderson
        }
45 8443effb Richard Henderson
        if (t & float_flag_underflow) {
46 8443effb Richard Henderson
            r |= FPCR_UNF;
47 8443effb Richard Henderson
        }
48 8443effb Richard Henderson
        if (t & float_flag_inexact) {
49 8443effb Richard Henderson
            r |= FPCR_INE;
50 8443effb Richard Henderson
        }
51 8443effb Richard Henderson
    }
52 8443effb Richard Henderson
53 8443effb Richard Henderson
    t = env->fpcr_exc_mask;
54 8443effb Richard Henderson
    if (t & float_flag_invalid) {
55 8443effb Richard Henderson
        r |= FPCR_INVD;
56 8443effb Richard Henderson
    }
57 8443effb Richard Henderson
    if (t & float_flag_divbyzero) {
58 8443effb Richard Henderson
        r |= FPCR_DZED;
59 8443effb Richard Henderson
    }
60 8443effb Richard Henderson
    if (t & float_flag_overflow) {
61 8443effb Richard Henderson
        r |= FPCR_OVFD;
62 8443effb Richard Henderson
    }
63 8443effb Richard Henderson
    if (t & float_flag_underflow) {
64 8443effb Richard Henderson
        r |= FPCR_UNFD;
65 8443effb Richard Henderson
    }
66 8443effb Richard Henderson
    if (t & float_flag_inexact) {
67 8443effb Richard Henderson
        r |= FPCR_INED;
68 8443effb Richard Henderson
    }
69 8443effb Richard Henderson
70 8443effb Richard Henderson
    switch (env->fpcr_dyn_round) {
71 ba0e276d Richard Henderson
    case float_round_nearest_even:
72 8443effb Richard Henderson
        r |= FPCR_DYN_NORMAL;
73 ba0e276d Richard Henderson
        break;
74 ba0e276d Richard Henderson
    case float_round_down:
75 8443effb Richard Henderson
        r |= FPCR_DYN_MINUS;
76 ba0e276d Richard Henderson
        break;
77 ba0e276d Richard Henderson
    case float_round_up:
78 8443effb Richard Henderson
        r |= FPCR_DYN_PLUS;
79 ba0e276d Richard Henderson
        break;
80 ba0e276d Richard Henderson
    case float_round_to_zero:
81 8443effb Richard Henderson
        r |= FPCR_DYN_CHOPPED;
82 ba0e276d Richard Henderson
        break;
83 ba0e276d Richard Henderson
    }
84 8443effb Richard Henderson
85 8443effb Richard Henderson
    if (env->fpcr_dnz) {
86 8443effb Richard Henderson
        r |= FPCR_DNZ;
87 8443effb Richard Henderson
    }
88 8443effb Richard Henderson
    if (env->fpcr_dnod) {
89 8443effb Richard Henderson
        r |= FPCR_DNOD;
90 8443effb Richard Henderson
    }
91 8443effb Richard Henderson
    if (env->fpcr_undz) {
92 8443effb Richard Henderson
        r |= FPCR_UNDZ;
93 8443effb Richard Henderson
    }
94 8443effb Richard Henderson
95 8443effb Richard Henderson
    return r;
96 ba0e276d Richard Henderson
}
97 ba0e276d Richard Henderson
98 ba0e276d Richard Henderson
void cpu_alpha_store_fpcr (CPUState *env, uint64_t val)
99 ba0e276d Richard Henderson
{
100 8443effb Richard Henderson
    uint8_t t;
101 8443effb Richard Henderson
102 8443effb Richard Henderson
    t = 0;
103 8443effb Richard Henderson
    if (val & FPCR_INV) {
104 8443effb Richard Henderson
        t |= float_flag_invalid;
105 8443effb Richard Henderson
    }
106 8443effb Richard Henderson
    if (val & FPCR_DZE) {
107 8443effb Richard Henderson
        t |= float_flag_divbyzero;
108 8443effb Richard Henderson
    }
109 8443effb Richard Henderson
    if (val & FPCR_OVF) {
110 8443effb Richard Henderson
        t |= float_flag_overflow;
111 8443effb Richard Henderson
    }
112 8443effb Richard Henderson
    if (val & FPCR_UNF) {
113 8443effb Richard Henderson
        t |= float_flag_underflow;
114 8443effb Richard Henderson
    }
115 8443effb Richard Henderson
    if (val & FPCR_INE) {
116 8443effb Richard Henderson
        t |= float_flag_inexact;
117 8443effb Richard Henderson
    }
118 8443effb Richard Henderson
    env->fpcr_exc_status = t;
119 8443effb Richard Henderson
120 8443effb Richard Henderson
    t = 0;
121 8443effb Richard Henderson
    if (val & FPCR_INVD) {
122 8443effb Richard Henderson
        t |= float_flag_invalid;
123 8443effb Richard Henderson
    }
124 8443effb Richard Henderson
    if (val & FPCR_DZED) {
125 8443effb Richard Henderson
        t |= float_flag_divbyzero;
126 8443effb Richard Henderson
    }
127 8443effb Richard Henderson
    if (val & FPCR_OVFD) {
128 8443effb Richard Henderson
        t |= float_flag_overflow;
129 8443effb Richard Henderson
    }
130 8443effb Richard Henderson
    if (val & FPCR_UNFD) {
131 8443effb Richard Henderson
        t |= float_flag_underflow;
132 8443effb Richard Henderson
    }
133 8443effb Richard Henderson
    if (val & FPCR_INED) {
134 8443effb Richard Henderson
        t |= float_flag_inexact;
135 8443effb Richard Henderson
    }
136 8443effb Richard Henderson
    env->fpcr_exc_mask = t;
137 8443effb Richard Henderson
138 8443effb Richard Henderson
    switch (val & FPCR_DYN_MASK) {
139 8443effb Richard Henderson
    case FPCR_DYN_CHOPPED:
140 8443effb Richard Henderson
        t = float_round_to_zero;
141 ba0e276d Richard Henderson
        break;
142 8443effb Richard Henderson
    case FPCR_DYN_MINUS:
143 8443effb Richard Henderson
        t = float_round_down;
144 ba0e276d Richard Henderson
        break;
145 8443effb Richard Henderson
    case FPCR_DYN_NORMAL:
146 8443effb Richard Henderson
        t = float_round_nearest_even;
147 ba0e276d Richard Henderson
        break;
148 8443effb Richard Henderson
    case FPCR_DYN_PLUS:
149 8443effb Richard Henderson
        t = float_round_up;
150 ba0e276d Richard Henderson
        break;
151 ba0e276d Richard Henderson
    }
152 8443effb Richard Henderson
    env->fpcr_dyn_round = t;
153 8443effb Richard Henderson
154 8443effb Richard Henderson
    env->fpcr_flush_to_zero
155 8443effb Richard Henderson
      = (val & (FPCR_UNDZ|FPCR_UNFD)) == (FPCR_UNDZ|FPCR_UNFD);
156 8443effb Richard Henderson
157 8443effb Richard Henderson
    env->fpcr_dnz = (val & FPCR_DNZ) != 0;
158 8443effb Richard Henderson
    env->fpcr_dnod = (val & FPCR_DNOD) != 0;
159 8443effb Richard Henderson
    env->fpcr_undz = (val & FPCR_UNDZ) != 0;
160 ba0e276d Richard Henderson
}
161 4c9649a9 j_mayer
162 5fafdf24 ths
#if defined(CONFIG_USER_ONLY)
163 4c9649a9 j_mayer
164 4c9649a9 j_mayer
int cpu_alpha_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
165 6ebbf390 j_mayer
                                int mmu_idx, int is_softmmu)
166 4c9649a9 j_mayer
{
167 4c9649a9 j_mayer
    if (rw == 2)
168 4c9649a9 j_mayer
        env->exception_index = EXCP_ITB_MISS;
169 4c9649a9 j_mayer
    else
170 4c9649a9 j_mayer
        env->exception_index = EXCP_DFAULT;
171 4c9649a9 j_mayer
    env->ipr[IPR_EXC_ADDR] = address;
172 3b46e624 ths
173 4c9649a9 j_mayer
    return 1;
174 4c9649a9 j_mayer
}
175 4c9649a9 j_mayer
176 4c9649a9 j_mayer
void do_interrupt (CPUState *env)
177 4c9649a9 j_mayer
{
178 4c9649a9 j_mayer
    env->exception_index = -1;
179 4c9649a9 j_mayer
}
180 4c9649a9 j_mayer
181 4c9649a9 j_mayer
#else
182 4c9649a9 j_mayer
183 c227f099 Anthony Liguori
target_phys_addr_t cpu_get_phys_page_debug (CPUState *env, target_ulong addr)
184 4c9649a9 j_mayer
{
185 4c9649a9 j_mayer
    return -1;
186 4c9649a9 j_mayer
}
187 4c9649a9 j_mayer
188 4c9649a9 j_mayer
int cpu_alpha_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
189 6ebbf390 j_mayer
                                int mmu_idx, int is_softmmu)
190 4c9649a9 j_mayer
{
191 4c9649a9 j_mayer
    uint32_t opc;
192 4c9649a9 j_mayer
193 4c9649a9 j_mayer
    if (rw == 2) {
194 4c9649a9 j_mayer
        /* Instruction translation buffer miss */
195 4c9649a9 j_mayer
        env->exception_index = EXCP_ITB_MISS;
196 4c9649a9 j_mayer
    } else {
197 4c9649a9 j_mayer
        if (env->ipr[IPR_EXC_ADDR] & 1)
198 4c9649a9 j_mayer
            env->exception_index = EXCP_DTB_MISS_PAL;
199 4c9649a9 j_mayer
        else
200 4c9649a9 j_mayer
            env->exception_index = EXCP_DTB_MISS_NATIVE;
201 4c9649a9 j_mayer
        opc = (ldl_code(env->pc) >> 21) << 4;
202 4c9649a9 j_mayer
        if (rw) {
203 4c9649a9 j_mayer
            opc |= 0x9;
204 4c9649a9 j_mayer
        } else {
205 4c9649a9 j_mayer
            opc |= 0x4;
206 4c9649a9 j_mayer
        }
207 4c9649a9 j_mayer
        env->ipr[IPR_MM_STAT] = opc;
208 4c9649a9 j_mayer
    }
209 4c9649a9 j_mayer
210 4c9649a9 j_mayer
    return 1;
211 4c9649a9 j_mayer
}
212 4c9649a9 j_mayer
213 4c9649a9 j_mayer
int cpu_alpha_mfpr (CPUState *env, int iprn, uint64_t *valp)
214 4c9649a9 j_mayer
{
215 4c9649a9 j_mayer
    uint64_t hwpcb;
216 4c9649a9 j_mayer
    int ret = 0;
217 4c9649a9 j_mayer
218 4c9649a9 j_mayer
    hwpcb = env->ipr[IPR_PCBB];
219 4c9649a9 j_mayer
    switch (iprn) {
220 4c9649a9 j_mayer
    case IPR_ASN:
221 4c9649a9 j_mayer
        if (env->features & FEATURE_ASN)
222 4c9649a9 j_mayer
            *valp = env->ipr[IPR_ASN];
223 4c9649a9 j_mayer
        else
224 4c9649a9 j_mayer
            *valp = 0;
225 4c9649a9 j_mayer
        break;
226 4c9649a9 j_mayer
    case IPR_ASTEN:
227 4c9649a9 j_mayer
        *valp = ((int64_t)(env->ipr[IPR_ASTEN] << 60)) >> 60;
228 4c9649a9 j_mayer
        break;
229 4c9649a9 j_mayer
    case IPR_ASTSR:
230 4c9649a9 j_mayer
        *valp = ((int64_t)(env->ipr[IPR_ASTSR] << 60)) >> 60;
231 4c9649a9 j_mayer
        break;
232 4c9649a9 j_mayer
    case IPR_DATFX:
233 4c9649a9 j_mayer
        /* Write only */
234 4c9649a9 j_mayer
        ret = -1;
235 4c9649a9 j_mayer
        break;
236 4c9649a9 j_mayer
    case IPR_ESP:
237 4c9649a9 j_mayer
        if (env->features & FEATURE_SPS)
238 4c9649a9 j_mayer
            *valp = env->ipr[IPR_ESP];
239 4c9649a9 j_mayer
        else
240 4c9649a9 j_mayer
            *valp = ldq_raw(hwpcb + 8);
241 4c9649a9 j_mayer
        break;
242 4c9649a9 j_mayer
    case IPR_FEN:
243 4c9649a9 j_mayer
        *valp = ((int64_t)(env->ipr[IPR_FEN] << 63)) >> 63;
244 4c9649a9 j_mayer
        break;
245 4c9649a9 j_mayer
    case IPR_IPIR:
246 4c9649a9 j_mayer
        /* Write-only */
247 4c9649a9 j_mayer
        ret = -1;
248 4c9649a9 j_mayer
        break;
249 4c9649a9 j_mayer
    case IPR_IPL:
250 4c9649a9 j_mayer
        *valp = ((int64_t)(env->ipr[IPR_IPL] << 59)) >> 59;
251 4c9649a9 j_mayer
        break;
252 4c9649a9 j_mayer
    case IPR_KSP:
253 4c9649a9 j_mayer
        if (!(env->ipr[IPR_EXC_ADDR] & 1)) {
254 4c9649a9 j_mayer
            ret = -1;
255 4c9649a9 j_mayer
        } else {
256 4c9649a9 j_mayer
            if (env->features & FEATURE_SPS)
257 4c9649a9 j_mayer
                *valp = env->ipr[IPR_KSP];
258 4c9649a9 j_mayer
            else
259 4c9649a9 j_mayer
                *valp = ldq_raw(hwpcb + 0);
260 4c9649a9 j_mayer
        }
261 4c9649a9 j_mayer
        break;
262 4c9649a9 j_mayer
    case IPR_MCES:
263 4c9649a9 j_mayer
        *valp = ((int64_t)(env->ipr[IPR_MCES] << 59)) >> 59;
264 4c9649a9 j_mayer
        break;
265 4c9649a9 j_mayer
    case IPR_PERFMON:
266 4c9649a9 j_mayer
        /* Implementation specific */
267 4c9649a9 j_mayer
        *valp = 0;
268 4c9649a9 j_mayer
        break;
269 4c9649a9 j_mayer
    case IPR_PCBB:
270 4c9649a9 j_mayer
        *valp = ((int64_t)env->ipr[IPR_PCBB] << 16) >> 16;
271 4c9649a9 j_mayer
        break;
272 4c9649a9 j_mayer
    case IPR_PRBR:
273 4c9649a9 j_mayer
        *valp = env->ipr[IPR_PRBR];
274 4c9649a9 j_mayer
        break;
275 4c9649a9 j_mayer
    case IPR_PTBR:
276 4c9649a9 j_mayer
        *valp = env->ipr[IPR_PTBR];
277 4c9649a9 j_mayer
        break;
278 4c9649a9 j_mayer
    case IPR_SCBB:
279 4c9649a9 j_mayer
        *valp = (int64_t)((int32_t)env->ipr[IPR_SCBB]);
280 4c9649a9 j_mayer
        break;
281 4c9649a9 j_mayer
    case IPR_SIRR:
282 4c9649a9 j_mayer
        /* Write-only */
283 4c9649a9 j_mayer
        ret = -1;
284 4c9649a9 j_mayer
        break;
285 4c9649a9 j_mayer
    case IPR_SISR:
286 4c9649a9 j_mayer
        *valp = (int64_t)((int16_t)env->ipr[IPR_SISR]);
287 4c9649a9 j_mayer
    case IPR_SSP:
288 4c9649a9 j_mayer
        if (env->features & FEATURE_SPS)
289 4c9649a9 j_mayer
            *valp = env->ipr[IPR_SSP];
290 4c9649a9 j_mayer
        else
291 4c9649a9 j_mayer
            *valp = ldq_raw(hwpcb + 16);
292 4c9649a9 j_mayer
        break;
293 4c9649a9 j_mayer
    case IPR_SYSPTBR:
294 4c9649a9 j_mayer
        if (env->features & FEATURE_VIRBND)
295 4c9649a9 j_mayer
            *valp = env->ipr[IPR_SYSPTBR];
296 4c9649a9 j_mayer
        else
297 4c9649a9 j_mayer
            ret = -1;
298 4c9649a9 j_mayer
        break;
299 4c9649a9 j_mayer
    case IPR_TBCHK:
300 4c9649a9 j_mayer
        if ((env->features & FEATURE_TBCHK)) {
301 4c9649a9 j_mayer
            /* XXX: TODO */
302 4c9649a9 j_mayer
            *valp = 0;
303 4c9649a9 j_mayer
            ret = -1;
304 4c9649a9 j_mayer
        } else {
305 4c9649a9 j_mayer
            ret = -1;
306 4c9649a9 j_mayer
        }
307 4c9649a9 j_mayer
        break;
308 4c9649a9 j_mayer
    case IPR_TBIA:
309 4c9649a9 j_mayer
        /* Write-only */
310 4c9649a9 j_mayer
        ret = -1;
311 4c9649a9 j_mayer
        break;
312 4c9649a9 j_mayer
    case IPR_TBIAP:
313 4c9649a9 j_mayer
        /* Write-only */
314 4c9649a9 j_mayer
        ret = -1;
315 4c9649a9 j_mayer
        break;
316 4c9649a9 j_mayer
    case IPR_TBIS:
317 4c9649a9 j_mayer
        /* Write-only */
318 4c9649a9 j_mayer
        ret = -1;
319 4c9649a9 j_mayer
        break;
320 4c9649a9 j_mayer
    case IPR_TBISD:
321 4c9649a9 j_mayer
        /* Write-only */
322 4c9649a9 j_mayer
        ret = -1;
323 4c9649a9 j_mayer
        break;
324 4c9649a9 j_mayer
    case IPR_TBISI:
325 4c9649a9 j_mayer
        /* Write-only */
326 4c9649a9 j_mayer
        ret = -1;
327 4c9649a9 j_mayer
        break;
328 4c9649a9 j_mayer
    case IPR_USP:
329 4c9649a9 j_mayer
        if (env->features & FEATURE_SPS)
330 4c9649a9 j_mayer
            *valp = env->ipr[IPR_USP];
331 4c9649a9 j_mayer
        else
332 4c9649a9 j_mayer
            *valp = ldq_raw(hwpcb + 24);
333 4c9649a9 j_mayer
        break;
334 4c9649a9 j_mayer
    case IPR_VIRBND:
335 4c9649a9 j_mayer
        if (env->features & FEATURE_VIRBND)
336 4c9649a9 j_mayer
            *valp = env->ipr[IPR_VIRBND];
337 4c9649a9 j_mayer
        else
338 4c9649a9 j_mayer
            ret = -1;
339 4c9649a9 j_mayer
        break;
340 4c9649a9 j_mayer
    case IPR_VPTB:
341 4c9649a9 j_mayer
        *valp = env->ipr[IPR_VPTB];
342 4c9649a9 j_mayer
        break;
343 4c9649a9 j_mayer
    case IPR_WHAMI:
344 4c9649a9 j_mayer
        *valp = env->ipr[IPR_WHAMI];
345 4c9649a9 j_mayer
        break;
346 4c9649a9 j_mayer
    default:
347 4c9649a9 j_mayer
        /* Invalid */
348 4c9649a9 j_mayer
        ret = -1;
349 4c9649a9 j_mayer
        break;
350 4c9649a9 j_mayer
    }
351 4c9649a9 j_mayer
352 4c9649a9 j_mayer
    return ret;
353 4c9649a9 j_mayer
}
354 4c9649a9 j_mayer
355 4c9649a9 j_mayer
int cpu_alpha_mtpr (CPUState *env, int iprn, uint64_t val, uint64_t *oldvalp)
356 4c9649a9 j_mayer
{
357 4c9649a9 j_mayer
    uint64_t hwpcb, tmp64;
358 4c9649a9 j_mayer
    uint8_t tmp8;
359 4c9649a9 j_mayer
    int ret = 0;
360 4c9649a9 j_mayer
361 4c9649a9 j_mayer
    hwpcb = env->ipr[IPR_PCBB];
362 4c9649a9 j_mayer
    switch (iprn) {
363 4c9649a9 j_mayer
    case IPR_ASN:
364 4c9649a9 j_mayer
        /* Read-only */
365 4c9649a9 j_mayer
        ret = -1;
366 4c9649a9 j_mayer
        break;
367 4c9649a9 j_mayer
    case IPR_ASTEN:
368 4c9649a9 j_mayer
        tmp8 = ((int8_t)(env->ipr[IPR_ASTEN] << 4)) >> 4;
369 4c9649a9 j_mayer
        *oldvalp = tmp8;
370 4c9649a9 j_mayer
        tmp8 &= val & 0xF;
371 4c9649a9 j_mayer
        tmp8 |= (val >> 4) & 0xF;
372 4c9649a9 j_mayer
        env->ipr[IPR_ASTEN] &= ~0xF;
373 4c9649a9 j_mayer
        env->ipr[IPR_ASTEN] |= tmp8;
374 4c9649a9 j_mayer
        ret = 1;
375 4c9649a9 j_mayer
        break;
376 4c9649a9 j_mayer
    case IPR_ASTSR:
377 4c9649a9 j_mayer
        tmp8 = ((int8_t)(env->ipr[IPR_ASTSR] << 4)) >> 4;
378 4c9649a9 j_mayer
        *oldvalp = tmp8;
379 4c9649a9 j_mayer
        tmp8 &= val & 0xF;
380 4c9649a9 j_mayer
        tmp8 |= (val >> 4) & 0xF;
381 4c9649a9 j_mayer
        env->ipr[IPR_ASTSR] &= ~0xF;
382 4c9649a9 j_mayer
        env->ipr[IPR_ASTSR] |= tmp8;
383 4c9649a9 j_mayer
        ret = 1;
384 4c9649a9 j_mayer
    case IPR_DATFX:
385 4c9649a9 j_mayer
        env->ipr[IPR_DATFX] &= ~0x1;
386 4c9649a9 j_mayer
        env->ipr[IPR_DATFX] |= val & 1;
387 4c9649a9 j_mayer
        tmp64 = ldq_raw(hwpcb + 56);
388 4c9649a9 j_mayer
        tmp64 &= ~0x8000000000000000ULL;
389 4c9649a9 j_mayer
        tmp64 |= (val & 1) << 63;
390 4c9649a9 j_mayer
        stq_raw(hwpcb + 56, tmp64);
391 4c9649a9 j_mayer
        break;
392 4c9649a9 j_mayer
    case IPR_ESP:
393 4c9649a9 j_mayer
        if (env->features & FEATURE_SPS)
394 4c9649a9 j_mayer
            env->ipr[IPR_ESP] = val;
395 4c9649a9 j_mayer
        else
396 4c9649a9 j_mayer
            stq_raw(hwpcb + 8, val);
397 4c9649a9 j_mayer
        break;
398 4c9649a9 j_mayer
    case IPR_FEN:
399 4c9649a9 j_mayer
        env->ipr[IPR_FEN] = val & 1;
400 4c9649a9 j_mayer
        tmp64 = ldq_raw(hwpcb + 56);
401 4c9649a9 j_mayer
        tmp64 &= ~1;
402 4c9649a9 j_mayer
        tmp64 |= val & 1;
403 4c9649a9 j_mayer
        stq_raw(hwpcb + 56, tmp64);
404 4c9649a9 j_mayer
        break;
405 4c9649a9 j_mayer
    case IPR_IPIR:
406 4c9649a9 j_mayer
        /* XXX: TODO: Send IRQ to CPU #ir[16] */
407 4c9649a9 j_mayer
        break;
408 4c9649a9 j_mayer
    case IPR_IPL:
409 4c9649a9 j_mayer
        *oldvalp = ((int64_t)(env->ipr[IPR_IPL] << 59)) >> 59;
410 4c9649a9 j_mayer
        env->ipr[IPR_IPL] &= ~0x1F;
411 4c9649a9 j_mayer
        env->ipr[IPR_IPL] |= val & 0x1F;
412 4c9649a9 j_mayer
        /* XXX: may issue an interrupt or ASR _now_ */
413 4c9649a9 j_mayer
        ret = 1;
414 4c9649a9 j_mayer
        break;
415 4c9649a9 j_mayer
    case IPR_KSP:
416 4c9649a9 j_mayer
        if (!(env->ipr[IPR_EXC_ADDR] & 1)) {
417 4c9649a9 j_mayer
            ret = -1;
418 4c9649a9 j_mayer
        } else {
419 4c9649a9 j_mayer
            if (env->features & FEATURE_SPS)
420 4c9649a9 j_mayer
                env->ipr[IPR_KSP] = val;
421 4c9649a9 j_mayer
            else
422 4c9649a9 j_mayer
                stq_raw(hwpcb + 0, val);
423 4c9649a9 j_mayer
        }
424 4c9649a9 j_mayer
        break;
425 4c9649a9 j_mayer
    case IPR_MCES:
426 4c9649a9 j_mayer
        env->ipr[IPR_MCES] &= ~((val & 0x7) | 0x18);
427 4c9649a9 j_mayer
        env->ipr[IPR_MCES] |= val & 0x18;
428 4c9649a9 j_mayer
        break;
429 4c9649a9 j_mayer
    case IPR_PERFMON:
430 4c9649a9 j_mayer
        /* Implementation specific */
431 4c9649a9 j_mayer
        *oldvalp = 0;
432 4c9649a9 j_mayer
        ret = 1;
433 4c9649a9 j_mayer
        break;
434 4c9649a9 j_mayer
    case IPR_PCBB:
435 4c9649a9 j_mayer
        /* Read-only */
436 4c9649a9 j_mayer
        ret = -1;
437 4c9649a9 j_mayer
        break;
438 4c9649a9 j_mayer
    case IPR_PRBR:
439 4c9649a9 j_mayer
        env->ipr[IPR_PRBR] = val;
440 4c9649a9 j_mayer
        break;
441 4c9649a9 j_mayer
    case IPR_PTBR:
442 4c9649a9 j_mayer
        /* Read-only */
443 4c9649a9 j_mayer
        ret = -1;
444 4c9649a9 j_mayer
        break;
445 4c9649a9 j_mayer
    case IPR_SCBB:
446 4c9649a9 j_mayer
        env->ipr[IPR_SCBB] = (uint32_t)val;
447 4c9649a9 j_mayer
        break;
448 4c9649a9 j_mayer
    case IPR_SIRR:
449 4c9649a9 j_mayer
        if (val & 0xF) {
450 4c9649a9 j_mayer
            env->ipr[IPR_SISR] |= 1 << (val & 0xF);
451 4c9649a9 j_mayer
            /* XXX: request a software interrupt _now_ */
452 4c9649a9 j_mayer
        }
453 4c9649a9 j_mayer
        break;
454 4c9649a9 j_mayer
    case IPR_SISR:
455 4c9649a9 j_mayer
        /* Read-only */
456 4c9649a9 j_mayer
        ret = -1;
457 4c9649a9 j_mayer
        break;
458 4c9649a9 j_mayer
    case IPR_SSP:
459 4c9649a9 j_mayer
        if (env->features & FEATURE_SPS)
460 4c9649a9 j_mayer
            env->ipr[IPR_SSP] = val;
461 4c9649a9 j_mayer
        else
462 4c9649a9 j_mayer
            stq_raw(hwpcb + 16, val);
463 4c9649a9 j_mayer
        break;
464 4c9649a9 j_mayer
    case IPR_SYSPTBR:
465 4c9649a9 j_mayer
        if (env->features & FEATURE_VIRBND)
466 4c9649a9 j_mayer
            env->ipr[IPR_SYSPTBR] = val;
467 4c9649a9 j_mayer
        else
468 4c9649a9 j_mayer
            ret = -1;
469 b2c58871 Blue Swirl
        break;
470 4c9649a9 j_mayer
    case IPR_TBCHK:
471 4c9649a9 j_mayer
        /* Read-only */
472 4c9649a9 j_mayer
        ret = -1;
473 4c9649a9 j_mayer
        break;
474 4c9649a9 j_mayer
    case IPR_TBIA:
475 4c9649a9 j_mayer
        tlb_flush(env, 1);
476 4c9649a9 j_mayer
        break;
477 4c9649a9 j_mayer
    case IPR_TBIAP:
478 4c9649a9 j_mayer
        tlb_flush(env, 1);
479 4c9649a9 j_mayer
        break;
480 4c9649a9 j_mayer
    case IPR_TBIS:
481 4c9649a9 j_mayer
        tlb_flush_page(env, val);
482 4c9649a9 j_mayer
        break;
483 4c9649a9 j_mayer
    case IPR_TBISD:
484 4c9649a9 j_mayer
        tlb_flush_page(env, val);
485 4c9649a9 j_mayer
        break;
486 4c9649a9 j_mayer
    case IPR_TBISI:
487 4c9649a9 j_mayer
        tlb_flush_page(env, val);
488 4c9649a9 j_mayer
        break;
489 4c9649a9 j_mayer
    case IPR_USP:
490 4c9649a9 j_mayer
        if (env->features & FEATURE_SPS)
491 4c9649a9 j_mayer
            env->ipr[IPR_USP] = val;
492 4c9649a9 j_mayer
        else
493 4c9649a9 j_mayer
            stq_raw(hwpcb + 24, val);
494 4c9649a9 j_mayer
        break;
495 4c9649a9 j_mayer
    case IPR_VIRBND:
496 4c9649a9 j_mayer
        if (env->features & FEATURE_VIRBND)
497 4c9649a9 j_mayer
            env->ipr[IPR_VIRBND] = val;
498 4c9649a9 j_mayer
        else
499 4c9649a9 j_mayer
            ret = -1;
500 4c9649a9 j_mayer
        break;
501 4c9649a9 j_mayer
    case IPR_VPTB:
502 4c9649a9 j_mayer
        env->ipr[IPR_VPTB] = val;
503 4c9649a9 j_mayer
        break;
504 4c9649a9 j_mayer
    case IPR_WHAMI:
505 4c9649a9 j_mayer
        /* Read-only */
506 4c9649a9 j_mayer
        ret = -1;
507 4c9649a9 j_mayer
        break;
508 4c9649a9 j_mayer
    default:
509 4c9649a9 j_mayer
        /* Invalid */
510 4c9649a9 j_mayer
        ret = -1;
511 4c9649a9 j_mayer
        break;
512 4c9649a9 j_mayer
    }
513 4c9649a9 j_mayer
514 4c9649a9 j_mayer
    return ret;
515 4c9649a9 j_mayer
}
516 4c9649a9 j_mayer
517 4c9649a9 j_mayer
void do_interrupt (CPUState *env)
518 4c9649a9 j_mayer
{
519 4c9649a9 j_mayer
    int excp;
520 4c9649a9 j_mayer
521 4c9649a9 j_mayer
    env->ipr[IPR_EXC_ADDR] = env->pc | 1;
522 4c9649a9 j_mayer
    excp = env->exception_index;
523 ee0dc6d3 Blue Swirl
    env->exception_index = -1;
524 4c9649a9 j_mayer
    env->error_code = 0;
525 4c9649a9 j_mayer
    /* XXX: disable interrupts and memory mapping */
526 4c9649a9 j_mayer
    if (env->ipr[IPR_PAL_BASE] != -1ULL) {
527 4c9649a9 j_mayer
        /* We use native PALcode */
528 4c9649a9 j_mayer
        env->pc = env->ipr[IPR_PAL_BASE] + excp;
529 4c9649a9 j_mayer
    } else {
530 4c9649a9 j_mayer
        /* We use emulated PALcode */
531 4c9649a9 j_mayer
        call_pal(env);
532 4c9649a9 j_mayer
        /* Emulate REI */
533 4c9649a9 j_mayer
        env->pc = env->ipr[IPR_EXC_ADDR] & ~7;
534 4c9649a9 j_mayer
        env->ipr[IPR_EXC_ADDR] = env->ipr[IPR_EXC_ADDR] & 1;
535 4c9649a9 j_mayer
        /* XXX: re-enable interrupts and memory mapping */
536 4c9649a9 j_mayer
    }
537 4c9649a9 j_mayer
}
538 4c9649a9 j_mayer
#endif
539 4c9649a9 j_mayer
540 5fafdf24 ths
void cpu_dump_state (CPUState *env, FILE *f,
541 4c9649a9 j_mayer
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
542 4c9649a9 j_mayer
                     int flags)
543 4c9649a9 j_mayer
{
544 b55266b5 blueswir1
    static const char *linux_reg_names[] = {
545 4c9649a9 j_mayer
        "v0 ", "t0 ", "t1 ", "t2 ", "t3 ", "t4 ", "t5 ", "t6 ",
546 4c9649a9 j_mayer
        "t7 ", "s0 ", "s1 ", "s2 ", "s3 ", "s4 ", "s5 ", "fp ",
547 4c9649a9 j_mayer
        "a0 ", "a1 ", "a2 ", "a3 ", "a4 ", "a5 ", "t8 ", "t9 ",
548 4c9649a9 j_mayer
        "t10", "t11", "ra ", "t12", "at ", "gp ", "sp ", "zero",
549 4c9649a9 j_mayer
    };
550 4c9649a9 j_mayer
    int i;
551 4c9649a9 j_mayer
552 4c9649a9 j_mayer
    cpu_fprintf(f, "     PC  " TARGET_FMT_lx "      PS  " TARGET_FMT_lx "\n",
553 4c9649a9 j_mayer
                env->pc, env->ps);
554 4c9649a9 j_mayer
    for (i = 0; i < 31; i++) {
555 4c9649a9 j_mayer
        cpu_fprintf(f, "IR%02d %s " TARGET_FMT_lx " ", i,
556 4c9649a9 j_mayer
                    linux_reg_names[i], env->ir[i]);
557 4c9649a9 j_mayer
        if ((i % 3) == 2)
558 4c9649a9 j_mayer
            cpu_fprintf(f, "\n");
559 4c9649a9 j_mayer
    }
560 6910b8f6 Richard Henderson
561 6910b8f6 Richard Henderson
    cpu_fprintf(f, "lock_a   " TARGET_FMT_lx " lock_v   " TARGET_FMT_lx "\n",
562 6910b8f6 Richard Henderson
                env->lock_addr, env->lock_value);
563 6910b8f6 Richard Henderson
564 4c9649a9 j_mayer
    for (i = 0; i < 31; i++) {
565 4c9649a9 j_mayer
        cpu_fprintf(f, "FIR%02d    " TARGET_FMT_lx " ", i,
566 4c9649a9 j_mayer
                    *((uint64_t *)(&env->fir[i])));
567 4c9649a9 j_mayer
        if ((i % 3) == 2)
568 4c9649a9 j_mayer
            cpu_fprintf(f, "\n");
569 4c9649a9 j_mayer
    }
570 6910b8f6 Richard Henderson
    cpu_fprintf(f, "\n");
571 4c9649a9 j_mayer
}