From: Thomas Huth <[email protected]> With the EDAT-1 facility, the MMU translation can stop at the segment table already, pointing to a 1 MB block.
Signed-off-by: Thomas Huth <[email protected]> Signed-off-by: Jens Freimann <[email protected]> Reviewed-by: David Hildenbrand <[email protected]> --- target-s390x/cpu.h | 4 ++++ target-s390x/helper.c | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h index f332d41..686d458 100644 --- a/target-s390x/cpu.h +++ b/target-s390x/cpu.h @@ -267,6 +267,9 @@ typedef struct CPUS390XState { #define FLAG_MASK_64 (PSW_MASK_64 >> 32) #define FLAG_MASK_32 0x00001000 +/* Control register 0 bits */ +#define CR0_EDAT 0x0000000000800000ULL + static inline int cpu_mmu_index (CPUS390XState *env) { if (env->psw.mask & PSW_MASK_PSTATE) { @@ -924,6 +927,7 @@ struct sysib_322 { #define _REGION_ENTRY_LENGTH 0x03 /* region third length */ #define _SEGMENT_ENTRY_ORIGIN ~0x7ffULL /* segment table origin */ +#define _SEGMENT_ENTRY_FC 0x400 /* format control */ #define _SEGMENT_ENTRY_RO 0x200 /* page protection bit */ #define _SEGMENT_ENTRY_INV 0x20 /* invalid segment table entry */ diff --git a/target-s390x/helper.c b/target-s390x/helper.c index aa628b8..89dc6e7 100644 --- a/target-s390x/helper.c +++ b/target-s390x/helper.c @@ -217,6 +217,10 @@ static int mmu_translate_asce(CPUS390XState *env, target_ulong vaddr, offs = (vaddr >> 17) & 0x3ff8; break; case _ASCE_TYPE_SEGMENT: + if (env && (env->cregs[0] & CR0_EDAT) && (asce & _SEGMENT_ENTRY_FC)) { + *raddr = (asce & 0xfffffffffff00000ULL) | (vaddr & 0xfffff); + return 0; + } offs = (vaddr >> 9) & 0x07f8; origin = asce & _SEGMENT_ENTRY_ORIGIN; break; -- 1.8.5.5
