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                                  (&regs->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