summary refs log tree commit diff stats
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 42e06eb85e..9a132e6d2c 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);