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