2 * Alpha emulation cpu helpers for qemu.
4 * Copyright (c) 2007 Jocelyn Mayer
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.
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.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA
28 #if defined(CONFIG_USER_ONLY)
30 int cpu_alpha_handle_mmu_fault (CPUState
*env
, target_ulong address
, int rw
,
31 int mmu_idx
, int is_softmmu
)
34 env
->exception_index
= EXCP_ITB_MISS
;
36 env
->exception_index
= EXCP_DFAULT
;
37 env
->ipr
[IPR_EXC_ADDR
] = address
;
42 target_phys_addr_t
cpu_get_phys_page_debug (CPUState
*env
, target_ulong addr
)
47 void do_interrupt (CPUState
*env
)
49 env
->exception_index
= -1;
54 target_phys_addr_t
cpu_get_phys_page_debug (CPUState
*env
, target_ulong addr
)
59 int cpu_alpha_handle_mmu_fault (CPUState
*env
, target_ulong address
, int rw
,
60 int mmu_idx
, int is_softmmu
)
65 /* Instruction translation buffer miss */
66 env
->exception_index
= EXCP_ITB_MISS
;
68 if (env
->ipr
[IPR_EXC_ADDR
] & 1)
69 env
->exception_index
= EXCP_DTB_MISS_PAL
;
71 env
->exception_index
= EXCP_DTB_MISS_NATIVE
;
72 opc
= (ldl_code(env
->pc
) >> 21) << 4;
78 env
->ipr
[IPR_MM_STAT
] = opc
;
84 int cpu_alpha_mfpr (CPUState
*env
, int iprn
, uint64_t *valp
)
89 hwpcb
= env
->ipr
[IPR_PCBB
];
92 if (env
->features
& FEATURE_ASN
)
93 *valp
= env
->ipr
[IPR_ASN
];
98 *valp
= ((int64_t)(env
->ipr
[IPR_ASTEN
] << 60)) >> 60;
101 *valp
= ((int64_t)(env
->ipr
[IPR_ASTSR
] << 60)) >> 60;
108 if (env
->features
& FEATURE_SPS
)
109 *valp
= env
->ipr
[IPR_ESP
];
111 *valp
= ldq_raw(hwpcb
+ 8);
114 *valp
= ((int64_t)(env
->ipr
[IPR_FEN
] << 63)) >> 63;
121 *valp
= ((int64_t)(env
->ipr
[IPR_IPL
] << 59)) >> 59;
124 if (!(env
->ipr
[IPR_EXC_ADDR
] & 1)) {
127 if (env
->features
& FEATURE_SPS
)
128 *valp
= env
->ipr
[IPR_KSP
];
130 *valp
= ldq_raw(hwpcb
+ 0);
134 *valp
= ((int64_t)(env
->ipr
[IPR_MCES
] << 59)) >> 59;
137 /* Implementation specific */
141 *valp
= ((int64_t)env
->ipr
[IPR_PCBB
] << 16) >> 16;
144 *valp
= env
->ipr
[IPR_PRBR
];
147 *valp
= env
->ipr
[IPR_PTBR
];
150 *valp
= (int64_t)((int32_t)env
->ipr
[IPR_SCBB
]);
157 *valp
= (int64_t)((int16_t)env
->ipr
[IPR_SISR
]);
159 if (env
->features
& FEATURE_SPS
)
160 *valp
= env
->ipr
[IPR_SSP
];
162 *valp
= ldq_raw(hwpcb
+ 16);
165 if (env
->features
& FEATURE_VIRBND
)
166 *valp
= env
->ipr
[IPR_SYSPTBR
];
171 if ((env
->features
& FEATURE_TBCHK
)) {
200 if (env
->features
& FEATURE_SPS
)
201 *valp
= env
->ipr
[IPR_USP
];
203 *valp
= ldq_raw(hwpcb
+ 24);
206 if (env
->features
& FEATURE_VIRBND
)
207 *valp
= env
->ipr
[IPR_VIRBND
];
212 *valp
= env
->ipr
[IPR_VPTB
];
215 *valp
= env
->ipr
[IPR_WHAMI
];
226 int cpu_alpha_mtpr (CPUState
*env
, int iprn
, uint64_t val
, uint64_t *oldvalp
)
228 uint64_t hwpcb
, tmp64
;
232 hwpcb
= env
->ipr
[IPR_PCBB
];
239 tmp8
= ((int8_t)(env
->ipr
[IPR_ASTEN
] << 4)) >> 4;
242 tmp8
|= (val
>> 4) & 0xF;
243 env
->ipr
[IPR_ASTEN
] &= ~0xF;
244 env
->ipr
[IPR_ASTEN
] |= tmp8
;
248 tmp8
= ((int8_t)(env
->ipr
[IPR_ASTSR
] << 4)) >> 4;
251 tmp8
|= (val
>> 4) & 0xF;
252 env
->ipr
[IPR_ASTSR
] &= ~0xF;
253 env
->ipr
[IPR_ASTSR
] |= tmp8
;
256 env
->ipr
[IPR_DATFX
] &= ~0x1;
257 env
->ipr
[IPR_DATFX
] |= val
& 1;
258 tmp64
= ldq_raw(hwpcb
+ 56);
259 tmp64
&= ~0x8000000000000000ULL
;
260 tmp64
|= (val
& 1) << 63;
261 stq_raw(hwpcb
+ 56, tmp64
);
264 if (env
->features
& FEATURE_SPS
)
265 env
->ipr
[IPR_ESP
] = val
;
267 stq_raw(hwpcb
+ 8, val
);
270 env
->ipr
[IPR_FEN
] = val
& 1;
271 tmp64
= ldq_raw(hwpcb
+ 56);
274 stq_raw(hwpcb
+ 56, tmp64
);
277 /* XXX: TODO: Send IRQ to CPU #ir[16] */
280 *oldvalp
= ((int64_t)(env
->ipr
[IPR_IPL
] << 59)) >> 59;
281 env
->ipr
[IPR_IPL
] &= ~0x1F;
282 env
->ipr
[IPR_IPL
] |= val
& 0x1F;
283 /* XXX: may issue an interrupt or ASR _now_ */
287 if (!(env
->ipr
[IPR_EXC_ADDR
] & 1)) {
290 if (env
->features
& FEATURE_SPS
)
291 env
->ipr
[IPR_KSP
] = val
;
293 stq_raw(hwpcb
+ 0, val
);
297 env
->ipr
[IPR_MCES
] &= ~((val
& 0x7) | 0x18);
298 env
->ipr
[IPR_MCES
] |= val
& 0x18;
301 /* Implementation specific */
310 env
->ipr
[IPR_PRBR
] = val
;
317 env
->ipr
[IPR_SCBB
] = (uint32_t)val
;
321 env
->ipr
[IPR_SISR
] |= 1 << (val
& 0xF);
322 /* XXX: request a software interrupt _now_ */
330 if (env
->features
& FEATURE_SPS
)
331 env
->ipr
[IPR_SSP
] = val
;
333 stq_raw(hwpcb
+ 16, val
);
336 if (env
->features
& FEATURE_VIRBND
)
337 env
->ipr
[IPR_SYSPTBR
] = val
;
351 tlb_flush_page(env
, val
);
354 tlb_flush_page(env
, val
);
357 tlb_flush_page(env
, val
);
360 if (env
->features
& FEATURE_SPS
)
361 env
->ipr
[IPR_USP
] = val
;
363 stq_raw(hwpcb
+ 24, val
);
366 if (env
->features
& FEATURE_VIRBND
)
367 env
->ipr
[IPR_VIRBND
] = val
;
372 env
->ipr
[IPR_VPTB
] = val
;
387 void do_interrupt (CPUState
*env
)
391 env
->ipr
[IPR_EXC_ADDR
] = env
->pc
| 1;
392 excp
= env
->exception_index
;
393 env
->exception_index
= 0;
395 /* XXX: disable interrupts and memory mapping */
396 if (env
->ipr
[IPR_PAL_BASE
] != -1ULL) {
397 /* We use native PALcode */
398 env
->pc
= env
->ipr
[IPR_PAL_BASE
] + excp
;
400 /* We use emulated PALcode */
403 env
->pc
= env
->ipr
[IPR_EXC_ADDR
] & ~7;
404 env
->ipr
[IPR_EXC_ADDR
] = env
->ipr
[IPR_EXC_ADDR
] & 1;
405 /* XXX: re-enable interrupts and memory mapping */
410 void cpu_dump_state (CPUState
*env
, FILE *f
,
411 int (*cpu_fprintf
)(FILE *f
, const char *fmt
, ...),
414 static const char *linux_reg_names
[] = {
415 "v0 ", "t0 ", "t1 ", "t2 ", "t3 ", "t4 ", "t5 ", "t6 ",
416 "t7 ", "s0 ", "s1 ", "s2 ", "s3 ", "s4 ", "s5 ", "fp ",
417 "a0 ", "a1 ", "a2 ", "a3 ", "a4 ", "a5 ", "t8 ", "t9 ",
418 "t10", "t11", "ra ", "t12", "at ", "gp ", "sp ", "zero",
422 cpu_fprintf(f
, " PC " TARGET_FMT_lx
" PS " TARGET_FMT_lx
"\n",
424 for (i
= 0; i
< 31; i
++) {
425 cpu_fprintf(f
, "IR%02d %s " TARGET_FMT_lx
" ", i
,
426 linux_reg_names
[i
], env
->ir
[i
]);
428 cpu_fprintf(f
, "\n");
430 cpu_fprintf(f
, "\n");
431 for (i
= 0; i
< 31; i
++) {
432 cpu_fprintf(f
, "FIR%02d " TARGET_FMT_lx
" ", i
,
433 *((uint64_t *)(&env
->fir
[i
])));
435 cpu_fprintf(f
, "\n");
437 cpu_fprintf(f
, "\nlock " TARGET_FMT_lx
"\n", env
->lock
);