Statistics
| Branch: | Revision:

root / target-alpha / helper.c @ 248c42f3

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