root / target-s390x / cpu.h @ 1ac5889f
History | View | Annotate | Download (32.5 kB)
1 |
/*
|
---|---|
2 |
* S/390 virtual CPU header
|
3 |
*
|
4 |
* Copyright (c) 2009 Ulrich Hecht
|
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
|
9 |
* version 2 of the License, or (at your option) any later version.
|
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
|
17 |
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
18 |
*/
|
19 |
#ifndef CPU_S390X_H
|
20 |
#define CPU_S390X_H
|
21 |
|
22 |
#include "config.h" |
23 |
#include "qemu-common.h" |
24 |
|
25 |
#define TARGET_LONG_BITS 64 |
26 |
|
27 |
#define ELF_MACHINE EM_S390
|
28 |
|
29 |
#define CPUArchState struct CPUS390XState |
30 |
|
31 |
#include "exec/cpu-defs.h" |
32 |
#define TARGET_PAGE_BITS 12 |
33 |
|
34 |
#define TARGET_PHYS_ADDR_SPACE_BITS 64 |
35 |
#define TARGET_VIRT_ADDR_SPACE_BITS 64 |
36 |
|
37 |
#include "exec/cpu-all.h" |
38 |
|
39 |
#include "fpu/softfloat.h" |
40 |
|
41 |
#define NB_MMU_MODES 3 |
42 |
|
43 |
#define MMU_MODE0_SUFFIX _primary
|
44 |
#define MMU_MODE1_SUFFIX _secondary
|
45 |
#define MMU_MODE2_SUFFIX _home
|
46 |
|
47 |
#define MMU_USER_IDX 1 |
48 |
|
49 |
#define MAX_EXT_QUEUE 16 |
50 |
|
51 |
typedef struct PSW { |
52 |
uint64_t mask; |
53 |
uint64_t addr; |
54 |
} PSW; |
55 |
|
56 |
typedef struct ExtQueue { |
57 |
uint32_t code; |
58 |
uint32_t param; |
59 |
uint32_t param64; |
60 |
} ExtQueue; |
61 |
|
62 |
typedef struct CPUS390XState { |
63 |
uint64_t regs[16]; /* GP registers */ |
64 |
CPU_DoubleU fregs[16]; /* FP registers */ |
65 |
uint32_t aregs[16]; /* access registers */ |
66 |
|
67 |
uint32_t fpc; /* floating-point control register */
|
68 |
uint32_t cc_op; |
69 |
|
70 |
float_status fpu_status; /* passed to softfloat lib */
|
71 |
|
72 |
/* The low part of a 128-bit return, or remainder of a divide. */
|
73 |
uint64_t retxl; |
74 |
|
75 |
PSW psw; |
76 |
|
77 |
uint64_t cc_src; |
78 |
uint64_t cc_dst; |
79 |
uint64_t cc_vr; |
80 |
|
81 |
uint64_t __excp_addr; |
82 |
uint64_t psa; |
83 |
|
84 |
uint32_t int_pgm_code; |
85 |
uint32_t int_pgm_ilen; |
86 |
|
87 |
uint32_t int_svc_code; |
88 |
uint32_t int_svc_ilen; |
89 |
|
90 |
uint64_t cregs[16]; /* control registers */ |
91 |
|
92 |
ExtQueue ext_queue[MAX_EXT_QUEUE]; |
93 |
int pending_int;
|
94 |
|
95 |
int ext_index;
|
96 |
|
97 |
CPU_COMMON |
98 |
|
99 |
/* reset does memset(0) up to here */
|
100 |
|
101 |
int cpu_num;
|
102 |
uint8_t *storage_keys; |
103 |
|
104 |
uint64_t tod_offset; |
105 |
uint64_t tod_basetime; |
106 |
QEMUTimer *tod_timer; |
107 |
|
108 |
QEMUTimer *cpu_timer; |
109 |
} CPUS390XState; |
110 |
|
111 |
#include "cpu-qom.h" |
112 |
|
113 |
#if defined(CONFIG_USER_ONLY)
|
114 |
static inline void cpu_clone_regs(CPUS390XState *env, target_ulong newsp) |
115 |
{ |
116 |
if (newsp) {
|
117 |
env->regs[15] = newsp;
|
118 |
} |
119 |
env->regs[0] = 0; |
120 |
} |
121 |
#endif
|
122 |
|
123 |
/* Interrupt Codes */
|
124 |
/* Program Interrupts */
|
125 |
#define PGM_OPERATION 0x0001 |
126 |
#define PGM_PRIVILEGED 0x0002 |
127 |
#define PGM_EXECUTE 0x0003 |
128 |
#define PGM_PROTECTION 0x0004 |
129 |
#define PGM_ADDRESSING 0x0005 |
130 |
#define PGM_SPECIFICATION 0x0006 |
131 |
#define PGM_DATA 0x0007 |
132 |
#define PGM_FIXPT_OVERFLOW 0x0008 |
133 |
#define PGM_FIXPT_DIVIDE 0x0009 |
134 |
#define PGM_DEC_OVERFLOW 0x000a |
135 |
#define PGM_DEC_DIVIDE 0x000b |
136 |
#define PGM_HFP_EXP_OVERFLOW 0x000c |
137 |
#define PGM_HFP_EXP_UNDERFLOW 0x000d |
138 |
#define PGM_HFP_SIGNIFICANCE 0x000e |
139 |
#define PGM_HFP_DIVIDE 0x000f |
140 |
#define PGM_SEGMENT_TRANS 0x0010 |
141 |
#define PGM_PAGE_TRANS 0x0011 |
142 |
#define PGM_TRANS_SPEC 0x0012 |
143 |
#define PGM_SPECIAL_OP 0x0013 |
144 |
#define PGM_OPERAND 0x0015 |
145 |
#define PGM_TRACE_TABLE 0x0016 |
146 |
#define PGM_SPACE_SWITCH 0x001c |
147 |
#define PGM_HFP_SQRT 0x001d |
148 |
#define PGM_PC_TRANS_SPEC 0x001f |
149 |
#define PGM_AFX_TRANS 0x0020 |
150 |
#define PGM_ASX_TRANS 0x0021 |
151 |
#define PGM_LX_TRANS 0x0022 |
152 |
#define PGM_EX_TRANS 0x0023 |
153 |
#define PGM_PRIM_AUTH 0x0024 |
154 |
#define PGM_SEC_AUTH 0x0025 |
155 |
#define PGM_ALET_SPEC 0x0028 |
156 |
#define PGM_ALEN_SPEC 0x0029 |
157 |
#define PGM_ALE_SEQ 0x002a |
158 |
#define PGM_ASTE_VALID 0x002b |
159 |
#define PGM_ASTE_SEQ 0x002c |
160 |
#define PGM_EXT_AUTH 0x002d |
161 |
#define PGM_STACK_FULL 0x0030 |
162 |
#define PGM_STACK_EMPTY 0x0031 |
163 |
#define PGM_STACK_SPEC 0x0032 |
164 |
#define PGM_STACK_TYPE 0x0033 |
165 |
#define PGM_STACK_OP 0x0034 |
166 |
#define PGM_ASCE_TYPE 0x0038 |
167 |
#define PGM_REG_FIRST_TRANS 0x0039 |
168 |
#define PGM_REG_SEC_TRANS 0x003a |
169 |
#define PGM_REG_THIRD_TRANS 0x003b |
170 |
#define PGM_MONITOR 0x0040 |
171 |
#define PGM_PER 0x0080 |
172 |
#define PGM_CRYPTO 0x0119 |
173 |
|
174 |
/* External Interrupts */
|
175 |
#define EXT_INTERRUPT_KEY 0x0040 |
176 |
#define EXT_CLOCK_COMP 0x1004 |
177 |
#define EXT_CPU_TIMER 0x1005 |
178 |
#define EXT_MALFUNCTION 0x1200 |
179 |
#define EXT_EMERGENCY 0x1201 |
180 |
#define EXT_EXTERNAL_CALL 0x1202 |
181 |
#define EXT_ETR 0x1406 |
182 |
#define EXT_SERVICE 0x2401 |
183 |
#define EXT_VIRTIO 0x2603 |
184 |
|
185 |
/* PSW defines */
|
186 |
#undef PSW_MASK_PER
|
187 |
#undef PSW_MASK_DAT
|
188 |
#undef PSW_MASK_IO
|
189 |
#undef PSW_MASK_EXT
|
190 |
#undef PSW_MASK_KEY
|
191 |
#undef PSW_SHIFT_KEY
|
192 |
#undef PSW_MASK_MCHECK
|
193 |
#undef PSW_MASK_WAIT
|
194 |
#undef PSW_MASK_PSTATE
|
195 |
#undef PSW_MASK_ASC
|
196 |
#undef PSW_MASK_CC
|
197 |
#undef PSW_MASK_PM
|
198 |
#undef PSW_MASK_64
|
199 |
|
200 |
#define PSW_MASK_PER 0x4000000000000000ULL |
201 |
#define PSW_MASK_DAT 0x0400000000000000ULL |
202 |
#define PSW_MASK_IO 0x0200000000000000ULL |
203 |
#define PSW_MASK_EXT 0x0100000000000000ULL |
204 |
#define PSW_MASK_KEY 0x00F0000000000000ULL |
205 |
#define PSW_SHIFT_KEY 56 |
206 |
#define PSW_MASK_MCHECK 0x0004000000000000ULL |
207 |
#define PSW_MASK_WAIT 0x0002000000000000ULL |
208 |
#define PSW_MASK_PSTATE 0x0001000000000000ULL |
209 |
#define PSW_MASK_ASC 0x0000C00000000000ULL |
210 |
#define PSW_MASK_CC 0x0000300000000000ULL |
211 |
#define PSW_MASK_PM 0x00000F0000000000ULL |
212 |
#define PSW_MASK_64 0x0000000100000000ULL |
213 |
#define PSW_MASK_32 0x0000000080000000ULL |
214 |
|
215 |
#undef PSW_ASC_PRIMARY
|
216 |
#undef PSW_ASC_ACCREG
|
217 |
#undef PSW_ASC_SECONDARY
|
218 |
#undef PSW_ASC_HOME
|
219 |
|
220 |
#define PSW_ASC_PRIMARY 0x0000000000000000ULL |
221 |
#define PSW_ASC_ACCREG 0x0000400000000000ULL |
222 |
#define PSW_ASC_SECONDARY 0x0000800000000000ULL |
223 |
#define PSW_ASC_HOME 0x0000C00000000000ULL |
224 |
|
225 |
/* tb flags */
|
226 |
|
227 |
#define FLAG_MASK_PER (PSW_MASK_PER >> 32) |
228 |
#define FLAG_MASK_DAT (PSW_MASK_DAT >> 32) |
229 |
#define FLAG_MASK_IO (PSW_MASK_IO >> 32) |
230 |
#define FLAG_MASK_EXT (PSW_MASK_EXT >> 32) |
231 |
#define FLAG_MASK_KEY (PSW_MASK_KEY >> 32) |
232 |
#define FLAG_MASK_MCHECK (PSW_MASK_MCHECK >> 32) |
233 |
#define FLAG_MASK_WAIT (PSW_MASK_WAIT >> 32) |
234 |
#define FLAG_MASK_PSTATE (PSW_MASK_PSTATE >> 32) |
235 |
#define FLAG_MASK_ASC (PSW_MASK_ASC >> 32) |
236 |
#define FLAG_MASK_CC (PSW_MASK_CC >> 32) |
237 |
#define FLAG_MASK_PM (PSW_MASK_PM >> 32) |
238 |
#define FLAG_MASK_64 (PSW_MASK_64 >> 32) |
239 |
#define FLAG_MASK_32 0x00001000 |
240 |
|
241 |
static inline int cpu_mmu_index (CPUS390XState *env) |
242 |
{ |
243 |
if (env->psw.mask & PSW_MASK_PSTATE) {
|
244 |
return 1; |
245 |
} |
246 |
|
247 |
return 0; |
248 |
} |
249 |
|
250 |
static inline void cpu_get_tb_cpu_state(CPUS390XState* env, target_ulong *pc, |
251 |
target_ulong *cs_base, int *flags)
|
252 |
{ |
253 |
*pc = env->psw.addr; |
254 |
*cs_base = 0;
|
255 |
*flags = ((env->psw.mask >> 32) & ~FLAG_MASK_CC) |
|
256 |
((env->psw.mask & PSW_MASK_32) ? FLAG_MASK_32 : 0);
|
257 |
} |
258 |
|
259 |
/* While the PoO talks about ILC (a number between 1-3) what is actually
|
260 |
stored in LowCore is shifted left one bit (an even between 2-6). As
|
261 |
this is the actual length of the insn and therefore more useful, that
|
262 |
is what we want to pass around and manipulate. To make sure that we
|
263 |
have applied this distinction universally, rename the "ILC" to "ILEN". */
|
264 |
static inline int get_ilen(uint8_t opc) |
265 |
{ |
266 |
switch (opc >> 6) { |
267 |
case 0: |
268 |
return 2; |
269 |
case 1: |
270 |
case 2: |
271 |
return 4; |
272 |
default:
|
273 |
return 6; |
274 |
} |
275 |
} |
276 |
|
277 |
#ifndef CONFIG_USER_ONLY
|
278 |
/* In several cases of runtime exceptions, we havn't recorded the true
|
279 |
instruction length. Use these codes when raising exceptions in order
|
280 |
to re-compute the length by examining the insn in memory. */
|
281 |
#define ILEN_LATER 0x20 |
282 |
#define ILEN_LATER_INC 0x21 |
283 |
#endif
|
284 |
|
285 |
S390CPU *cpu_s390x_init(const char *cpu_model); |
286 |
void s390x_translate_init(void); |
287 |
int cpu_s390x_exec(CPUS390XState *s);
|
288 |
void cpu_s390x_close(CPUS390XState *s);
|
289 |
void do_interrupt (CPUS390XState *env);
|
290 |
|
291 |
/* you can call this signal handler from your SIGBUS and SIGSEGV
|
292 |
signal handlers to inform the virtual CPU of exceptions. non zero
|
293 |
is returned if the signal was handled by the virtual CPU. */
|
294 |
int cpu_s390x_signal_handler(int host_signum, void *pinfo, |
295 |
void *puc);
|
296 |
int cpu_s390x_handle_mmu_fault (CPUS390XState *env, target_ulong address, int rw, |
297 |
int mmu_idx);
|
298 |
#define cpu_handle_mmu_fault cpu_s390x_handle_mmu_fault
|
299 |
|
300 |
|
301 |
#ifndef CONFIG_USER_ONLY
|
302 |
void s390x_tod_timer(void *opaque); |
303 |
void s390x_cpu_timer(void *opaque); |
304 |
|
305 |
int s390_virtio_hypercall(CPUS390XState *env, uint64_t mem, uint64_t hypercall);
|
306 |
|
307 |
#ifdef CONFIG_KVM
|
308 |
void kvm_s390_interrupt(S390CPU *cpu, int type, uint32_t code); |
309 |
void kvm_s390_virtio_irq(S390CPU *cpu, int config_change, uint64_t token); |
310 |
void kvm_s390_interrupt_internal(S390CPU *cpu, int type, uint32_t parm, |
311 |
uint64_t parm64, int vm);
|
312 |
#else
|
313 |
static inline void kvm_s390_interrupt(S390CPU *cpu, int type, uint32_t code) |
314 |
{ |
315 |
} |
316 |
|
317 |
static inline void kvm_s390_virtio_irq(S390CPU *cpu, int config_change, |
318 |
uint64_t token) |
319 |
{ |
320 |
} |
321 |
|
322 |
static inline void kvm_s390_interrupt_internal(S390CPU *cpu, int type, |
323 |
uint32_t parm, uint64_t parm64, |
324 |
int vm)
|
325 |
{ |
326 |
} |
327 |
#endif
|
328 |
S390CPU *s390_cpu_addr2state(uint16_t cpu_addr); |
329 |
void s390_add_running_cpu(CPUS390XState *env);
|
330 |
unsigned s390_del_running_cpu(CPUS390XState *env);
|
331 |
|
332 |
/* service interrupts are floating therefore we must not pass an cpustate */
|
333 |
void s390_sclp_extint(uint32_t parm);
|
334 |
|
335 |
/* from s390-virtio-bus */
|
336 |
extern const hwaddr virtio_size; |
337 |
|
338 |
#else
|
339 |
static inline void s390_add_running_cpu(CPUS390XState *env) |
340 |
{ |
341 |
} |
342 |
|
343 |
static inline unsigned s390_del_running_cpu(CPUS390XState *env) |
344 |
{ |
345 |
return 0; |
346 |
} |
347 |
#endif
|
348 |
void cpu_lock(void); |
349 |
void cpu_unlock(void); |
350 |
|
351 |
static inline void cpu_set_tls(CPUS390XState *env, target_ulong newtls) |
352 |
{ |
353 |
env->aregs[0] = newtls >> 32; |
354 |
env->aregs[1] = newtls & 0xffffffffULL; |
355 |
} |
356 |
|
357 |
#define cpu_init(model) (&cpu_s390x_init(model)->env)
|
358 |
#define cpu_exec cpu_s390x_exec
|
359 |
#define cpu_gen_code cpu_s390x_gen_code
|
360 |
#define cpu_signal_handler cpu_s390x_signal_handler
|
361 |
|
362 |
#include "exec/exec-all.h" |
363 |
|
364 |
#define EXCP_EXT 1 /* external interrupt */ |
365 |
#define EXCP_SVC 2 /* supervisor call (syscall) */ |
366 |
#define EXCP_PGM 3 /* program interruption */ |
367 |
|
368 |
#define INTERRUPT_EXT (1 << 0) |
369 |
#define INTERRUPT_TOD (1 << 1) |
370 |
#define INTERRUPT_CPUTIMER (1 << 2) |
371 |
|
372 |
/* Program Status Word. */
|
373 |
#define S390_PSWM_REGNUM 0 |
374 |
#define S390_PSWA_REGNUM 1 |
375 |
/* General Purpose Registers. */
|
376 |
#define S390_R0_REGNUM 2 |
377 |
#define S390_R1_REGNUM 3 |
378 |
#define S390_R2_REGNUM 4 |
379 |
#define S390_R3_REGNUM 5 |
380 |
#define S390_R4_REGNUM 6 |
381 |
#define S390_R5_REGNUM 7 |
382 |
#define S390_R6_REGNUM 8 |
383 |
#define S390_R7_REGNUM 9 |
384 |
#define S390_R8_REGNUM 10 |
385 |
#define S390_R9_REGNUM 11 |
386 |
#define S390_R10_REGNUM 12 |
387 |
#define S390_R11_REGNUM 13 |
388 |
#define S390_R12_REGNUM 14 |
389 |
#define S390_R13_REGNUM 15 |
390 |
#define S390_R14_REGNUM 16 |
391 |
#define S390_R15_REGNUM 17 |
392 |
/* Access Registers. */
|
393 |
#define S390_A0_REGNUM 18 |
394 |
#define S390_A1_REGNUM 19 |
395 |
#define S390_A2_REGNUM 20 |
396 |
#define S390_A3_REGNUM 21 |
397 |
#define S390_A4_REGNUM 22 |
398 |
#define S390_A5_REGNUM 23 |
399 |
#define S390_A6_REGNUM 24 |
400 |
#define S390_A7_REGNUM 25 |
401 |
#define S390_A8_REGNUM 26 |
402 |
#define S390_A9_REGNUM 27 |
403 |
#define S390_A10_REGNUM 28 |
404 |
#define S390_A11_REGNUM 29 |
405 |
#define S390_A12_REGNUM 30 |
406 |
#define S390_A13_REGNUM 31 |
407 |
#define S390_A14_REGNUM 32 |
408 |
#define S390_A15_REGNUM 33 |
409 |
/* Floating Point Control Word. */
|
410 |
#define S390_FPC_REGNUM 34 |
411 |
/* Floating Point Registers. */
|
412 |
#define S390_F0_REGNUM 35 |
413 |
#define S390_F1_REGNUM 36 |
414 |
#define S390_F2_REGNUM 37 |
415 |
#define S390_F3_REGNUM 38 |
416 |
#define S390_F4_REGNUM 39 |
417 |
#define S390_F5_REGNUM 40 |
418 |
#define S390_F6_REGNUM 41 |
419 |
#define S390_F7_REGNUM 42 |
420 |
#define S390_F8_REGNUM 43 |
421 |
#define S390_F9_REGNUM 44 |
422 |
#define S390_F10_REGNUM 45 |
423 |
#define S390_F11_REGNUM 46 |
424 |
#define S390_F12_REGNUM 47 |
425 |
#define S390_F13_REGNUM 48 |
426 |
#define S390_F14_REGNUM 49 |
427 |
#define S390_F15_REGNUM 50 |
428 |
/* Total. */
|
429 |
#define S390_NUM_REGS 51 |
430 |
|
431 |
/* CC optimization */
|
432 |
|
433 |
enum cc_op {
|
434 |
CC_OP_CONST0 = 0, /* CC is 0 */ |
435 |
CC_OP_CONST1, /* CC is 1 */
|
436 |
CC_OP_CONST2, /* CC is 2 */
|
437 |
CC_OP_CONST3, /* CC is 3 */
|
438 |
|
439 |
CC_OP_DYNAMIC, /* CC calculation defined by env->cc_op */
|
440 |
CC_OP_STATIC, /* CC value is env->cc_op */
|
441 |
|
442 |
CC_OP_NZ, /* env->cc_dst != 0 */
|
443 |
CC_OP_LTGT_32, /* signed less/greater than (32bit) */
|
444 |
CC_OP_LTGT_64, /* signed less/greater than (64bit) */
|
445 |
CC_OP_LTUGTU_32, /* unsigned less/greater than (32bit) */
|
446 |
CC_OP_LTUGTU_64, /* unsigned less/greater than (64bit) */
|
447 |
CC_OP_LTGT0_32, /* signed less/greater than 0 (32bit) */
|
448 |
CC_OP_LTGT0_64, /* signed less/greater than 0 (64bit) */
|
449 |
|
450 |
CC_OP_ADD_64, /* overflow on add (64bit) */
|
451 |
CC_OP_ADDU_64, /* overflow on unsigned add (64bit) */
|
452 |
CC_OP_SUB_64, /* overflow on subtraction (64bit) */
|
453 |
CC_OP_SUBU_64, /* overflow on unsigned subtraction (64bit) */
|
454 |
CC_OP_ABS_64, /* sign eval on abs (64bit) */
|
455 |
CC_OP_NABS_64, /* sign eval on nabs (64bit) */
|
456 |
|
457 |
CC_OP_ADD_32, /* overflow on add (32bit) */
|
458 |
CC_OP_ADDU_32, /* overflow on unsigned add (32bit) */
|
459 |
CC_OP_SUB_32, /* overflow on subtraction (32bit) */
|
460 |
CC_OP_SUBU_32, /* overflow on unsigned subtraction (32bit) */
|
461 |
CC_OP_ABS_32, /* sign eval on abs (64bit) */
|
462 |
CC_OP_NABS_32, /* sign eval on nabs (64bit) */
|
463 |
|
464 |
CC_OP_COMP_32, /* complement */
|
465 |
CC_OP_COMP_64, /* complement */
|
466 |
|
467 |
CC_OP_TM_32, /* test under mask (32bit) */
|
468 |
CC_OP_TM_64, /* test under mask (64bit) */
|
469 |
|
470 |
CC_OP_LTGT_F32, /* FP compare (32bit) */
|
471 |
CC_OP_LTGT_F64, /* FP compare (64bit) */
|
472 |
|
473 |
CC_OP_NZ_F32, /* FP dst != 0 (32bit) */
|
474 |
CC_OP_NZ_F64, /* FP dst != 0 (64bit) */
|
475 |
|
476 |
CC_OP_ICM, /* insert characters under mask */
|
477 |
CC_OP_SLAG, /* Calculate shift left signed */
|
478 |
CC_OP_MAX |
479 |
}; |
480 |
|
481 |
static const char *cc_names[] = { |
482 |
[CC_OP_CONST0] = "CC_OP_CONST0",
|
483 |
[CC_OP_CONST1] = "CC_OP_CONST1",
|
484 |
[CC_OP_CONST2] = "CC_OP_CONST2",
|
485 |
[CC_OP_CONST3] = "CC_OP_CONST3",
|
486 |
[CC_OP_DYNAMIC] = "CC_OP_DYNAMIC",
|
487 |
[CC_OP_STATIC] = "CC_OP_STATIC",
|
488 |
[CC_OP_NZ] = "CC_OP_NZ",
|
489 |
[CC_OP_LTGT_32] = "CC_OP_LTGT_32",
|
490 |
[CC_OP_LTGT_64] = "CC_OP_LTGT_64",
|
491 |
[CC_OP_LTUGTU_32] = "CC_OP_LTUGTU_32",
|
492 |
[CC_OP_LTUGTU_64] = "CC_OP_LTUGTU_64",
|
493 |
[CC_OP_LTGT0_32] = "CC_OP_LTGT0_32",
|
494 |
[CC_OP_LTGT0_64] = "CC_OP_LTGT0_64",
|
495 |
[CC_OP_ADD_64] = "CC_OP_ADD_64",
|
496 |
[CC_OP_ADDU_64] = "CC_OP_ADDU_64",
|
497 |
[CC_OP_SUB_64] = "CC_OP_SUB_64",
|
498 |
[CC_OP_SUBU_64] = "CC_OP_SUBU_64",
|
499 |
[CC_OP_ABS_64] = "CC_OP_ABS_64",
|
500 |
[CC_OP_NABS_64] = "CC_OP_NABS_64",
|
501 |
[CC_OP_ADD_32] = "CC_OP_ADD_32",
|
502 |
[CC_OP_ADDU_32] = "CC_OP_ADDU_32",
|
503 |
[CC_OP_SUB_32] = "CC_OP_SUB_32",
|
504 |
[CC_OP_SUBU_32] = "CC_OP_SUBU_32",
|
505 |
[CC_OP_ABS_32] = "CC_OP_ABS_32",
|
506 |
[CC_OP_NABS_32] = "CC_OP_NABS_32",
|
507 |
[CC_OP_COMP_32] = "CC_OP_COMP_32",
|
508 |
[CC_OP_COMP_64] = "CC_OP_COMP_64",
|
509 |
[CC_OP_TM_32] = "CC_OP_TM_32",
|
510 |
[CC_OP_TM_64] = "CC_OP_TM_64",
|
511 |
[CC_OP_LTGT_F32] = "CC_OP_LTGT_F32",
|
512 |
[CC_OP_LTGT_F64] = "CC_OP_LTGT_F64",
|
513 |
[CC_OP_NZ_F32] = "CC_OP_NZ_F32",
|
514 |
[CC_OP_NZ_F64] = "CC_OP_NZ_F64",
|
515 |
[CC_OP_ICM] = "CC_OP_ICM",
|
516 |
[CC_OP_SLAG] = "CC_OP_SLAG",
|
517 |
}; |
518 |
|
519 |
static inline const char *cc_name(int cc_op) |
520 |
{ |
521 |
return cc_names[cc_op];
|
522 |
} |
523 |
|
524 |
typedef struct LowCore |
525 |
{ |
526 |
/* prefix area: defined by architecture */
|
527 |
uint32_t ccw1[2]; /* 0x000 */ |
528 |
uint32_t ccw2[4]; /* 0x008 */ |
529 |
uint8_t pad1[0x80-0x18]; /* 0x018 */ |
530 |
uint32_t ext_params; /* 0x080 */
|
531 |
uint16_t cpu_addr; /* 0x084 */
|
532 |
uint16_t ext_int_code; /* 0x086 */
|
533 |
uint16_t svc_ilen; /* 0x088 */
|
534 |
uint16_t svc_code; /* 0x08a */
|
535 |
uint16_t pgm_ilen; /* 0x08c */
|
536 |
uint16_t pgm_code; /* 0x08e */
|
537 |
uint32_t data_exc_code; /* 0x090 */
|
538 |
uint16_t mon_class_num; /* 0x094 */
|
539 |
uint16_t per_perc_atmid; /* 0x096 */
|
540 |
uint64_t per_address; /* 0x098 */
|
541 |
uint8_t exc_access_id; /* 0x0a0 */
|
542 |
uint8_t per_access_id; /* 0x0a1 */
|
543 |
uint8_t op_access_id; /* 0x0a2 */
|
544 |
uint8_t ar_access_id; /* 0x0a3 */
|
545 |
uint8_t pad2[0xA8-0xA4]; /* 0x0a4 */ |
546 |
uint64_t trans_exc_code; /* 0x0a8 */
|
547 |
uint64_t monitor_code; /* 0x0b0 */
|
548 |
uint16_t subchannel_id; /* 0x0b8 */
|
549 |
uint16_t subchannel_nr; /* 0x0ba */
|
550 |
uint32_t io_int_parm; /* 0x0bc */
|
551 |
uint32_t io_int_word; /* 0x0c0 */
|
552 |
uint8_t pad3[0xc8-0xc4]; /* 0x0c4 */ |
553 |
uint32_t stfl_fac_list; /* 0x0c8 */
|
554 |
uint8_t pad4[0xe8-0xcc]; /* 0x0cc */ |
555 |
uint32_t mcck_interruption_code[2]; /* 0x0e8 */ |
556 |
uint8_t pad5[0xf4-0xf0]; /* 0x0f0 */ |
557 |
uint32_t external_damage_code; /* 0x0f4 */
|
558 |
uint64_t failing_storage_address; /* 0x0f8 */
|
559 |
uint8_t pad6[0x120-0x100]; /* 0x100 */ |
560 |
PSW restart_old_psw; /* 0x120 */
|
561 |
PSW external_old_psw; /* 0x130 */
|
562 |
PSW svc_old_psw; /* 0x140 */
|
563 |
PSW program_old_psw; /* 0x150 */
|
564 |
PSW mcck_old_psw; /* 0x160 */
|
565 |
PSW io_old_psw; /* 0x170 */
|
566 |
uint8_t pad7[0x1a0-0x180]; /* 0x180 */ |
567 |
PSW restart_psw; /* 0x1a0 */
|
568 |
PSW external_new_psw; /* 0x1b0 */
|
569 |
PSW svc_new_psw; /* 0x1c0 */
|
570 |
PSW program_new_psw; /* 0x1d0 */
|
571 |
PSW mcck_new_psw; /* 0x1e0 */
|
572 |
PSW io_new_psw; /* 0x1f0 */
|
573 |
PSW return_psw; /* 0x200 */
|
574 |
uint8_t irb[64]; /* 0x210 */ |
575 |
uint64_t sync_enter_timer; /* 0x250 */
|
576 |
uint64_t async_enter_timer; /* 0x258 */
|
577 |
uint64_t exit_timer; /* 0x260 */
|
578 |
uint64_t last_update_timer; /* 0x268 */
|
579 |
uint64_t user_timer; /* 0x270 */
|
580 |
uint64_t system_timer; /* 0x278 */
|
581 |
uint64_t last_update_clock; /* 0x280 */
|
582 |
uint64_t steal_clock; /* 0x288 */
|
583 |
PSW return_mcck_psw; /* 0x290 */
|
584 |
uint8_t pad8[0xc00-0x2a0]; /* 0x2a0 */ |
585 |
/* System info area */
|
586 |
uint64_t save_area[16]; /* 0xc00 */ |
587 |
uint8_t pad9[0xd40-0xc80]; /* 0xc80 */ |
588 |
uint64_t kernel_stack; /* 0xd40 */
|
589 |
uint64_t thread_info; /* 0xd48 */
|
590 |
uint64_t async_stack; /* 0xd50 */
|
591 |
uint64_t kernel_asce; /* 0xd58 */
|
592 |
uint64_t user_asce; /* 0xd60 */
|
593 |
uint64_t panic_stack; /* 0xd68 */
|
594 |
uint64_t user_exec_asce; /* 0xd70 */
|
595 |
uint8_t pad10[0xdc0-0xd78]; /* 0xd78 */ |
596 |
|
597 |
/* SMP info area: defined by DJB */
|
598 |
uint64_t clock_comparator; /* 0xdc0 */
|
599 |
uint64_t ext_call_fast; /* 0xdc8 */
|
600 |
uint64_t percpu_offset; /* 0xdd0 */
|
601 |
uint64_t current_task; /* 0xdd8 */
|
602 |
uint32_t softirq_pending; /* 0xde0 */
|
603 |
uint32_t pad_0x0de4; /* 0xde4 */
|
604 |
uint64_t int_clock; /* 0xde8 */
|
605 |
uint8_t pad12[0xe00-0xdf0]; /* 0xdf0 */ |
606 |
|
607 |
/* 0xe00 is used as indicator for dump tools */
|
608 |
/* whether the kernel died with panic() or not */
|
609 |
uint32_t panic_magic; /* 0xe00 */
|
610 |
|
611 |
uint8_t pad13[0x11b8-0xe04]; /* 0xe04 */ |
612 |
|
613 |
/* 64 bit extparam used for pfault, diag 250 etc */
|
614 |
uint64_t ext_params2; /* 0x11B8 */
|
615 |
|
616 |
uint8_t pad14[0x1200-0x11C0]; /* 0x11C0 */ |
617 |
|
618 |
/* System info area */
|
619 |
|
620 |
uint64_t floating_pt_save_area[16]; /* 0x1200 */ |
621 |
uint64_t gpregs_save_area[16]; /* 0x1280 */ |
622 |
uint32_t st_status_fixed_logout[4]; /* 0x1300 */ |
623 |
uint8_t pad15[0x1318-0x1310]; /* 0x1310 */ |
624 |
uint32_t prefixreg_save_area; /* 0x1318 */
|
625 |
uint32_t fpt_creg_save_area; /* 0x131c */
|
626 |
uint8_t pad16[0x1324-0x1320]; /* 0x1320 */ |
627 |
uint32_t tod_progreg_save_area; /* 0x1324 */
|
628 |
uint32_t cpu_timer_save_area[2]; /* 0x1328 */ |
629 |
uint32_t clock_comp_save_area[2]; /* 0x1330 */ |
630 |
uint8_t pad17[0x1340-0x1338]; /* 0x1338 */ |
631 |
uint32_t access_regs_save_area[16]; /* 0x1340 */ |
632 |
uint64_t cregs_save_area[16]; /* 0x1380 */ |
633 |
|
634 |
/* align to the top of the prefix area */
|
635 |
|
636 |
uint8_t pad18[0x2000-0x1400]; /* 0x1400 */ |
637 |
} QEMU_PACKED LowCore; |
638 |
|
639 |
/* STSI */
|
640 |
#define STSI_LEVEL_MASK 0x00000000f0000000ULL |
641 |
#define STSI_LEVEL_CURRENT 0x0000000000000000ULL |
642 |
#define STSI_LEVEL_1 0x0000000010000000ULL |
643 |
#define STSI_LEVEL_2 0x0000000020000000ULL |
644 |
#define STSI_LEVEL_3 0x0000000030000000ULL |
645 |
#define STSI_R0_RESERVED_MASK 0x000000000fffff00ULL |
646 |
#define STSI_R0_SEL1_MASK 0x00000000000000ffULL |
647 |
#define STSI_R1_RESERVED_MASK 0x00000000ffff0000ULL |
648 |
#define STSI_R1_SEL2_MASK 0x000000000000ffffULL |
649 |
|
650 |
/* Basic Machine Configuration */
|
651 |
struct sysib_111 {
|
652 |
uint32_t res1[8];
|
653 |
uint8_t manuf[16];
|
654 |
uint8_t type[4];
|
655 |
uint8_t res2[12];
|
656 |
uint8_t model[16];
|
657 |
uint8_t sequence[16];
|
658 |
uint8_t plant[4];
|
659 |
uint8_t res3[156];
|
660 |
}; |
661 |
|
662 |
/* Basic Machine CPU */
|
663 |
struct sysib_121 {
|
664 |
uint32_t res1[80];
|
665 |
uint8_t sequence[16];
|
666 |
uint8_t plant[4];
|
667 |
uint8_t res2[2];
|
668 |
uint16_t cpu_addr; |
669 |
uint8_t res3[152];
|
670 |
}; |
671 |
|
672 |
/* Basic Machine CPUs */
|
673 |
struct sysib_122 {
|
674 |
uint8_t res1[32];
|
675 |
uint32_t capability; |
676 |
uint16_t total_cpus; |
677 |
uint16_t active_cpus; |
678 |
uint16_t standby_cpus; |
679 |
uint16_t reserved_cpus; |
680 |
uint16_t adjustments[2026];
|
681 |
}; |
682 |
|
683 |
/* LPAR CPU */
|
684 |
struct sysib_221 {
|
685 |
uint32_t res1[80];
|
686 |
uint8_t sequence[16];
|
687 |
uint8_t plant[4];
|
688 |
uint16_t cpu_id; |
689 |
uint16_t cpu_addr; |
690 |
uint8_t res3[152];
|
691 |
}; |
692 |
|
693 |
/* LPAR CPUs */
|
694 |
struct sysib_222 {
|
695 |
uint32_t res1[32];
|
696 |
uint16_t lpar_num; |
697 |
uint8_t res2; |
698 |
uint8_t lcpuc; |
699 |
uint16_t total_cpus; |
700 |
uint16_t conf_cpus; |
701 |
uint16_t standby_cpus; |
702 |
uint16_t reserved_cpus; |
703 |
uint8_t name[8];
|
704 |
uint32_t caf; |
705 |
uint8_t res3[16];
|
706 |
uint16_t dedicated_cpus; |
707 |
uint16_t shared_cpus; |
708 |
uint8_t res4[180];
|
709 |
}; |
710 |
|
711 |
/* VM CPUs */
|
712 |
struct sysib_322 {
|
713 |
uint8_t res1[31];
|
714 |
uint8_t count; |
715 |
struct {
|
716 |
uint8_t res2[4];
|
717 |
uint16_t total_cpus; |
718 |
uint16_t conf_cpus; |
719 |
uint16_t standby_cpus; |
720 |
uint16_t reserved_cpus; |
721 |
uint8_t name[8];
|
722 |
uint32_t caf; |
723 |
uint8_t cpi[16];
|
724 |
uint8_t res3[24];
|
725 |
} vm[8];
|
726 |
uint8_t res4[3552];
|
727 |
}; |
728 |
|
729 |
/* MMU defines */
|
730 |
#define _ASCE_ORIGIN ~0xfffULL /* segment table origin */ |
731 |
#define _ASCE_SUBSPACE 0x200 /* subspace group control */ |
732 |
#define _ASCE_PRIVATE_SPACE 0x100 /* private space control */ |
733 |
#define _ASCE_ALT_EVENT 0x80 /* storage alteration event control */ |
734 |
#define _ASCE_SPACE_SWITCH 0x40 /* space switch event */ |
735 |
#define _ASCE_REAL_SPACE 0x20 /* real space control */ |
736 |
#define _ASCE_TYPE_MASK 0x0c /* asce table type mask */ |
737 |
#define _ASCE_TYPE_REGION1 0x0c /* region first table type */ |
738 |
#define _ASCE_TYPE_REGION2 0x08 /* region second table type */ |
739 |
#define _ASCE_TYPE_REGION3 0x04 /* region third table type */ |
740 |
#define _ASCE_TYPE_SEGMENT 0x00 /* segment table type */ |
741 |
#define _ASCE_TABLE_LENGTH 0x03 /* region table length */ |
742 |
|
743 |
#define _REGION_ENTRY_ORIGIN ~0xfffULL /* region/segment table origin */ |
744 |
#define _REGION_ENTRY_INV 0x20 /* invalid region table entry */ |
745 |
#define _REGION_ENTRY_TYPE_MASK 0x0c /* region/segment table type mask */ |
746 |
#define _REGION_ENTRY_TYPE_R1 0x0c /* region first table type */ |
747 |
#define _REGION_ENTRY_TYPE_R2 0x08 /* region second table type */ |
748 |
#define _REGION_ENTRY_TYPE_R3 0x04 /* region third table type */ |
749 |
#define _REGION_ENTRY_LENGTH 0x03 /* region third length */ |
750 |
|
751 |
#define _SEGMENT_ENTRY_ORIGIN ~0x7ffULL /* segment table origin */ |
752 |
#define _SEGMENT_ENTRY_RO 0x200 /* page protection bit */ |
753 |
#define _SEGMENT_ENTRY_INV 0x20 /* invalid segment table entry */ |
754 |
|
755 |
#define _PAGE_RO 0x200 /* HW read-only bit */ |
756 |
#define _PAGE_INVALID 0x400 /* HW invalid bit */ |
757 |
|
758 |
#define SK_C (0x1 << 1) |
759 |
#define SK_R (0x1 << 2) |
760 |
#define SK_F (0x1 << 3) |
761 |
#define SK_ACC_MASK (0xf << 4) |
762 |
|
763 |
|
764 |
/* EBCDIC handling */
|
765 |
static const uint8_t ebcdic2ascii[] = { |
766 |
0x00, 0x01, 0x02, 0x03, 0x07, 0x09, 0x07, 0x7F, |
767 |
0x07, 0x07, 0x07, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, |
768 |
0x10, 0x11, 0x12, 0x13, 0x07, 0x0A, 0x08, 0x07, |
769 |
0x18, 0x19, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, |
770 |
0x07, 0x07, 0x1C, 0x07, 0x07, 0x0A, 0x17, 0x1B, |
771 |
0x07, 0x07, 0x07, 0x07, 0x07, 0x05, 0x06, 0x07, |
772 |
0x07, 0x07, 0x16, 0x07, 0x07, 0x07, 0x07, 0x04, |
773 |
0x07, 0x07, 0x07, 0x07, 0x14, 0x15, 0x07, 0x1A, |
774 |
0x20, 0xFF, 0x83, 0x84, 0x85, 0xA0, 0x07, 0x86, |
775 |
0x87, 0xA4, 0x5B, 0x2E, 0x3C, 0x28, 0x2B, 0x21, |
776 |
0x26, 0x82, 0x88, 0x89, 0x8A, 0xA1, 0x8C, 0x07, |
777 |
0x8D, 0xE1, 0x5D, 0x24, 0x2A, 0x29, 0x3B, 0x5E, |
778 |
0x2D, 0x2F, 0x07, 0x8E, 0x07, 0x07, 0x07, 0x8F, |
779 |
0x80, 0xA5, 0x07, 0x2C, 0x25, 0x5F, 0x3E, 0x3F, |
780 |
0x07, 0x90, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, |
781 |
0x70, 0x60, 0x3A, 0x23, 0x40, 0x27, 0x3D, 0x22, |
782 |
0x07, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, |
783 |
0x68, 0x69, 0xAE, 0xAF, 0x07, 0x07, 0x07, 0xF1, |
784 |
0xF8, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, |
785 |
0x71, 0x72, 0xA6, 0xA7, 0x91, 0x07, 0x92, 0x07, |
786 |
0xE6, 0x7E, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, |
787 |
0x79, 0x7A, 0xAD, 0xAB, 0x07, 0x07, 0x07, 0x07, |
788 |
0x9B, 0x9C, 0x9D, 0xFA, 0x07, 0x07, 0x07, 0xAC, |
789 |
0xAB, 0x07, 0xAA, 0x7C, 0x07, 0x07, 0x07, 0x07, |
790 |
0x7B, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, |
791 |
0x48, 0x49, 0x07, 0x93, 0x94, 0x95, 0xA2, 0x07, |
792 |
0x7D, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, |
793 |
0x51, 0x52, 0x07, 0x96, 0x81, 0x97, 0xA3, 0x98, |
794 |
0x5C, 0xF6, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, |
795 |
0x59, 0x5A, 0xFD, 0x07, 0x99, 0x07, 0x07, 0x07, |
796 |
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, |
797 |
0x38, 0x39, 0x07, 0x07, 0x9A, 0x07, 0x07, 0x07, |
798 |
}; |
799 |
|
800 |
static const uint8_t ascii2ebcdic [] = { |
801 |
0x00, 0x01, 0x02, 0x03, 0x37, 0x2D, 0x2E, 0x2F, |
802 |
0x16, 0x05, 0x15, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, |
803 |
0x10, 0x11, 0x12, 0x13, 0x3C, 0x3D, 0x32, 0x26, |
804 |
0x18, 0x19, 0x3F, 0x27, 0x22, 0x1D, 0x1E, 0x1F, |
805 |
0x40, 0x5A, 0x7F, 0x7B, 0x5B, 0x6C, 0x50, 0x7D, |
806 |
0x4D, 0x5D, 0x5C, 0x4E, 0x6B, 0x60, 0x4B, 0x61, |
807 |
0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, |
808 |
0xF8, 0xF9, 0x7A, 0x5E, 0x4C, 0x7E, 0x6E, 0x6F, |
809 |
0x7C, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, |
810 |
0xC8, 0xC9, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, |
811 |
0xD7, 0xD8, 0xD9, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, |
812 |
0xE7, 0xE8, 0xE9, 0xBA, 0xE0, 0xBB, 0xB0, 0x6D, |
813 |
0x79, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, |
814 |
0x88, 0x89, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, |
815 |
0x97, 0x98, 0x99, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, |
816 |
0xA7, 0xA8, 0xA9, 0xC0, 0x4F, 0xD0, 0xA1, 0x07, |
817 |
0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, |
818 |
0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, |
819 |
0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, |
820 |
0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, |
821 |
0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, |
822 |
0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, |
823 |
0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, |
824 |
0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, |
825 |
0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, |
826 |
0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, |
827 |
0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, |
828 |
0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, |
829 |
0x3F, 0x59, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, |
830 |
0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, |
831 |
0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, |
832 |
0x90, 0x3F, 0x3F, 0x3F, 0x3F, 0xEA, 0x3F, 0xFF |
833 |
}; |
834 |
|
835 |
static inline void ebcdic_put(uint8_t *p, const char *ascii, int len) |
836 |
{ |
837 |
int i;
|
838 |
|
839 |
for (i = 0; i < len; i++) { |
840 |
p[i] = ascii2ebcdic[(int)ascii[i]];
|
841 |
} |
842 |
} |
843 |
|
844 |
#define SIGP_SENSE 0x01 |
845 |
#define SIGP_EXTERNAL_CALL 0x02 |
846 |
#define SIGP_EMERGENCY 0x03 |
847 |
#define SIGP_START 0x04 |
848 |
#define SIGP_STOP 0x05 |
849 |
#define SIGP_RESTART 0x06 |
850 |
#define SIGP_STOP_STORE_STATUS 0x09 |
851 |
#define SIGP_INITIAL_CPU_RESET 0x0b |
852 |
#define SIGP_CPU_RESET 0x0c |
853 |
#define SIGP_SET_PREFIX 0x0d |
854 |
#define SIGP_STORE_STATUS_ADDR 0x0e |
855 |
#define SIGP_SET_ARCH 0x12 |
856 |
|
857 |
/* cpu status bits */
|
858 |
#define SIGP_STAT_EQUIPMENT_CHECK 0x80000000UL |
859 |
#define SIGP_STAT_INCORRECT_STATE 0x00000200UL |
860 |
#define SIGP_STAT_INVALID_PARAMETER 0x00000100UL |
861 |
#define SIGP_STAT_EXT_CALL_PENDING 0x00000080UL |
862 |
#define SIGP_STAT_STOPPED 0x00000040UL |
863 |
#define SIGP_STAT_OPERATOR_INTERV 0x00000020UL |
864 |
#define SIGP_STAT_CHECK_STOP 0x00000010UL |
865 |
#define SIGP_STAT_INOPERATIVE 0x00000004UL |
866 |
#define SIGP_STAT_INVALID_ORDER 0x00000002UL |
867 |
#define SIGP_STAT_RECEIVER_CHECK 0x00000001UL |
868 |
|
869 |
void load_psw(CPUS390XState *env, uint64_t mask, uint64_t addr);
|
870 |
int mmu_translate(CPUS390XState *env, target_ulong vaddr, int rw, uint64_t asc, |
871 |
target_ulong *raddr, int *flags);
|
872 |
int sclp_service_call(uint32_t sccb, uint64_t code);
|
873 |
uint32_t calc_cc(CPUS390XState *env, uint32_t cc_op, uint64_t src, uint64_t dst, |
874 |
uint64_t vr); |
875 |
|
876 |
#define TARGET_HAS_ICE 1 |
877 |
|
878 |
/* The value of the TOD clock for 1.1.1970. */
|
879 |
#define TOD_UNIX_EPOCH 0x7d91048bca000000ULL |
880 |
|
881 |
/* Converts ns to s390's clock format */
|
882 |
static inline uint64_t time2tod(uint64_t ns) { |
883 |
return (ns << 9) / 125; |
884 |
} |
885 |
|
886 |
static inline void cpu_inject_ext(CPUS390XState *env, uint32_t code, uint32_t param, |
887 |
uint64_t param64) |
888 |
{ |
889 |
if (env->ext_index == MAX_EXT_QUEUE - 1) { |
890 |
/* ugh - can't queue anymore. Let's drop. */
|
891 |
return;
|
892 |
} |
893 |
|
894 |
env->ext_index++; |
895 |
assert(env->ext_index < MAX_EXT_QUEUE); |
896 |
|
897 |
env->ext_queue[env->ext_index].code = code; |
898 |
env->ext_queue[env->ext_index].param = param; |
899 |
env->ext_queue[env->ext_index].param64 = param64; |
900 |
|
901 |
env->pending_int |= INTERRUPT_EXT; |
902 |
cpu_interrupt(env, CPU_INTERRUPT_HARD); |
903 |
} |
904 |
|
905 |
static inline bool cpu_has_work(CPUState *cpu) |
906 |
{ |
907 |
CPUS390XState *env = &S390_CPU(cpu)->env; |
908 |
|
909 |
return (env->interrupt_request & CPU_INTERRUPT_HARD) &&
|
910 |
(env->psw.mask & PSW_MASK_EXT); |
911 |
} |
912 |
|
913 |
static inline void cpu_pc_from_tb(CPUS390XState *env, TranslationBlock* tb) |
914 |
{ |
915 |
env->psw.addr = tb->pc; |
916 |
} |
917 |
|
918 |
/* fpu_helper.c */
|
919 |
uint32_t set_cc_f32(CPUS390XState *env, float32 v1, float32 v2); |
920 |
uint32_t set_cc_f64(CPUS390XState *env, float64 v1, float64 v2); |
921 |
uint32_t set_cc_nz_f32(float32 v); |
922 |
uint32_t set_cc_nz_f64(float64 v); |
923 |
|
924 |
/* misc_helper.c */
|
925 |
void program_interrupt(CPUS390XState *env, uint32_t code, int ilen); |
926 |
|
927 |
#endif
|