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