xref: /openbmc/qemu/target/s390x/s390x-internal.h (revision 3adbf0bb8a78f17a1e9390b59e51eb1a47d8ac98)
1 /*
2  * s390x internal definitions and helpers
3  *
4  * Copyright (c) 2009 Ulrich Hecht
5  *
6  * This work is licensed under the terms of the GNU GPL, version 2 or later.
7  * See the COPYING file in the top-level directory.
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
17 typedef struct LowCore {
18     /* prefix area: defined by architecture */
19     uint32_t        ccw1[2];                  /* 0x000 */
20     uint32_t        ccw2[4];                  /* 0x008 */
21     uint8_t         pad1[0x80 - 0x18];        /* 0x018 */
22     uint32_t        ext_params;               /* 0x080 */
23     uint16_t        cpu_addr;                 /* 0x084 */
24     uint16_t        ext_int_code;             /* 0x086 */
25     uint16_t        svc_ilen;                 /* 0x088 */
26     uint16_t        svc_code;                 /* 0x08a */
27     uint16_t        pgm_ilen;                 /* 0x08c */
28     uint16_t        pgm_code;                 /* 0x08e */
29     uint32_t        data_exc_code;            /* 0x090 */
30     uint16_t        mon_class_num;            /* 0x094 */
31     uint16_t        per_perc_atmid;           /* 0x096 */
32     uint64_t        per_address;              /* 0x098 */
33     uint8_t         exc_access_id;            /* 0x0a0 */
34     uint8_t         per_access_id;            /* 0x0a1 */
35     uint8_t         op_access_id;             /* 0x0a2 */
36     uint8_t         ar_access_id;             /* 0x0a3 */
37     uint8_t         pad2[0xA8 - 0xA4];        /* 0x0a4 */
38     uint64_t        trans_exc_code;           /* 0x0a8 */
39     uint64_t        monitor_code;             /* 0x0b0 */
40     uint16_t        subchannel_id;            /* 0x0b8 */
41     uint16_t        subchannel_nr;            /* 0x0ba */
42     uint32_t        io_int_parm;              /* 0x0bc */
43     uint32_t        io_int_word;              /* 0x0c0 */
44     uint8_t         pad3[0xc8 - 0xc4];        /* 0x0c4 */
45     uint32_t        stfl_fac_list;            /* 0x0c8 */
46     uint8_t         pad4[0xe8 - 0xcc];        /* 0x0cc */
47     uint64_t        mcic;                     /* 0x0e8 */
48     uint8_t         pad5[0xf4 - 0xf0];        /* 0x0f0 */
49     uint32_t        external_damage_code;     /* 0x0f4 */
50     uint64_t        failing_storage_address;  /* 0x0f8 */
51     uint8_t         pad6[0x110 - 0x100];      /* 0x100 */
52     uint64_t        per_breaking_event_addr;  /* 0x110 */
53     uint8_t         pad7[0x120 - 0x118];      /* 0x118 */
54     PSW             restart_old_psw;          /* 0x120 */
55     PSW             external_old_psw;         /* 0x130 */
56     PSW             svc_old_psw;              /* 0x140 */
57     PSW             program_old_psw;          /* 0x150 */
58     PSW             mcck_old_psw;             /* 0x160 */
59     PSW             io_old_psw;               /* 0x170 */
60     uint8_t         pad8[0x1a0 - 0x180];      /* 0x180 */
61     PSW             restart_new_psw;          /* 0x1a0 */
62     PSW             external_new_psw;         /* 0x1b0 */
63     PSW             svc_new_psw;              /* 0x1c0 */
64     PSW             program_new_psw;          /* 0x1d0 */
65     PSW             mcck_new_psw;             /* 0x1e0 */
66     PSW             io_new_psw;               /* 0x1f0 */
67     uint8_t         pad13[0x11b0 - 0x200];    /* 0x200 */
68 
69     uint64_t        mcesad;                    /* 0x11B0 */
70 
71     /* 64 bit extparam used for pfault, diag 250 etc  */
72     uint64_t        ext_params2;               /* 0x11B8 */
73 
74     uint8_t         pad14[0x1200 - 0x11C0];    /* 0x11C0 */
75 
76     /* System info area */
77 
78     uint64_t        floating_pt_save_area[16]; /* 0x1200 */
79     uint64_t        gpregs_save_area[16];      /* 0x1280 */
80     uint32_t        st_status_fixed_logout[4]; /* 0x1300 */
81     uint8_t         pad15[0x1318 - 0x1310];    /* 0x1310 */
82     uint32_t        prefixreg_save_area;       /* 0x1318 */
83     uint32_t        fpt_creg_save_area;        /* 0x131c */
84     uint8_t         pad16[0x1324 - 0x1320];    /* 0x1320 */
85     uint32_t        tod_progreg_save_area;     /* 0x1324 */
86     uint64_t        cpu_timer_save_area;       /* 0x1328 */
87     uint64_t        clock_comp_save_area;      /* 0x1330 */
88     uint8_t         pad17[0x1340 - 0x1338];    /* 0x1338 */
89     uint32_t        access_regs_save_area[16]; /* 0x1340 */
90     uint64_t        cregs_save_area[16];       /* 0x1380 */
91 
92     /* align to the top of the prefix area */
93 
94     uint8_t         pad18[0x2000 - 0x1400];    /* 0x1400 */
95 } QEMU_PACKED LowCore;
96 QEMU_BUILD_BUG_ON(sizeof(LowCore) != 8192);
97 #endif /* CONFIG_USER_ONLY */
98 
99 #define MAX_ILEN 6
100 
101 /* While the PoO talks about ILC (a number between 1-3) what is actually
102    stored in LowCore is shifted left one bit (an even between 2-6).  As
103    this is the actual length of the insn and therefore more useful, that
104    is what we want to pass around and manipulate.  To make sure that we
105    have applied this distinction universally, rename the "ILC" to "ILEN".  */
get_ilen(uint8_t opc)106 static 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 /* Compute the ATMID field that is stored in the per_perc_atmid lowcore
120    entry when a PER exception is triggered.  */
get_per_atmid(CPUS390XState * env)121 static 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 
wrap_address(CPUS390XState * env,uint64_t a)131 static 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             /* 24-Bit mode */
136             a &= 0x00ffffff;
137         } else {
138             /* 31-Bit mode */
139             a &= 0x7fffffff;
140         }
141     }
142     return a;
143 }
144 
145 /* CC optimization */
146 
147 /* Instead of computing the condition codes after each x86 instruction,
148  * QEMU just stores the result (called CC_DST), the type of operation
149  * (called CC_OP) and whatever operands are needed (CC_SRC and possibly
150  * CC_VR). When the condition codes are needed, the condition codes can
151  * be calculated using this information. Condition codes are not generated
152  * if they are only needed for conditional branches.
153  */
154 enum cc_op {
155     CC_OP_CONST0 = 0,           /* CC is 0 */
156     CC_OP_CONST1,               /* CC is 1 */
157     CC_OP_CONST2,               /* CC is 2 */
158     CC_OP_CONST3,               /* CC is 3 */
159 
160     CC_OP_DYNAMIC,              /* CC calculation defined by env->cc_op */
161     CC_OP_STATIC,               /* CC value is env->cc_op */
162 
163     CC_OP_NZ,                   /* env->cc_dst != 0 */
164     CC_OP_ADDU,                 /* dst != 0, src = carry out (0,1) */
165     CC_OP_SUBU,                 /* dst != 0, src = borrow out (0,-1) */
166 
167     CC_OP_LTGT_32,              /* signed less/greater than (32bit) */
168     CC_OP_LTGT_64,              /* signed less/greater than (64bit) */
169     CC_OP_LTUGTU_32,            /* unsigned less/greater than (32bit) */
170     CC_OP_LTUGTU_64,            /* unsigned less/greater than (64bit) */
171     CC_OP_LTGT0_32,             /* signed less/greater than 0 (32bit) */
172     CC_OP_LTGT0_64,             /* signed less/greater than 0 (64bit) */
173 
174     CC_OP_ADD_64,               /* overflow on add (64bit) */
175     CC_OP_SUB_64,               /* overflow on subtraction (64bit) */
176     CC_OP_ABS_64,               /* sign eval on abs (64bit) */
177     CC_OP_NABS_64,              /* sign eval on nabs (64bit) */
178     CC_OP_MULS_64,              /* overflow on signed multiply (64bit) */
179 
180     CC_OP_ADD_32,               /* overflow on add (32bit) */
181     CC_OP_SUB_32,               /* overflow on subtraction (32bit) */
182     CC_OP_ABS_32,               /* sign eval on abs (64bit) */
183     CC_OP_NABS_32,              /* sign eval on nabs (64bit) */
184     CC_OP_MULS_32,              /* overflow on signed multiply (32bit) */
185 
186     CC_OP_COMP_32,              /* complement */
187     CC_OP_COMP_64,              /* complement */
188 
189     CC_OP_TM_32,                /* test under mask (32bit) */
190     CC_OP_TM_64,                /* test under mask (64bit) */
191 
192     CC_OP_NZ_F32,               /* FP dst != 0 (32bit) */
193     CC_OP_NZ_F64,               /* FP dst != 0 (64bit) */
194     CC_OP_NZ_F128,              /* FP dst != 0 (128bit) */
195 
196     CC_OP_ICM,                  /* insert characters under mask */
197     CC_OP_SLA,                  /* Calculate shift left signed */
198     CC_OP_FLOGR,                /* find leftmost one */
199     CC_OP_LCBB,                 /* load count to block boundary */
200     CC_OP_VC,                   /* vector compare result */
201     CC_OP_MAX
202 };
203 
204 #ifndef CONFIG_USER_ONLY
205 
decode_basedisp_s(CPUS390XState * env,uint32_t ipb,uint8_t * ar)206 static 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 /* Base/displacement are at the same locations. */
225 #define decode_basedisp_rs decode_basedisp_s
226 
227 #endif /* CONFIG_USER_ONLY */
228 
229 /* arch_dump.c */
230 int s390_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cs,
231                               int cpuid, DumpState *s);
232 
233 
234 /* cc_helper.c */
235 const char *cc_name(enum cc_op cc_op);
236 uint32_t calc_cc(CPUS390XState *env, uint32_t cc_op, uint64_t src, uint64_t dst,
237                  uint64_t vr);
238 
239 /* cpu.c */
240 #ifndef CONFIG_USER_ONLY
241 unsigned int s390_count_running_cpus(void);
242 void s390_cpu_halt(S390CPU *cpu);
243 void s390_cpu_unhalt(S390CPU *cpu);
244 void s390_cpu_system_init(Object *obj);
245 bool s390_cpu_system_realize(DeviceState *dev, Error **errp);
246 void s390_cpu_finalize(Object *obj);
247 void s390_cpu_system_class_init(CPUClass *cc);
248 void s390_cpu_machine_reset_cb(void *opaque);
249 bool s390_cpu_has_work(CPUState *cs);
250 #endif /* CONFIG_USER_ONLY */
251 
252 
253 /* cpu_models.c */
254 void s390_cpu_model_class_register_props(ObjectClass *oc);
255 void s390_realize_cpu_model(CPUState *cs, Error **errp);
256 S390CPUModel *get_max_cpu_model(Error **errp);
257 void apply_cpu_model(const S390CPUModel *model, Error **errp);
258 ObjectClass *s390_cpu_class_by_name(const char *name);
259 
260 
261 /* excp_helper.c */
262 void s390x_cpu_debug_excp_handler(CPUState *cs);
263 void s390_cpu_do_interrupt(CPUState *cpu);
264 bool s390_cpu_exec_interrupt(CPUState *cpu, int int_req);
265 
266 #ifdef CONFIG_USER_ONLY
267 void s390_cpu_record_sigsegv(CPUState *cs, vaddr address,
268                              MMUAccessType access_type,
269                              bool maperr, uintptr_t retaddr);
270 void s390_cpu_record_sigbus(CPUState *cs, vaddr address,
271                             MMUAccessType access_type, uintptr_t retaddr);
272 #else
273 bool s390_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
274                        MMUAccessType access_type, int mmu_idx,
275                        bool probe, uintptr_t retaddr);
276 G_NORETURN void s390x_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
277                                               MMUAccessType access_type, int mmu_idx,
278                                               uintptr_t retaddr);
279 #endif
280 
281 
282 /* fpu_helper.c */
283 uint32_t set_cc_nz_f32(float32 v);
284 uint32_t set_cc_nz_f64(float64 v);
285 uint32_t set_cc_nz_f128(float128 v);
286 #define S390_IEEE_MASK_INVALID   0x80
287 #define S390_IEEE_MASK_DIVBYZERO 0x40
288 #define S390_IEEE_MASK_OVERFLOW  0x20
289 #define S390_IEEE_MASK_UNDERFLOW 0x10
290 #define S390_IEEE_MASK_INEXACT   0x08
291 #define S390_IEEE_MASK_QUANTUM   0x04
292 uint8_t s390_softfloat_exc_to_ieee(unsigned int exc);
293 int s390_swap_bfp_rounding_mode(CPUS390XState *env, int m3);
294 void s390_restore_bfp_rounding_mode(CPUS390XState *env, int old_mode);
295 int float_comp_to_cc(CPUS390XState *env, FloatRelation float_compare);
296 
297 #define DCMASK_ZERO             0x0c00
298 #define DCMASK_NORMAL           0x0300
299 #define DCMASK_SUBNORMAL        0x00c0
300 #define DCMASK_INFINITY         0x0030
301 #define DCMASK_QUIET_NAN        0x000c
302 #define DCMASK_SIGNALING_NAN    0x0003
303 #define DCMASK_NAN              0x000f
304 #define DCMASK_NEGATIVE         0x0555
305 uint16_t float32_dcmask(CPUS390XState *env, float32 f1);
306 uint16_t float64_dcmask(CPUS390XState *env, float64 f1);
307 uint16_t float128_dcmask(CPUS390XState *env, float128 f1);
308 
309 
310 /* gdbstub.c */
311 int s390_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
312 int s390_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
313 void s390_cpu_gdb_init(CPUState *cs);
314 
315 
316 /* helper.c */
317 void s390_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
318 void do_restart_interrupt(CPUS390XState *env);
319 #ifndef CONFIG_USER_ONLY
320 void s390_cpu_recompute_watchpoints(CPUState *cs);
321 void s390x_tod_timer(void *opaque);
322 void s390x_cpu_timer(void *opaque);
323 void s390_handle_wait(S390CPU *cpu);
324 hwaddr s390_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
325 hwaddr s390_cpu_get_phys_addr_debug(CPUState *cpu, vaddr addr);
326 #define S390_STORE_STATUS_DEF_ADDR offsetof(LowCore, floating_pt_save_area)
327 int s390_store_status(S390CPU *cpu, hwaddr addr, bool store_arch);
328 int s390_store_adtl_status(S390CPU *cpu, hwaddr addr, hwaddr len);
329 LowCore *cpu_map_lowcore(CPUS390XState *env);
330 void cpu_unmap_lowcore(LowCore *lowcore);
331 #endif /* CONFIG_USER_ONLY */
332 
333 
334 /* interrupt.c */
335 void trigger_pgm_exception(CPUS390XState *env, uint32_t code);
336 #ifndef CONFIG_USER_ONLY
337 void cpu_inject_clock_comparator(S390CPU *cpu);
338 void cpu_inject_cpu_timer(S390CPU *cpu);
339 void cpu_inject_emergency_signal(S390CPU *cpu, uint16_t src_cpu_addr);
340 int cpu_inject_external_call(S390CPU *cpu, uint16_t src_cpu_addr);
341 bool s390_cpu_has_io_int(S390CPU *cpu);
342 bool s390_cpu_has_ext_int(S390CPU *cpu);
343 bool s390_cpu_has_mcck_int(S390CPU *cpu);
344 bool s390_cpu_has_int(S390CPU *cpu);
345 bool s390_cpu_has_restart_int(S390CPU *cpu);
346 bool s390_cpu_has_stop_int(S390CPU *cpu);
347 void cpu_inject_restart(S390CPU *cpu);
348 void cpu_inject_stop(S390CPU *cpu);
349 #endif /* CONFIG_USER_ONLY */
350 
351 
352 /* ioinst.c */
353 #ifndef CONFIG_USER_ONLY
354 void ioinst_handle_xsch(S390CPU *cpu, uint64_t reg1, uintptr_t ra);
355 void ioinst_handle_csch(S390CPU *cpu, uint64_t reg1, uintptr_t ra);
356 void ioinst_handle_hsch(S390CPU *cpu, uint64_t reg1, uintptr_t ra);
357 void ioinst_handle_msch(S390CPU *cpu, uint64_t reg1, uint32_t ipb,
358                         uintptr_t ra);
359 void ioinst_handle_ssch(S390CPU *cpu, uint64_t reg1, uint32_t ipb,
360                         uintptr_t ra);
361 void ioinst_handle_stcrw(S390CPU *cpu, uint32_t ipb, uintptr_t ra);
362 void ioinst_handle_stsch(S390CPU *cpu, uint64_t reg1, uint32_t ipb,
363                          uintptr_t ra);
364 int ioinst_handle_tsch(S390CPU *cpu, uint64_t reg1, uint32_t ipb, uintptr_t ra);
365 void ioinst_handle_chsc(S390CPU *cpu, uint32_t ipb, uintptr_t ra);
366 void ioinst_handle_schm(S390CPU *cpu, uint64_t reg1, uint64_t reg2,
367                         uint32_t ipb, uintptr_t ra);
368 void ioinst_handle_rsch(S390CPU *cpu, uint64_t reg1, uintptr_t ra);
369 void ioinst_handle_rchp(S390CPU *cpu, uint64_t reg1, uintptr_t ra);
370 void ioinst_handle_sal(S390CPU *cpu, uint64_t reg1, uintptr_t ra);
371 #endif /* CONFIG_USER_ONLY */
372 
373 
374 /* mem_helper.c */
375 target_ulong mmu_real2abs(CPUS390XState *env, target_ulong raddr);
376 void probe_write_access(CPUS390XState *env, uint64_t addr, uint64_t len,
377                         uintptr_t ra);
378 
379 
380 /* mmu_helper.c */
381 bool mmu_absolute_addr_valid(target_ulong addr, bool is_write);
382 /* Special access mode only valid for mmu_translate() */
383 #define MMU_S390_LRA        -1
384 int mmu_translate(CPUS390XState *env, target_ulong vaddr, int rw, uint64_t asc,
385                   target_ulong *raddr, int *flags, uint64_t *tec);
386 int mmu_translate_real(CPUS390XState *env, target_ulong raddr, int rw,
387                        target_ulong *addr, int *flags, uint64_t *tec);
388 
389 
390 /* misc_helper.c */
391 int handle_diag_288(CPUS390XState *env, uint64_t r1, uint64_t r3);
392 void handle_diag_308(CPUS390XState *env, uint64_t r1, uint64_t r3,
393                      uintptr_t ra);
394 
395 
396 /* translate.c */
397 void s390x_translate_init(void);
398 void s390x_translate_code(CPUState *cs, TranslationBlock *tb,
399                           int *max_insns, vaddr pc, void *host_pc);
400 void s390x_restore_state_to_opc(CPUState *cs,
401                                 const TranslationBlock *tb,
402                                 const uint64_t *data);
403 
404 /* sigp.c */
405 int handle_sigp(CPUS390XState *env, uint8_t order, uint64_t r1, uint64_t r3);
406 void do_stop_interrupt(CPUS390XState *env);
407 
408 #endif /* S390X_INTERNAL_H */
409