4 * Copyright (c) 2009 Ulrich Hecht
5 * Copyright (c) 2011 Alexander Graf
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
21 #include "qemu/osdep.h"
22 #include "qapi/error.h"
24 #include "exec/gdbstub.h"
25 #include "qemu/timer.h"
26 #include "exec/cpu_ldst.h"
27 #ifndef CONFIG_USER_ONLY
28 #include "sysemu/sysemu.h"
32 //#define DEBUG_S390_STDOUT
35 #ifdef DEBUG_S390_STDOUT
36 #define DPRINTF(fmt, ...) \
37 do { fprintf(stderr, fmt, ## __VA_ARGS__); \
38 if (qemu_log_separate()) qemu_log(fmt, ##__VA_ARGS__); } while (0)
40 #define DPRINTF(fmt, ...) \
41 do { qemu_log(fmt, ## __VA_ARGS__); } while (0)
44 #define DPRINTF(fmt, ...) \
49 #ifndef CONFIG_USER_ONLY
50 void s390x_tod_timer(void *opaque
)
52 S390CPU
*cpu
= opaque
;
53 CPUS390XState
*env
= &cpu
->env
;
55 env
->pending_int
|= INTERRUPT_TOD
;
56 cpu_interrupt(CPU(cpu
), CPU_INTERRUPT_HARD
);
59 void s390x_cpu_timer(void *opaque
)
61 S390CPU
*cpu
= opaque
;
62 CPUS390XState
*env
= &cpu
->env
;
64 env
->pending_int
|= INTERRUPT_CPUTIMER
;
65 cpu_interrupt(CPU(cpu
), CPU_INTERRUPT_HARD
);
69 S390CPU
*cpu_s390x_create(const char *cpu_model
, Error
**errp
)
73 cpu
= S390_CPU(object_new(TYPE_S390_CPU
));
78 S390CPU
*s390x_new_cpu(const char *cpu_model
, int64_t id
, Error
**errp
)
83 cpu
= cpu_s390x_create(cpu_model
, &err
);
88 object_property_set_int(OBJECT(cpu
), id
, "id", &err
);
92 object_property_set_bool(OBJECT(cpu
), true, "realized", &err
);
96 error_propagate(errp
, err
);
97 object_unref(OBJECT(cpu
));
103 S390CPU
*cpu_s390x_init(const char *cpu_model
)
107 /* Use to track CPU ID for linux-user only */
108 static int64_t next_cpu_id
;
110 cpu
= s390x_new_cpu(cpu_model
, next_cpu_id
++, &err
);
112 error_report_err(err
);
117 #if defined(CONFIG_USER_ONLY)
119 void s390_cpu_do_interrupt(CPUState
*cs
)
121 cs
->exception_index
= -1;
124 int s390_cpu_handle_mmu_fault(CPUState
*cs
, vaddr address
,
127 S390CPU
*cpu
= S390_CPU(cs
);
129 cs
->exception_index
= EXCP_PGM
;
130 cpu
->env
.int_pgm_code
= PGM_ADDRESSING
;
131 /* On real machines this value is dropped into LowMem. Since this
132 is userland, simply put this someplace that cpu_loop can find it. */
133 cpu
->env
.__excp_addr
= address
;
137 #else /* !CONFIG_USER_ONLY */
139 /* Ensure to exit the TB after this call! */
140 void trigger_pgm_exception(CPUS390XState
*env
, uint32_t code
, uint32_t ilen
)
142 CPUState
*cs
= CPU(s390_env_get_cpu(env
));
144 cs
->exception_index
= EXCP_PGM
;
145 env
->int_pgm_code
= code
;
146 env
->int_pgm_ilen
= ilen
;
149 int s390_cpu_handle_mmu_fault(CPUState
*cs
, vaddr orig_vaddr
,
152 S390CPU
*cpu
= S390_CPU(cs
);
153 CPUS390XState
*env
= &cpu
->env
;
154 uint64_t asc
= cpu_mmu_idx_to_asc(mmu_idx
);
155 target_ulong vaddr
, raddr
;
158 DPRINTF("%s: address 0x%" VADDR_PRIx
" rw %d mmu_idx %d\n",
159 __func__
, orig_vaddr
, rw
, mmu_idx
);
161 orig_vaddr
&= TARGET_PAGE_MASK
;
165 if (!(env
->psw
.mask
& PSW_MASK_64
)) {
169 if (mmu_translate(env
, vaddr
, rw
, asc
, &raddr
, &prot
, true)) {
170 /* Translation ended in exception */
174 /* check out of RAM access */
175 if (raddr
> ram_size
) {
176 DPRINTF("%s: raddr %" PRIx64
" > ram_size %" PRIx64
"\n", __func__
,
177 (uint64_t)raddr
, (uint64_t)ram_size
);
178 trigger_pgm_exception(env
, PGM_ADDRESSING
, ILEN_LATER
);
182 qemu_log_mask(CPU_LOG_MMU
, "%s: set tlb %" PRIx64
" -> %" PRIx64
" (%x)\n",
183 __func__
, (uint64_t)vaddr
, (uint64_t)raddr
, prot
);
185 tlb_set_page(cs
, orig_vaddr
, raddr
, prot
,
186 mmu_idx
, TARGET_PAGE_SIZE
);
191 hwaddr
s390_cpu_get_phys_page_debug(CPUState
*cs
, vaddr vaddr
)
193 S390CPU
*cpu
= S390_CPU(cs
);
194 CPUS390XState
*env
= &cpu
->env
;
197 uint64_t asc
= env
->psw
.mask
& PSW_MASK_ASC
;
200 if (!(env
->psw
.mask
& PSW_MASK_64
)) {
204 if (mmu_translate(env
, vaddr
, MMU_INST_FETCH
, asc
, &raddr
, &prot
, false)) {
210 hwaddr
s390_cpu_get_phys_addr_debug(CPUState
*cs
, vaddr vaddr
)
215 page
= vaddr
& TARGET_PAGE_MASK
;
216 phys_addr
= cpu_get_phys_page_debug(cs
, page
);
217 phys_addr
+= (vaddr
& ~TARGET_PAGE_MASK
);
222 void load_psw(CPUS390XState
*env
, uint64_t mask
, uint64_t addr
)
224 uint64_t old_mask
= env
->psw
.mask
;
226 env
->psw
.addr
= addr
;
227 env
->psw
.mask
= mask
;
229 env
->cc_op
= (mask
>> 44) & 3;
232 if ((old_mask
^ mask
) & PSW_MASK_PER
) {
233 s390_cpu_recompute_watchpoints(CPU(s390_env_get_cpu(env
)));
236 if (mask
& PSW_MASK_WAIT
) {
237 S390CPU
*cpu
= s390_env_get_cpu(env
);
238 if (s390_cpu_halt(cpu
) == 0) {
239 #ifndef CONFIG_USER_ONLY
240 qemu_system_shutdown_request();
246 static uint64_t get_psw_mask(CPUS390XState
*env
)
248 uint64_t r
= env
->psw
.mask
;
251 env
->cc_op
= calc_cc(env
, env
->cc_op
, env
->cc_src
, env
->cc_dst
,
255 assert(!(env
->cc_op
& ~3));
256 r
|= (uint64_t)env
->cc_op
<< 44;
262 static LowCore
*cpu_map_lowcore(CPUS390XState
*env
)
264 S390CPU
*cpu
= s390_env_get_cpu(env
);
266 hwaddr len
= sizeof(LowCore
);
268 lowcore
= cpu_physical_memory_map(env
->psa
, &len
, 1);
270 if (len
< sizeof(LowCore
)) {
271 cpu_abort(CPU(cpu
), "Could not map lowcore\n");
277 static void cpu_unmap_lowcore(LowCore
*lowcore
)
279 cpu_physical_memory_unmap(lowcore
, sizeof(LowCore
), 1, sizeof(LowCore
));
282 void do_restart_interrupt(CPUS390XState
*env
)
287 lowcore
= cpu_map_lowcore(env
);
289 lowcore
->restart_old_psw
.mask
= cpu_to_be64(get_psw_mask(env
));
290 lowcore
->restart_old_psw
.addr
= cpu_to_be64(env
->psw
.addr
);
291 mask
= be64_to_cpu(lowcore
->restart_new_psw
.mask
);
292 addr
= be64_to_cpu(lowcore
->restart_new_psw
.addr
);
294 cpu_unmap_lowcore(lowcore
);
296 load_psw(env
, mask
, addr
);
299 static void do_program_interrupt(CPUS390XState
*env
)
303 int ilen
= env
->int_pgm_ilen
;
307 ilen
= get_ilen(cpu_ldub_code(env
, env
->psw
.addr
));
310 ilen
= get_ilen(cpu_ldub_code(env
, env
->psw
.addr
));
311 env
->psw
.addr
+= ilen
;
314 assert(ilen
== 2 || ilen
== 4 || ilen
== 6);
317 qemu_log_mask(CPU_LOG_INT
, "%s: code=0x%x ilen=%d\n",
318 __func__
, env
->int_pgm_code
, ilen
);
320 lowcore
= cpu_map_lowcore(env
);
322 /* Signal PER events with the exception. */
323 if (env
->per_perc_atmid
) {
324 env
->int_pgm_code
|= PGM_PER
;
325 lowcore
->per_address
= cpu_to_be64(env
->per_address
);
326 lowcore
->per_perc_atmid
= cpu_to_be16(env
->per_perc_atmid
);
327 env
->per_perc_atmid
= 0;
330 lowcore
->pgm_ilen
= cpu_to_be16(ilen
);
331 lowcore
->pgm_code
= cpu_to_be16(env
->int_pgm_code
);
332 lowcore
->program_old_psw
.mask
= cpu_to_be64(get_psw_mask(env
));
333 lowcore
->program_old_psw
.addr
= cpu_to_be64(env
->psw
.addr
);
334 mask
= be64_to_cpu(lowcore
->program_new_psw
.mask
);
335 addr
= be64_to_cpu(lowcore
->program_new_psw
.addr
);
336 lowcore
->per_breaking_event_addr
= cpu_to_be64(env
->gbea
);
338 cpu_unmap_lowcore(lowcore
);
340 DPRINTF("%s: %x %x %" PRIx64
" %" PRIx64
"\n", __func__
,
341 env
->int_pgm_code
, ilen
, env
->psw
.mask
,
344 load_psw(env
, mask
, addr
);
347 static void do_svc_interrupt(CPUS390XState
*env
)
352 lowcore
= cpu_map_lowcore(env
);
354 lowcore
->svc_code
= cpu_to_be16(env
->int_svc_code
);
355 lowcore
->svc_ilen
= cpu_to_be16(env
->int_svc_ilen
);
356 lowcore
->svc_old_psw
.mask
= cpu_to_be64(get_psw_mask(env
));
357 lowcore
->svc_old_psw
.addr
= cpu_to_be64(env
->psw
.addr
+ env
->int_svc_ilen
);
358 mask
= be64_to_cpu(lowcore
->svc_new_psw
.mask
);
359 addr
= be64_to_cpu(lowcore
->svc_new_psw
.addr
);
361 cpu_unmap_lowcore(lowcore
);
363 load_psw(env
, mask
, addr
);
365 /* When a PER event is pending, the PER exception has to happen
366 immediately after the SERVICE CALL one. */
367 if (env
->per_perc_atmid
) {
368 env
->int_pgm_code
= PGM_PER
;
369 env
->int_pgm_ilen
= env
->int_svc_ilen
;
370 do_program_interrupt(env
);
374 #define VIRTIO_SUBCODE_64 0x0D00
376 static void do_ext_interrupt(CPUS390XState
*env
)
378 S390CPU
*cpu
= s390_env_get_cpu(env
);
383 if (!(env
->psw
.mask
& PSW_MASK_EXT
)) {
384 cpu_abort(CPU(cpu
), "Ext int w/o ext mask\n");
387 if (env
->ext_index
< 0 || env
->ext_index
>= MAX_EXT_QUEUE
) {
388 cpu_abort(CPU(cpu
), "Ext queue overrun: %d\n", env
->ext_index
);
391 q
= &env
->ext_queue
[env
->ext_index
];
392 lowcore
= cpu_map_lowcore(env
);
394 lowcore
->ext_int_code
= cpu_to_be16(q
->code
);
395 lowcore
->ext_params
= cpu_to_be32(q
->param
);
396 lowcore
->ext_params2
= cpu_to_be64(q
->param64
);
397 lowcore
->external_old_psw
.mask
= cpu_to_be64(get_psw_mask(env
));
398 lowcore
->external_old_psw
.addr
= cpu_to_be64(env
->psw
.addr
);
399 lowcore
->cpu_addr
= cpu_to_be16(env
->cpu_num
| VIRTIO_SUBCODE_64
);
400 mask
= be64_to_cpu(lowcore
->external_new_psw
.mask
);
401 addr
= be64_to_cpu(lowcore
->external_new_psw
.addr
);
403 cpu_unmap_lowcore(lowcore
);
406 if (env
->ext_index
== -1) {
407 env
->pending_int
&= ~INTERRUPT_EXT
;
410 DPRINTF("%s: %" PRIx64
" %" PRIx64
"\n", __func__
,
411 env
->psw
.mask
, env
->psw
.addr
);
413 load_psw(env
, mask
, addr
);
416 static void do_io_interrupt(CPUS390XState
*env
)
418 S390CPU
*cpu
= s390_env_get_cpu(env
);
425 if (!(env
->psw
.mask
& PSW_MASK_IO
)) {
426 cpu_abort(CPU(cpu
), "I/O int w/o I/O mask\n");
429 for (isc
= 0; isc
< ARRAY_SIZE(env
->io_index
); isc
++) {
432 if (env
->io_index
[isc
] < 0) {
435 if (env
->io_index
[isc
] >= MAX_IO_QUEUE
) {
436 cpu_abort(CPU(cpu
), "I/O queue overrun for isc %d: %d\n",
437 isc
, env
->io_index
[isc
]);
440 q
= &env
->io_queue
[env
->io_index
[isc
]][isc
];
441 isc_bits
= ISC_TO_ISC_BITS(IO_INT_WORD_ISC(q
->word
));
442 if (!(env
->cregs
[6] & isc_bits
)) {
450 lowcore
= cpu_map_lowcore(env
);
452 lowcore
->subchannel_id
= cpu_to_be16(q
->id
);
453 lowcore
->subchannel_nr
= cpu_to_be16(q
->nr
);
454 lowcore
->io_int_parm
= cpu_to_be32(q
->parm
);
455 lowcore
->io_int_word
= cpu_to_be32(q
->word
);
456 lowcore
->io_old_psw
.mask
= cpu_to_be64(get_psw_mask(env
));
457 lowcore
->io_old_psw
.addr
= cpu_to_be64(env
->psw
.addr
);
458 mask
= be64_to_cpu(lowcore
->io_new_psw
.mask
);
459 addr
= be64_to_cpu(lowcore
->io_new_psw
.addr
);
461 cpu_unmap_lowcore(lowcore
);
463 env
->io_index
[isc
]--;
465 DPRINTF("%s: %" PRIx64
" %" PRIx64
"\n", __func__
,
466 env
->psw
.mask
, env
->psw
.addr
);
467 load_psw(env
, mask
, addr
);
469 if (env
->io_index
[isc
] >= 0) {
476 env
->pending_int
&= ~INTERRUPT_IO
;
481 static void do_mchk_interrupt(CPUS390XState
*env
)
483 S390CPU
*cpu
= s390_env_get_cpu(env
);
489 if (!(env
->psw
.mask
& PSW_MASK_MCHECK
)) {
490 cpu_abort(CPU(cpu
), "Machine check w/o mchk mask\n");
493 if (env
->mchk_index
< 0 || env
->mchk_index
>= MAX_MCHK_QUEUE
) {
494 cpu_abort(CPU(cpu
), "Mchk queue overrun: %d\n", env
->mchk_index
);
497 q
= &env
->mchk_queue
[env
->mchk_index
];
500 /* Don't know how to handle this... */
501 cpu_abort(CPU(cpu
), "Unknown machine check type %d\n", q
->type
);
503 if (!(env
->cregs
[14] & (1 << 28))) {
504 /* CRW machine checks disabled */
508 lowcore
= cpu_map_lowcore(env
);
510 for (i
= 0; i
< 16; i
++) {
511 lowcore
->floating_pt_save_area
[i
] = cpu_to_be64(get_freg(env
, i
)->ll
);
512 lowcore
->gpregs_save_area
[i
] = cpu_to_be64(env
->regs
[i
]);
513 lowcore
->access_regs_save_area
[i
] = cpu_to_be32(env
->aregs
[i
]);
514 lowcore
->cregs_save_area
[i
] = cpu_to_be64(env
->cregs
[i
]);
516 lowcore
->prefixreg_save_area
= cpu_to_be32(env
->psa
);
517 lowcore
->fpt_creg_save_area
= cpu_to_be32(env
->fpc
);
518 lowcore
->tod_progreg_save_area
= cpu_to_be32(env
->todpr
);
519 lowcore
->cpu_timer_save_area
[0] = cpu_to_be32(env
->cputm
>> 32);
520 lowcore
->cpu_timer_save_area
[1] = cpu_to_be32((uint32_t)env
->cputm
);
521 lowcore
->clock_comp_save_area
[0] = cpu_to_be32(env
->ckc
>> 32);
522 lowcore
->clock_comp_save_area
[1] = cpu_to_be32((uint32_t)env
->ckc
);
524 lowcore
->mcck_interruption_code
[0] = cpu_to_be32(0x00400f1d);
525 lowcore
->mcck_interruption_code
[1] = cpu_to_be32(0x40330000);
526 lowcore
->mcck_old_psw
.mask
= cpu_to_be64(get_psw_mask(env
));
527 lowcore
->mcck_old_psw
.addr
= cpu_to_be64(env
->psw
.addr
);
528 mask
= be64_to_cpu(lowcore
->mcck_new_psw
.mask
);
529 addr
= be64_to_cpu(lowcore
->mcck_new_psw
.addr
);
531 cpu_unmap_lowcore(lowcore
);
534 if (env
->mchk_index
== -1) {
535 env
->pending_int
&= ~INTERRUPT_MCHK
;
538 DPRINTF("%s: %" PRIx64
" %" PRIx64
"\n", __func__
,
539 env
->psw
.mask
, env
->psw
.addr
);
541 load_psw(env
, mask
, addr
);
544 void s390_cpu_do_interrupt(CPUState
*cs
)
546 S390CPU
*cpu
= S390_CPU(cs
);
547 CPUS390XState
*env
= &cpu
->env
;
549 qemu_log_mask(CPU_LOG_INT
, "%s: %d at pc=%" PRIx64
"\n",
550 __func__
, cs
->exception_index
, env
->psw
.addr
);
552 s390_cpu_set_state(CPU_STATE_OPERATING
, cpu
);
553 /* handle machine checks */
554 if ((env
->psw
.mask
& PSW_MASK_MCHECK
) &&
555 (cs
->exception_index
== -1)) {
556 if (env
->pending_int
& INTERRUPT_MCHK
) {
557 cs
->exception_index
= EXCP_MCHK
;
560 /* handle external interrupts */
561 if ((env
->psw
.mask
& PSW_MASK_EXT
) &&
562 cs
->exception_index
== -1) {
563 if (env
->pending_int
& INTERRUPT_EXT
) {
564 /* code is already in env */
565 cs
->exception_index
= EXCP_EXT
;
566 } else if (env
->pending_int
& INTERRUPT_TOD
) {
567 cpu_inject_ext(cpu
, 0x1004, 0, 0);
568 cs
->exception_index
= EXCP_EXT
;
569 env
->pending_int
&= ~INTERRUPT_EXT
;
570 env
->pending_int
&= ~INTERRUPT_TOD
;
571 } else if (env
->pending_int
& INTERRUPT_CPUTIMER
) {
572 cpu_inject_ext(cpu
, 0x1005, 0, 0);
573 cs
->exception_index
= EXCP_EXT
;
574 env
->pending_int
&= ~INTERRUPT_EXT
;
575 env
->pending_int
&= ~INTERRUPT_TOD
;
578 /* handle I/O interrupts */
579 if ((env
->psw
.mask
& PSW_MASK_IO
) &&
580 (cs
->exception_index
== -1)) {
581 if (env
->pending_int
& INTERRUPT_IO
) {
582 cs
->exception_index
= EXCP_IO
;
586 switch (cs
->exception_index
) {
588 do_program_interrupt(env
);
591 do_svc_interrupt(env
);
594 do_ext_interrupt(env
);
597 do_io_interrupt(env
);
600 do_mchk_interrupt(env
);
603 cs
->exception_index
= -1;
605 if (!env
->pending_int
) {
606 cs
->interrupt_request
&= ~CPU_INTERRUPT_HARD
;
610 bool s390_cpu_exec_interrupt(CPUState
*cs
, int interrupt_request
)
612 if (interrupt_request
& CPU_INTERRUPT_HARD
) {
613 S390CPU
*cpu
= S390_CPU(cs
);
614 CPUS390XState
*env
= &cpu
->env
;
616 if (env
->psw
.mask
& PSW_MASK_EXT
) {
617 s390_cpu_do_interrupt(cs
);
624 void s390_cpu_recompute_watchpoints(CPUState
*cs
)
626 const int wp_flags
= BP_CPU
| BP_MEM_WRITE
| BP_STOP_BEFORE_ACCESS
;
627 S390CPU
*cpu
= S390_CPU(cs
);
628 CPUS390XState
*env
= &cpu
->env
;
630 /* We are called when the watchpoints have changed. First
632 cpu_watchpoint_remove_all(cs
, BP_CPU
);
634 /* Return if PER is not enabled */
635 if (!(env
->psw
.mask
& PSW_MASK_PER
)) {
639 /* Return if storage-alteration event is not enabled. */
640 if (!(env
->cregs
[9] & PER_CR9_EVENT_STORE
)) {
644 if (env
->cregs
[10] == 0 && env
->cregs
[11] == -1LL) {
645 /* We can't create a watchoint spanning the whole memory range, so
646 split it in two parts. */
647 cpu_watchpoint_insert(cs
, 0, 1ULL << 63, wp_flags
, NULL
);
648 cpu_watchpoint_insert(cs
, 1ULL << 63, 1ULL << 63, wp_flags
, NULL
);
649 } else if (env
->cregs
[10] > env
->cregs
[11]) {
650 /* The address range loops, create two watchpoints. */
651 cpu_watchpoint_insert(cs
, env
->cregs
[10], -env
->cregs
[10],
653 cpu_watchpoint_insert(cs
, 0, env
->cregs
[11] + 1, wp_flags
, NULL
);
656 /* Default case, create a single watchpoint. */
657 cpu_watchpoint_insert(cs
, env
->cregs
[10],
658 env
->cregs
[11] - env
->cregs
[10] + 1,
663 void s390x_cpu_debug_excp_handler(CPUState
*cs
)
665 S390CPU
*cpu
= S390_CPU(cs
);
666 CPUS390XState
*env
= &cpu
->env
;
667 CPUWatchpoint
*wp_hit
= cs
->watchpoint_hit
;
669 if (wp_hit
&& wp_hit
->flags
& BP_CPU
) {
670 /* FIXME: When the storage-alteration-space control bit is set,
671 the exception should only be triggered if the memory access
672 is done using an address space with the storage-alteration-event
673 bit set. We have no way to detect that with the current
675 cs
->watchpoint_hit
= NULL
;
677 env
->per_address
= env
->psw
.addr
;
678 env
->per_perc_atmid
|= PER_CODE_EVENT_STORE
| get_per_atmid(env
);
679 /* FIXME: We currently no way to detect the address space used
680 to trigger the watchpoint. For now just consider it is the
681 current default ASC. This turn to be true except when MVCP
682 and MVCS instrutions are not used. */
683 env
->per_perc_atmid
|= env
->psw
.mask
& (PSW_MASK_ASC
) >> 46;
685 /* Remove all watchpoints to re-execute the code. A PER exception
686 will be triggered, it will call load_psw which will recompute
688 cpu_watchpoint_remove_all(cs
, BP_CPU
);
689 cpu_resume_from_signal(cs
, NULL
);
692 #endif /* CONFIG_USER_ONLY */