aboutsummaryrefslogtreecommitdiff
path: root/target-s390x/helper.c
diff options
context:
space:
mode:
Diffstat (limited to 'target-s390x/helper.c')
-rw-r--r--target-s390x/helper.c67
1 files changed, 33 insertions, 34 deletions
diff --git a/target-s390x/helper.c b/target-s390x/helper.c
index 42e06eb..9a132e6 100644
--- a/target-s390x/helper.c
+++ b/target-s390x/helper.c
@@ -99,10 +99,10 @@ void do_interrupt(CPUS390XState *env)
int cpu_s390x_handle_mmu_fault(CPUS390XState *env, target_ulong address,
int rw, int mmu_idx)
{
- /* fprintf(stderr, "%s: address 0x%lx rw %d mmu_idx %d\n",
- __func__, address, rw, mmu_idx); */
- env->exception_index = EXCP_ADDR;
- /* FIXME: find out how this works on a real machine */
+ env->exception_index = EXCP_PGM;
+ env->int_pgm_code = PGM_ADDRESSING;
+ /* On real machines this value is dropped into LowMem. Since this
+ is userland, simply put this someplace that cpu_loop can find it. */
env->__excp_addr = address;
return 1;
}
@@ -111,11 +111,11 @@ int cpu_s390x_handle_mmu_fault(CPUS390XState *env, target_ulong address,
/* Ensure to exit the TB after this call! */
static void trigger_pgm_exception(CPUS390XState *env, uint32_t code,
- uint32_t ilc)
+ uint32_t ilen)
{
env->exception_index = EXCP_PGM;
env->int_pgm_code = code;
- env->int_pgm_ilc = ilc;
+ env->int_pgm_ilen = ilen;
}
static int trans_bits(CPUS390XState *env, uint64_t mode)
@@ -143,30 +143,30 @@ static int trans_bits(CPUS390XState *env, uint64_t mode)
static void trigger_prot_fault(CPUS390XState *env, target_ulong vaddr,
uint64_t mode)
{
- int ilc = ILC_LATER_INC_2;
+ int ilen = ILEN_LATER_INC;
int bits = trans_bits(env, mode) | 4;
DPRINTF("%s: vaddr=%016" PRIx64 " bits=%d\n", __func__, vaddr, bits);
stq_phys(env->psa + offsetof(LowCore, trans_exc_code), vaddr | bits);
- trigger_pgm_exception(env, PGM_PROTECTION, ilc);
+ trigger_pgm_exception(env, PGM_PROTECTION, ilen);
}
static void trigger_page_fault(CPUS390XState *env, target_ulong vaddr,
uint32_t type, uint64_t asc, int rw)
{
- int ilc = ILC_LATER;
+ int ilen = ILEN_LATER;
int bits = trans_bits(env, asc);
+ /* Code accesses have an undefined ilc. */
if (rw == 2) {
- /* code has is undefined ilc */
- ilc = 2;
+ ilen = 2;
}
DPRINTF("%s: vaddr=%016" PRIx64 " bits=%d\n", __func__, vaddr, bits);
stq_phys(env->psa + offsetof(LowCore, trans_exc_code), vaddr | bits);
- trigger_pgm_exception(env, type, ilc);
+ trigger_pgm_exception(env, type, ilen);
}
static int mmu_translate_asce(CPUS390XState *env, target_ulong vaddr,
@@ -406,7 +406,7 @@ int cpu_s390x_handle_mmu_fault(CPUS390XState *env, target_ulong orig_vaddr,
if (raddr > (ram_size + virtio_size)) {
DPRINTF("%s: aaddr %" PRIx64 " > ram_size %" PRIx64 "\n", __func__,
(uint64_t)aaddr, (uint64_t)ram_size);
- trigger_pgm_exception(env, PGM_ADDRESSING, ILC_LATER);
+ trigger_pgm_exception(env, PGM_ADDRESSING, ILEN_LATER);
return 1;
}
@@ -454,18 +454,19 @@ void load_psw(CPUS390XState *env, uint64_t mask, uint64_t addr)
env->psw.addr = addr;
env->psw.mask = mask;
- env->cc_op = (mask >> 13) & 3;
+ env->cc_op = (mask >> 44) & 3;
}
static uint64_t get_psw_mask(CPUS390XState *env)
{
- uint64_t r = env->psw.mask;
+ uint64_t r;
env->cc_op = calc_cc(env, env->cc_op, env->cc_src, env->cc_dst, env->cc_vr);
- r &= ~(3ULL << 13);
+ r = env->psw.mask;
+ r &= ~PSW_MASK_CC;
assert(!(env->cc_op & ~3));
- r |= env->cc_op << 13;
+ r |= (uint64_t)env->cc_op << 44;
return r;
}
@@ -479,9 +480,9 @@ static void do_svc_interrupt(CPUS390XState *env)
lowcore = cpu_physical_memory_map(env->psa, &len, 1);
lowcore->svc_code = cpu_to_be16(env->int_svc_code);
- lowcore->svc_ilc = cpu_to_be16(env->int_svc_ilc);
+ lowcore->svc_ilen = cpu_to_be16(env->int_svc_ilen);
lowcore->svc_old_psw.mask = cpu_to_be64(get_psw_mask(env));
- lowcore->svc_old_psw.addr = cpu_to_be64(env->psw.addr + (env->int_svc_ilc));
+ lowcore->svc_old_psw.addr = cpu_to_be64(env->psw.addr + env->int_svc_ilen);
mask = be64_to_cpu(lowcore->svc_new_psw.mask);
addr = be64_to_cpu(lowcore->svc_new_psw.addr);
@@ -495,28 +496,26 @@ static void do_program_interrupt(CPUS390XState *env)
uint64_t mask, addr;
LowCore *lowcore;
hwaddr len = TARGET_PAGE_SIZE;
- int ilc = env->int_pgm_ilc;
+ int ilen = env->int_pgm_ilen;
- switch (ilc) {
- case ILC_LATER:
- ilc = get_ilc(cpu_ldub_code(env, env->psw.addr));
- break;
- case ILC_LATER_INC:
- ilc = get_ilc(cpu_ldub_code(env, env->psw.addr));
- env->psw.addr += ilc * 2;
+ switch (ilen) {
+ case ILEN_LATER:
+ ilen = get_ilen(cpu_ldub_code(env, env->psw.addr));
break;
- case ILC_LATER_INC_2:
- ilc = get_ilc(cpu_ldub_code(env, env->psw.addr)) * 2;
- env->psw.addr += ilc;
+ case ILEN_LATER_INC:
+ ilen = get_ilen(cpu_ldub_code(env, env->psw.addr));
+ env->psw.addr += ilen;
break;
+ default:
+ assert(ilen == 2 || ilen == 4 || ilen == 6);
}
- qemu_log_mask(CPU_LOG_INT, "%s: code=0x%x ilc=%d\n",
- __func__, env->int_pgm_code, ilc);
+ qemu_log_mask(CPU_LOG_INT, "%s: code=0x%x ilen=%d\n",
+ __func__, env->int_pgm_code, ilen);
lowcore = cpu_physical_memory_map(env->psa, &len, 1);
- lowcore->pgm_ilc = cpu_to_be16(ilc);
+ lowcore->pgm_ilen = cpu_to_be16(ilen);
lowcore->pgm_code = cpu_to_be16(env->int_pgm_code);
lowcore->program_old_psw.mask = cpu_to_be64(get_psw_mask(env));
lowcore->program_old_psw.addr = cpu_to_be64(env->psw.addr);
@@ -526,7 +525,7 @@ static void do_program_interrupt(CPUS390XState *env)
cpu_physical_memory_unmap(lowcore, len, 1, len);
DPRINTF("%s: %x %x %" PRIx64 " %" PRIx64 "\n", __func__,
- env->int_pgm_code, ilc, env->psw.mask,
+ env->int_pgm_code, ilen, env->psw.mask,
env->psw.addr);
load_psw(env, mask, addr);