1 /* SIE.C (c) Copyright Jan Jaeger, 1999-2009 */
2 /* Interpretive Execution */
3
4 /* This module contains the SIE instruction as */
5 /* described in IBM S/370 Extended Architecture */
6 /* Interpretive Execution, SA22-7095-01 */
7 /* and */
8 /* Enterprise Systems Architecture / Extended Configuration */
9 /* Principles of Operation, SC24-5594-02 and SC24-5965-00 */
10
11 /* z/Architecture support - (c) Copyright Jan Jaeger, 1999-2007 */
12
13 #include "hstdinc.h"
14
15 // #define SIE_DEBUG
16 //
17
18 #if !defined(_HENGINE_DLL_)
19 #define _HENGINE_DLL_
20 #endif
21
22 #if !defined(_SIE_C_)
23 #define _SIE_C_
24 #endif
25
26 #include "hercules.h"
27 #include "opcode.h"
28 #include "inline.h"
29
30 #if defined(_FEATURE_SIE)
31
32 #if !defined(_SIE_C)
33
34 #define _SIE_C
35
36 int s370_run_sie (REGS *regs);
37 int s390_run_sie (REGS *regs);
38 #if defined(_900)
39 int z900_run_sie (REGS *regs);
40 #endif /*defined(_900)*/
41 static int (* run_sie[GEN_MAXARCH]) (REGS *regs) =
42 {
43 #if defined(_370)
44 s370_run_sie,
45 #endif
46 #if defined(_390)
47 s390_run_sie,
48 #endif
49 #if defined(_900)
50 z900_run_sie
51 #endif
52 };
53
54 #define GUESTREGS (regs->guestregs)
55 #define STATEBK ((SIEBK *)GUESTREGS->siebk)
56
57 #define SIE_I_STOP(_guestregs) \
58 ((_guestregs)->siebk->v & SIE_V_STOP)
59
60 #define SIE_I_EXT(_guestregs) \
61 (((_guestregs)->siebk->v & SIE_V_EXT) \
62 && ((_guestregs)->psw.sysmask & PSW_EXTMASK))
63
64 #define SIE_I_HOST(_hostregs) IC_INTERRUPT_CPU(_hostregs)
65
66 #if defined(SIE_DEBUG_PERFMON)
67 #define SIE_PERF_MAXNEG 0x1F
68 static int sie_perfmon[0x41 + SIE_PERF_MAXNEG];
69 #define SIE_PERFMON(_code) \
70 do { \
71 sie_perfmon[(_code) + SIE_PERF_MAXNEG] ++; \
72 } while(0)
73 #define SIE_PERF_PGMINT \
74 (code <= 0 ? code : (((code-1) & 0x3F)+1))
sie_perfmon_disp()75 void *sie_perfmon_disp()
76 {
77 static char *dbg_name[] = {
78 /* -31 */ "SIE re-dispatch state descriptor",
79 /* -30 */ "SIE exit",
80 /* -29 */ "SIE run",
81 /* -28 */ "SIE runloop 1",
82 /* -27 */ "SIE runloop 2",
83 /* -26 */ "SIE interrupt check",
84 /* -25 */ "SIE execute instruction",
85 /* -24 */ "SIE unrolled execute",
86 /* -23 */ NULL,
87 /* -22 */ NULL,
88 /* -21 */ NULL,
89 /* -20 */ NULL,
90 /* -19 */ NULL,
91 /* -18 */ NULL,
92 /* -17 */ "SIE intercept I/O instruction",
93 /* -16 */ "SIE intercept I/O interrupt pending",
94 /* -15 */ "SIE intercept I/O interrupt",
95 /* -14 */ "SIE intercept PER interrupt",
96 /* -13 */ "SIE validity check",
97 /* -12 */ "SIE intercept external interrupt pending",
98 /* -11 */ "SIE intercept machine check interrupt",
99 /* -10 */ "SIE intercept restart interrupt",
100 /* -9 */ "SIE intercept stop request",
101 /* -8 */ "SIE intercept virtual machine wait",
102 /* -7 */ "SIE intercept I/O interrupt request",
103 /* -6 */ "SIE intercept external interrupt request",
104 /* -5 */ "SIE intercept instruction completion",
105 /* -4 */ "SIE intercept instruction",
106 /* -3 */ "SIE host program interrupt",
107 /* -2 */ "SIE host interrupt",
108 /* -1 */ "SIE no intercept",
109 /* 0 */ "SIE entry",
110 /* 01 */ "SIE intercept Operation exception",
111 /* 02 */ "SIE intercept Privileged-operation exception",
112 /* 03 */ "SIE intercept Execute exception",
113 /* 04 */ "SIE intercept Protection exception",
114 /* 05 */ "SIE intercept Addressing exception",
115 /* 06 */ "SIE intercept Specification exception",
116 /* 07 */ "SIE intercept Data exception",
117 /* 08 */ "SIE intercept Fixed-point-overflow exception",
118 /* 09 */ "SIE intercept Fixed-point-divide exception",
119 /* 0A */ "SIE intercept Decimal-overflow exception",
120 /* 0B */ "SIE intercept Decimal-divide exception",
121 /* 0C */ "SIE intercept HFP-exponent-overflow exception",
122 /* 0D */ "SIE intercept HFP-exponent-underflow exception",
123 /* 0E */ "SIE intercept HFP-significance exception",
124 /* 0F */ "SIE intercept HFP-floating-point-divide exception",
125 /* 10 */ "SIE intercept Segment-translation exception",
126 /* 11 */ "SIE intercept Page-translation exception",
127 /* 12 */ "SIE intercept Translation-specification exception",
128 /* 13 */ "SIE intercept Special-operation exception",
129 /* 14 */ "SIE intercept Pseudo-page-fault exception",
130 /* 15 */ "SIE intercept Operand exception",
131 /* 16 */ "SIE intercept Trace-table exception",
132 /* 17 */ "SIE intercept ASN-translation exception",
133 /* 18 */ "SIE intercept Page access exception",
134 /* 19 */ "SIE intercept Vector/Crypto operation exception",
135 /* 1A */ "SIE intercept Page state exception",
136 /* 1B */ "SIE intercept Page transition exception",
137 /* 1C */ "SIE intercept Space-switch event",
138 /* 1D */ "SIE intercept Square-root exception",
139 /* 1E */ "SIE intercept Unnormalized-operand exception",
140 /* 1F */ "SIE intercept PC-translation specification exception",
141 /* 20 */ "SIE intercept AFX-translation exception",
142 /* 21 */ "SIE intercept ASX-translation exception",
143 /* 22 */ "SIE intercept LX-translation exception",
144 /* 23 */ "SIE intercept EX-translation exception",
145 /* 24 */ "SIE intercept Primary-authority exception",
146 /* 25 */ "SIE intercept LFX-translation exception",
147 /* 26 */ "SIE intercept LSX-translation exception",
148 /* 27 */ "SIE intercept Control-switch exception",
149 /* 28 */ "SIE intercept ALET-specification exception",
150 /* 29 */ "SIE intercept ALEN-translation exception",
151 /* 2A */ "SIE intercept ALE-sequence exception",
152 /* 2B */ "SIE intercept ASTE-validity exception",
153 /* 2C */ "SIE intercept ASTE-sequence exception",
154 /* 2D */ "SIE intercept Extended-authority exception",
155 /* 2E */ "SIE intercept LSTE-sequence exception",
156 /* 2F */ "SIE intercept ASTE-instance exception",
157 /* 30 */ "SIE intercept Stack-full exception",
158 /* 31 */ "SIE intercept Stack-empty exception",
159 /* 32 */ "SIE intercept Stack-specification exception",
160 /* 33 */ "SIE intercept Stack-type exception",
161 /* 34 */ "SIE intercept Stack-operation exception",
162 /* 35 */ NULL,
163 /* 36 */ NULL,
164 /* 37 */ NULL,
165 /* 38 */ "SIE intercept ASCE-type exception",
166 /* 39 */ "SIE intercept Region-first-translation exception",
167 /* 3A */ "SIE intercept Region-second-translation exception",
168 /* 3B */ "SIE intercept Region-third-translation exception",
169 /* 3C */ NULL,
170 /* 3D */ NULL,
171 /* 3E */ NULL,
172 /* 3F */ NULL,
173 /* 40 */ "SIE intercept Monitor event" };
174
175 if(sie_perfmon[SIE_PERF_ENTER+SIE_PERF_MAXNEG])
176 {
177 int i;
178 for(i = 0; i < 0x61; i++)
179 if(sie_perfmon[i])
180 logmsg("%9u: %s\n",sie_perfmon[i],dbg_name[i]);
181 logmsg("%9u: Average instructions/SIE invocation\n",
182 (sie_perfmon[SIE_PERF_EXEC+SIE_PERF_MAXNEG] +
183 sie_perfmon[SIE_PERF_EXEC_U+SIE_PERF_MAXNEG]*7) /
184 sie_perfmon[SIE_PERF_ENTER+SIE_PERF_MAXNEG]);
185 }
186 else
187 logmsg("No SIE performance data\n");
188 }
189 #else
190 #define SIE_PERFMON(_code)
191 #endif
192
193 #endif /*!defined(_SIE_C)*/
194
195 #undef SIE_I_WAIT
196 #if defined(_FEATURE_WAITSTATE_ASSIST)
197 #define SIE_I_WAIT(_guestregs) \
198 (WAITSTATE(&(_guestregs)->psw) && !((_guestregs)->siebk->ec[0] & SIE_EC0_WAIA))
199 #else
200 #define SIE_I_WAIT(_guestregs) \
201 (WAITSTATE(&(_guestregs)->psw))
202 #endif
203
204 #undef SIE_I_IO
205 #if defined(FEATURE_BCMODE)
206 #define SIE_I_IO(_guestregs) \
207 (((_guestregs)->siebk->v & SIE_V_IO) \
208 && ((_guestregs)->psw.sysmask \
209 & (ECMODE(&(_guestregs)->psw) ? PSW_IOMASK : 0xFE) ))
210 #else /*!defined(FEATURE_BCMODE)*/
211 #define SIE_I_IO(_guestregs) \
212 (((_guestregs)->siebk->v & SIE_V_IO) \
213 && ((_guestregs)->psw.sysmask & PSW_IOMASK ))
214 #endif /*!defined(FEATURE_BCMODE)*/
215
216 #endif /*defined(_FEATURE_SIE)*/
217 #if defined(FEATURE_INTERPRETIVE_EXECUTION)
218
219 /*-------------------------------------------------------------------*/
220 /* B214 SIE - Start Interpretive Execution [S] */
221 /*-------------------------------------------------------------------*/
DEF_INST(start_interpretive_execution)222 DEF_INST(start_interpretive_execution)
223 {
224 int b2; /* Values of R fields */
225 RADR effective_addr2; /* address of state desc. */
226 int n; /* Loop counter */
227 U16 lhcpu; /* Last Host CPU address */
228 volatile int icode = 0; /* Interception code */
229 U64 dreg;
230
231 S(inst, regs, b2, effective_addr2);
232
233 SIE_INTERCEPT(regs);
234
235 PRIV_CHECK(regs);
236
237 PTT(PTT_CL_SIE,"SIE", regs->GR_L(14), regs->GR_L(15), (U32)(effective_addr2 & 0xffffffff));
238
239 SIE_PERFMON(SIE_PERF_ENTER);
240
241 #if !defined(FEATURE_ESAME) && !defined(FEATURE_MULTIPLE_CONTROLLED_DATA_SPACE)
242 if(!regs->psw.amode || !PRIMARY_SPACE_MODE(&(regs->psw)))
243 ARCH_DEP(program_interrupt) (regs, PGM_SPECIAL_OPERATION_EXCEPTION);
244 #endif
245
246 if((effective_addr2 & (sizeof(SIEBK)-1)) != 0
247 #if defined(FEATURE_ESAME)
248 || (effective_addr2 & 0xFFFFFFFFFFFFF000ULL) == 0
249 || (effective_addr2 & 0xFFFFFFFFFFFFF000ULL) == regs->PX)
250 #else /*!defined(FEATURE_ESAME)*/
251 || (effective_addr2 & 0x7FFFF000) == 0
252 || (effective_addr2 & 0x7FFFF000) == regs->PX)
253 #endif /*!defined(FEATURE_ESAME)*/
254 ARCH_DEP(program_interrupt) (regs, PGM_SPECIFICATION_EXCEPTION);
255
256 /* Perform serialization and checkpoint synchronization */
257 PERFORM_SERIALIZATION (regs);
258 PERFORM_CHKPT_SYNC (regs);
259
260 #if defined(SIE_DEBUG)
261 logmsg(_("SIE: state descriptor " F_RADR "\n"),effective_addr2);
262 ARCH_DEP(display_inst) (regs, regs->instinvalid ? NULL : regs->ip);
263 #endif /*defined(SIE_DEBUG)*/
264
265 if(effective_addr2 > regs->mainlim - (sizeof(SIEBK)-1))
266 ARCH_DEP(program_interrupt) (regs, PGM_ADDRESSING_EXCEPTION);
267
268 /*
269 * As long as regs->sie_active is off, no serialization is
270 * required for GUESTREGS. sie_active should always be off here.
271 * Any other thread looking at sie_active holds the intlock.
272 */
273 if (regs->sie_active)
274 {
275 OBTAIN_INTLOCK(regs);
276 regs->sie_active = 0;
277 RELEASE_INTLOCK(regs);
278 }
279
280 /* Initialize guestregs if first time */
281 if (GUESTREGS == NULL)
282 {
283 GUESTREGS = calloc (sizeof(REGS), 1);
284 if (GUESTREGS == NULL)
285 {
286 logmsg (_("HHCCP079E CPU%4.4X: calloc failed for sie regs: %s\n"),
287 regs->cpuad, strerror(errno));
288 #if !defined(NO_SIGABEND_HANDLER)
289 signal_thread(sysblk.cputid[regs->cpuad], SIGUSR1);
290 #endif
291 return;
292 }
293 cpu_init (regs->cpuad, GUESTREGS, regs);
294 }
295
296 /* Direct pointer to state descriptor block */
297 GUESTREGS->siebk = (void*)(regs->mainstor + effective_addr2);
298
299 #if defined(FEATURE_ESAME)
300 if (STATEBK->mx & SIE_MX_ESAME)
301 {
302 GUESTREGS->arch_mode = ARCH_900;
303 GUESTREGS->program_interrupt = &z900_program_interrupt;
304 GUESTREGS->trace_br = (func)&z900_trace_br;
305 icode = z900_load_psw(GUESTREGS, STATEBK->psw);
306 }
307 #else /*!defined(FEATURE_ESAME)*/
308 if (STATEBK->m & SIE_M_370)
309 {
310 #if defined(_370)
311 GUESTREGS->arch_mode = ARCH_370;
312 GUESTREGS->program_interrupt = &s370_program_interrupt;
313 icode = s370_load_psw(GUESTREGS, STATEBK->psw);
314 #else
315 /* Validity intercept when 370 mode not installed */
316 SIE_SET_VI(SIE_VI_WHO_CPU, SIE_VI_WHEN_SIENT,
317 SIE_VI_WHY_370NI, GUESTREGS);
318 STATEBK->c = SIE_C_VALIDITY;
319 return;
320 #endif
321 }
322 #endif /*!defined(FEATURE_ESAME)*/
323 else
324 #if !defined(FEATURE_ESAME)
325 if (STATEBK->m & SIE_M_XA)
326 #endif /*!defined(FEATURE_ESAME)*/
327 {
328 GUESTREGS->arch_mode = ARCH_390;
329 GUESTREGS->program_interrupt = &s390_program_interrupt;
330 GUESTREGS->trace_br = (func)&s390_trace_br;
331 icode = s390_load_psw(GUESTREGS, STATEBK->psw);
332 }
333 #if !defined(FEATURE_ESAME)
334 else
335 {
336 /* Validity intercept for invalid mode */
337 SIE_SET_VI(SIE_VI_WHO_CPU, SIE_VI_WHEN_SIENT,
338 SIE_VI_WHY_MODE, GUESTREGS);
339 STATEBK->c = SIE_C_VALIDITY;
340 return;
341 }
342 #endif /*!defined(FEATURE_ESAME)*/
343
344 /* Prefered guest indication */
345 GUESTREGS->sie_pref = (STATEBK->m & SIE_M_VR) ? 1 : 0;
346
347 /* Load prefix from state descriptor */
348 FETCH_FW(GUESTREGS->PX, STATEBK->prefix);
349 GUESTREGS->PX &=
350 #if !defined(FEATURE_ESAME)
351 PX_MASK;
352 #else /*defined(FEATURE_ESAME)*/
353 (GUESTREGS->arch_mode == ARCH_900) ? PX_MASK : 0x7FFFF000;
354 #endif /*defined(FEATURE_ESAME)*/
355
356 #if defined(FEATURE_REGION_RELOCATE)
357 if(STATEBK->mx & SIE_MX_RRF)
358 {
359 RADR mso, msl, eso = 0, esl = 0;
360
361 if(STATEBK->zone >= FEATURE_SIE_MAXZONES)
362 {
363 /* Validity intercept for invalid zone */
364 SIE_SET_VI(SIE_VI_WHO_CPU, SIE_VI_WHEN_SIENT,
365 SIE_VI_WHY_AZNNI, GUESTREGS);
366 STATEBK->c = SIE_C_VALIDITY;
367 return;
368 }
369
370 mso = sysblk.zpb[STATEBK->zone].mso << 20;
371 msl = (sysblk.zpb[STATEBK->zone].msl << 20) | 0xFFFFF;
372 eso = sysblk.zpb[STATEBK->zone].eso << 20;
373 esl = (sysblk.zpb[STATEBK->zone].esl << 20) | 0xFFFFF;
374
375 if(mso > msl)
376 {
377 /* Validity intercept for invalid zone */
378 SIE_SET_VI(SIE_VI_WHO_CPU, SIE_VI_WHEN_SIENT,
379 SIE_VI_WHY_MSDEF, GUESTREGS);
380 STATEBK->c = SIE_C_VALIDITY;
381 return;
382 }
383
384 /* Ensure addressing exceptions on incorrect zone defs */
385 if(mso > regs->mainlim || msl > regs->mainlim)
386 mso = msl = 0;
387
388
389 #if defined(SIE_DEBUG)
390 logmsg(_("SIE: zone %d: mso=" F_RADR " msl=" F_RADR "\n"),
391 STATEBK->zone, mso, msl);
392 #endif /*defined(SIE_DEBUG)*/
393
394 GUESTREGS->sie_pref = 1;
395 GUESTREGS->sie_mso = 0;
396 GUESTREGS->mainstor = &(sysblk.mainstor[mso]);
397 GUESTREGS->mainlim = msl - mso;
398 GUESTREGS->storkeys = &(STORAGE_KEY(mso, &sysblk));
399 GUESTREGS->sie_xso = eso;
400 GUESTREGS->sie_xsl = esl;
401 GUESTREGS->sie_xso *= (XSTORE_INCREMENT_SIZE >> XSTORE_PAGESHIFT);
402 GUESTREGS->sie_xsl *= (XSTORE_INCREMENT_SIZE >> XSTORE_PAGESHIFT);
403 }
404 else
405 #endif /*defined(FEATURE_REGION_RELOCATE)*/
406 {
407 GUESTREGS->mainstor = sysblk.mainstor;
408 GUESTREGS->storkeys = sysblk.storkeys;
409
410 if(STATEBK->zone)
411 {
412 /* Validity intercept for invalid zone */
413 SIE_SET_VI(SIE_VI_WHO_CPU, SIE_VI_WHEN_SIENT,
414 SIE_VI_WHY_AZNNZ, GUESTREGS);
415 STATEBK->c = SIE_C_VALIDITY;
416 return;
417 }
418
419 #if defined(FEATURE_ESAME)
420 /* Load main storage origin */
421 FETCH_DW(GUESTREGS->sie_mso,STATEBK->mso);
422 GUESTREGS->sie_mso &= SIE2_MS_MASK;
423
424 /* Load main storage extend */
425 FETCH_DW(GUESTREGS->mainlim,STATEBK->mse);
426 GUESTREGS->mainlim |= ~SIE2_MS_MASK;
427
428 if(GUESTREGS->sie_mso > GUESTREGS->mainlim)
429 {
430 SIE_SET_VI(SIE_VI_WHO_CPU, SIE_VI_WHEN_SIENT,
431 SIE_VI_WHY_MSDEF, GUESTREGS);
432 STATEBK->c = SIE_C_VALIDITY;
433 return;
434 }
435
436 /* Calculate main storage size */
437 GUESTREGS->mainlim -= GUESTREGS->sie_mso;
438
439 #else /*!defined(FEATURE_ESAME)*/
440 /* Load main storage origin */
441 FETCH_HW(GUESTREGS->sie_mso,STATEBK->mso);
442 GUESTREGS->sie_mso <<= 16;
443
444 /* Load main storage extend */
445 FETCH_HW(GUESTREGS->mainlim,STATEBK->mse);
446 GUESTREGS->mainlim = ((GUESTREGS->mainlim + 1) << 16) - 1;
447 #endif /*!defined(FEATURE_ESAME)*/
448
449 /* Load expanded storage origin */
450 GUESTREGS->sie_xso = STATEBK->xso[0] << 16
451 | STATEBK->xso[1] << 8
452 | STATEBK->xso[2];
453 GUESTREGS->sie_xso *= (XSTORE_INCREMENT_SIZE >> XSTORE_PAGESHIFT);
454
455 /* Load expanded storage limit */
456 GUESTREGS->sie_xsl = STATEBK->xsl[0] << 16
457 | STATEBK->xsl[1] << 8
458 | STATEBK->xsl[2];
459 GUESTREGS->sie_xsl *= (XSTORE_INCREMENT_SIZE >> XSTORE_PAGESHIFT);
460 }
461
462 /* Validate Guest prefix */
463 if(GUESTREGS->PX > GUESTREGS->mainlim)
464 {
465 SIE_SET_VI(SIE_VI_WHO_CPU, SIE_VI_WHEN_SIENT,
466 SIE_VI_WHY_PFOUT, GUESTREGS);
467 STATEBK->c = SIE_C_VALIDITY;
468 return;
469 }
470
471 /* System Control Area Origin */
472 FETCH_FW(GUESTREGS->sie_scao, STATEBK->scao);
473 if(GUESTREGS->sie_scao > regs->mainlim)
474 {
475 SIE_SET_VI(SIE_VI_WHO_CPU, SIE_VI_WHEN_SIENT,
476 SIE_VI_WHY_SCADR, GUESTREGS);
477 STATEBK->c = SIE_C_VALIDITY;
478 return;
479 }
480
481 /* Validate MSO */
482 if (GUESTREGS->sie_mso)
483 {
484 /* Preferred guest must have zero MSO */
485 if (GUESTREGS->sie_pref)
486 {
487 SIE_SET_VI(SIE_VI_WHO_CPU, SIE_VI_WHEN_SIENT,
488 SIE_VI_WHY_MSONZ, GUESTREGS);
489 STATEBK->c = SIE_C_VALIDITY;
490 return;
491 }
492
493 /* MCDS guest must have zero MSO */
494 if (STATEBK->mx & SIE_MX_XC)
495 {
496 SIE_SET_VI(SIE_VI_WHO_CPU, SIE_VI_WHEN_SIENT,
497 SIE_VI_WHY_MSODS, GUESTREGS);
498 STATEBK->c = SIE_C_VALIDITY;
499 return;
500 }
501 }
502
503 #if !defined(FEATURE_ESAME)
504 /* Reference and Change Preservation Origin */
505 FETCH_FW(GUESTREGS->sie_rcpo, STATEBK->rcpo);
506 if (!GUESTREGS->sie_rcpo && !GUESTREGS->sie_pref)
507 {
508 SIE_SET_VI(SIE_VI_WHO_CPU, SIE_VI_WHEN_SIENT,
509 SIE_VI_WHY_RCZER, GUESTREGS);
510 STATEBK->c = SIE_C_VALIDITY;
511 return;
512 }
513 #endif /*!defined(FEATURE_ESAME)*/
514
515 /* Load the CPU timer */
516 FETCH_DW(dreg, STATEBK->cputimer);
517 set_cpu_timer(GUESTREGS, dreg);
518
519 /* Load the TOD clock offset for this guest */
520 FETCH_DW(GUESTREGS->sie_epoch, STATEBK->epoch);
521 GUESTREGS->tod_epoch = regs->tod_epoch + (GUESTREGS->sie_epoch >> 8);
522
523 /* Load the clock comparator */
524 FETCH_DW(GUESTREGS->clkc, STATEBK->clockcomp);
525 GUESTREGS->clkc >>= 8; /* Internal Hercules format */
526
527 /* Load TOD Programmable Field */
528 FETCH_HW(GUESTREGS->todpr, STATEBK->todpf);
529
530 /* Load the guest registers */
531 memcpy(GUESTREGS->gr, regs->gr, 14 * sizeof(regs->gr[0]));
532 memcpy(GUESTREGS->ar, regs->ar, 16 * sizeof(regs->ar[0]));
533 memcpy(GUESTREGS->fpr, regs->fpr, 32 * sizeof(regs->fpr[0]));
534 #if defined(FEATURE_BINARY_FLOATING_POINT)
535 GUESTREGS->fpc = regs->fpc;
536 #endif /*defined(FEATURE_BINARY_FLOATING_POINT)*/
537
538 /* Load GR14 */
539 FETCH_W(GUESTREGS->GR(14), STATEBK->gr14);
540
541 /* Load GR15 */
542 FETCH_W(GUESTREGS->GR(15), STATEBK->gr15);
543
544 /* Load control registers */
545 for(n = 0;n < 16; n++)
546 FETCH_W(GUESTREGS->CR(n), STATEBK->cr[n]);
547
548 FETCH_HW(lhcpu, STATEBK->lhcpu);
549 /*
550 * If this is not the last host cpu that dispatched this state
551 * descriptor then clear the guest TLB entries
552 */
553 if (regs->cpuad != lhcpu
554 || SIE_STATE(GUESTREGS) != effective_addr2)
555 {
556 SIE_PERFMON(SIE_PERF_ENTER_F);
557
558 /* Absolute address of state descriptor block */
559 SIE_STATE(GUESTREGS) = effective_addr2;
560
561 /* Update Last Host CPU address */
562 STORE_HW(STATEBK->lhcpu, regs->cpuad);
563 }
564
565 /* Purge guest TLB entries */
566 /* Note ISW 20160729 : Forcibly purge TLB and ALB */
567 ARCH_DEP(purge_tlb) (GUESTREGS);
568 ARCH_DEP(purge_alb) (GUESTREGS);
569
570 /* Initialize interrupt mask and state */
571 SET_IC_MASK(GUESTREGS);
572 SET_IC_INITIAL_STATE(GUESTREGS);
573 SET_IC_PER(GUESTREGS);
574
575 /* Initialize accelerated address lookup values */
576 SET_AEA_MODE(GUESTREGS);
577 SET_AEA_COMMON(GUESTREGS);
578 INVALIDATE_AIA(GUESTREGS);
579
580 GUESTREGS->tracing = regs->tracing;
581
582 /*
583 * Do setjmp(progjmp) because translate_addr() may result in
584 * longjmp(progjmp) for addressing exceptions.
585 */
586 if(!setjmp(GUESTREGS->progjmp))
587 {
588 /*
589 * Set sie_active to 1. This means other threads may now
590 * access guestregs when holding intlock.
591 * This is the *only* place sie_active is set to one.
592 */
593 OBTAIN_INTLOCK(regs);
594 regs->sie_active = 1;
595 RELEASE_INTLOCK(regs);
596
597 /* Get PSA pointer and ensure PSA is paged in */
598 if(GUESTREGS->sie_pref)
599 {
600 GUESTREGS->psa = (PSA_3XX*)(GUESTREGS->mainstor + GUESTREGS->PX);
601 GUESTREGS->sie_px = GUESTREGS->PX;
602 }
603 else
604 {
605 if (ARCH_DEP(translate_addr) (GUESTREGS->sie_mso + GUESTREGS->PX,
606 USE_PRIMARY_SPACE, regs, ACCTYPE_SIE))
607 {
608 SIE_SET_VI(SIE_VI_WHO_CPU, SIE_VI_WHEN_SIENT,
609 SIE_VI_WHY_PFACC, GUESTREGS);
610 STATEBK->c = SIE_C_VALIDITY;
611 OBTAIN_INTLOCK(regs);
612 regs->sie_active = 0;
613 RELEASE_INTLOCK(regs);
614 return;
615 }
616
617 /* Convert host real address to host absolute address */
618 GUESTREGS->sie_px = APPLY_PREFIXING (regs->dat.raddr, regs->PX);
619
620 if (regs->dat.protect || GUESTREGS->sie_px > regs->mainlim)
621 {
622 SIE_SET_VI(SIE_VI_WHO_CPU, SIE_VI_WHEN_SIENT,
623 SIE_VI_WHY_PFACC, GUESTREGS);
624 STATEBK->c = SIE_C_VALIDITY;
625 OBTAIN_INTLOCK(regs);
626 regs->sie_active = 0;
627 RELEASE_INTLOCK(regs);
628 return;
629 }
630 GUESTREGS->psa = (PSA_3XX*)(GUESTREGS->mainstor + GUESTREGS->sie_px);
631 }
632
633 /* Intialize guest timers */
634 OBTAIN_INTLOCK(regs);
635
636 /* CPU timer */
637 if(CPU_TIMER(GUESTREGS) < 0)
638 ON_IC_PTIMER(GUESTREGS);
639
640 /* Clock comparator */
641 if( TOD_CLOCK(GUESTREGS) > GUESTREGS->clkc )
642 ON_IC_CLKC(GUESTREGS);
643
644 #if !defined(FEATURE_ESAME)
645 /* Interval timer if S/370 and timer is enabled */
646 if((STATEBK->m & SIE_M_370) && !(STATEBK->m & SIE_M_ITMOF))
647 {
648 S32 itimer, olditimer;
649 U32 residue;
650
651 /* Set the interval timer pending according to the T bit
652 in the state control */
653 if(STATEBK->s & SIE_S_T)
654 ON_IC_ITIMER(GUESTREGS);
655
656 /* Fetch the residu from the state descriptor */
657 FETCH_FW(residue,STATEBK->residue);
658
659 /* Fetch the timer value from location 80 */
660 FETCH_FW(olditimer,GUESTREGS->psa->inttimer);
661
662 /* Bit position 23 of the interval timer is decremented
663 once for each multiple of 3,333 usecs containded in
664 bit position 0-19 of the residue counter */
665 itimer = olditimer - ((residue / 3333) >> 4);
666
667 /* Store the timer back */
668 STORE_FW(GUESTREGS->psa->inttimer, itimer);
669
670 /* Set interrupt flag and interval timer interrupt pending
671 if the interval timer went from positive to negative */
672 if (itimer < 0 && olditimer >= 0)
673 ON_IC_ITIMER(GUESTREGS);
674 }
675
676 #endif /*!defined(FEATURE_ESAME)*/
677
678 RELEASE_INTLOCK(regs);
679
680 /* Early exceptions associated with the guest load_psw() */
681 if(icode)
682 GUESTREGS->program_interrupt (GUESTREGS, icode);
683
684 /* Run SIE in guests architecture mode */
685 icode = run_sie[GUESTREGS->arch_mode] (regs);
686
687 } /* if (setjmp(GUESTREGS->progjmp)) */
688
689 ARCH_DEP(sie_exit) (regs, icode);
690
691 /* Perform serialization and checkpoint synchronization */
692 PERFORM_SERIALIZATION (regs);
693 PERFORM_CHKPT_SYNC (regs);
694
695 longjmp(regs->progjmp, SIE_NO_INTERCEPT);
696 }
697
698
699 /* Exit SIE state, restore registers and update the state descriptor */
ARCH_DEP(sie_exit)700 void ARCH_DEP(sie_exit) (REGS *regs, int code)
701 {
702 int n;
703
704 #if defined(OPTION_PTTRACE)
705 if(pttclass & PTT_CL_SIE)
706 {
707 U32 nt1 = 0, nt2 = 0;
708 BYTE *ip;
709 if(!GUESTREGS->instinvalid)
710 {
711
712 if(GUESTREGS->ip[0] == 0x44
713 #if defined(FEATURE_EXECUTE_EXTENSIONS_FACILITY)
714 || (GUESTREGS->ip[0] == 0xc6 && !(GUESTREGS->ip[1] & 0x0f))
715 #endif /*defined(FEATURE_EXECUTE_EXTENSIONS_FACILITY)*/
716 )
717 {
718 ip = GUESTREGS->exinst;
719 nt2 = (GUESTREGS->ip[0] == 0x44) ? 0x44 : ((0xc6 << 8) | (GUESTREGS->ip[1] & 0x0f));
720 }
721 else
722 ip = GUESTREGS->ip;
723 nt1 = (ip[0] << 24) | (ip[1] << 16);
724 if(ILC(ip[0]) > 2)
725 nt1 |= (ip[2] << 8) | ip[3];
726 if(ILC(ip[0]) > 4)
727 nt2 |= (ip[4] << 24) | (ip[5] << 16);
728 }
729
730 PTT(PTT_CL_SIE,"*SIE", nt1, nt2, code);
731 }
732 #endif /*defined(OPTION_PTTRACE)*/
733
734 #if defined(SIE_DEBUG)
735 logmsg(_("SIE: interception code %d\n"),code);
736 ARCH_DEP(display_inst) (GUESTREGS,
737 GUESTREGS->instinvalid ? NULL : GUESTREGS->ip);
738 #endif /*defined(SIE_DEBUG)*/
739
740 SIE_PERFMON(SIE_PERF_EXIT);
741 SIE_PERFMON(SIE_PERF_PGMINT);
742
743 /* Indicate we have left SIE mode */
744 OBTAIN_INTLOCK(regs);
745 regs->sie_active = 0;
746 RELEASE_INTLOCK(regs);
747
748 /* zeroize interception status */
749 STATEBK->f = 0;
750
751 switch(code > 0 ? code & ~PGM_PER_EVENT : code)
752 {
753 case SIE_HOST_INTERRUPT:
754 /* If a host interrupt is pending
755 then backup the psw and exit */
756 SET_PSW_IA(regs);
757 UPD_PSW_IA (regs, regs->psw.IA -REAL_ILC(regs));
758 break;
759 case SIE_HOST_PGMINT:
760 break;
761 case SIE_INTERCEPT_INST:
762 STATEBK->c = SIE_C_INST;
763 break;
764 case SIE_INTERCEPT_PER:
765 STATEBK->f |= SIE_F_IF;
766 /*fallthru*/
767 case SIE_INTERCEPT_INSTCOMP:
768 STATEBK->c = SIE_C_PGMINST;
769 break;
770 case SIE_INTERCEPT_WAIT:
771 STATEBK->c = SIE_C_WAIT;
772 break;
773 case SIE_INTERCEPT_STOPREQ:
774 STATEBK->c = SIE_C_STOPREQ;
775 break;
776 case SIE_INTERCEPT_IOREQ:
777 STATEBK->c = SIE_C_IOREQ;
778 break;
779 case SIE_INTERCEPT_EXTREQ:
780 STATEBK->c = SIE_C_EXTREQ;
781 break;
782 case SIE_INTERCEPT_EXT:
783 STATEBK->c = SIE_C_EXTINT;
784 break;
785 case SIE_INTERCEPT_VALIDITY:
786 STATEBK->c = SIE_C_VALIDITY;
787 break;
788 case SIE_INTERCEPT_IOINT:
789 case SIE_INTERCEPT_IOINTP:
790 STATEBK->c = SIE_C_IOINT;
791 break;
792 case SIE_INTERCEPT_IOINST:
793 STATEBK->c = SIE_C_IOINST;
794 break;
795 case PGM_OPERATION_EXCEPTION:
796 STATEBK->c = SIE_C_OPEREXC;
797 break;
798 default:
799 STATEBK->c = SIE_C_PGMINT;
800 break;
801 }
802
803 /* Save CPU timer */
804 STORE_DW(STATEBK->cputimer, cpu_timer(GUESTREGS));
805
806 /* Save clock comparator */
807 STORE_DW(STATEBK->clockcomp, GUESTREGS->clkc << 8);
808
809 #if defined(_FEATURE_INTERVAL_TIMER) && !defined(FEATURE_ESAME)
810 /* If this is a S/370 guest, and the interval timer is enabled
811 then save the timer state control bit */
812 if( (STATEBK->m & SIE_M_370)
813 && !(STATEBK->m & SIE_M_ITMOF))
814 {
815 /* Save the shadow interval timer */
816 s370_store_int_timer(regs);
817
818 if(IS_IC_ITIMER(GUESTREGS))
819 STATEBK->s |= SIE_S_T;
820 else
821 STATEBK->s &= ~SIE_S_T;
822 }
823 #endif /*defined(_FEATURE_INTERVAL_TIMER) && !defined(FEATURE_ESAME)*/
824
825 /* Save TOD Programmable Field */
826 STORE_HW(STATEBK->todpf, GUESTREGS->todpr);
827
828 /* Save GR14 */
829 STORE_W(STATEBK->gr14, GUESTREGS->GR(14));
830
831 /* Save GR15 */
832 STORE_W(STATEBK->gr15, GUESTREGS->GR(15));
833
834 /* Store the PSW */
835 if(GUESTREGS->arch_mode == ARCH_390)
836 s390_store_psw (GUESTREGS, STATEBK->psw);
837 #if defined(_370) || defined(_900)
838 else
839 #endif
840 #if defined(FEATURE_ESAME)
841 z900_store_psw (GUESTREGS, STATEBK->psw);
842 #else /*!defined(FEATURE_ESAME)*/
843 #if defined(_370)
844 s370_store_psw (GUESTREGS, STATEBK->psw);
845 #endif
846 #endif /*!defined(FEATURE_ESAME)*/
847
848 /* save control registers */
849 for(n = 0;n < 16; n++)
850 STORE_W(STATEBK->cr[n], GUESTREGS->CR(n));
851
852 /* Update the approprate host registers */
853 memcpy(regs->gr, GUESTREGS->gr, 14 * sizeof(regs->gr[0]));
854 memcpy(regs->ar, GUESTREGS->ar, 16 * sizeof(regs->ar[0]));
855 memcpy(regs->fpr, GUESTREGS->fpr, 32 * sizeof(regs->fpr[0]));
856 #if defined(FEATURE_BINARY_FLOATING_POINT)
857 regs->fpc = GUESTREGS->fpc;
858 #endif /*defined(FEATURE_BINARY_FLOATING_POINT)*/
859 INVALIDATE_AIA(regs);
860 SET_AEA_MODE(regs);
861
862 /* Zeroize the interruption parameters */
863 memset(STATEBK->ipa, 0, 10);
864
865 if( STATEBK->c == SIE_C_INST
866 || STATEBK->c == SIE_C_PGMINST
867 || STATEBK->c == SIE_C_OPEREXC
868 || STATEBK->c == SIE_C_IOINST )
869 {
870 /* Indicate interception format 2 */
871 STATEBK->f |= SIE_F_IN;
872
873 #if defined(_FEATURE_PER)
874 /* Handle PER or concurrent PER event */
875 if( OPEN_IC_PER(GUESTREGS)
876 && ECMODE(&GUESTREGS->psw)
877 && (GUESTREGS->psw.sysmask & PSW_PERMODE) )
878 {
879 PSA *psa;
880 #if defined(_FEATURE_PER2)
881 GUESTREGS->perc |= OPEN_IC_PER(GUESTREGS) >> ((32 - IC_CR9_SHIFT) - 16);
882 /* Positions 14 and 15 contain zeros if a storage alteration
883 event was not indicated */
884 if( !(OPEN_IC_PER_SA(GUESTREGS))
885 || (OPEN_IC_PER_STURA(GUESTREGS)) )
886 GUESTREGS->perc &= 0xFFFC;
887
888 #endif /*defined(_FEATURE_PER2)*/
889 /* Point to PSA fields in state descriptor */
890 psa = (void*)(regs->mainstor + SIE_STATE(GUESTREGS) + SIE_IP_PSA_OFFSET);
891 STORE_HW(psa->perint, GUESTREGS->perc);
892 STORE_W(psa->peradr, GUESTREGS->peradr);
893 }
894
895 if (IS_IC_PER_IF(GUESTREGS))
896 STATEBK->f |= SIE_F_IF;
897
898 /* Reset any pending PER indication */
899 OFF_IC_PER(GUESTREGS);
900 #endif /*defined(_FEATURE_PER)*/
901
902 /* Backup to the previous instruction */
903 GUESTREGS->ip -= REAL_ILC(GUESTREGS);
904 if (GUESTREGS->ip < GUESTREGS->aip)
905 GUESTREGS->ip = GUESTREGS->inst;
906
907 /* Update interception parameters in the state descriptor */
908 if(GUESTREGS->ip[0] == 0x44
909 #if defined(FEATURE_EXECUTE_EXTENSIONS_FACILITY)
910 || (GUESTREGS->ip[0] == 0xc6 && !(GUESTREGS->ip[1] & 0x0f))
911 #endif /*defined(FEATURE_EXECUTE_EXTENSIONS_FACILITY)*/
912 )
913 {
914 int exilc;
915 STATEBK->f |= SIE_F_EX;
916 exilc = ILC(GUESTREGS->exinst[0]);
917 memcpy(STATEBK->ipa, GUESTREGS->exinst, exilc);
918 }
919 else
920 {
921 if(!GUESTREGS->instinvalid)
922 memcpy(STATEBK->ipa, GUESTREGS->ip, ILC(GUESTREGS->ip[0]));
923 }
924
925 }
926
927 }
928 #endif /*defined(FEATURE_INTERPRETIVE_EXECUTION)*/
929
930
931 #if defined(_FEATURE_SIE)
932 /* Execute guest instructions */
ARCH_DEP(run_sie)933 int ARCH_DEP(run_sie) (REGS *regs)
934 {
935 int icode; /* SIE longjmp intercept code */
936 BYTE oldv; /* siebk->v change check reference */
937 BYTE *ip; /* instruction pointer */
938
939 SIE_PERFMON(SIE_PERF_RUNSIE);
940
941 #if defined(_FEATURE_PER)
942 /* Reset any PER pending indication */
943 OFF_IC_PER(GUESTREGS);
944 #endif /*defined(_FEATURE_PER)*/
945
946 #ifdef FEATURE_INTERVAL_TIMER
947 /* Load the shadow interval timer */
948 {
949 S32 itimer;
950 FETCH_FW(itimer,GUESTREGS->psa->inttimer);
951 set_int_timer(GUESTREGS, itimer);
952 }
953 #endif
954
955 do {
956 SIE_PERFMON(SIE_PERF_RUNLOOP_1);
957 if(!(icode = setjmp(GUESTREGS->progjmp)))
958 do
959 {
960 SIE_PERFMON(SIE_PERF_RUNLOOP_2);
961
962 /* Keep a copy if SIEBK 'v' field for later checks */
963 oldv=GUESTREGS->siebk->v;
964
965 /* Set `execflag' to 0 in case EXecuted instruction did progjmp */
966 GUESTREGS->execflag = 0;
967
968 if(
969 SIE_I_STOP(GUESTREGS)
970 || SIE_I_EXT(GUESTREGS)
971 || SIE_I_IO(GUESTREGS)
972 )
973 break;
974
975 if( SIE_IC_INTERRUPT_CPU(GUESTREGS) )
976 {
977 SIE_PERFMON(SIE_PERF_INTCHECK);
978
979 /* Process PER program interrupts */
980 if( OPEN_IC_PER(GUESTREGS) )
981 ARCH_DEP(program_interrupt) (GUESTREGS, PGM_PER_EVENT);
982
983 OBTAIN_INTLOCK(regs);
984 OFF_IC_INTERRUPT(GUESTREGS);
985
986 /* Set psw.IA and invalidate the aia */
987 INVALIDATE_AIA(GUESTREGS);
988
989 if( OPEN_IC_EXTPENDING(GUESTREGS) )
990 ARCH_DEP(perform_external_interrupt) (GUESTREGS);
991
992 if( (STATEBK->ec[0] & SIE_EC0_IOA) && OPEN_IC_IOPENDING(GUESTREGS) )
993 {
994 PERFORM_SERIALIZATION (GUESTREGS);
995 PERFORM_CHKPT_SYNC (GUESTREGS);
996 ARCH_DEP (perform_io_interrupt) (GUESTREGS);
997 }
998
999 #if defined(_FEATURE_WAITSTATE_ASSIST)
1000 /* Wait state assist */
1001 if (WAITSTATE(&GUESTREGS->psw) && (STATEBK->ec[0] & SIE_EC0_WAIA))
1002 {
1003
1004 /* Test for disabled wait PSW and issue message */
1005 if( IS_IC_DISABLED_WAIT_PSW(GUESTREGS) )
1006 {
1007 RELEASE_INTLOCK(regs);
1008 longjmp(GUESTREGS->progjmp, SIE_INTERCEPT_WAIT);
1009 }
1010
1011 if(
1012 SIE_I_STOP(GUESTREGS)
1013 || SIE_I_EXT(GUESTREGS)
1014 || SIE_I_IO(GUESTREGS)
1015 || SIE_I_HOST(regs)
1016 )
1017 {
1018 RELEASE_INTLOCK(regs);
1019 break;
1020 }
1021
1022 SET_AEA_MODE(GUESTREGS);
1023
1024 {
1025 struct timespec waittime;
1026 U64 now = host_tod();
1027 waittime.tv_sec = now / 1000000;
1028 waittime.tv_nsec = ((now % 1000000) + 3333) * 1000;
1029 #ifdef OPTION_MIPS_COUNTING
1030 regs->waittod = now;
1031 #endif
1032 sysblk.waiting_mask |= regs->cpubit;
1033 sysblk.intowner = LOCK_OWNER_NONE;
1034 timed_wait_condition
1035 (®s->intcond, &sysblk.intlock, &waittime);
1036 while (sysblk.syncing)
1037 wait_condition (&sysblk.sync_bc_cond, &sysblk.intlock);
1038 sysblk.intowner = regs->cpuad;
1039 sysblk.waiting_mask ^= regs->cpubit;
1040 #ifdef OPTION_MIPS_COUNTING
1041 regs->waittime += host_tod() - regs->waittod;
1042 regs->waittod = 0;
1043 #endif
1044 }
1045
1046 RELEASE_INTLOCK(regs);
1047
1048 break;
1049
1050 } /* end if(wait) */
1051 #endif
1052
1053 RELEASE_INTLOCK(regs);
1054 }
1055
1056 if(
1057 SIE_I_WAIT(GUESTREGS)
1058 )
1059 break;
1060
1061 ip = INSTRUCTION_FETCH(GUESTREGS, 0);
1062
1063 #if defined(SIE_DEBUG)
1064 /* Display the instruction */
1065 ARCH_DEP(display_inst) (GUESTREGS,
1066 GUESTREGS->instinvalid ? NULL : ip);
1067 #endif /*defined(SIE_DEBUG)*/
1068
1069 SIE_PERFMON(SIE_PERF_EXEC);
1070 GUESTREGS->instcount = 1;
1071 EXECUTE_INSTRUCTION(ip, GUESTREGS);
1072
1073 do
1074 {
1075 SIE_PERFMON(SIE_PERF_EXEC_U);
1076
1077 UNROLLED_EXECUTE(GUESTREGS);
1078 UNROLLED_EXECUTE(GUESTREGS);
1079 UNROLLED_EXECUTE(GUESTREGS);
1080 UNROLLED_EXECUTE(GUESTREGS);
1081 UNROLLED_EXECUTE(GUESTREGS);
1082 UNROLLED_EXECUTE(GUESTREGS);
1083
1084 GUESTREGS->instcount += 12;
1085
1086 UNROLLED_EXECUTE(GUESTREGS);
1087 UNROLLED_EXECUTE(GUESTREGS);
1088 UNROLLED_EXECUTE(GUESTREGS);
1089 UNROLLED_EXECUTE(GUESTREGS);
1090 UNROLLED_EXECUTE(GUESTREGS);
1091 UNROLLED_EXECUTE(GUESTREGS);
1092
1093 } while( likely(!SIE_I_HOST(regs)
1094 && GUESTREGS->siebk->v==oldv
1095 && !SIE_INTERRUPT_PENDING(GUESTREGS)));
1096 /******************************************/
1097 /* ABOVE : Keep executing instructions */
1098 /* in a tight loop until... */
1099 /* - A Host Interrupt is made pending */
1100 /* - An external source changes siebk->v */
1101 /* - A guest interrupt is made pending */
1102 /******************************************/
1103
1104 regs->instcount += GUESTREGS->instcount;
1105
1106 } while( unlikely(!SIE_I_HOST(regs)
1107 && !SIE_I_WAIT(GUESTREGS)
1108 && !SIE_I_EXT(GUESTREGS)
1109 && !SIE_I_IO(GUESTREGS)
1110 && !SIE_INTERRUPT_PENDING(GUESTREGS)));
1111 /******************************************/
1112 /* ABOVE : Remain in SIE until... */
1113 /* - A Host Interrupt is made pending */
1114 /* - A Sie defined irpt becomes enabled */
1115 /* - A guest interrupt is made pending */
1116 /******************************************/
1117
1118
1119 if(icode == 0 || icode == SIE_NO_INTERCEPT)
1120 {
1121 /* Check PER first, higher priority */
1122 if( OPEN_IC_PER(GUESTREGS) )
1123 ARCH_DEP(program_interrupt) (GUESTREGS, PGM_PER_EVENT);
1124
1125 if( SIE_I_EXT(GUESTREGS) )
1126 icode = SIE_INTERCEPT_EXTREQ;
1127 else
1128 if( SIE_I_IO(GUESTREGS) )
1129 icode = SIE_INTERCEPT_IOREQ;
1130 else
1131 if( SIE_I_STOP(GUESTREGS) )
1132 icode = SIE_INTERCEPT_STOPREQ;
1133 else
1134 if( SIE_I_WAIT(GUESTREGS) )
1135 icode = SIE_INTERCEPT_WAIT;
1136 else
1137 if( SIE_I_HOST(regs) )
1138 icode = SIE_HOST_INTERRUPT;
1139 }
1140
1141 } while(icode == 0 || icode == SIE_NO_INTERCEPT);
1142
1143 return icode;
1144 }
1145
1146
1147 #if defined(FEATURE_INTERPRETIVE_EXECUTION)
1148 #if defined(FEATURE_REGION_RELOCATE)
1149 /*-------------------------------------------------------------------*/
1150 /* B23D STZP - Store Zone Parameter [S] */
1151 /*-------------------------------------------------------------------*/
DEF_INST(store_zone_parameter)1152 DEF_INST(store_zone_parameter)
1153 {
1154 int b2; /* Values of R fields */
1155 RADR effective_addr2; /* address of state desc. */
1156 ZPB zpb; /* Zone Parameter Block */
1157 int zone; /* Zone number */
1158
1159 S(inst, regs, b2, effective_addr2);
1160
1161 PRIV_CHECK(regs);
1162
1163 SIE_INTERCEPT(regs);
1164
1165 PTT(PTT_CL_IO,"STZP", regs->GR_L(1), regs->GR_L(2),regs->psw.IA_L);
1166
1167 FW_CHECK(regs->GR(2), regs);
1168
1169 zone = regs->GR_LHLCL(1);
1170
1171 if(zone >= FEATURE_SIE_MAXZONES)
1172 {
1173 PTT(PTT_CL_ERR,"*STZP", regs->GR_L(1), regs->GR_L(2),regs->psw.IA_L);
1174 regs->psw.cc = 3;
1175 return;
1176 }
1177
1178 STORE_W(zpb.mso,sysblk.zpb[zone].mso);
1179 STORE_W(zpb.msl,sysblk.zpb[zone].msl);
1180 STORE_W(zpb.eso,sysblk.zpb[zone].eso);
1181 STORE_W(zpb.esl,sysblk.zpb[zone].esl);
1182
1183 ARCH_DEP(vstorec(&zpb, sizeof(ZPB)-1,regs->GR(2), 2, regs));
1184
1185 regs->psw.cc = 0;
1186 }
1187
1188
1189 /*-------------------------------------------------------------------*/
1190 /* B23E SZP - Set Zone Parameter [S] */
1191 /*-------------------------------------------------------------------*/
DEF_INST(set_zone_parameter)1192 DEF_INST(set_zone_parameter)
1193 {
1194 int b2; /* Values of R fields */
1195 RADR effective_addr2; /* address of state desc. */
1196 ZPB zpb; /* Zone Parameter Block */
1197 int zone; /* Zone number */
1198 RADR mso, /* Main Storage Origin */
1199 msl, /* Main Storage Length */
1200 eso, /* Expanded Storage Origin */
1201 esl; /* Expanded Storage Length */
1202
1203 S(inst, regs, b2, effective_addr2);
1204
1205 PRIV_CHECK(regs);
1206
1207 SIE_INTERCEPT(regs);
1208
1209 PTT(PTT_CL_IO,"SZP", regs->GR_L(1), regs->GR_L(2),regs->psw.IA_L);
1210
1211 FW_CHECK(regs->GR(2), regs);
1212
1213 zone = regs->GR_LHLCL(1);
1214
1215 if(zone == 0 || zone >= FEATURE_SIE_MAXZONES)
1216 {
1217 PTT(PTT_CL_ERR,"*SZP", regs->GR_L(1), regs->GR_L(2),regs->psw.IA_L);
1218 regs->psw.cc = 3;
1219 return;
1220 }
1221
1222 ARCH_DEP(vfetchc(&zpb, sizeof(ZPB)-1,regs->GR(2), 2, regs));
1223
1224 FETCH_W(mso,zpb.mso);
1225 FETCH_W(msl,zpb.msl);
1226 FETCH_W(eso,zpb.eso);
1227 FETCH_W(esl,zpb.esl);
1228
1229 #if defined(FEATURE_ESAME)
1230 if( (mso & ~ZPB2_MS_VALID)
1231 || (msl & ~ZPB2_MS_VALID)
1232 || (eso & ~ZPB2_ES_VALID)
1233 || (esl & ~ZPB2_ES_VALID) )
1234 ARCH_DEP(program_interrupt) (regs, PGM_OPERAND_EXCEPTION);
1235 #endif /*defined(FEATURE_ESAME)*/
1236
1237 sysblk.zpb[zone].mso = mso;
1238 sysblk.zpb[zone].msl = msl;
1239 sysblk.zpb[zone].eso = eso;
1240 sysblk.zpb[zone].esl = esl;
1241
1242 regs->psw.cc = 0;
1243 }
1244 #endif /*defined(FEATURE_REGION_RELOCATE)*/
1245
1246
1247 #if defined(FEATURE_IO_ASSIST)
1248 /*-------------------------------------------------------------------*/
1249 /* B23F TPZI - Test Pending Zone Interrupt [S] */
1250 /*-------------------------------------------------------------------*/
DEF_INST(test_pending_zone_interrupt)1251 DEF_INST(test_pending_zone_interrupt)
1252 {
1253 int b2; /* Values of R fields */
1254 RADR effective_addr2; /* address of state desc. */
1255 U32 ioid; /* I/O interruption address */
1256 U32 ioparm; /* I/O interruption parameter*/
1257 U32 iointid; /* I/O interruption ident */
1258 FWORD tpziid[3];
1259 int zone; /* Zone number */
1260
1261 S(inst, regs, b2, effective_addr2);
1262
1263 PRIV_CHECK(regs);
1264
1265 SIE_INTERCEPT(regs);
1266
1267 PTT(PTT_CL_IO,"TPZI", regs->GR_L(1),(U32)(effective_addr2 & 0xffffffff),regs->psw.IA_L);
1268
1269 FW_CHECK(regs->GR(2), regs);
1270
1271 /* Perform serialization and checkpoint-synchronization */
1272 PERFORM_SERIALIZATION (regs);
1273 PERFORM_CHKPT_SYNC (regs);
1274
1275 zone = regs->GR_LHLCL(1);
1276
1277 if(zone >= FEATURE_SIE_MAXZONES)
1278 {
1279 PTT(PTT_CL_ERR,"*TPZI", regs->GR_L(1),(U32)(effective_addr2 & 0xffffffff),regs->psw.IA_L);
1280 regs->psw.cc = 0;
1281 return;
1282 }
1283
1284 if( IS_IC_IOPENDING )
1285 {
1286 /* Obtain the interrupt lock */
1287 OBTAIN_INTLOCK(regs);
1288
1289 /* Test (but don't clear!) pending interrupt, and set condition code */
1290 if( ARCH_DEP(present_zone_io_interrupt) (&ioid, &ioparm,
1291 &iointid, zone) )
1292
1293 /* Store the SSID word and I/O parameter if an interrupt was pending */
1294 {
1295 /* Store interruption parms */
1296 STORE_FW(tpziid[0],ioid);
1297 STORE_FW(tpziid[1],ioparm);
1298 STORE_FW(tpziid[2],iointid);
1299
1300 /* Release the interrupt lock */
1301 RELEASE_INTLOCK(regs);
1302
1303 ARCH_DEP(vstorec(&tpziid, sizeof(tpziid)-1,regs->GR(2), 2, regs));
1304
1305 regs->psw.cc = 1;
1306 }
1307 else
1308 {
1309 /* Release the interrupt lock */
1310 RELEASE_INTLOCK(regs);
1311 regs->psw.cc = 0;
1312 }
1313
1314 }
1315 else
1316 regs->psw.cc = 0;
1317 }
1318
1319
1320 /*-------------------------------------------------------------------*/
1321 /* DIAG 002 - Update Interrupt Interlock Control Bit in PMCW */
1322 /*-------------------------------------------------------------------*/
ARCH_DEP(diagnose_002)1323 void ARCH_DEP(diagnose_002) (REGS *regs, int r1, int r3)
1324 {
1325 DEVBLK *dev;
1326 U32 newgr1;
1327
1328 /* Program check if the ssid including lcss is invalid */
1329 SSID_CHECK(regs);
1330
1331 /* Locate the device block for this subchannel */
1332 dev = find_device_by_subchan (regs->GR_L(1));
1333
1334 /* Condition code 3 if subchannel does not exist,
1335 is not valid, or is not enabled */
1336 if (dev == NULL
1337 || (dev->pmcw.flag5 & PMCW5_V) == 0
1338 || (dev->pmcw.flag5 & PMCW5_E) == 0)
1339 {
1340 PTT(PTT_CL_ERR,"*DIAG002", regs->GR_L(r1),regs->GR_L(r3),regs->GR_L(1));
1341 regs->psw.cc = 3;
1342 return;
1343 }
1344
1345 /* Obtain the device lock */
1346 obtain_lock (&dev->lock);
1347
1348 /* Set newgr1 to the current value of pending and interlock control */
1349 newgr1 = ((dev->scsw.flag3 & SCSW3_SC_PEND)
1350 || (dev->pciscsw.flag3 & SCSW3_SC_PEND)) ? 0x02 : 0;
1351 if(dev->pmcw.flag27 & PMCW27_I)
1352 newgr1 |= 0x01;
1353
1354 /* Do a compare-and-swap operation on the interrupt interlock
1355 control bit where both interlock and pending bits are
1356 compared, but only the interlock bit is swapped */
1357 if((regs->GR_L(r1) & 0x03) == newgr1)
1358 {
1359 dev->pmcw.flag27 &= ~PMCW27_I;
1360 dev->pmcw.flag27 |= (regs->GR_L(r3) & 0x01) ? PMCW27_I : 0;
1361 regs->psw.cc = 0;
1362 }
1363 else
1364 {
1365 regs->GR_L(r1) &= ~0x03;
1366 regs->GR_L(r1) |= newgr1;
1367 regs->psw.cc = 1;
1368 }
1369
1370 /* Release the device lock */
1371 release_lock (&dev->lock);
1372 }
1373 #endif /*defined(FEATURE_IO_ASSIST)*/
1374 #endif /*defined(FEATURE_INTERPRETIVE_EXECUTION)*/
1375
1376
1377 #endif
1378
1379
1380 #if !defined(_GEN_ARCH)
1381
1382 #if defined(_ARCHMODE2)
1383 #define _GEN_ARCH _ARCHMODE2
1384 #include "sie.c"
1385 #endif
1386
1387 #if defined(_ARCHMODE3)
1388 #undef _GEN_ARCH
1389 #define _GEN_ARCH _ARCHMODE3
1390 #include "sie.c"
1391 #endif
1392
1393 #endif /*!defined(_GEN_ARCH)*/
1394