diff options
author | Thomas Huth | 2017-05-18 19:26:40 +0200 |
---|---|---|
committer | Richard Henderson | 2017-06-06 23:34:31 +0200 |
commit | f79f1ca4a20d4070179903bbaafc13f5f90b7873 (patch) | |
tree | 5921a73bc3333cde97f964bda0daab4999789405 /target/s390x/mem_helper.c | |
parent | Merge remote-tracking branch 'remotes/xtensa/tags/20170606-xtensa' into staging (diff) | |
download | qemu-f79f1ca4a20d4070179903bbaafc13f5f90b7873.tar.gz qemu-f79f1ca4a20d4070179903bbaafc13f5f90b7873.tar.xz qemu-f79f1ca4a20d4070179903bbaafc13f5f90b7873.zip |
target/s390x: Add support for the TEST BLOCK instruction
TEST BLOCK was likely once used to execute basic memory
tests, but nowadays it's just a (slow) way to clear a page.
Reviewed-by: Aurelien Jarno <aurelien@aurel32.net>
Reviewed-by: David Hildenbrand <david@redhat.com>
Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Thomas Huth <thuth@redhat.com>
Message-Id: <1495128400-23759-1-git-send-email-thuth@redhat.com>
Signed-off-by: Richard Henderson <rth@twiddle.net>
Diffstat (limited to 'target/s390x/mem_helper.c')
-rw-r--r-- | target/s390x/mem_helper.c | 28 |
1 files changed, 28 insertions, 0 deletions
diff --git a/target/s390x/mem_helper.c b/target/s390x/mem_helper.c index f6e5bcec5d..0c6a0d9612 100644 --- a/target/s390x/mem_helper.c +++ b/target/s390x/mem_helper.c @@ -20,6 +20,7 @@ #include "qemu/osdep.h" #include "cpu.h" +#include "exec/address-spaces.h" #include "exec/helper-proto.h" #include "exec/exec-all.h" #include "exec/cpu_ldst.h" @@ -973,6 +974,33 @@ void HELPER(stctl)(CPUS390XState *env, uint32_t r1, uint64_t a2, uint32_t r3) } } +uint32_t HELPER(testblock)(CPUS390XState *env, uint64_t real_addr) +{ + CPUState *cs = CPU(s390_env_get_cpu(env)); + uint64_t abs_addr; + int i; + + real_addr = fix_address(env, real_addr); + abs_addr = mmu_real2abs(env, real_addr) & TARGET_PAGE_MASK; + if (!address_space_access_valid(&address_space_memory, abs_addr, + TARGET_PAGE_SIZE, true)) { + program_interrupt(env, PGM_ADDRESSING, 4); + return 1; + } + + /* Check low-address protection */ + if ((env->cregs[0] & CR0_LOWPROT) && real_addr < 0x2000) { + program_interrupt(env, PGM_PROTECTION, 4); + return 1; + } + + for (i = 0; i < TARGET_PAGE_SIZE; i += 8) { + stq_phys(cs->as, abs_addr + i, 0); + } + + return 0; +} + uint32_t HELPER(tprot)(uint64_t a1, uint64_t a2) { /* XXX implement */ |