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 ---