mmu_helper.c (3dc29061f3291bf0b6cda9cc7bc04aa94101b52e) | mmu_helper.c (3a06f981925bfade8f5e650655fce0b38dbd6649) |
---|---|
1/* 2 * S390x MMU related functions 3 * 4 * Copyright (c) 2011 Alexander Graf 5 * Copyright (c) 2015 Thomas Huth, IBM Corporation 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by --- 107 unchanged lines hidden (view full) --- 116 117static int mmu_translate_asce(CPUS390XState *env, target_ulong vaddr, 118 uint64_t asc, uint64_t asce, target_ulong *raddr, 119 int *flags, int rw, bool exc) 120{ 121 const bool edat1 = (env->cregs[0] & CR0_EDAT) && 122 s390_has_feat(S390_FEAT_EDAT); 123 const bool edat2 = edat1 && s390_has_feat(S390_FEAT_EDAT_2); | 1/* 2 * S390x MMU related functions 3 * 4 * Copyright (c) 2011 Alexander Graf 5 * Copyright (c) 2015 Thomas Huth, IBM Corporation 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by --- 107 unchanged lines hidden (view full) --- 116 117static int mmu_translate_asce(CPUS390XState *env, target_ulong vaddr, 118 uint64_t asc, uint64_t asce, target_ulong *raddr, 119 int *flags, int rw, bool exc) 120{ 121 const bool edat1 = (env->cregs[0] & CR0_EDAT) && 122 s390_has_feat(S390_FEAT_EDAT); 123 const bool edat2 = edat1 && s390_has_feat(S390_FEAT_EDAT_2); |
124 const bool iep = (env->cregs[0] & CR0_IEP) && 125 s390_has_feat(S390_FEAT_INSTRUCTION_EXEC_PROT); |
|
124 const int asce_tl = asce & ASCE_TABLE_LENGTH; 125 const int asce_p = asce & ASCE_PRIVATE_SPACE; 126 hwaddr gaddr = asce & ASCE_ORIGIN; 127 uint64_t entry; 128 129 if (asce & ASCE_REAL_SPACE) { 130 /* direct mapping */ 131 *raddr = vaddr; --- 88 unchanged lines hidden (view full) --- 220 } 221 if (edat2 && (entry & REGION3_ENTRY_CR) && asce_p) { 222 return PGM_TRANS_SPEC; 223 } 224 if (edat1 && (entry & REGION_ENTRY_P)) { 225 *flags &= ~PAGE_WRITE; 226 } 227 if (edat2 && (entry & REGION3_ENTRY_FC)) { | 126 const int asce_tl = asce & ASCE_TABLE_LENGTH; 127 const int asce_p = asce & ASCE_PRIVATE_SPACE; 128 hwaddr gaddr = asce & ASCE_ORIGIN; 129 uint64_t entry; 130 131 if (asce & ASCE_REAL_SPACE) { 132 /* direct mapping */ 133 *raddr = vaddr; --- 88 unchanged lines hidden (view full) --- 222 } 223 if (edat2 && (entry & REGION3_ENTRY_CR) && asce_p) { 224 return PGM_TRANS_SPEC; 225 } 226 if (edat1 && (entry & REGION_ENTRY_P)) { 227 *flags &= ~PAGE_WRITE; 228 } 229 if (edat2 && (entry & REGION3_ENTRY_FC)) { |
230 if (iep && (entry & REGION3_ENTRY_IEP)) { 231 *flags &= ~PAGE_EXEC; 232 } |
|
228 *raddr = (entry & REGION3_ENTRY_RFAA) | 229 (vaddr & ~REGION3_ENTRY_RFAA); 230 return 0; 231 } 232 if (VADDR_SEGMENT_TL(vaddr) < (entry & REGION_ENTRY_TF) >> 6 || 233 VADDR_SEGMENT_TL(vaddr) > (entry & REGION_ENTRY_TL)) { 234 return PGM_SEGMENT_TRANS; 235 } --- 11 unchanged lines hidden (view full) --- 247 } 248 if ((entry & SEGMENT_ENTRY_CS) && asce_p) { 249 return PGM_TRANS_SPEC; 250 } 251 if (entry & SEGMENT_ENTRY_P) { 252 *flags &= ~PAGE_WRITE; 253 } 254 if (edat1 && (entry & SEGMENT_ENTRY_FC)) { | 233 *raddr = (entry & REGION3_ENTRY_RFAA) | 234 (vaddr & ~REGION3_ENTRY_RFAA); 235 return 0; 236 } 237 if (VADDR_SEGMENT_TL(vaddr) < (entry & REGION_ENTRY_TF) >> 6 || 238 VADDR_SEGMENT_TL(vaddr) > (entry & REGION_ENTRY_TL)) { 239 return PGM_SEGMENT_TRANS; 240 } --- 11 unchanged lines hidden (view full) --- 252 } 253 if ((entry & SEGMENT_ENTRY_CS) && asce_p) { 254 return PGM_TRANS_SPEC; 255 } 256 if (entry & SEGMENT_ENTRY_P) { 257 *flags &= ~PAGE_WRITE; 258 } 259 if (edat1 && (entry & SEGMENT_ENTRY_FC)) { |
260 if (iep && (entry & SEGMENT_ENTRY_IEP)) { 261 *flags &= ~PAGE_EXEC; 262 } |
|
255 *raddr = (entry & SEGMENT_ENTRY_SFAA) | 256 (vaddr & ~SEGMENT_ENTRY_SFAA); 257 return 0; 258 } 259 gaddr = (entry & SEGMENT_ENTRY_ORIGIN) + VADDR_PAGE_TX(vaddr) * 8; 260 break; 261 } 262 --- 4 unchanged lines hidden (view full) --- 267 return PGM_PAGE_TRANS; 268 } 269 if (entry & PAGE_ENTRY_0) { 270 return PGM_TRANS_SPEC; 271 } 272 if (entry & PAGE_ENTRY_P) { 273 *flags &= ~PAGE_WRITE; 274 } | 263 *raddr = (entry & SEGMENT_ENTRY_SFAA) | 264 (vaddr & ~SEGMENT_ENTRY_SFAA); 265 return 0; 266 } 267 gaddr = (entry & SEGMENT_ENTRY_ORIGIN) + VADDR_PAGE_TX(vaddr) * 8; 268 break; 269 } 270 --- 4 unchanged lines hidden (view full) --- 275 return PGM_PAGE_TRANS; 276 } 277 if (entry & PAGE_ENTRY_0) { 278 return PGM_TRANS_SPEC; 279 } 280 if (entry & PAGE_ENTRY_P) { 281 *flags &= ~PAGE_WRITE; 282 } |
283 if (iep && (entry & PAGE_ENTRY_IEP)) { 284 *flags &= ~PAGE_EXEC; 285 } |
|
275 276 *raddr = entry & TARGET_PAGE_MASK; 277 return 0; 278} 279 280static void mmu_handle_skey(target_ulong addr, int rw, int *flags) 281{ 282 static S390SKeysClass *skeyclass; --- 142 unchanged lines hidden (view full) --- 425 if (exc) { 426 /* DAT sets bit 61 only */ 427 tec |= 0x4; 428 trigger_access_exception(env, PGM_PROTECTION, ilen, tec); 429 } 430 return -1; 431 } 432 | 286 287 *raddr = entry & TARGET_PAGE_MASK; 288 return 0; 289} 290 291static void mmu_handle_skey(target_ulong addr, int rw, int *flags) 292{ 293 static S390SKeysClass *skeyclass; --- 142 unchanged lines hidden (view full) --- 436 if (exc) { 437 /* DAT sets bit 61 only */ 438 tec |= 0x4; 439 trigger_access_exception(env, PGM_PROTECTION, ilen, tec); 440 } 441 return -1; 442 } 443 |
444 /* check for Instruction-Execution-Protection */ 445 if (unlikely(rw == MMU_INST_FETCH && !(*flags & PAGE_EXEC))) { 446 if (exc) { 447 /* IEP sets bit 56 and 61 */ 448 tec |= 0x84; 449 trigger_access_exception(env, PGM_PROTECTION, ilen, tec); 450 } 451 return -1; 452 } 453 |
|
433nodat: 434 /* Convert real address -> absolute address */ 435 *raddr = mmu_real2abs(env, *raddr); 436 437 mmu_handle_skey(*raddr, rw, flags); 438 return 0; 439} 440 --- 122 unchanged lines hidden --- | 454nodat: 455 /* Convert real address -> absolute address */ 456 *raddr = mmu_real2abs(env, *raddr); 457 458 mmu_handle_skey(*raddr, rw, flags); 459 return 0; 460} 461 --- 122 unchanged lines hidden --- |