]>
Commit | Line | Data |
---|---|---|
4c9649a9 JM |
1 | /* |
2 | * Alpha emulation cpu definitions for qemu. | |
5fafdf24 | 3 | * |
4c9649a9 JM |
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 | |
d6ea4236 | 9 | * version 2.1 of the License, or (at your option) any later version. |
4c9649a9 JM |
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 | |
8167ee88 | 17 | * License along with this library; if not, see <http://www.gnu.org/licenses/>. |
4c9649a9 JM |
18 | */ |
19 | ||
07f5a258 MA |
20 | #ifndef ALPHA_CPU_H |
21 | #define ALPHA_CPU_H | |
4c9649a9 | 22 | |
1dc8e6b7 | 23 | #include "cpu-qom.h" |
74433bf0 | 24 | #include "exec/cpu-defs.h" |
69242e7e | 25 | #include "qemu/cpu-float.h" |
4c9649a9 | 26 | |
5ee4f3c2 RH |
27 | /* Alpha processors have a weak memory model */ |
28 | #define TCG_GUEST_DEFAULT_MO (0) | |
29 | ||
4c9649a9 JM |
30 | #define ICACHE_LINE_SIZE 32 |
31 | #define DCACHE_LINE_SIZE 32 | |
32 | ||
4c9649a9 JM |
33 | /* Alpha major type */ |
34 | enum { | |
35 | ALPHA_EV3 = 1, | |
36 | ALPHA_EV4 = 2, | |
37 | ALPHA_SIM = 3, | |
38 | ALPHA_LCA = 4, | |
39 | ALPHA_EV5 = 5, /* 21164 */ | |
40 | ALPHA_EV45 = 6, /* 21064A */ | |
41 | ALPHA_EV56 = 7, /* 21164A */ | |
42 | }; | |
43 | ||
44 | /* EV4 minor type */ | |
45 | enum { | |
46 | ALPHA_EV4_2 = 0, | |
47 | ALPHA_EV4_3 = 1, | |
48 | }; | |
49 | ||
50 | /* LCA minor type */ | |
51 | enum { | |
52 | ALPHA_LCA_1 = 1, /* 21066 */ | |
53 | ALPHA_LCA_2 = 2, /* 20166 */ | |
54 | ALPHA_LCA_3 = 3, /* 21068 */ | |
55 | ALPHA_LCA_4 = 4, /* 21068 */ | |
56 | ALPHA_LCA_5 = 5, /* 21066A */ | |
57 | ALPHA_LCA_6 = 6, /* 21068A */ | |
58 | }; | |
59 | ||
60 | /* EV5 minor type */ | |
61 | enum { | |
62 | ALPHA_EV5_1 = 1, /* Rev BA, CA */ | |
63 | ALPHA_EV5_2 = 2, /* Rev DA, EA */ | |
64 | ALPHA_EV5_3 = 3, /* Pass 3 */ | |
65 | ALPHA_EV5_4 = 4, /* Pass 3.2 */ | |
66 | ALPHA_EV5_5 = 5, /* Pass 4 */ | |
67 | }; | |
68 | ||
69 | /* EV45 minor type */ | |
70 | enum { | |
71 | ALPHA_EV45_1 = 1, /* Pass 1 */ | |
72 | ALPHA_EV45_2 = 2, /* Pass 1.1 */ | |
73 | ALPHA_EV45_3 = 3, /* Pass 2 */ | |
74 | }; | |
75 | ||
76 | /* EV56 minor type */ | |
77 | enum { | |
78 | ALPHA_EV56_1 = 1, /* Pass 1 */ | |
79 | ALPHA_EV56_2 = 2, /* Pass 2 */ | |
80 | }; | |
81 | ||
82 | enum { | |
83 | IMPLVER_2106x = 0, /* EV4, EV45 & LCA45 */ | |
84 | IMPLVER_21164 = 1, /* EV5, EV56 & PCA45 */ | |
85 | IMPLVER_21264 = 2, /* EV6, EV67 & EV68x */ | |
86 | IMPLVER_21364 = 3, /* EV7 & EV79 */ | |
87 | }; | |
88 | ||
89 | enum { | |
90 | AMASK_BWX = 0x00000001, | |
91 | AMASK_FIX = 0x00000002, | |
92 | AMASK_CIX = 0x00000004, | |
93 | AMASK_MVI = 0x00000100, | |
94 | AMASK_TRAP = 0x00000200, | |
95 | AMASK_PREFETCH = 0x00001000, | |
96 | }; | |
97 | ||
98 | enum { | |
99 | VAX_ROUND_NORMAL = 0, | |
100 | VAX_ROUND_CHOPPED, | |
101 | }; | |
102 | ||
103 | enum { | |
104 | IEEE_ROUND_NORMAL = 0, | |
105 | IEEE_ROUND_DYNAMIC, | |
106 | IEEE_ROUND_PLUS, | |
107 | IEEE_ROUND_MINUS, | |
108 | IEEE_ROUND_CHOPPED, | |
109 | }; | |
110 | ||
111 | /* IEEE floating-point operations encoding */ | |
112 | /* Trap mode */ | |
113 | enum { | |
114 | FP_TRAP_I = 0x0, | |
115 | FP_TRAP_U = 0x1, | |
116 | FP_TRAP_S = 0x4, | |
117 | FP_TRAP_SU = 0x5, | |
118 | FP_TRAP_SUI = 0x7, | |
119 | }; | |
120 | ||
121 | /* Rounding mode */ | |
122 | enum { | |
123 | FP_ROUND_CHOPPED = 0x0, | |
124 | FP_ROUND_MINUS = 0x1, | |
125 | FP_ROUND_NORMAL = 0x2, | |
126 | FP_ROUND_DYNAMIC = 0x3, | |
127 | }; | |
128 | ||
f3d3aad4 RH |
129 | /* FPCR bits -- right-shifted 32 so we can use a uint32_t. */ |
130 | #define FPCR_SUM (1U << (63 - 32)) | |
131 | #define FPCR_INED (1U << (62 - 32)) | |
132 | #define FPCR_UNFD (1U << (61 - 32)) | |
133 | #define FPCR_UNDZ (1U << (60 - 32)) | |
134 | #define FPCR_DYN_SHIFT (58 - 32) | |
135 | #define FPCR_DYN_CHOPPED (0U << FPCR_DYN_SHIFT) | |
136 | #define FPCR_DYN_MINUS (1U << FPCR_DYN_SHIFT) | |
137 | #define FPCR_DYN_NORMAL (2U << FPCR_DYN_SHIFT) | |
138 | #define FPCR_DYN_PLUS (3U << FPCR_DYN_SHIFT) | |
139 | #define FPCR_DYN_MASK (3U << FPCR_DYN_SHIFT) | |
140 | #define FPCR_IOV (1U << (57 - 32)) | |
141 | #define FPCR_INE (1U << (56 - 32)) | |
142 | #define FPCR_UNF (1U << (55 - 32)) | |
143 | #define FPCR_OVF (1U << (54 - 32)) | |
144 | #define FPCR_DZE (1U << (53 - 32)) | |
145 | #define FPCR_INV (1U << (52 - 32)) | |
146 | #define FPCR_OVFD (1U << (51 - 32)) | |
147 | #define FPCR_DZED (1U << (50 - 32)) | |
148 | #define FPCR_INVD (1U << (49 - 32)) | |
149 | #define FPCR_DNZ (1U << (48 - 32)) | |
150 | #define FPCR_DNOD (1U << (47 - 32)) | |
151 | #define FPCR_STATUS_MASK (FPCR_IOV | FPCR_INE | FPCR_UNF \ | |
152 | | FPCR_OVF | FPCR_DZE | FPCR_INV) | |
ba0e276d RH |
153 | |
154 | /* The silly software trap enables implemented by the kernel emulation. | |
155 | These are more or less architecturally required, since the real hardware | |
156 | has read-as-zero bits in the FPCR when the features aren't implemented. | |
157 | For the purposes of QEMU, we pretend the FPCR can hold everything. */ | |
f3d3aad4 RH |
158 | #define SWCR_TRAP_ENABLE_INV (1U << 1) |
159 | #define SWCR_TRAP_ENABLE_DZE (1U << 2) | |
160 | #define SWCR_TRAP_ENABLE_OVF (1U << 3) | |
161 | #define SWCR_TRAP_ENABLE_UNF (1U << 4) | |
162 | #define SWCR_TRAP_ENABLE_INE (1U << 5) | |
163 | #define SWCR_TRAP_ENABLE_DNO (1U << 6) | |
164 | #define SWCR_TRAP_ENABLE_MASK ((1U << 7) - (1U << 1)) | |
165 | ||
166 | #define SWCR_MAP_DMZ (1U << 12) | |
167 | #define SWCR_MAP_UMZ (1U << 13) | |
168 | #define SWCR_MAP_MASK (SWCR_MAP_DMZ | SWCR_MAP_UMZ) | |
169 | ||
170 | #define SWCR_STATUS_INV (1U << 17) | |
171 | #define SWCR_STATUS_DZE (1U << 18) | |
172 | #define SWCR_STATUS_OVF (1U << 19) | |
173 | #define SWCR_STATUS_UNF (1U << 20) | |
174 | #define SWCR_STATUS_INE (1U << 21) | |
175 | #define SWCR_STATUS_DNO (1U << 22) | |
176 | #define SWCR_STATUS_MASK ((1U << 23) - (1U << 17)) | |
ba0e276d | 177 | |
21ba8564 RH |
178 | #define SWCR_STATUS_TO_EXCSUM_SHIFT 16 |
179 | ||
ba0e276d RH |
180 | #define SWCR_MASK (SWCR_TRAP_ENABLE_MASK | SWCR_MAP_MASK | SWCR_STATUS_MASK) |
181 | ||
8417845e RH |
182 | /* MMU modes definitions */ |
183 | ||
6a73ecf5 | 184 | /* Alpha has 5 MMU modes: PALcode, Kernel, Executive, Supervisor, and User. |
8417845e RH |
185 | The Unix PALcode only exposes the kernel and user modes; presumably |
186 | executive and supervisor are used by VMS. | |
187 | ||
188 | PALcode itself uses physical mode for code and kernel mode for data; | |
189 | there are PALmode instructions that can access data via physical mode | |
190 | or via an os-installed "alternate mode", which is one of the 4 above. | |
191 | ||
6a73ecf5 RH |
192 | That said, we're only emulating Unix PALcode, and not attempting VMS, |
193 | so we don't need to implement Executive and Supervisor. QEMU's own | |
194 | PALcode cheats and usees the KSEG mapping for its code+data rather than | |
195 | physical addresses. */ | |
8417845e | 196 | |
8417845e RH |
197 | #define MMU_KERNEL_IDX 0 |
198 | #define MMU_USER_IDX 1 | |
6a73ecf5 | 199 | #define MMU_PHYS_IDX 2 |
8417845e | 200 | |
1ea4a06a | 201 | typedef struct CPUArchState { |
4c9649a9 | 202 | uint64_t ir[31]; |
8443effb | 203 | float64 fir[31]; |
4c9649a9 | 204 | uint64_t pc; |
4c9649a9 | 205 | uint64_t unique; |
6910b8f6 | 206 | uint64_t lock_addr; |
6910b8f6 | 207 | uint64_t lock_value; |
f3d3aad4 RH |
208 | |
209 | /* The FPCR, and disassembled portions thereof. */ | |
210 | uint32_t fpcr; | |
21ba8564 RH |
211 | #ifdef CONFIG_USER_ONLY |
212 | uint32_t swcr; | |
213 | #endif | |
f3d3aad4 | 214 | uint32_t fpcr_exc_enable; |
8443effb | 215 | float_status fp_status; |
8443effb RH |
216 | uint8_t fpcr_dyn_round; |
217 | uint8_t fpcr_flush_to_zero; | |
8443effb | 218 | |
bcd2625d RH |
219 | /* Mask of PALmode, Processor State et al. Most of this gets copied |
220 | into the TranslatorBlock flags and controls code generation. */ | |
221 | uint32_t flags; | |
26b46094 | 222 | |
bcd2625d | 223 | /* The high 32-bits of the processor cycle counter. */ |
26b46094 | 224 | uint32_t pcc_ofs; |
129d8aa5 RH |
225 | |
226 | /* These pass data from the exception logic in the translator and | |
227 | helpers to the OS entry point. This is used for both system | |
228 | emulation and user-mode. */ | |
229 | uint64_t trap_arg0; | |
230 | uint64_t trap_arg1; | |
231 | uint64_t trap_arg2; | |
4c9649a9 | 232 | |
26b46094 RH |
233 | #if !defined(CONFIG_USER_ONLY) |
234 | /* The internal data required by our emulation of the Unix PALcode. */ | |
235 | uint64_t exc_addr; | |
236 | uint64_t palbr; | |
237 | uint64_t ptbr; | |
238 | uint64_t vptptr; | |
239 | uint64_t sysval; | |
240 | uint64_t usp; | |
241 | uint64_t shadow[8]; | |
242 | uint64_t scratch[24]; | |
243 | #endif | |
244 | ||
c781cf96 | 245 | /* This alarm doesn't exist in real hardware; we wish it did. */ |
c781cf96 RH |
246 | uint64_t alarm_expire; |
247 | ||
4c9649a9 | 248 | int error_code; |
4c9649a9 JM |
249 | |
250 | uint32_t features; | |
251 | uint32_t amask; | |
252 | int implver; | |
1ea4a06a | 253 | } CPUAlphaState; |
4c9649a9 | 254 | |
1dc8e6b7 PB |
255 | /** |
256 | * AlphaCPU: | |
257 | * @env: #CPUAlphaState | |
258 | * | |
259 | * An Alpha CPU. | |
260 | */ | |
b36e239e | 261 | struct ArchCPU { |
1dc8e6b7 PB |
262 | /*< private >*/ |
263 | CPUState parent_obj; | |
264 | /*< public >*/ | |
265 | ||
5b146dc7 | 266 | CPUNegativeOffsetState neg; |
1dc8e6b7 PB |
267 | CPUAlphaState env; |
268 | ||
269 | /* This alarm doesn't exist in real hardware; we wish it did. */ | |
270 | QEMUTimer *alarm_timer; | |
271 | }; | |
272 | ||
1dc8e6b7 PB |
273 | |
274 | #ifndef CONFIG_USER_ONLY | |
8a9358cc | 275 | extern const VMStateDescription vmstate_alpha_cpu; |
1dc8e6b7 PB |
276 | |
277 | void alpha_cpu_do_interrupt(CPUState *cpu); | |
278 | bool alpha_cpu_exec_interrupt(CPUState *cpu, int int_req); | |
6d2d454a | 279 | hwaddr alpha_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr); |
9354e694 | 280 | #endif /* !CONFIG_USER_ONLY */ |
90c84c56 | 281 | void alpha_cpu_dump_state(CPUState *cs, FILE *f, int flags); |
a010bdbe | 282 | int alpha_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg); |
1dc8e6b7 | 283 | int alpha_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg); |
1dc8e6b7 | 284 | |
494342b3 | 285 | #define cpu_list alpha_cpu_list |
9467d44c | 286 | |
022c62cb | 287 | #include "exec/cpu-all.h" |
4c9649a9 JM |
288 | |
289 | enum { | |
290 | FEATURE_ASN = 0x00000001, | |
291 | FEATURE_SPS = 0x00000002, | |
292 | FEATURE_VIRBND = 0x00000004, | |
293 | FEATURE_TBCHK = 0x00000008, | |
294 | }; | |
295 | ||
296 | enum { | |
07b6c13b RH |
297 | EXCP_RESET, |
298 | EXCP_MCHK, | |
299 | EXCP_SMP_INTERRUPT, | |
300 | EXCP_CLK_INTERRUPT, | |
301 | EXCP_DEV_INTERRUPT, | |
302 | EXCP_MMFAULT, | |
303 | EXCP_UNALIGN, | |
304 | EXCP_OPCDEC, | |
305 | EXCP_ARITH, | |
306 | EXCP_FEN, | |
307 | EXCP_CALL_PAL, | |
4c9649a9 JM |
308 | }; |
309 | ||
6a80e088 RH |
310 | /* Alpha-specific interrupt pending bits. */ |
311 | #define CPU_INTERRUPT_TIMER CPU_INTERRUPT_TGT_EXT_0 | |
312 | #define CPU_INTERRUPT_SMP CPU_INTERRUPT_TGT_EXT_1 | |
313 | #define CPU_INTERRUPT_MCHK CPU_INTERRUPT_TGT_EXT_2 | |
314 | ||
a3b9af16 RH |
315 | /* OSF/1 Page table bits. */ |
316 | enum { | |
317 | PTE_VALID = 0x0001, | |
318 | PTE_FOR = 0x0002, /* used for page protection (fault on read) */ | |
319 | PTE_FOW = 0x0004, /* used for page protection (fault on write) */ | |
320 | PTE_FOE = 0x0008, /* used for page protection (fault on exec) */ | |
321 | PTE_ASM = 0x0010, | |
322 | PTE_KRE = 0x0100, | |
323 | PTE_URE = 0x0200, | |
324 | PTE_KWE = 0x1000, | |
325 | PTE_UWE = 0x2000 | |
326 | }; | |
327 | ||
ea879fc7 RH |
328 | /* Hardware interrupt (entInt) constants. */ |
329 | enum { | |
330 | INT_K_IP, | |
331 | INT_K_CLK, | |
332 | INT_K_MCHK, | |
333 | INT_K_DEV, | |
334 | INT_K_PERF, | |
335 | }; | |
336 | ||
337 | /* Memory management (entMM) constants. */ | |
338 | enum { | |
339 | MM_K_TNV, | |
340 | MM_K_ACV, | |
341 | MM_K_FOR, | |
342 | MM_K_FOE, | |
343 | MM_K_FOW | |
344 | }; | |
345 | ||
346 | /* Arithmetic exception (entArith) constants. */ | |
347 | enum { | |
348 | EXC_M_SWC = 1, /* Software completion */ | |
349 | EXC_M_INV = 2, /* Invalid operation */ | |
350 | EXC_M_DZE = 4, /* Division by zero */ | |
351 | EXC_M_FOV = 8, /* Overflow */ | |
352 | EXC_M_UNF = 16, /* Underflow */ | |
353 | EXC_M_INE = 32, /* Inexact result */ | |
354 | EXC_M_IOV = 64 /* Integer Overflow */ | |
355 | }; | |
356 | ||
357 | /* Processor status constants. */ | |
bcd2625d RH |
358 | /* Low 3 bits are interrupt mask level. */ |
359 | #define PS_INT_MASK 7u | |
ea879fc7 | 360 | |
bcd2625d RH |
361 | /* Bits 4 and 5 are the mmu mode. The VMS PALcode uses all 4 modes; |
362 | The Unix PALcode only uses bit 4. */ | |
363 | #define PS_USER_MODE 8u | |
364 | ||
365 | /* CPUAlphaState->flags constants. These are layed out so that we | |
366 | can set or reset the pieces individually by assigning to the byte, | |
367 | or manipulated as a whole. */ | |
368 | ||
369 | #define ENV_FLAG_PAL_SHIFT 0 | |
370 | #define ENV_FLAG_PS_SHIFT 8 | |
371 | #define ENV_FLAG_RX_SHIFT 16 | |
372 | #define ENV_FLAG_FEN_SHIFT 24 | |
373 | ||
374 | #define ENV_FLAG_PAL_MODE (1u << ENV_FLAG_PAL_SHIFT) | |
375 | #define ENV_FLAG_PS_USER (PS_USER_MODE << ENV_FLAG_PS_SHIFT) | |
376 | #define ENV_FLAG_RX_FLAG (1u << ENV_FLAG_RX_SHIFT) | |
377 | #define ENV_FLAG_FEN (1u << ENV_FLAG_FEN_SHIFT) | |
378 | ||
379 | #define ENV_FLAG_TB_MASK \ | |
380 | (ENV_FLAG_PAL_MODE | ENV_FLAG_PS_USER | ENV_FLAG_FEN) | |
ea879fc7 | 381 | |
fed14246 RH |
382 | #define TB_FLAG_UNALIGN (1u << 1) |
383 | ||
97ed5ccd | 384 | static inline int cpu_mmu_index(CPUAlphaState *env, bool ifetch) |
ea879fc7 | 385 | { |
bcd2625d RH |
386 | int ret = env->flags & ENV_FLAG_PS_USER ? MMU_USER_IDX : MMU_KERNEL_IDX; |
387 | if (env->flags & ENV_FLAG_PAL_MODE) { | |
388 | ret = MMU_KERNEL_IDX; | |
bba9bdce | 389 | } |
bcd2625d | 390 | return ret; |
ea879fc7 | 391 | } |
4c9649a9 | 392 | |
4c9649a9 JM |
393 | enum { |
394 | IR_V0 = 0, | |
395 | IR_T0 = 1, | |
396 | IR_T1 = 2, | |
397 | IR_T2 = 3, | |
398 | IR_T3 = 4, | |
399 | IR_T4 = 5, | |
400 | IR_T5 = 6, | |
401 | IR_T6 = 7, | |
402 | IR_T7 = 8, | |
403 | IR_S0 = 9, | |
404 | IR_S1 = 10, | |
405 | IR_S2 = 11, | |
406 | IR_S3 = 12, | |
407 | IR_S4 = 13, | |
408 | IR_S5 = 14, | |
409 | IR_S6 = 15, | |
a4b388ff | 410 | IR_FP = IR_S6, |
4c9649a9 JM |
411 | IR_A0 = 16, |
412 | IR_A1 = 17, | |
413 | IR_A2 = 18, | |
414 | IR_A3 = 19, | |
415 | IR_A4 = 20, | |
416 | IR_A5 = 21, | |
417 | IR_T8 = 22, | |
418 | IR_T9 = 23, | |
419 | IR_T10 = 24, | |
420 | IR_T11 = 25, | |
421 | IR_RA = 26, | |
422 | IR_T12 = 27, | |
a4b388ff | 423 | IR_PV = IR_T12, |
4c9649a9 JM |
424 | IR_AT = 28, |
425 | IR_GP = 29, | |
426 | IR_SP = 30, | |
427 | IR_ZERO = 31, | |
428 | }; | |
429 | ||
0c28246f AF |
430 | void alpha_translate_init(void); |
431 | ||
73a25e83 IM |
432 | #define ALPHA_CPU_TYPE_SUFFIX "-" TYPE_ALPHA_CPU |
433 | #define ALPHA_CPU_TYPE_NAME(model) model ALPHA_CPU_TYPE_SUFFIX | |
0dacec87 | 434 | #define CPU_RESOLVING_TYPE TYPE_ALPHA_CPU |
73a25e83 | 435 | |
0442428a | 436 | void alpha_cpu_list(void); |
8905770b MAL |
437 | G_NORETURN void dynamic_excp(CPUAlphaState *, uintptr_t, int, int); |
438 | G_NORETURN void arith_excp(CPUAlphaState *, uintptr_t, int, uint64_t); | |
95870356 | 439 | |
4d5712f1 AF |
440 | uint64_t cpu_alpha_load_fpcr (CPUAlphaState *env); |
441 | void cpu_alpha_store_fpcr (CPUAlphaState *env, uint64_t val); | |
59124384 RH |
442 | uint64_t cpu_alpha_load_gr(CPUAlphaState *env, unsigned reg); |
443 | void cpu_alpha_store_gr(CPUAlphaState *env, unsigned reg, uint64_t val); | |
90113883 RH |
444 | |
445 | #ifdef CONFIG_USER_ONLY | |
446 | void alpha_cpu_record_sigsegv(CPUState *cs, vaddr address, | |
447 | MMUAccessType access_type, | |
448 | bool maperr, uintptr_t retaddr); | |
e7424abc RH |
449 | void alpha_cpu_record_sigbus(CPUState *cs, vaddr address, |
450 | MMUAccessType access_type, uintptr_t retaddr); | |
90113883 RH |
451 | #else |
452 | bool alpha_cpu_tlb_fill(CPUState *cs, vaddr address, int size, | |
453 | MMUAccessType access_type, int mmu_idx, | |
454 | bool probe, uintptr_t retaddr); | |
8905770b MAL |
455 | G_NORETURN void alpha_cpu_do_unaligned_access(CPUState *cpu, vaddr addr, |
456 | MMUAccessType access_type, int mmu_idx, | |
457 | uintptr_t retaddr); | |
6ad4d7ee PM |
458 | void alpha_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr, |
459 | vaddr addr, unsigned size, | |
460 | MMUAccessType access_type, | |
461 | int mmu_idx, MemTxAttrs attrs, | |
462 | MemTxResult response, uintptr_t retaddr); | |
5b450407 | 463 | #endif |
4c9649a9 | 464 | |
bb5de525 AJ |
465 | static inline void cpu_get_tb_cpu_state(CPUAlphaState *env, vaddr *pc, |
466 | uint64_t *cs_base, uint32_t *pflags) | |
6b917547 AL |
467 | { |
468 | *pc = env->pc; | |
469 | *cs_base = 0; | |
bcd2625d | 470 | *pflags = env->flags & ENV_FLAG_TB_MASK; |
fed14246 RH |
471 | #ifdef CONFIG_USER_ONLY |
472 | *pflags |= TB_FLAG_UNALIGN * !env_cpu(env)->prctl_unalign_sigbus; | |
473 | #endif | |
6b917547 AL |
474 | } |
475 | ||
21ba8564 RH |
476 | #ifdef CONFIG_USER_ONLY |
477 | /* Copied from linux ieee_swcr_to_fpcr. */ | |
478 | static inline uint64_t alpha_ieee_swcr_to_fpcr(uint64_t swcr) | |
479 | { | |
480 | uint64_t fpcr = 0; | |
481 | ||
482 | fpcr |= (swcr & SWCR_STATUS_MASK) << 35; | |
483 | fpcr |= (swcr & SWCR_MAP_DMZ) << 36; | |
484 | fpcr |= (~swcr & (SWCR_TRAP_ENABLE_INV | |
485 | | SWCR_TRAP_ENABLE_DZE | |
486 | | SWCR_TRAP_ENABLE_OVF)) << 48; | |
487 | fpcr |= (~swcr & (SWCR_TRAP_ENABLE_UNF | |
488 | | SWCR_TRAP_ENABLE_INE)) << 57; | |
489 | fpcr |= (swcr & SWCR_MAP_UMZ ? FPCR_UNDZ | FPCR_UNFD : 0); | |
490 | fpcr |= (~swcr & SWCR_TRAP_ENABLE_DNO) << 41; | |
491 | ||
492 | return fpcr; | |
493 | } | |
494 | ||
495 | /* Copied from linux ieee_fpcr_to_swcr. */ | |
496 | static inline uint64_t alpha_ieee_fpcr_to_swcr(uint64_t fpcr) | |
497 | { | |
498 | uint64_t swcr = 0; | |
499 | ||
500 | swcr |= (fpcr >> 35) & SWCR_STATUS_MASK; | |
501 | swcr |= (fpcr >> 36) & SWCR_MAP_DMZ; | |
502 | swcr |= (~fpcr >> 48) & (SWCR_TRAP_ENABLE_INV | |
503 | | SWCR_TRAP_ENABLE_DZE | |
504 | | SWCR_TRAP_ENABLE_OVF); | |
505 | swcr |= (~fpcr >> 57) & (SWCR_TRAP_ENABLE_UNF | SWCR_TRAP_ENABLE_INE); | |
506 | swcr |= (fpcr >> 47) & SWCR_MAP_UMZ; | |
507 | swcr |= (~fpcr >> 41) & SWCR_TRAP_ENABLE_DNO; | |
508 | ||
509 | return swcr; | |
510 | } | |
511 | #endif /* CONFIG_USER_ONLY */ | |
512 | ||
07f5a258 | 513 | #endif /* ALPHA_CPU_H */ |