1
2
3
4
5
6
7
8
9
10#ifndef S390X_INTERNAL_H
11#define S390X_INTERNAL_H
12
13#include "cpu.h"
14#include "fpu/softfloat.h"
15
16#ifndef CONFIG_USER_ONLY
17typedef struct LowCore {
18
19 uint32_t ccw1[2];
20 uint32_t ccw2[4];
21 uint8_t pad1[0x80 - 0x18];
22 uint32_t ext_params;
23 uint16_t cpu_addr;
24 uint16_t ext_int_code;
25 uint16_t svc_ilen;
26 uint16_t svc_code;
27 uint16_t pgm_ilen;
28 uint16_t pgm_code;
29 uint32_t data_exc_code;
30 uint16_t mon_class_num;
31 uint16_t per_perc_atmid;
32 uint64_t per_address;
33 uint8_t exc_access_id;
34 uint8_t per_access_id;
35 uint8_t op_access_id;
36 uint8_t ar_access_id;
37 uint8_t pad2[0xA8 - 0xA4];
38 uint64_t trans_exc_code;
39 uint64_t monitor_code;
40 uint16_t subchannel_id;
41 uint16_t subchannel_nr;
42 uint32_t io_int_parm;
43 uint32_t io_int_word;
44 uint8_t pad3[0xc8 - 0xc4];
45 uint32_t stfl_fac_list;
46 uint8_t pad4[0xe8 - 0xcc];
47 uint64_t mcic;
48 uint8_t pad5[0xf4 - 0xf0];
49 uint32_t external_damage_code;
50 uint64_t failing_storage_address;
51 uint8_t pad6[0x110 - 0x100];
52 uint64_t per_breaking_event_addr;
53 uint8_t pad7[0x120 - 0x118];
54 PSW restart_old_psw;
55 PSW external_old_psw;
56 PSW svc_old_psw;
57 PSW program_old_psw;
58 PSW mcck_old_psw;
59 PSW io_old_psw;
60 uint8_t pad8[0x1a0 - 0x180];
61 PSW restart_new_psw;
62 PSW external_new_psw;
63 PSW svc_new_psw;
64 PSW program_new_psw;
65 PSW mcck_new_psw;
66 PSW io_new_psw;
67 uint8_t pad13[0x11b0 - 0x200];
68
69 uint64_t mcesad;
70
71
72 uint64_t ext_params2;
73
74 uint8_t pad14[0x1200 - 0x11C0];
75
76
77
78 uint64_t floating_pt_save_area[16];
79 uint64_t gpregs_save_area[16];
80 uint32_t st_status_fixed_logout[4];
81 uint8_t pad15[0x1318 - 0x1310];
82 uint32_t prefixreg_save_area;
83 uint32_t fpt_creg_save_area;
84 uint8_t pad16[0x1324 - 0x1320];
85 uint32_t tod_progreg_save_area;
86 uint64_t cpu_timer_save_area;
87 uint64_t clock_comp_save_area;
88 uint8_t pad17[0x1340 - 0x1338];
89 uint32_t access_regs_save_area[16];
90 uint64_t cregs_save_area[16];
91
92
93
94 uint8_t pad18[0x2000 - 0x1400];
95} QEMU_PACKED LowCore;
96QEMU_BUILD_BUG_ON(sizeof(LowCore) != 8192);
97#endif
98
99#define MAX_ILEN 6
100
101
102
103
104
105
106static inline int get_ilen(uint8_t opc)
107{
108 switch (opc >> 6) {
109 case 0:
110 return 2;
111 case 1:
112 case 2:
113 return 4;
114 default:
115 return 6;
116 }
117}
118
119
120
121static inline uint8_t get_per_atmid(CPUS390XState *env)
122{
123 return ((env->psw.mask & PSW_MASK_64) ? (1 << 7) : 0) |
124 (1 << 6) |
125 ((env->psw.mask & PSW_MASK_32) ? (1 << 5) : 0) |
126 ((env->psw.mask & PSW_MASK_DAT) ? (1 << 4) : 0) |
127 ((env->psw.mask & PSW_ASC_SECONDARY) ? (1 << 3) : 0) |
128 ((env->psw.mask & PSW_ASC_ACCREG) ? (1 << 2) : 0);
129}
130
131static inline uint64_t wrap_address(CPUS390XState *env, uint64_t a)
132{
133 if (!(env->psw.mask & PSW_MASK_64)) {
134 if (!(env->psw.mask & PSW_MASK_32)) {
135
136 a &= 0x00ffffff;
137 } else {
138
139 a &= 0x7fffffff;
140 }
141 }
142 return a;
143}
144
145
146
147
148
149
150
151
152
153
154enum cc_op {
155 CC_OP_CONST0 = 0,
156 CC_OP_CONST1,
157 CC_OP_CONST2,
158 CC_OP_CONST3,
159
160 CC_OP_DYNAMIC,
161 CC_OP_STATIC,
162
163 CC_OP_NZ,
164 CC_OP_ADDU,
165 CC_OP_SUBU,
166
167 CC_OP_LTGT_32,
168 CC_OP_LTGT_64,
169 CC_OP_LTUGTU_32,
170 CC_OP_LTUGTU_64,
171 CC_OP_LTGT0_32,
172 CC_OP_LTGT0_64,
173
174 CC_OP_ADD_64,
175 CC_OP_SUB_64,
176 CC_OP_ABS_64,
177 CC_OP_NABS_64,
178 CC_OP_MULS_64,
179
180 CC_OP_ADD_32,
181 CC_OP_SUB_32,
182 CC_OP_ABS_32,
183 CC_OP_NABS_32,
184 CC_OP_MULS_32,
185
186 CC_OP_COMP_32,
187 CC_OP_COMP_64,
188
189 CC_OP_TM_32,
190 CC_OP_TM_64,
191
192 CC_OP_NZ_F32,
193 CC_OP_NZ_F64,
194 CC_OP_NZ_F128,
195
196 CC_OP_ICM,
197 CC_OP_SLA,
198 CC_OP_FLOGR,
199 CC_OP_LCBB,
200 CC_OP_VC,
201 CC_OP_MAX
202};
203
204#ifndef CONFIG_USER_ONLY
205
206static inline hwaddr decode_basedisp_s(CPUS390XState *env, uint32_t ipb,
207 uint8_t *ar)
208{
209 hwaddr addr = 0;
210 uint8_t reg;
211
212 reg = ipb >> 28;
213 if (reg > 0) {
214 addr = env->regs[reg];
215 }
216 addr += (ipb >> 16) & 0xfff;
217 if (ar) {
218 *ar = reg;
219 }
220
221 return addr;
222}
223
224
225#define decode_basedisp_rs decode_basedisp_s
226
227#endif
228
229
230int s390_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cs,
231 int cpuid, DumpState *s);
232
233
234
235const char *cc_name(enum cc_op cc_op);
236uint32_t calc_cc(CPUS390XState *env, uint32_t cc_op, uint64_t src, uint64_t dst,
237 uint64_t vr);
238
239
240#ifndef CONFIG_USER_ONLY
241unsigned int s390_cpu_halt(S390CPU *cpu);
242void s390_cpu_unhalt(S390CPU *cpu);
243void s390_cpu_init_sysemu(Object *obj);
244bool s390_cpu_realize_sysemu(DeviceState *dev, Error **errp);
245void s390_cpu_finalize(Object *obj);
246void s390_cpu_class_init_sysemu(CPUClass *cc);
247void s390_cpu_machine_reset_cb(void *opaque);
248
249#else
250static inline unsigned int s390_cpu_halt(S390CPU *cpu)
251{
252 return 0;
253}
254
255static inline void s390_cpu_unhalt(S390CPU *cpu)
256{
257}
258#endif
259
260
261
262void s390_cpu_model_class_register_props(ObjectClass *oc);
263void s390_realize_cpu_model(CPUState *cs, Error **errp);
264S390CPUModel *get_max_cpu_model(Error **errp);
265void apply_cpu_model(const S390CPUModel *model, Error **errp);
266ObjectClass *s390_cpu_class_by_name(const char *name);
267
268
269
270void s390x_cpu_debug_excp_handler(CPUState *cs);
271void s390_cpu_do_interrupt(CPUState *cpu);
272bool s390_cpu_exec_interrupt(CPUState *cpu, int int_req);
273
274#ifdef CONFIG_USER_ONLY
275void s390_cpu_record_sigsegv(CPUState *cs, vaddr address,
276 MMUAccessType access_type,
277 bool maperr, uintptr_t retaddr);
278void s390_cpu_record_sigbus(CPUState *cs, vaddr address,
279 MMUAccessType access_type, uintptr_t retaddr);
280#else
281bool s390_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
282 MMUAccessType access_type, int mmu_idx,
283 bool probe, uintptr_t retaddr);
284G_NORETURN void s390x_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
285 MMUAccessType access_type, int mmu_idx,
286 uintptr_t retaddr);
287#endif
288
289
290
291uint32_t set_cc_nz_f32(float32 v);
292uint32_t set_cc_nz_f64(float64 v);
293uint32_t set_cc_nz_f128(float128 v);
294#define S390_IEEE_MASK_INVALID 0x80
295#define S390_IEEE_MASK_DIVBYZERO 0x40
296#define S390_IEEE_MASK_OVERFLOW 0x20
297#define S390_IEEE_MASK_UNDERFLOW 0x10
298#define S390_IEEE_MASK_INEXACT 0x08
299#define S390_IEEE_MASK_QUANTUM 0x04
300uint8_t s390_softfloat_exc_to_ieee(unsigned int exc);
301int s390_swap_bfp_rounding_mode(CPUS390XState *env, int m3);
302void s390_restore_bfp_rounding_mode(CPUS390XState *env, int old_mode);
303int float_comp_to_cc(CPUS390XState *env, FloatRelation float_compare);
304
305#define DCMASK_ZERO 0x0c00
306#define DCMASK_NORMAL 0x0300
307#define DCMASK_SUBNORMAL 0x00c0
308#define DCMASK_INFINITY 0x0030
309#define DCMASK_QUIET_NAN 0x000c
310#define DCMASK_SIGNALING_NAN 0x0003
311#define DCMASK_NAN 0x000f
312#define DCMASK_NEGATIVE 0x0555
313uint16_t float32_dcmask(CPUS390XState *env, float32 f1);
314uint16_t float64_dcmask(CPUS390XState *env, float64 f1);
315uint16_t float128_dcmask(CPUS390XState *env, float128 f1);
316
317
318
319int s390_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
320int s390_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
321void s390_cpu_gdb_init(CPUState *cs);
322
323
324
325void s390_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
326void do_restart_interrupt(CPUS390XState *env);
327#ifndef CONFIG_USER_ONLY
328void s390_cpu_recompute_watchpoints(CPUState *cs);
329void s390x_tod_timer(void *opaque);
330void s390x_cpu_timer(void *opaque);
331void s390_handle_wait(S390CPU *cpu);
332hwaddr s390_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
333hwaddr s390_cpu_get_phys_addr_debug(CPUState *cpu, vaddr addr);
334#define S390_STORE_STATUS_DEF_ADDR offsetof(LowCore, floating_pt_save_area)
335int s390_store_status(S390CPU *cpu, hwaddr addr, bool store_arch);
336int s390_store_adtl_status(S390CPU *cpu, hwaddr addr, hwaddr len);
337LowCore *cpu_map_lowcore(CPUS390XState *env);
338void cpu_unmap_lowcore(LowCore *lowcore);
339#endif
340
341
342
343void trigger_pgm_exception(CPUS390XState *env, uint32_t code);
344void cpu_inject_clock_comparator(S390CPU *cpu);
345void cpu_inject_cpu_timer(S390CPU *cpu);
346void cpu_inject_emergency_signal(S390CPU *cpu, uint16_t src_cpu_addr);
347int cpu_inject_external_call(S390CPU *cpu, uint16_t src_cpu_addr);
348bool s390_cpu_has_io_int(S390CPU *cpu);
349bool s390_cpu_has_ext_int(S390CPU *cpu);
350bool s390_cpu_has_mcck_int(S390CPU *cpu);
351bool s390_cpu_has_int(S390CPU *cpu);
352bool s390_cpu_has_restart_int(S390CPU *cpu);
353bool s390_cpu_has_stop_int(S390CPU *cpu);
354void cpu_inject_restart(S390CPU *cpu);
355void cpu_inject_stop(S390CPU *cpu);
356
357
358
359void ioinst_handle_xsch(S390CPU *cpu, uint64_t reg1, uintptr_t ra);
360void ioinst_handle_csch(S390CPU *cpu, uint64_t reg1, uintptr_t ra);
361void ioinst_handle_hsch(S390CPU *cpu, uint64_t reg1, uintptr_t ra);
362void ioinst_handle_msch(S390CPU *cpu, uint64_t reg1, uint32_t ipb,
363 uintptr_t ra);
364void ioinst_handle_ssch(S390CPU *cpu, uint64_t reg1, uint32_t ipb,
365 uintptr_t ra);
366void ioinst_handle_stcrw(S390CPU *cpu, uint32_t ipb, uintptr_t ra);
367void ioinst_handle_stsch(S390CPU *cpu, uint64_t reg1, uint32_t ipb,
368 uintptr_t ra);
369int ioinst_handle_tsch(S390CPU *cpu, uint64_t reg1, uint32_t ipb, uintptr_t ra);
370void ioinst_handle_chsc(S390CPU *cpu, uint32_t ipb, uintptr_t ra);
371void ioinst_handle_schm(S390CPU *cpu, uint64_t reg1, uint64_t reg2,
372 uint32_t ipb, uintptr_t ra);
373void ioinst_handle_rsch(S390CPU *cpu, uint64_t reg1, uintptr_t ra);
374void ioinst_handle_rchp(S390CPU *cpu, uint64_t reg1, uintptr_t ra);
375void ioinst_handle_sal(S390CPU *cpu, uint64_t reg1, uintptr_t ra);
376
377
378
379target_ulong mmu_real2abs(CPUS390XState *env, target_ulong raddr);
380void probe_write_access(CPUS390XState *env, uint64_t addr, uint64_t len,
381 uintptr_t ra);
382
383
384
385bool mmu_absolute_addr_valid(target_ulong addr, bool is_write);
386
387#define MMU_S390_LRA -1
388int mmu_translate(CPUS390XState *env, target_ulong vaddr, int rw, uint64_t asc,
389 target_ulong *raddr, int *flags, uint64_t *tec);
390int mmu_translate_real(CPUS390XState *env, target_ulong raddr, int rw,
391 target_ulong *addr, int *flags, uint64_t *tec);
392
393
394
395int handle_diag_288(CPUS390XState *env, uint64_t r1, uint64_t r3);
396void handle_diag_308(CPUS390XState *env, uint64_t r1, uint64_t r3,
397 uintptr_t ra);
398
399
400
401void s390x_translate_init(void);
402void s390x_restore_state_to_opc(CPUState *cs,
403 const TranslationBlock *tb,
404 const uint64_t *data);
405
406
407int handle_sigp(CPUS390XState *env, uint8_t order, uint64_t r1, uint64_t r3);
408void do_stop_interrupt(CPUS390XState *env);
409
410#endif
411