summaryrefslogtreecommitdiff
path: root/target-s390x/op_helper.c
diff options
context:
space:
mode:
authorBlue Swirl <blauwirbel@gmail.com>2011-11-19 11:17:58 +0000
committerBlue Swirl <blauwirbel@gmail.com>2011-11-19 11:17:58 +0000
commit25cc4a768d91817bc3b4bf9b3a270c4791509cd7 (patch)
tree78a65c66213c777fd87d68192ab82bc0f80b6d1e /target-s390x/op_helper.c
parent05a86f23e5ca83348eface349429341cefb8697b (diff)
parent326384d5b6dcea69ca44695ee807f8b50234ab71 (diff)
downloadqemu-25cc4a768d91817bc3b4bf9b3a270c4791509cd7.tar.gz
Merge branch 's390-1.0' of git://repo.or.cz/qemu/agraf
* 's390-1.0' of git://repo.or.cz/qemu/agraf: s390x: initialize virtio dev region tcg: Use TCGReg for standard tcg-target entry points. tcg: Standardize on TCGReg as the enum for hard registers s390x: Add shutdown for TCG s390-virtio machine s390: Fix cpu shutdown for KVM s390: fix short kernel command lines s390: fix reset hypercall to reset the status s390x: implement SIGP restart and shutdown s390x: implement rrbe instruction properly s390x: update R and C bits in storage key s390x: make ipte 31-bit aware s390x: add ldeb instruction
Diffstat (limited to 'target-s390x/op_helper.c')
-rw-r--r--target-s390x/op_helper.c43
1 files changed, 37 insertions, 6 deletions
diff --git a/target-s390x/op_helper.c b/target-s390x/op_helper.c
index cd57678150..137bae74a0 100644
--- a/target-s390x/op_helper.c
+++ b/target-s390x/op_helper.c
@@ -29,6 +29,10 @@
#include <linux/kvm.h>
#endif
+#if !defined (CONFIG_USER_ONLY)
+#include "sysemu.h"
+#endif
+
/*****************************************************************************/
/* Softmmu support */
#if !defined (CONFIG_USER_ONLY)
@@ -1631,6 +1635,15 @@ void HELPER(maebr)(uint32_t f1, uint32_t f3, uint32_t f2)
&env->fpu_status);
}
+/* convert 32-bit float to 64-bit float */
+void HELPER(ldeb)(uint32_t f1, uint64_t a2)
+{
+ uint32_t v2;
+ v2 = ldl(a2);
+ env->fregs[f1].d = float32_to_float64(v2,
+ &env->fpu_status);
+}
+
/* convert 64-bit float to 128-bit float */
void HELPER(lxdb)(uint32_t f1, uint64_t a2)
{
@@ -2752,7 +2765,6 @@ uint64_t HELPER(iske)(uint64_t r2)
return 0;
}
- /* XXX maybe use qemu's internal keys? */
return env->storage_keys[addr / TARGET_PAGE_SIZE];
}
@@ -2771,14 +2783,15 @@ void HELPER(sske)(uint32_t r1, uint64_t r2)
/* reset reference bit extended */
uint32_t HELPER(rrbe)(uint32_t r1, uint64_t r2)
{
+ uint8_t re;
+ uint8_t key;
if (r2 > ram_size) {
return 0;
}
- /* XXX implement */
-#if 0
- env->storage_keys[r2 / TARGET_PAGE_SIZE] &= ~SK_REFERENCED;
-#endif
+ key = env->storage_keys[r2 / TARGET_PAGE_SIZE];
+ re = key & (SK_R | SK_C);
+ env->storage_keys[r2 / TARGET_PAGE_SIZE] = (key & ~SK_R);
/*
* cc
@@ -2788,7 +2801,8 @@ uint32_t HELPER(rrbe)(uint32_t r1, uint64_t r2)
* 2 Reference bit one; change bit zero
* 3 Reference bit one; change bit one
*/
- return 0;
+
+ return re >> 1;
}
/* compare and swap and purge */
@@ -2891,6 +2905,16 @@ uint32_t HELPER(sigp)(uint64_t order_code, uint32_t r1, uint64_t cpu_addr)
env->regs[r1] &= 0xffffffff00000000ULL;
cc = 1;
break;
+#if !defined (CONFIG_USER_ONLY)
+ case SIGP_RESTART:
+ qemu_system_reset_request();
+ cpu_loop_exit(env);
+ break;
+ case SIGP_STOP:
+ qemu_system_shutdown_request();
+ cpu_loop_exit(env);
+ break;
+#endif
default:
/* unknown sigp */
fprintf(stderr, "XXX unknown sigp: 0x%" PRIx64 "\n", order_code);
@@ -2941,6 +2965,13 @@ void HELPER(ipte)(uint64_t pte_addr, uint64_t vaddr)
/* XXX we exploit the fact that Linux passes the exact virtual
address here - it's not obliged to! */
tlb_flush_page(env, page);
+
+ /* XXX 31-bit hack */
+ if (page & 0x80000000) {
+ tlb_flush_page(env, page & ~0x80000000);
+ } else {
+ tlb_flush_page(env, page | 0x80000000);
+ }
}
/* flush local tlb */