1 /* INLINE.H (c) Copyright Jan Jaeger, 2000-2009 */
2 /* Inline function definitions */
3
4 /* Original author Roger Bowler, 1999 */
5 /* Interpretive Execution - (c) Copyright Jan Jaeger, 1999-2009 */
6 /* z/Architecture support - (c) Copyright Jan Jaeger, 1999-2009 */
7
8 /* Storage protection override fix Jan Jaeger 31/08/00 */
9 /* ESAME low-address protection v208d Roger Bowler 20/01/01 */
10 /* ESAME subspace replacement v208e Roger Bowler 27/01/01 */
11 /* Multiply/Divide Logical instructions Vic Cross 13/02/2001 */
12
13 // #define INLINE_STORE_FETCH_ADDR_CHECK
14
15 #if defined(FEATURE_DUAL_ADDRESS_SPACE)
16 _DAT_C_STATIC U16 ARCH_DEP(translate_asn) (U16 asn, REGS *regs,
17 U32 *asteo, U32 aste[]);
18 _DAT_C_STATIC int ARCH_DEP(authorize_asn) (U16 ax, U32 aste[],
19 int atemask, REGS *regs);
20 #endif
21 #if defined(FEATURE_ACCESS_REGISTERS)
22 _DAT_C_STATIC U16 ARCH_DEP(translate_alet) (U32 alet, U16 eax,
23 int acctype, REGS *regs, U32 *asteo, U32 aste[]);
24 _DAT_C_STATIC void ARCH_DEP(purge_alb_all) ();
25 _DAT_C_STATIC void ARCH_DEP(purge_alb) (REGS *regs);
26 #endif
27 _DAT_C_STATIC int ARCH_DEP(translate_addr) (VADR vaddr, int arn,
28 REGS *regs, int acctype);
29 _DAT_C_STATIC void ARCH_DEP(purge_tlb_all) ();
30 _DAT_C_STATIC void ARCH_DEP(purge_tlb) (REGS *regs);
31 _DAT_C_STATIC void ARCH_DEP(purge_tlbe_all) (RADR pfra);
32 _DAT_C_STATIC void ARCH_DEP(purge_tlbe) (REGS *regs, RADR pfra);
33 _DAT_C_STATIC void ARCH_DEP(invalidate_tlb) (REGS *regs, BYTE mask);
34 #if ARCH_MODE == ARCH_390 && defined(_900)
35 _DAT_C_STATIC void z900_invalidate_tlb (REGS *regs, BYTE mask);
36 #endif
37 _DAT_C_STATIC void ARCH_DEP(invalidate_tlbe) (REGS *regs, BYTE *main);
38 _DAT_C_STATIC void ARCH_DEP(invalidate_pte) (BYTE ibyte, RADR op1,
39 U32 op2, REGS *regs);
40 _LOGICAL_C_STATIC BYTE *ARCH_DEP(logical_to_main) (VADR addr, int arn,
41 REGS *regs, int acctype, BYTE akey);
42
43 #if defined(_FEATURE_SIE) && ARCH_MODE != ARCH_900
44 _LOGICAL_C_STATIC BYTE *s390_logical_to_main (U32 addr, int arn, REGS *regs,
45 int acctype, BYTE akey);
46 _DAT_C_STATIC int s390_translate_addr (U32 vaddr, int arn, REGS *regs,
47 int acctype);
48 #endif /*defined(_FEATURE_SIE)*/
49
50 #if defined(_FEATURE_ZSIE)
51 _LOGICAL_C_STATIC BYTE *z900_logical_to_main (U64 addr, int arn, REGS *regs,
52 int acctype, BYTE akey);
53 _DAT_C_STATIC int z900_translate_addr (U64 vaddr, int arn, REGS *regs,
54 int acctype);
55 #endif /*defined(_FEATURE_ZSIE)*/
56
57 _VSTORE_C_STATIC void ARCH_DEP(vstorec) (void *src, BYTE len,
58 VADR addr, int arn, REGS *regs);
59 _VSTORE_C_STATIC void ARCH_DEP(vstoreb) (BYTE value, VADR addr,
60 int arn, REGS *regs);
61 _VSTORE_C_STATIC void ARCH_DEP(vstore2) (U16 value, VADR addr, int arn,
62 REGS *regs);
63 _VSTORE_C_STATIC void ARCH_DEP(vstore4) (U32 value, VADR addr, int arn,
64 REGS *regs);
65 _VSTORE_C_STATIC void ARCH_DEP(vstore8) (U64 value, VADR addr, int arn,
66 REGS *regs);
67 _VSTORE_C_STATIC void ARCH_DEP(vfetchc) (void *dest, BYTE len,
68 VADR addr, int arn, REGS *regs);
69 _VSTORE_C_STATIC BYTE ARCH_DEP(vfetchb) (VADR addr, int arn,
70 REGS *regs);
71 _VSTORE_C_STATIC U16 ARCH_DEP(vfetch2) (VADR addr, int arn,
72 REGS *regs);
73 _VSTORE_C_STATIC U32 ARCH_DEP(vfetch4) (VADR addr, int arn,
74 REGS *regs);
75 _VSTORE_C_STATIC U64 ARCH_DEP(vfetch8) (VADR addr, int arn,
76 REGS *regs);
77 _VSTORE_C_STATIC void ARCH_DEP(move_chars) (VADR addr1, int arn1,
78 BYTE key1, VADR addr2, int arn2, BYTE key2, int len, REGS *regs);
79 _VSTORE_C_STATIC void ARCH_DEP(validate_operand) (VADR addr, int arn,
80 int len, int acctype, REGS *regs);
81 _VFETCH_C_STATIC BYTE * ARCH_DEP(instfetch) (REGS *regs, int exec);
82
83 #if defined(_FEATURE_SIE) && defined(_370) && !defined(_IEEE_C_)
84 _VFETCH_C_STATIC BYTE * s370_instfetch (REGS *regs, int exec);
85 #endif /*defined(_FEATURE_SIE)*/
86
87 #if defined(_FEATURE_ZSIE) && defined(_900)
88 _VFETCH_C_STATIC BYTE * s390_instfetch (REGS *regs, int exec);
89 #endif /*defined(_FEATURE_ZSIE)*/
90
91 #if !defined(_INLINE_H)
92
93 #define _INLINE_H
94
95
96 /*-------------------------------------------------------------------*/
97 /* Add two unsigned fullwords giving an unsigned fullword result */
98 /* and return the condition code for the AL or ALR instruction */
99 /*-------------------------------------------------------------------*/
add_logical(U32 * result,U32 op1,U32 op2)100 static inline int add_logical(U32 *result, U32 op1, U32 op2)
101 {
102 *result = op1 + op2;
103 return (*result == 0 ? 0 : 1) | (op1 > *result ? 2 : 0);
104 } /* end function add_logical */
105
106
107 /*-------------------------------------------------------------------*/
108 /* Subtract two unsigned fullwords giving unsigned fullword result */
109 /* and return the condition code for the SL or SLR instruction */
110 /*-------------------------------------------------------------------*/
sub_logical(U32 * result,U32 op1,U32 op2)111 static inline int sub_logical(U32 *result, U32 op1, U32 op2)
112 {
113 *result = op1 - op2;
114 return (*result == 0 ? 0 : 1) | (op1 < *result ? 0 : 2);
115 } /* end function sub_logical */
116
117
118 /*-------------------------------------------------------------------*/
119 /* Add two signed fullwords giving a signed fullword result */
120 /* and return the condition code for the A or AR instruction */
121 /*-------------------------------------------------------------------*/
add_signed(U32 * result,U32 op1,U32 op2)122 static inline int add_signed(U32 *result, U32 op1, U32 op2)
123 {
124 *result = (S32)op1 + (S32)op2;
125
126 return ((S32)*result > 0) ?
127 ((S32)op1 < 0 && (S32)op2 < 0) ? 3 : 2 :
128 ((S32)*result < 0) ?
129 ((S32)op1 >= 0 && (S32)op2 >= 0) ? 3 : 1 :
130 ((S32)op1 < 0 && (S32)op2 < 0) ? 3 : 0;
131
132 /* return (((S32)op1 < 0 && (S32)op2 < 0 && (S32)*result >= 0)
133 || ((S32)op1 >= 0 && (S32)op2 >= 0 && (S32)*result < 0)) ? 3 :
134 (S32)*result < 0 ? 1 :
135 (S32)*result > 0 ? 2 : 0; */
136 } /* end function add_signed */
137
138
139 /*-------------------------------------------------------------------*/
140 /* Subtract two signed fullwords giving a signed fullword result */
141 /* and return the condition code for the S or SR instruction */
142 /*-------------------------------------------------------------------*/
sub_signed(U32 * result,U32 op1,U32 op2)143 static inline int sub_signed(U32 *result, U32 op1, U32 op2)
144 {
145 *result = (S32)op1 - (S32)op2;
146
147 return ((S32)*result > 0) ?
148 ((S32)op1 < 0 && (S32)op2 >= 0) ? 3 : 2 :
149 ((S32)*result < 0) ?
150 ((S32)op1 >= 0 && (S32)op2 < 0) ? 3 : 1 :
151 ((S32)op1 < 0 && (S32)op2 >= 0) ? 3 : 0;
152
153 /* return (((S32)op1 < 0 && (S32)op2 >= 0 && (S32)*result >= 0)
154 || ((S32)op1 >= 0 && (S32)op2 < 0 && (S32)*result < 0)) ? 3 :
155 (S32)*result < 0 ? 1 :
156 (S32)*result > 0 ? 2 : 0; */
157 } /* end function sub_signed */
158
159
160 /*-------------------------------------------------------------------*/
161 /* Multiply two signed fullwords giving a signed doubleword result */
162 /*-------------------------------------------------------------------*/
mul_signed(U32 * resulthi,U32 * resultlo,U32 op1,U32 op2)163 static inline void mul_signed ( U32 *resulthi, U32 *resultlo,
164 U32 op1, U32 op2 )
165 {
166 S64 r;
167
168 r = (S64)(S32)op1 * (S32)op2;
169 *resulthi = (U32)((U64)r >> 32);
170 *resultlo = (U32)((U64)r & 0xFFFFFFFF);
171 } /* end function mul_signed */
172
173
174 /*-------------------------------------------------------------------*/
175 /* Divide a signed doubleword dividend by a signed fullword divisor */
176 /* giving a signed fullword remainder and a signed fullword quotient.*/
177 /* Returns 0 if successful, 1 if divide overflow. */
178 /*-------------------------------------------------------------------*/
div_signed(U32 * remainder,U32 * quotient,U32 dividendhi,U32 dividendlo,U32 divisor)179 static inline int div_signed ( U32 *remainder, U32 *quotient,
180 U32 dividendhi, U32 dividendlo, U32 divisor )
181 {
182 U64 dividend;
183 S64 quot, rem;
184
185 if (divisor == 0) return 1;
186 dividend = (U64)dividendhi << 32 | dividendlo;
187 quot = (S64)dividend / (S32)divisor;
188 rem = (S64)dividend % (S32)divisor;
189 if (quot < -2147483648LL || quot > 2147483647LL) return 1;
190 *quotient = (U32)quot;
191 *remainder = (U32)rem;
192 return 0;
193 } /* end function div_signed */
194
195 /*
196 * The following routines were moved from esame.c rev 1.139 21oct2005
197 */
198
199 /*-------------------------------------------------------------------*/
200 /* Add two unsigned doublewords giving an unsigned doubleword result */
201 /* and return the condition code for the ALG or ALGR instruction */
202 /*-------------------------------------------------------------------*/
add_logical_long(U64 * result,U64 op1,U64 op2)203 static inline int add_logical_long(U64 *result, U64 op1, U64 op2)
204 {
205 *result = op1 + op2;
206 return (*result == 0 ? 0 : 1) | (op1 > *result ? 2 : 0);
207 } /* end function add_logical_long */
208
209
210 /*-------------------------------------------------------------------*/
211 /* Subtract unsigned doublewords giving unsigned doubleword result */
212 /* and return the condition code for the SLG or SLGR instruction */
213 /*-------------------------------------------------------------------*/
sub_logical_long(U64 * result,U64 op1,U64 op2)214 static inline int sub_logical_long(U64 *result, U64 op1, U64 op2)
215 {
216 *result = op1 - op2;
217 return (*result == 0 ? 0 : 1) | (op1 < *result ? 0 : 2);
218 } /* end function sub_logical_long */
219
220
221 /*-------------------------------------------------------------------*/
222 /* Add two signed doublewords giving a signed doubleword result */
223 /* and return the condition code for the AG or AGR instruction */
224 /*-------------------------------------------------------------------*/
add_signed_long(U64 * result,U64 op1,U64 op2)225 static inline int add_signed_long(U64 *result, U64 op1, U64 op2)
226 {
227 *result = (S64)op1 + (S64)op2;
228
229 return (((S64)op1 < 0 && (S64)op2 < 0 && (S64)*result >= 0)
230 || ((S64)op1 >= 0 && (S64)op2 >= 0 && (S64)*result < 0)) ? 3 :
231 (S64)*result < 0 ? 1 :
232 (S64)*result > 0 ? 2 : 0;
233 } /* end function add_signed_long */
234
235
236 /*-------------------------------------------------------------------*/
237 /* Subtract two signed doublewords giving signed doubleword result */
238 /* and return the condition code for the SG or SGR instruction */
239 /*-------------------------------------------------------------------*/
sub_signed_long(U64 * result,U64 op1,U64 op2)240 static inline int sub_signed_long(U64 *result, U64 op1, U64 op2)
241 {
242 *result = (S64)op1 - (S64)op2;
243
244 return (((S64)op1 < 0 && (S64)op2 >= 0 && (S64)*result >= 0)
245 || ((S64)op1 >= 0 && (S64)op2 < 0 && (S64)*result < 0)) ? 3 :
246 (S64)*result < 0 ? 1 :
247 (S64)*result > 0 ? 2 : 0;
248 } /* end function sub_signed_long */
249
250
251 /*-------------------------------------------------------------------*/
252 /* Divide an unsigned 128-bit dividend by an unsigned 64-bit divisor */
253 /* giving unsigned 64-bit remainder and unsigned 64-bit quotient. */
254 /* Returns 0 if successful, 1 if divide overflow. */
255 /*-------------------------------------------------------------------*/
div_logical_long(U64 * rem,U64 * quot,U64 high,U64 lo,U64 d)256 static inline int div_logical_long
257 (U64 *rem, U64 *quot, U64 high, U64 lo, U64 d)
258 {
259 int i;
260
261 *quot = 0;
262 if (high >= d) return 1;
263 for (i = 0; i < 64; i++)
264 {
265 int ovf;
266 ovf = high >> 63;
267 high = (high << 1) | (lo >> 63);
268 lo <<= 1;
269 *quot <<= 1;
270 if (high >= d || ovf)
271 {
272 *quot += 1;
273 high -= d;
274 }
275 }
276 *rem = high;
277 return 0;
278 } /* end function div_logical_long */
279
280
281 /*-------------------------------------------------------------------*/
282 /* Multiply two unsigned doublewords giving unsigned 128-bit result */
283 /*-------------------------------------------------------------------*/
mult_logical_long(U64 * high,U64 * lo,U64 md,U64 mr)284 static inline int mult_logical_long
285 (U64 *high, U64 *lo, U64 md, U64 mr)
286 {
287 int i;
288
289 *high = 0; *lo = 0;
290 for (i = 0; i < 64; i++)
291 {
292 U64 ovf;
293 ovf = *high;
294 if (md & 1)
295 *high += mr;
296 md >>= 1;
297 *lo = (*lo >> 1) | (*high << 63);
298 if(ovf > *high)
299 *high = (*high >> 1) | 0x8000000000000000ULL;
300 else
301 *high >>= 1;
302 }
303 return 0;
304 } /* end function mult_logical_long */
305
306
307 #endif /*!defined(_INLINE_H)*/
308
309
310 /*-------------------------------------------------------------------*/
311 /* Test for fetch protected storage location. */
312 /* */
313 /* Input: */
314 /* addr Logical address of storage location */
315 /* skey Storage key with fetch, reference, and change bits */
316 /* and one low-order zero appended */
317 /* akey Access key with 4 low-order zeroes appended */
318 /* regs Pointer to the CPU register context */
319 /* regs->dat.private 1=Location is in a private address space */
320 /* Return value: */
321 /* 1=Fetch protected, 0=Not fetch protected */
322 /*-------------------------------------------------------------------*/
ARCH_DEP(is_fetch_protected)323 static inline int ARCH_DEP(is_fetch_protected) (VADR addr, BYTE skey,
324 BYTE akey, REGS *regs)
325 {
326 UNREFERENCED_370(addr);
327 UNREFERENCED_370(regs);
328
329 /* [3.4.1] Fetch is allowed if access key is zero, regardless
330 of the storage key and fetch protection bit */
331 /* [3.4.1] Fetch protection prohibits fetch if storage key fetch
332 protect bit is on and access key does not match storage key */
333 if (likely(akey == 0
334 || akey == (skey & STORKEY_KEY)
335 || !(skey & STORKEY_FETCH)))
336 return 0;
337
338 #ifdef FEATURE_FETCH_PROTECTION_OVERRIDE
339 /* [3.4.1.2] Fetch protection override allows fetch from first
340 2K of non-private address spaces if CR0 bit 6 is set */
341 if (addr < 2048
342 && (regs->CR(0) & CR0_FETCH_OVRD)
343 && regs->dat.private == 0)
344 return 0;
345 #endif /*FEATURE_FETCH_PROTECTION_OVERRIDE*/
346
347 #ifdef FEATURE_STORAGE_PROTECTION_OVERRIDE
348 /* [3.4.1.1] Storage protection override allows access to
349 locations with storage key 9, regardless of the access key,
350 provided that CR0 bit 7 is set */
351 if ((skey & STORKEY_KEY) == 0x90
352 && (regs->CR(0) & CR0_STORE_OVRD))
353 return 0;
354 #endif /*FEATURE_STORAGE_PROTECTION_OVERRIDE*/
355
356 /* Return one if location is fetch protected */
357 return 1;
358
359 } /* end function is_fetch_protected */
360
361 /*-------------------------------------------------------------------*/
362 /* Test for low-address protection. */
363 /* */
364 /* Input: */
365 /* addr Logical address of storage location */
366 /* regs Pointer to the CPU register context */
367 /* regs->dat.private 1=Location is in a private address space */
368 /* Return value: */
369 /* 1=Low-address protected, 0=Not low-address protected */
370 /*-------------------------------------------------------------------*/
ARCH_DEP(is_low_address_protected)371 static inline int ARCH_DEP(is_low_address_protected) (VADR addr,
372 REGS *regs)
373 {
374 #if defined (FEATURE_ESAME)
375 /* For ESAME, low-address protection applies to locations
376 0-511 (0000-01FF) and 4096-4607 (1000-11FF) */
377 if (addr & 0xFFFFFFFFFFFFEE00ULL)
378 #else /*!defined(FEATURE_ESAME)*/
379 /* For S/370 and ESA/390, low-address protection applies
380 to locations 0-511 only */
381 if (addr > 511)
382 #endif /*!defined(FEATURE_ESAME)*/
383 return 0;
384
385 /* Low-address protection applies only if the low-address
386 protection control bit in control register 0 is set */
387 if ((regs->CR(0) & CR0_LOW_PROT) == 0)
388 return 0;
389
390 #if defined(_FEATURE_SIE)
391 /* Host low-address protection is not applied to guest
392 references to guest storage */
393 if (regs->sie_active)
394 return 0;
395 #endif /*defined(_FEATURE_SIE)*/
396
397 /* Low-address protection does not apply to private address
398 spaces */
399 if (regs->dat.private)
400 return 0;
401
402 /* Return one if location is low-address protected */
403 return 1;
404
405 } /* end function is_low_address_protected */
406
407 /*-------------------------------------------------------------------*/
408 /* Test for store protected storage location. */
409 /* */
410 /* Input: */
411 /* addr Logical address of storage location */
412 /* skey Storage key with fetch, reference, and change bits */
413 /* and one low-order zero appended */
414 /* akey Access key with 4 low-order zeroes appended */
415 /* regs Pointer to the CPU register context */
416 /* regs->dat.private 1=Location is in a private address space */
417 /* regs->dat.protect 1=Access list protected or page protected */
418 /* Return value: */
419 /* 1=Store protected, 0=Not store protected */
420 /*-------------------------------------------------------------------*/
ARCH_DEP(is_store_protected)421 static inline int ARCH_DEP(is_store_protected) (VADR addr, BYTE skey,
422 BYTE akey, REGS *regs)
423 {
424 /* [3.4.4] Low-address protection prohibits stores into certain
425 locations in the prefixed storage area of non-private address
426 address spaces, if the low-address control bit in CR0 is set,
427 regardless of the access key and storage key */
428 if (ARCH_DEP(is_low_address_protected) (addr, regs))
429 return 1;
430
431 /* Access-list controlled protection prohibits all stores into
432 the address space, and page protection prohibits all stores
433 into the page, regardless of the access key and storage key */
434 if (regs->dat.protect)
435 return 1;
436 #if defined(_FEATURE_SIE)
437 if(SIE_MODE(regs) && regs->hostregs->dat.protect)
438 return 1;
439 #endif
440
441 /* [3.4.1] Store is allowed if access key is zero, regardless
442 of the storage key */
443 if (akey == 0)
444 return 0;
445
446 #ifdef FEATURE_STORAGE_PROTECTION_OVERRIDE
447 /* [3.4.1.1] Storage protection override allows access to
448 locations with storage key 9, regardless of the access key,
449 provided that CR0 bit 7 is set */
450 if ((skey & STORKEY_KEY) == 0x90
451 && (regs->CR(0) & CR0_STORE_OVRD))
452 return 0;
453 #endif /*FEATURE_STORAGE_PROTECTION_OVERRIDE*/
454
455 /* [3.4.1] Store protection prohibits stores if the access
456 key does not match the storage key */
457 if (akey != (skey & STORKEY_KEY))
458 return 1;
459
460 /* Return zero if location is not store protected */
461 return 0;
462
463 } /* end function is_store_protected */
464
465
466 /*-------------------------------------------------------------------*/
467 /* Return mainstor address of absolute address. */
468 /* The caller is assumed to have already checked that the absolute */
469 /* address is within the limit of main storage. */
470 /*-------------------------------------------------------------------*/
471 #if defined(INLINE_STORE_FETCH_ADDR_CHECK)
ARCH_DEP(fetch_main_absolute)472 static inline BYTE *ARCH_DEP(fetch_main_absolute) (RADR addr,
473 REGS *regs, int len)
474 #else
475 static inline BYTE *ARCH_DEP(fetch_main_absolute) (RADR addr,
476 REGS *regs)
477 #endif
478 {
479 #if defined(INLINE_STORE_FETCH_ADDR_CHECK)
480 if(addr > regs->mainlim - len)
481 regs->program_interrupt (regs, PGM_ADDRESSING_EXCEPTION);
482 #endif /*defined(INLINE_STORE_FETCH_ADDR_CHECK)*/
483
484 SIE_TRANSLATE(&addr, ACCTYPE_READ, regs);
485
486 /* Set the main storage reference bit */
487 STORAGE_KEY(addr, regs) |= STORKEY_REF;
488
489 /* Return absolute storage mainstor address */
490 return (regs->mainstor + addr);
491
492 } /* end function fetch_main_absolute */
493
494
495 /*-------------------------------------------------------------------*/
496 /* Fetch a doubleword from absolute storage. */
497 /* The caller is assumed to have already checked that the absolute */
498 /* address is within the limit of main storage. */
499 /* All bytes of the word are fetched concurrently as observed by */
500 /* other CPUs. The doubleword is first fetched as an integer, then */
501 /* the bytes are reversed into host byte order if necessary. */
502 /*-------------------------------------------------------------------*/
ARCH_DEP(fetch_doubleword_absolute)503 static inline U64 ARCH_DEP(fetch_doubleword_absolute) (RADR addr,
504 REGS *regs)
505 {
506 // The change below affects 32 bit hosts that use something like
507 // cmpxchg8b to fetch the doubleword concurrently.
508 // This routine is mainly called by DAT in 64 bit guest mode
509 // to access DAT-related values. In most `well-behaved' OS's,
510 // other CPUs should not be interfering with these values
511 #if !defined(OPTION_STRICT_ALIGNMENT)
512 return CSWAP64(*(U64 *)FETCH_MAIN_ABSOLUTE(addr, regs, 8));
513 #else
514 return fetch_dw(FETCH_MAIN_ABSOLUTE(addr, regs, 8));
515 #endif
516 } /* end function fetch_doubleword_absolute */
517
518
519 /*-------------------------------------------------------------------*/
520 /* Fetch a fullword from absolute storage. */
521 /* The caller is assumed to have already checked that the absolute */
522 /* address is within the limit of main storage. */
523 /* All bytes of the word are fetched concurrently as observed by */
524 /* other CPUs. The fullword is first fetched as an integer, then */
525 /* the bytes are reversed into host byte order if necessary. */
526 /*-------------------------------------------------------------------*/
ARCH_DEP(fetch_fullword_absolute)527 static inline U32 ARCH_DEP(fetch_fullword_absolute) (RADR addr,
528 REGS *regs)
529 {
530 return fetch_fw(FETCH_MAIN_ABSOLUTE(addr, regs, 4));
531 } /* end function fetch_fullword_absolute */
532
533
534 /*-------------------------------------------------------------------*/
535 /* Fetch a halfword from absolute storage. */
536 /* The caller is assumed to have already checked that the absolute */
537 /* address is within the limit of main storage. */
538 /* All bytes of the halfword are fetched concurrently as observed by */
539 /* other CPUs. The halfword is first fetched as an integer, then */
540 /* the bytes are reversed into host byte order if necessary. */
541 /*-------------------------------------------------------------------*/
ARCH_DEP(fetch_halfword_absolute)542 static inline U16 ARCH_DEP(fetch_halfword_absolute) (RADR addr,
543 REGS *regs)
544 {
545 return fetch_hw(FETCH_MAIN_ABSOLUTE(addr, regs, 2));
546 } /* end function fetch_halfword_absolute */
547
548
549 /*-------------------------------------------------------------------*/
550 /* Store doubleword into absolute storage. */
551 /* All bytes of the word are stored concurrently as observed by */
552 /* other CPUs. The bytes of the word are reversed if necessary */
553 /* and the word is then stored as an integer in absolute storage. */
554 /*-------------------------------------------------------------------*/
ARCH_DEP(store_doubleword_absolute)555 static inline void ARCH_DEP(store_doubleword_absolute) (U64 value,
556 RADR addr, REGS *regs)
557 {
558 #if defined(INLINE_STORE_FETCH_ADDR_CHECK)
559 if(addr > regs->mainlim - 8)
560 regs->program_interrupt (regs, PGM_ADDRESSING_EXCEPTION);
561 #endif /*defined(INLINE_STORE_FETCH_ADDR_CHECK)*/
562
563 SIE_TRANSLATE(&addr, ACCTYPE_WRITE, regs);
564
565 /* Set the main storage reference and change bits */
566 STORAGE_KEY(addr, regs) |= (STORKEY_REF | STORKEY_CHANGE);
567
568 /* Store the doubleword into absolute storage */
569 store_dw(regs->mainstor + addr, value);
570
571 } /* end function store_doubleword_absolute */
572
573
574 /*-------------------------------------------------------------------*/
575 /* Store a fullword into absolute storage. */
576 /* All bytes of the word are stored concurrently as observed by */
577 /* other CPUs. The bytes of the word are reversed if necessary */
578 /* and the word is then stored as an integer in absolute storage. */
579 /*-------------------------------------------------------------------*/
ARCH_DEP(store_fullword_absolute)580 static inline void ARCH_DEP(store_fullword_absolute) (U32 value,
581 RADR addr, REGS *regs)
582 {
583 #if defined(INLINE_STORE_FETCH_ADDR_CHECK)
584 if(addr > regs->mainlim - 4)
585 regs->program_interrupt (regs, PGM_ADDRESSING_EXCEPTION);
586 #endif /*defined(INLINE_STORE_FETCH_ADDR_CHECK)*/
587
588 SIE_TRANSLATE(&addr, ACCTYPE_WRITE, regs);
589
590 /* Set the main storage reference and change bits */
591 STORAGE_KEY(addr, regs) |= (STORKEY_REF | STORKEY_CHANGE);
592
593 /* Store the fullword into absolute storage */
594 store_fw(regs->mainstor + addr, value);
595
596 } /* end function store_fullword_absolute */
597
598
599 /*-------------------------------------------------------------------*/
600 /* Perform subspace replacement */
601 /* */
602 /* Input: */
603 /* std Original segment table designation (STD) or ASCE */
604 /* asteo ASTE origin obtained by ASN translation */
605 /* xcode Pointer to field to receive exception code, or NULL */
606 /* regs Pointer to the CPU register context */
607 /* */
608 /* Output: */
609 /* xcode Exception code or zero (if xcode is not NULL) */
610 /* */
611 /* Return value: */
612 /* On successful completion, the exception code field (if not */
613 /* NULL) is set to zero, and the function return value is the */
614 /* STD resulting from subspace replacement, or is the original */
615 /* STD if subspace replacement is not applicable. */
616 /* */
617 /* Operation: */
618 /* If the ASF control is enabled, and the STD or ASCE is a */
619 /* member of a subspace-group (bit 22 is one), and the */
620 /* dispatchable unit is subspace active (DUCT word 1 bit 0 is */
621 /* one), and the ASTE obtained by ASN translation is the ASTE */
622 /* for the base space of the dispatchable unit, then the STD */
623 /* or ASCE is replaced (except for the event control bits) by */
624 /* the STD or ASCE from the ASTE for the subspace in which the */
625 /* dispatchable unit last had control; otherwise the STD or */
626 /* ASCE remains unchanged. */
627 /* */
628 /* Error conditions: */
629 /* If an ASTE validity exception or ASTE sequence exception */
630 /* occurs, and the xcode parameter is a non-NULL pointer, */
631 /* then the exception code is returned in the xcode field */
632 /* and the function return value is zero. */
633 /* For all other error conditions a program check is generated */
634 /* and the function does not return. */
635 /* */
636 /*-------------------------------------------------------------------*/
ARCH_DEP(subspace_replace)637 static inline RADR ARCH_DEP(subspace_replace) (RADR std, U32 asteo,
638 U16 *xcode, REGS *regs)
639 {
640 U32 ducto; /* DUCT origin */
641 U32 duct0; /* DUCT word 0 */
642 U32 duct1; /* DUCT word 1 */
643 U32 duct3; /* DUCT word 3 */
644 U32 ssasteo; /* Subspace ASTE origin */
645 U32 ssaste[16]; /* Subspace ASTE */
646 BYTE *p; /* Mainstor pointer */
647
648 /* Clear the exception code field, if provided */
649 if (xcode != NULL) *xcode = 0;
650
651 /* Return the original STD unchanged if the address-space function
652 control (CR0 bit 15) is zero, or if the subspace-group control
653 (bit 22 of the STD) is zero */
654 if (!ASF_ENABLED(regs)
655 || (std & SSGROUP_BIT) == 0)
656 return std;
657
658 /* Load the DUCT origin address */
659 ducto = regs->CR(2) & CR2_DUCTO;
660 ducto = APPLY_PREFIXING (ducto, regs->PX);
661
662 /* Program check if DUCT origin address is invalid */
663 if (ducto > regs->mainlim)
664 regs->program_interrupt (regs, PGM_ADDRESSING_EXCEPTION);
665
666 /* Fetch DUCT words 0, 1, and 3 from absolute storage
667 (note: the DUCT cannot cross a page boundary) */
668 p = FETCH_MAIN_ABSOLUTE(ducto, regs, 16);
669 duct0 = fetch_fw(p);
670 duct1 = fetch_fw(p+4);
671 duct3 = fetch_fw(p+12);
672
673 /* Return the original STD unchanged if the dispatchable unit is
674 not subspace active or if the ASTE obtained by ASN translation
675 is not the same as the base ASTE for the dispatchable unit */
676 if ((duct1 & DUCT1_SA) == 0
677 || asteo != (duct0 & DUCT0_BASTEO))
678 return std;
679
680 /* Load the subspace ASTE origin from the DUCT */
681 ssasteo = duct1 & DUCT1_SSASTEO;
682 ssasteo = APPLY_PREFIXING (ssasteo, regs->PX);
683
684 /* Program check if ASTE origin address is invalid */
685 if (ssasteo > regs->mainlim)
686 regs->program_interrupt (regs, PGM_ADDRESSING_EXCEPTION);
687
688 /* Fetch subspace ASTE words 0, 2, 3, and 5 from absolute
689 storage (note: the ASTE cannot cross a page boundary) */
690 p = FETCH_MAIN_ABSOLUTE(ssasteo, regs, 24);
691 ssaste[0] = fetch_fw(p);
692 ssaste[2] = fetch_fw(p+8);
693 #if defined(FEATURE_ESAME)
694 ssaste[3] = fetch_fw(p+12);
695 #endif /*defined(FEATURE_ESAME)*/
696 ssaste[5] = fetch_fw(p+20);
697
698 /* ASTE validity exception if subspace ASTE invalid bit is one */
699 if (ssaste[0] & ASTE0_INVALID)
700 {
701 regs->excarid = 0;
702 if (xcode == NULL)
703 regs->program_interrupt (regs, PGM_ASTE_VALIDITY_EXCEPTION);
704 else
705 *xcode = PGM_ASTE_VALIDITY_EXCEPTION;
706 return 0;
707 }
708
709 /* ASTE sequence exception if the subspace ASTE sequence
710 number does not match the sequence number in the DUCT */
711 if ((ssaste[5] & ASTE5_ASTESN) != (duct3 & DUCT3_SSASTESN))
712 {
713 regs->excarid = 0;
714 if (xcode == NULL)
715 regs->program_interrupt (regs, PGM_ASTE_SEQUENCE_EXCEPTION);
716 else
717 *xcode = PGM_ASTE_SEQUENCE_EXCEPTION;
718 return 0;
719 }
720
721 /* Replace the STD or ASCE with the subspace ASTE STD or ASCE,
722 except for the space switch event bit and the storage
723 alteration event bit, which remain unchanged */
724 std &= (SSEVENT_BIT | SAEVENT_BIT);
725 std |= (ASTE_AS_DESIGNATOR(ssaste)
726 & ~((RADR)(SSEVENT_BIT | SAEVENT_BIT)));
727
728 /* Return the STD resulting from subspace replacement */
729 return std;
730
731 } /* end function subspace_replace */
732
733
734 #include "dat.h"
735
736 #include "vstore.h"
737
738 /* end of INLINE.H */
739