1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21#include "qemu/osdep.h"
22#include "qemu/cutils.h"
23#include "qemu/main-loop.h"
24#include "cpu.h"
25#include "s390x-internal.h"
26#include "qemu/host-utils.h"
27#include "exec/helper-proto.h"
28#include "qemu/timer.h"
29#include "exec/exec-all.h"
30#include "exec/cpu_ldst.h"
31#include "qapi/error.h"
32#include "tcg_s390x.h"
33#include "s390-tod.h"
34
35#if !defined(CONFIG_USER_ONLY)
36#include "sysemu/cpus.h"
37#include "sysemu/sysemu.h"
38#include "hw/s390x/ebcdic.h"
39#include "hw/s390x/s390-virtio-hcall.h"
40#include "hw/s390x/sclp.h"
41#include "hw/s390x/s390_flic.h"
42#include "hw/s390x/ioinst.h"
43#include "hw/s390x/s390-pci-inst.h"
44#include "hw/boards.h"
45#include "hw/s390x/tod.h"
46#endif
47
48
49#ifdef DEBUG_HELPER
50#define HELPER_LOG(x...) qemu_log(x)
51#else
52#define HELPER_LOG(x...)
53#endif
54
55
56void HELPER(exception)(CPUS390XState *env, uint32_t excp)
57{
58 CPUState *cs = env_cpu(env);
59
60 HELPER_LOG("%s: exception %d\n", __func__, excp);
61 cs->exception_index = excp;
62 cpu_loop_exit(cs);
63}
64
65
66uint64_t HELPER(stpt)(CPUS390XState *env)
67{
68#if defined(CONFIG_USER_ONLY)
69
70
71
72
73
74 return UINT64_MAX - (uint64_t)cpu_get_host_ticks();
75#else
76 return time2tod(env->cputm - qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
77#endif
78}
79
80
81uint64_t HELPER(stck)(CPUS390XState *env)
82{
83#ifdef CONFIG_USER_ONLY
84 struct timespec ts;
85 uint64_t ns;
86
87 clock_gettime(CLOCK_REALTIME, &ts);
88 ns = ts.tv_sec * NANOSECONDS_PER_SECOND + ts.tv_nsec;
89
90 return TOD_UNIX_EPOCH + time2tod(ns);
91#else
92 S390TODState *td = s390_get_todstate();
93 S390TODClass *tdc = S390_TOD_GET_CLASS(td);
94 S390TOD tod;
95
96 tdc->get(td, &tod, &error_abort);
97 return tod.low;
98#endif
99}
100
101#ifndef CONFIG_USER_ONLY
102
103uint32_t HELPER(servc)(CPUS390XState *env, uint64_t r1, uint64_t r2)
104{
105 qemu_mutex_lock_iothread();
106 int r = sclp_service_call(env, r1, r2);
107 qemu_mutex_unlock_iothread();
108 if (r < 0) {
109 tcg_s390_program_interrupt(env, -r, GETPC());
110 }
111 return r;
112}
113
114void HELPER(diag)(CPUS390XState *env, uint32_t r1, uint32_t r3, uint32_t num)
115{
116 uint64_t r;
117
118 switch (num) {
119 case 0x500:
120
121 qemu_mutex_lock_iothread();
122 r = s390_virtio_hypercall(env);
123 qemu_mutex_unlock_iothread();
124 break;
125 case 0x44:
126
127 r = 0;
128 break;
129 case 0x308:
130
131 qemu_mutex_lock_iothread();
132 handle_diag_308(env, r1, r3, GETPC());
133 qemu_mutex_unlock_iothread();
134 r = 0;
135 break;
136 case 0x288:
137
138 r = handle_diag_288(env, r1, r3);
139 break;
140 default:
141 r = -1;
142 break;
143 }
144
145 if (r) {
146 tcg_s390_program_interrupt(env, PGM_SPECIFICATION, GETPC());
147 }
148}
149
150
151void HELPER(spx)(CPUS390XState *env, uint64_t a1)
152{
153 const uint32_t prefix = a1 & 0x7fffe000;
154 const uint32_t old_prefix = env->psa;
155 CPUState *cs = env_cpu(env);
156
157 if (prefix == old_prefix) {
158 return;
159 }
160
161
162
163
164 if (!mmu_absolute_addr_valid(prefix, true)) {
165 tcg_s390_program_interrupt(env, PGM_ADDRESSING, GETPC());
166 }
167
168 env->psa = prefix;
169 HELPER_LOG("prefix: %#x\n", prefix);
170 tlb_flush_page(cs, 0);
171 tlb_flush_page(cs, TARGET_PAGE_SIZE);
172 if (prefix != 0) {
173 tlb_flush_page(cs, prefix);
174 tlb_flush_page(cs, prefix + TARGET_PAGE_SIZE);
175 }
176 if (old_prefix != 0) {
177 tlb_flush_page(cs, old_prefix);
178 tlb_flush_page(cs, old_prefix + TARGET_PAGE_SIZE);
179 }
180}
181
182static void update_ckc_timer(CPUS390XState *env)
183{
184 S390TODState *td = s390_get_todstate();
185 uint64_t time;
186
187
188 timer_del(env->tod_timer);
189 g_assert(qemu_mutex_iothread_locked());
190 env->pending_int &= ~INTERRUPT_EXT_CLOCK_COMPARATOR;
191
192
193 if (env->ckc == -1ULL) {
194 return;
195 }
196
197
198 time = env->ckc - td->base.low;
199
200
201 time = tod2time(time);
202
203 timer_mod(env->tod_timer, time);
204}
205
206
207void HELPER(sckc)(CPUS390XState *env, uint64_t ckc)
208{
209 env->ckc = ckc;
210
211 qemu_mutex_lock_iothread();
212 update_ckc_timer(env);
213 qemu_mutex_unlock_iothread();
214}
215
216void tcg_s390_tod_updated(CPUState *cs, run_on_cpu_data opaque)
217{
218 S390CPU *cpu = S390_CPU(cs);
219
220 update_ckc_timer(&cpu->env);
221}
222
223
224uint32_t HELPER(sck)(CPUS390XState *env, uint64_t tod_low)
225{
226 S390TODState *td = s390_get_todstate();
227 S390TODClass *tdc = S390_TOD_GET_CLASS(td);
228 S390TOD tod = {
229 .high = 0,
230 .low = tod_low,
231 };
232
233 qemu_mutex_lock_iothread();
234 tdc->set(td, &tod, &error_abort);
235 qemu_mutex_unlock_iothread();
236 return 0;
237}
238
239
240void HELPER(sckpf)(CPUS390XState *env, uint64_t r0)
241{
242 uint32_t val = r0;
243
244 if (val & 0xffff0000) {
245 tcg_s390_program_interrupt(env, PGM_SPECIFICATION, GETPC());
246 }
247 env->todpr = val;
248}
249
250
251uint64_t HELPER(stckc)(CPUS390XState *env)
252{
253 return env->ckc;
254}
255
256
257void HELPER(spt)(CPUS390XState *env, uint64_t time)
258{
259 if (time == -1ULL) {
260 return;
261 }
262
263
264 time = tod2time(time);
265
266 env->cputm = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + time;
267
268 timer_mod(env->cpu_timer, env->cputm);
269}
270
271
272uint32_t HELPER(stsi)(CPUS390XState *env, uint64_t a0, uint64_t r0, uint64_t r1)
273{
274 const uintptr_t ra = GETPC();
275 const uint32_t sel1 = r0 & STSI_R0_SEL1_MASK;
276 const uint32_t sel2 = r1 & STSI_R1_SEL2_MASK;
277 const MachineState *ms = MACHINE(qdev_get_machine());
278 uint16_t total_cpus = 0, conf_cpus = 0, reserved_cpus = 0;
279 S390CPU *cpu = env_archcpu(env);
280 SysIB sysib = { };
281 int i, cc = 0;
282
283 if ((r0 & STSI_R0_FC_MASK) > STSI_R0_FC_LEVEL_3) {
284
285 return 3;
286 }
287
288 if ((r0 & STSI_R0_RESERVED_MASK) || (r1 & STSI_R1_RESERVED_MASK)) {
289 tcg_s390_program_interrupt(env, PGM_SPECIFICATION, ra);
290 }
291
292 if ((r0 & STSI_R0_FC_MASK) == STSI_R0_FC_CURRENT) {
293
294 env->regs[0] = STSI_R0_FC_LEVEL_3;
295 return 0;
296 }
297
298 if (a0 & ~TARGET_PAGE_MASK) {
299 tcg_s390_program_interrupt(env, PGM_SPECIFICATION, ra);
300 }
301
302
303 for (i = 0; i < ms->possible_cpus->len; i++) {
304 total_cpus++;
305 if (ms->possible_cpus->cpus[i].cpu) {
306 conf_cpus++;
307 } else {
308 reserved_cpus++;
309 }
310 }
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325 switch (r0 & STSI_R0_FC_MASK) {
326 case STSI_R0_FC_LEVEL_1:
327 if ((sel1 == 1) && (sel2 == 1)) {
328
329 char type[5] = {};
330
331 ebcdic_put(sysib.sysib_111.manuf, "QEMU ", 16);
332
333 snprintf(type, ARRAY_SIZE(type), "%X", cpu->model->def->type);
334 ebcdic_put(sysib.sysib_111.type, type, 4);
335
336 ebcdic_put(sysib.sysib_111.model, "QEMU ", 16);
337 ebcdic_put(sysib.sysib_111.sequence, "QEMU ", 16);
338 ebcdic_put(sysib.sysib_111.plant, "QEMU", 4);
339 } else if ((sel1 == 2) && (sel2 == 1)) {
340
341 ebcdic_put(sysib.sysib_121.sequence, "QEMUQEMUQEMUQEMU", 16);
342 ebcdic_put(sysib.sysib_121.plant, "QEMU", 4);
343 sysib.sysib_121.cpu_addr = cpu_to_be16(env->core_id);
344 } else if ((sel1 == 2) && (sel2 == 2)) {
345
346 sysib.sysib_122.capability = cpu_to_be32(0x443afc29);
347 sysib.sysib_122.total_cpus = cpu_to_be16(total_cpus);
348 sysib.sysib_122.conf_cpus = cpu_to_be16(conf_cpus);
349 sysib.sysib_122.reserved_cpus = cpu_to_be16(reserved_cpus);
350 } else {
351 cc = 3;
352 }
353 break;
354 case STSI_R0_FC_LEVEL_2:
355 if ((sel1 == 2) && (sel2 == 1)) {
356
357 ebcdic_put(sysib.sysib_221.sequence, "QEMUQEMUQEMUQEMU", 16);
358 ebcdic_put(sysib.sysib_221.plant, "QEMU", 4);
359 sysib.sysib_221.cpu_addr = cpu_to_be16(env->core_id);
360 } else if ((sel1 == 2) && (sel2 == 2)) {
361
362 sysib.sysib_222.lcpuc = 0x80;
363 sysib.sysib_222.total_cpus = cpu_to_be16(total_cpus);
364 sysib.sysib_222.conf_cpus = cpu_to_be16(conf_cpus);
365 sysib.sysib_222.reserved_cpus = cpu_to_be16(reserved_cpus);
366 ebcdic_put(sysib.sysib_222.name, "QEMU ", 8);
367 sysib.sysib_222.caf = cpu_to_be32(1000);
368 sysib.sysib_222.dedicated_cpus = cpu_to_be16(conf_cpus);
369 } else {
370 cc = 3;
371 }
372 break;
373 case STSI_R0_FC_LEVEL_3:
374 if ((sel1 == 2) && (sel2 == 2)) {
375
376 sysib.sysib_322.count = 1;
377 sysib.sysib_322.vm[0].total_cpus = cpu_to_be16(total_cpus);
378 sysib.sysib_322.vm[0].conf_cpus = cpu_to_be16(conf_cpus);
379 sysib.sysib_322.vm[0].reserved_cpus = cpu_to_be16(reserved_cpus);
380 sysib.sysib_322.vm[0].caf = cpu_to_be32(1000);
381
382 ebcdic_put(sysib.sysib_322.vm[0].cpi, "KVM/Linux ", 16);
383 sysib.sysib_322.vm[0].ext_name_encoding = 2;
384
385
386 if (qemu_name) {
387 memset(sysib.sysib_322.vm[0].name, 0x40,
388 sizeof(sysib.sysib_322.vm[0].name));
389 ebcdic_put(sysib.sysib_322.vm[0].name, qemu_name,
390 MIN(sizeof(sysib.sysib_322.vm[0].name),
391 strlen(qemu_name)));
392 strpadcpy((char *)sysib.sysib_322.ext_names[0],
393 sizeof(sysib.sysib_322.ext_names[0]),
394 qemu_name, '\0');
395
396 } else {
397 ebcdic_put(sysib.sysib_322.vm[0].name, "TCGguest", 8);
398 strcpy((char *)sysib.sysib_322.ext_names[0], "TCGguest");
399 }
400
401
402 memcpy(sysib.sysib_322.vm[0].uuid, &qemu_uuid,
403 sizeof(sysib.sysib_322.vm[0].uuid));
404 } else {
405 cc = 3;
406 }
407 break;
408 }
409
410 if (cc == 0) {
411 if (s390_cpu_virt_mem_write(cpu, a0, 0, &sysib, sizeof(sysib))) {
412 s390_cpu_virt_mem_handle_exc(cpu, ra);
413 }
414 }
415
416 return cc;
417}
418
419uint32_t HELPER(sigp)(CPUS390XState *env, uint64_t order_code, uint32_t r1,
420 uint32_t r3)
421{
422 int cc;
423
424
425 qemu_mutex_lock_iothread();
426 cc = handle_sigp(env, order_code & SIGP_ORDER_MASK, r1, r3);
427 qemu_mutex_unlock_iothread();
428
429 return cc;
430}
431#endif
432
433#ifndef CONFIG_USER_ONLY
434void HELPER(xsch)(CPUS390XState *env, uint64_t r1)
435{
436 S390CPU *cpu = env_archcpu(env);
437 qemu_mutex_lock_iothread();
438 ioinst_handle_xsch(cpu, r1, GETPC());
439 qemu_mutex_unlock_iothread();
440}
441
442void HELPER(csch)(CPUS390XState *env, uint64_t r1)
443{
444 S390CPU *cpu = env_archcpu(env);
445 qemu_mutex_lock_iothread();
446 ioinst_handle_csch(cpu, r1, GETPC());
447 qemu_mutex_unlock_iothread();
448}
449
450void HELPER(hsch)(CPUS390XState *env, uint64_t r1)
451{
452 S390CPU *cpu = env_archcpu(env);
453 qemu_mutex_lock_iothread();
454 ioinst_handle_hsch(cpu, r1, GETPC());
455 qemu_mutex_unlock_iothread();
456}
457
458void HELPER(msch)(CPUS390XState *env, uint64_t r1, uint64_t inst)
459{
460 S390CPU *cpu = env_archcpu(env);
461 qemu_mutex_lock_iothread();
462 ioinst_handle_msch(cpu, r1, inst >> 16, GETPC());
463 qemu_mutex_unlock_iothread();
464}
465
466void HELPER(rchp)(CPUS390XState *env, uint64_t r1)
467{
468 S390CPU *cpu = env_archcpu(env);
469 qemu_mutex_lock_iothread();
470 ioinst_handle_rchp(cpu, r1, GETPC());
471 qemu_mutex_unlock_iothread();
472}
473
474void HELPER(rsch)(CPUS390XState *env, uint64_t r1)
475{
476 S390CPU *cpu = env_archcpu(env);
477 qemu_mutex_lock_iothread();
478 ioinst_handle_rsch(cpu, r1, GETPC());
479 qemu_mutex_unlock_iothread();
480}
481
482void HELPER(sal)(CPUS390XState *env, uint64_t r1)
483{
484 S390CPU *cpu = env_archcpu(env);
485
486 qemu_mutex_lock_iothread();
487 ioinst_handle_sal(cpu, r1, GETPC());
488 qemu_mutex_unlock_iothread();
489}
490
491void HELPER(schm)(CPUS390XState *env, uint64_t r1, uint64_t r2, uint64_t inst)
492{
493 S390CPU *cpu = env_archcpu(env);
494
495 qemu_mutex_lock_iothread();
496 ioinst_handle_schm(cpu, r1, r2, inst >> 16, GETPC());
497 qemu_mutex_unlock_iothread();
498}
499
500void HELPER(ssch)(CPUS390XState *env, uint64_t r1, uint64_t inst)
501{
502 S390CPU *cpu = env_archcpu(env);
503 qemu_mutex_lock_iothread();
504 ioinst_handle_ssch(cpu, r1, inst >> 16, GETPC());
505 qemu_mutex_unlock_iothread();
506}
507
508void HELPER(stcrw)(CPUS390XState *env, uint64_t inst)
509{
510 S390CPU *cpu = env_archcpu(env);
511
512 qemu_mutex_lock_iothread();
513 ioinst_handle_stcrw(cpu, inst >> 16, GETPC());
514 qemu_mutex_unlock_iothread();
515}
516
517void HELPER(stsch)(CPUS390XState *env, uint64_t r1, uint64_t inst)
518{
519 S390CPU *cpu = env_archcpu(env);
520 qemu_mutex_lock_iothread();
521 ioinst_handle_stsch(cpu, r1, inst >> 16, GETPC());
522 qemu_mutex_unlock_iothread();
523}
524
525uint32_t HELPER(tpi)(CPUS390XState *env, uint64_t addr)
526{
527 const uintptr_t ra = GETPC();
528 S390CPU *cpu = env_archcpu(env);
529 QEMUS390FLICState *flic = s390_get_qemu_flic(s390_get_flic());
530 QEMUS390FlicIO *io = NULL;
531 LowCore *lowcore;
532
533 if (addr & 0x3) {
534 tcg_s390_program_interrupt(env, PGM_SPECIFICATION, ra);
535 }
536
537 qemu_mutex_lock_iothread();
538 io = qemu_s390_flic_dequeue_io(flic, env->cregs[6]);
539 if (!io) {
540 qemu_mutex_unlock_iothread();
541 return 0;
542 }
543
544 if (addr) {
545 struct {
546 uint16_t id;
547 uint16_t nr;
548 uint32_t parm;
549 } intc = {
550 .id = cpu_to_be16(io->id),
551 .nr = cpu_to_be16(io->nr),
552 .parm = cpu_to_be32(io->parm),
553 };
554
555 if (s390_cpu_virt_mem_write(cpu, addr, 0, &intc, sizeof(intc))) {
556
557 s390_io_interrupt(io->id, io->nr, io->parm, io->word);
558 qemu_mutex_unlock_iothread();
559 g_free(io);
560 s390_cpu_virt_mem_handle_exc(cpu, ra);
561 return 0;
562 }
563 } else {
564
565 lowcore = cpu_map_lowcore(env);
566 lowcore->subchannel_id = cpu_to_be16(io->id);
567 lowcore->subchannel_nr = cpu_to_be16(io->nr);
568 lowcore->io_int_parm = cpu_to_be32(io->parm);
569 lowcore->io_int_word = cpu_to_be32(io->word);
570 cpu_unmap_lowcore(lowcore);
571 }
572
573 g_free(io);
574 qemu_mutex_unlock_iothread();
575 return 1;
576}
577
578void HELPER(tsch)(CPUS390XState *env, uint64_t r1, uint64_t inst)
579{
580 S390CPU *cpu = env_archcpu(env);
581 qemu_mutex_lock_iothread();
582 ioinst_handle_tsch(cpu, r1, inst >> 16, GETPC());
583 qemu_mutex_unlock_iothread();
584}
585
586void HELPER(chsc)(CPUS390XState *env, uint64_t inst)
587{
588 S390CPU *cpu = env_archcpu(env);
589 qemu_mutex_lock_iothread();
590 ioinst_handle_chsc(cpu, inst >> 16, GETPC());
591 qemu_mutex_unlock_iothread();
592}
593#endif
594
595#ifndef CONFIG_USER_ONLY
596void HELPER(per_check_exception)(CPUS390XState *env)
597{
598 if (env->per_perc_atmid) {
599 tcg_s390_program_interrupt(env, PGM_PER, GETPC());
600 }
601}
602
603
604
605static inline bool get_per_in_range(CPUS390XState *env, uint64_t addr)
606{
607 if (env->cregs[10] <= env->cregs[11]) {
608 return env->cregs[10] <= addr && addr <= env->cregs[11];
609 } else {
610 return env->cregs[10] <= addr || addr <= env->cregs[11];
611 }
612}
613
614void HELPER(per_branch)(CPUS390XState *env, uint64_t from, uint64_t to)
615{
616 if ((env->cregs[9] & PER_CR9_EVENT_BRANCH)) {
617 if (!(env->cregs[9] & PER_CR9_CONTROL_BRANCH_ADDRESS)
618 || get_per_in_range(env, to)) {
619 env->per_address = from;
620 env->per_perc_atmid = PER_CODE_EVENT_BRANCH | get_per_atmid(env);
621 }
622 }
623}
624
625void HELPER(per_ifetch)(CPUS390XState *env, uint64_t addr)
626{
627 if ((env->cregs[9] & PER_CR9_EVENT_IFETCH) && get_per_in_range(env, addr)) {
628 env->per_address = addr;
629 env->per_perc_atmid = PER_CODE_EVENT_IFETCH | get_per_atmid(env);
630
631
632
633 if (env->cregs[9] & PER_CR9_EVENT_NULLIFICATION) {
634 CPUState *cs = env_cpu(env);
635
636 env->per_perc_atmid |= PER_CODE_EVENT_NULLIFICATION;
637 env->int_pgm_code = PGM_PER;
638 env->int_pgm_ilen = get_ilen(cpu_ldub_code(env, addr));
639
640 cs->exception_index = EXCP_PGM;
641 cpu_loop_exit(cs);
642 }
643 }
644}
645
646void HELPER(per_store_real)(CPUS390XState *env)
647{
648 if ((env->cregs[9] & PER_CR9_EVENT_STORE) &&
649 (env->cregs[9] & PER_CR9_EVENT_STORE_REAL)) {
650
651 env->per_address = env->psw.addr;
652 env->per_perc_atmid = PER_CODE_EVENT_STORE_REAL | get_per_atmid(env);
653 }
654}
655#endif
656
657static uint8_t stfl_bytes[2048];
658static unsigned int used_stfl_bytes;
659
660static void prepare_stfl(void)
661{
662 static bool initialized;
663 int i;
664
665
666 if (initialized) {
667 return;
668 }
669
670 s390_get_feat_block(S390_FEAT_TYPE_STFL, stfl_bytes);
671 for (i = 0; i < sizeof(stfl_bytes); i++) {
672 if (stfl_bytes[i]) {
673 used_stfl_bytes = i + 1;
674 }
675 }
676 initialized = true;
677}
678
679#ifndef CONFIG_USER_ONLY
680void HELPER(stfl)(CPUS390XState *env)
681{
682 LowCore *lowcore;
683
684 lowcore = cpu_map_lowcore(env);
685 prepare_stfl();
686 memcpy(&lowcore->stfl_fac_list, stfl_bytes, sizeof(lowcore->stfl_fac_list));
687 cpu_unmap_lowcore(lowcore);
688}
689#endif
690
691uint32_t HELPER(stfle)(CPUS390XState *env, uint64_t addr)
692{
693 const uintptr_t ra = GETPC();
694 const int count_bytes = ((env->regs[0] & 0xff) + 1) * 8;
695 int max_bytes;
696 int i;
697
698 if (addr & 0x7) {
699 tcg_s390_program_interrupt(env, PGM_SPECIFICATION, ra);
700 }
701
702 prepare_stfl();
703 max_bytes = ROUND_UP(used_stfl_bytes, 8);
704
705
706
707
708
709
710 for (i = 0; i < MIN(count_bytes, max_bytes); ++i) {
711 cpu_stb_data_ra(env, addr + i, stfl_bytes[i], ra);
712 }
713
714 env->regs[0] = deposit64(env->regs[0], 0, 8, (max_bytes / 8) - 1);
715 return count_bytes >= max_bytes ? 0 : 3;
716}
717
718#ifndef CONFIG_USER_ONLY
719
720
721
722
723
724
725
726void HELPER(clp)(CPUS390XState *env, uint32_t r2)
727{
728 S390CPU *cpu = env_archcpu(env);
729
730 qemu_mutex_lock_iothread();
731 clp_service_call(cpu, r2, GETPC());
732 qemu_mutex_unlock_iothread();
733}
734
735void HELPER(pcilg)(CPUS390XState *env, uint32_t r1, uint32_t r2)
736{
737 S390CPU *cpu = env_archcpu(env);
738
739 qemu_mutex_lock_iothread();
740 pcilg_service_call(cpu, r1, r2, GETPC());
741 qemu_mutex_unlock_iothread();
742}
743
744void HELPER(pcistg)(CPUS390XState *env, uint32_t r1, uint32_t r2)
745{
746 S390CPU *cpu = env_archcpu(env);
747
748 qemu_mutex_lock_iothread();
749 pcistg_service_call(cpu, r1, r2, GETPC());
750 qemu_mutex_unlock_iothread();
751}
752
753void HELPER(stpcifc)(CPUS390XState *env, uint32_t r1, uint64_t fiba,
754 uint32_t ar)
755{
756 S390CPU *cpu = env_archcpu(env);
757
758 qemu_mutex_lock_iothread();
759 stpcifc_service_call(cpu, r1, fiba, ar, GETPC());
760 qemu_mutex_unlock_iothread();
761}
762
763void HELPER(sic)(CPUS390XState *env, uint64_t r1, uint64_t r3)
764{
765 int r;
766
767 qemu_mutex_lock_iothread();
768 r = css_do_sic(env, (r3 >> 27) & 0x7, r1 & 0xffff);
769 qemu_mutex_unlock_iothread();
770
771 if (r) {
772 tcg_s390_program_interrupt(env, -r, GETPC());
773 }
774}
775
776void HELPER(rpcit)(CPUS390XState *env, uint32_t r1, uint32_t r2)
777{
778 S390CPU *cpu = env_archcpu(env);
779
780 qemu_mutex_lock_iothread();
781 rpcit_service_call(cpu, r1, r2, GETPC());
782 qemu_mutex_unlock_iothread();
783}
784
785void HELPER(pcistb)(CPUS390XState *env, uint32_t r1, uint32_t r3,
786 uint64_t gaddr, uint32_t ar)
787{
788 S390CPU *cpu = env_archcpu(env);
789
790 qemu_mutex_lock_iothread();
791 pcistb_service_call(cpu, r1, r3, gaddr, ar, GETPC());
792 qemu_mutex_unlock_iothread();
793}
794
795void HELPER(mpcifc)(CPUS390XState *env, uint32_t r1, uint64_t fiba,
796 uint32_t ar)
797{
798 S390CPU *cpu = env_archcpu(env);
799
800 qemu_mutex_lock_iothread();
801 mpcifc_service_call(cpu, r1, fiba, ar, GETPC());
802 qemu_mutex_unlock_iothread();
803}
804#endif
805