1 /* CPU.C        (c) Copyright Roger Bowler, 1994-2009                */
2 /*              ESA/390 CPU Emulator                                 */
3 
4 /* Interpretive Execution - (c) Copyright Jan Jaeger, 1999-2009      */
5 /* z/Architecture support - (c) Copyright Jan Jaeger, 1999-2009      */
6 
7 /*-------------------------------------------------------------------*/
8 /* This module implements the CPU instruction execution function of  */
9 /* the S/370 and ESA/390 architectures, as described in the manuals  */
10 /* GA22-7000-03 System/370 Principles of Operation                   */
11 /* SA22-7201-06 ESA/390 Principles of Operation                      */
12 /* SA22-7832-00 z/Architecture Principles of Operation               */
13 /*-------------------------------------------------------------------*/
14 
15 /*-------------------------------------------------------------------*/
16 /* Additional credits:                                               */
17 /*      Nullification corrections by Jan Jaeger                      */
18 /*      Set priority by Reed H. Petty from an idea by Steve Gay      */
19 /*      Corrections to program check by Jan Jaeger                   */
20 /*      Light optimization on critical path by Valery Pogonchenko    */
21 /*      OSTAILOR parameter by Jay Maynard                            */
22 /*      CPU timer and clock comparator interrupt improvements by     */
23 /*          Jan Jaeger, after a suggestion by Willem Konynenberg     */
24 /*      Instruction decode rework - Jan Jaeger                       */
25 /*      Modifications for Interpretive Execution (SIE) by Jan Jaeger */
26 /*      Basic FP extensions support - Peter Kuschnerus           v209*/
27 /*      ASN-and-LX-reuse facility - Roger Bowler, June 2004      @ALR*/
28 /*-------------------------------------------------------------------*/
29 
30 #include "hstdinc.h"
31 
32 #if !defined(_HENGINE_DLL_)
33 #define _HENGINE_DLL_
34 #endif
35 
36 #if !defined(_CPU_C_)
37 #define _CPU_C_
38 #endif
39 
40 #include "hercules.h"
41 #include "opcode.h"
42 #include "inline.h"
43 
44 /*-------------------------------------------------------------------*/
45 /* Put a CPU in check-stop state                                     */
46 /* Must hold the system intlock                                      */
47 /*-------------------------------------------------------------------*/
ARCH_DEP(checkstop_cpu)48 void ARCH_DEP(checkstop_cpu)(REGS *regs)
49 {
50     regs->cpustate=CPUSTATE_STOPPING;
51     regs->checkstop=1;
52     ON_IC_INTERRUPT(regs);
53 }
54 /*-------------------------------------------------------------------*/
55 /* Put all the CPUs in the configuration in check-stop state         */
56 /*-------------------------------------------------------------------*/
ARCH_DEP(checkstop_config)57 void ARCH_DEP(checkstop_config)(void)
58 {
59     int i;
60     for(i=0;i<MAX_CPU;i++)
61     {
62         if(IS_CPU_ONLINE(i))
63         {
64             ARCH_DEP(checkstop_cpu)(sysblk.regs[i]);
65         }
66     }
67     WAKEUP_CPUS_MASK(sysblk.waiting_mask);
68 }
69 
70 /*-------------------------------------------------------------------*/
71 /* Store current PSW at a specified address in main storage          */
72 /*-------------------------------------------------------------------*/
ARCH_DEP(store_psw)73 void ARCH_DEP(store_psw) (REGS *regs, BYTE *addr)
74 {
75 
76     /* Ensure psw.IA is set */
77     if (!regs->psw.zeroilc)
78         SET_PSW_IA(regs);
79 
80 #if defined(FEATURE_BCMODE)
81     if ( ECMODE(&regs->psw) ) {
82 #endif /*defined(FEATURE_BCMODE)*/
83 #if !defined(FEATURE_ESAME)
84         STORE_FW ( addr,
85                    ( (regs->psw.sysmask << 24)
86                    | ((regs->psw.pkey | regs->psw.states) << 16)
87                    | ( ( (regs->psw.asc)
88                        | (regs->psw.cc << 4)
89                        | (regs->psw.progmask)
90                        ) << 8
91                      )
92                    | regs->psw.zerobyte
93                    )
94                  );
95         if(unlikely(regs->psw.zeroilc))
96             STORE_FW ( addr + 4, regs->psw.IA | (regs->psw.amode ? 0x80000000 : 0) );
97         else
98             STORE_FW ( addr + 4,
99                    ( (regs->psw.IA & ADDRESS_MAXWRAP(regs)) | (regs->psw.amode ? 0x80000000 : 0) )
100                  );
101 #endif /*!defined(FEATURE_ESAME)*/
102 #if defined(FEATURE_BCMODE)
103     } else {
104         STORE_FW ( addr,
105                    ( (regs->psw.sysmask << 24)
106                    | ((regs->psw.pkey | regs->psw.states) << 16)
107                    | (regs->psw.intcode)
108                    )
109                  );
110         if(unlikely(regs->psw.zeroilc))
111             STORE_FW ( addr + 4,
112                    ( ( (REAL_ILC(regs) << 5)
113                      | (regs->psw.cc << 4)
114                      | regs->psw.progmask
115                      ) << 24
116                    ) | regs->psw.IA
117                  );
118         else
119             STORE_FW ( addr + 4,
120                    ( ( (REAL_ILC(regs) << 5)
121                      | (regs->psw.cc << 4)
122                      | regs->psw.progmask
123                      ) << 24
124                    ) | (regs->psw.IA & ADDRESS_MAXWRAP(regs))
125                  );
126     }
127 #elif defined(FEATURE_ESAME)
128         STORE_FW ( addr,
129                    ( (regs->psw.sysmask << 24)
130                    | ((regs->psw.pkey | regs->psw.states) << 16)
131                    | ( ( (regs->psw.asc)
132                        | (regs->psw.cc << 4)
133                        | (regs->psw.progmask)
134                        ) << 8
135                      )
136                    | (regs->psw.amode64 ? 0x01 : 0)
137                    | regs->psw.zerobyte
138                    )
139                  );
140         STORE_FW ( addr + 4,
141                    ( (regs->psw.amode ? 0x80000000 : 0 )
142                    | regs->psw.zeroword
143                    )
144                  );
145         STORE_DW ( addr + 8, regs->psw.IA_G );
146 #endif /*defined(FEATURE_ESAME)*/
147 } /* end function ARCH_DEP(store_psw) */
148 
149 /*-------------------------------------------------------------------*/
150 /* Load current PSW from a specified address in main storage         */
151 /* Returns 0 if valid, 0x0006 if specification exception             */
152 /*-------------------------------------------------------------------*/
ARCH_DEP(load_psw)153 int ARCH_DEP(load_psw) (REGS *regs, BYTE *addr)
154 {
155     INVALIDATE_AIA(regs);
156 
157     regs->psw.zeroilc = 1;
158 
159     regs->psw.sysmask = addr[0];
160     regs->psw.pkey    = (addr[1] & 0xF0);
161     regs->psw.states  = (addr[1] & 0x0F);
162 
163 #if defined(FEATURE_BCMODE)
164     if ( ECMODE(&regs->psw) ) {
165 #endif /*defined(FEATURE_BCMODE)*/
166 
167         SET_IC_ECMODE_MASK(regs);
168 
169         /* Processing for EC mode PSW */
170         regs->psw.intcode  = 0;
171         regs->psw.asc      = (addr[2] & 0xC0);
172         regs->psw.cc       = (addr[2] & 0x30) >> 4;
173         regs->psw.progmask = (addr[2] & 0x0F);
174         regs->psw.amode    = (addr[4] & 0x80) ? 1 : 0;
175 
176 #if defined(FEATURE_ESAME)
177         regs->psw.zerobyte = addr[3] & 0xFE;
178         regs->psw.amode64  = addr[3] & 0x01;
179         regs->psw.zeroword = fetch_fw(addr+4) & 0x7FFFFFFF;
180         regs->psw.IA       = fetch_dw (addr + 8);
181         regs->psw.AMASK    = regs->psw.amode64 ? AMASK64
182                            : regs->psw.amode   ? AMASK31 : AMASK24;
183 #else /*!defined(FEATURE_ESAME)*/
184         regs->psw.zerobyte = addr[3];
185         regs->psw.amode64  = 0;
186         regs->psw.IA       = fetch_fw(addr + 4) & 0x7FFFFFFF;
187         regs->psw.AMASK    = regs->psw.amode ? AMASK31 : AMASK24;
188 #endif /*!defined(FEATURE_ESAME)*/
189 
190         /* Bits 0 and 2-4 of system mask must be zero */
191         if ((addr[0] & 0xB8) != 0)
192             return PGM_SPECIFICATION_EXCEPTION;
193 
194 #if defined(FEATURE_ESAME)
195         /* For ESAME, bit 12 must be zero */
196         if (NOTESAME(&regs->psw))
197             return PGM_SPECIFICATION_EXCEPTION;
198 
199         /* Bits 24-30 must be zero */
200         if (regs->psw.zerobyte)
201             return PGM_SPECIFICATION_EXCEPTION;
202 
203         /* Bits 33-63 must be zero */
204         if ( regs->psw.zeroword )
205             return PGM_SPECIFICATION_EXCEPTION;
206 #else /*!defined(FEATURE_ESAME)*/
207         /* Bits 24-31 must be zero */
208         if ( regs->psw.zerobyte )
209             return PGM_SPECIFICATION_EXCEPTION;
210 
211         /* For ESA/390, bit 12 must be one */
212         if (!ECMODE(&regs->psw))
213             return PGM_SPECIFICATION_EXCEPTION;
214 #endif /*!defined(FEATURE_ESAME)*/
215 
216 #ifndef FEATURE_DUAL_ADDRESS_SPACE
217         /* If DAS feature not installed then bit 16 must be zero */
218         if (SPACE_BIT(&regs->psw))
219             return PGM_SPECIFICATION_EXCEPTION;
220 #endif /*!FEATURE_DUAL_ADDRESS_SPACE*/
221 
222 #ifndef FEATURE_ACCESS_REGISTERS
223         /* If not ESA/370 or ESA/390 then bit 17 must be zero */
224         if (AR_BIT(&regs->psw))
225             return PGM_SPECIFICATION_EXCEPTION;
226 #endif /*!FEATURE_ACCESS_REGISTERS*/
227 
228         /* Check validity of amode and instruction address */
229 #if defined(FEATURE_ESAME)
230         /* For ESAME, bit 32 cannot be zero if bit 31 is one */
231         if (regs->psw.amode64 && !regs->psw.amode)
232             return PGM_SPECIFICATION_EXCEPTION;
233 
234         /* If bit 32 is zero then IA cannot exceed 24 bits */
235         if (!regs->psw.amode && regs->psw.IA > 0x00FFFFFF)
236             return PGM_SPECIFICATION_EXCEPTION;
237 
238         /* If bit 31 is zero then IA cannot exceed 31 bits */
239         if (!regs->psw.amode64 && regs->psw.IA > 0x7FFFFFFF)
240             return PGM_SPECIFICATION_EXCEPTION;
241 #else /*!defined(FEATURE_ESAME)*/
242   #ifdef FEATURE_BIMODAL_ADDRESSING
243         /* For 370-XA, ESA/370, and ESA/390,
244            if amode=24, bits 33-39 must be zero */
245         if (!regs->psw.amode && regs->psw.IA > 0x00FFFFFF)
246             return PGM_SPECIFICATION_EXCEPTION;
247   #else /*!FEATURE_BIMODAL_ADDRESSING*/
248         /* For S/370, bits 32-39 must be zero */
249         if (addr[4] != 0x00)
250             return PGM_SPECIFICATION_EXCEPTION;
251   #endif /*!FEATURE_BIMODAL_ADDRESSING*/
252 #endif /*!defined(FEATURE_ESAME)*/
253 
254 #if defined(FEATURE_BCMODE)
255     } else {
256 
257         SET_IC_BCMODE_MASK(regs);
258 
259         /* Processing for S/370 BC mode PSW */
260         regs->psw.intcode = fetch_hw (addr + 2);
261         regs->psw.cc = (addr[4] & 0x30) >> 4;
262         regs->psw.progmask = (addr[4] & 0x0F);
263 
264         FETCH_FW(regs->psw.IA, addr + 4);
265         regs->psw.IA &= 0x00FFFFFF;
266         regs->psw.AMASK = AMASK24;
267 
268         regs->psw.zerobyte = 0;
269         regs->psw.asc = 0;
270         regs->psw.amode64 = regs->psw.amode = 0;
271     }
272 #endif /*defined(FEATURE_BCMODE)*/
273 
274 #if defined(FEATURE_MULTIPLE_CONTROLLED_DATA_SPACE)
275     /* Bits 5 and 16 must be zero in XC mode */
276     if( SIE_STATB(regs, MX, XC)
277       && ( (regs->psw.sysmask & PSW_DATMODE) || SPACE_BIT(&regs->psw)) )
278         return PGM_SPECIFICATION_EXCEPTION;
279 #endif /*defined(FEATURE_MULTIPLE_CONTROLLED_DATA_SPACE)*/
280 
281     regs->psw.zeroilc = 0;
282 
283     /* Check for wait state PSW */
284     if (WAITSTATE(&regs->psw) && CPU_STEPPING_OR_TRACING_ALL)
285     {
286         logmsg (_("HHCCP043I Wait state PSW loaded: "));
287         display_psw (regs);
288     }
289 
290     TEST_SET_AEA_MODE(regs);
291 
292     return 0;
293 } /* end function ARCH_DEP(load_psw) */
294 
295 /*-------------------------------------------------------------------*/
296 /* Load program interrupt new PSW                                    */
297 /*-------------------------------------------------------------------*/
298 void (ATTR_REGPARM(2) ARCH_DEP(program_interrupt)) (REGS *regs, int pcode)
299 {
300 PSA    *psa;                            /* -> Prefixed storage area  */
301 REGS   *realregs;                       /* True regs structure       */
302 RADR    px;                             /* host real address of pfx  */
303 int     code;                           /* pcode without PER ind.    */
304 int     ilc;                            /* instruction length        */
305 #if defined(FEATURE_ESAME)
306 /** FIXME : SEE ISW20090110-1 */
307 void   *zmoncode=NULL;                  /* special reloc for z/Arch  */
308                  /* FIXME : zmoncode not being initialized here raises
309                     a potentially non-initialized warning in GCC..
310                     can't find why. ISW 2009/02/04 */
311                                         /* mon call SIE intercept    */
312 #endif
313 #if defined(FEATURE_INTERPRETIVE_EXECUTION)
314 int     sie_ilc=0;                      /* SIE instruction length    */
315 #endif
316 #if defined(_FEATURE_SIE)
317 int     nointercept;                    /* True for virtual pgmint   */
318 #endif /*defined(_FEATURE_SIE)*/
319 #if defined(OPTION_FOOTPRINT_BUFFER)
320 U32     n;
321 #endif /*defined(OPTION_FOOTPRINT_BUFFER)*/
322 char    dxcstr[8]={0};                  /* " DXC=xx" if data excptn  */
323 
324 static char *pgmintname[] = {
325         /* 01 */        "Operation exception",
326         /* 02 */        "Privileged-operation exception",
327         /* 03 */        "Execute exception",
328         /* 04 */        "Protection exception",
329         /* 05 */        "Addressing exception",
330         /* 06 */        "Specification exception",
331         /* 07 */        "Data exception",
332         /* 08 */        "Fixed-point-overflow exception",
333         /* 09 */        "Fixed-point-divide exception",
334         /* 0A */        "Decimal-overflow exception",
335         /* 0B */        "Decimal-divide exception",
336         /* 0C */        "HFP-exponent-overflow exception",
337         /* 0D */        "HFP-exponent-underflow exception",
338         /* 0E */        "HFP-significance exception",
339         /* 0F */        "HFP-floating-point-divide exception",
340         /* 10 */        "Segment-translation exception",
341         /* 11 */        "Page-translation exception",
342         /* 12 */        "Translation-specification exception",
343         /* 13 */        "Special-operation exception",
344         /* 14 */        "Pseudo-page-fault exception",
345         /* 15 */        "Operand exception",
346         /* 16 */        "Trace-table exception",
347         /* 17 */        "ASN-translation exception",
348         /* 18 */        "Page access exception",
349         /* 19 */        "Vector/Crypto operation exception",
350         /* 1A */        "Page state exception",
351         /* 1B */        "Page transition exception",
352         /* 1C */        "Space-switch event",
353         /* 1D */        "Square-root exception",
354         /* 1E */        "Unnormalized-operand exception",
355         /* 1F */        "PC-translation specification exception",
356         /* 20 */        "AFX-translation exception",
357         /* 21 */        "ASX-translation exception",
358         /* 22 */        "LX-translation exception",
359         /* 23 */        "EX-translation exception",
360         /* 24 */        "Primary-authority exception",
361         /* 25 */        "Secondary-authority exception",
362         /* 26 */        "LFX-translation exception",            /*@ALR*/
363         /* 27 */        "LSX-translation exception",            /*@ALR*/
364         /* 28 */        "ALET-specification exception",
365         /* 29 */        "ALEN-translation exception",
366         /* 2A */        "ALE-sequence exception",
367         /* 2B */        "ASTE-validity exception",
368         /* 2C */        "ASTE-sequence exception",
369         /* 2D */        "Extended-authority exception",
370         /* 2E */        "LSTE-sequence exception",              /*@ALR*/
371         /* 2F */        "ASTE-instance exception",              /*@ALR*/
372         /* 30 */        "Stack-full exception",
373         /* 31 */        "Stack-empty exception",
374         /* 32 */        "Stack-specification exception",
375         /* 33 */        "Stack-type exception",
376         /* 34 */        "Stack-operation exception",
377         /* 35 */        "Unassigned exception",
378         /* 36 */        "Unassigned exception",
379         /* 37 */        "Unassigned exception",
380         /* 38 */        "ASCE-type exception",
381         /* 39 */        "Region-first-translation exception",
382         /* 3A */        "Region-second-translation exception",
383         /* 3B */        "Region-third-translation exception",
384         /* 3C */        "Unassigned exception",
385         /* 3D */        "Unassigned exception",
386         /* 3E */        "Unassigned exception",
387         /* 3F */        "Unassigned exception",
388         /* 40 */        "Monitor event" };
389 
390         /* 26 */ /* was "Page-fault-assist exception", */
391         /* 27 */ /* was "Control-switch exception", */
392 
393     /* If called with ghost registers (ie from hercules command
394        then ignore all interrupt handling and report the error
395        to the caller */
396     if(regs->ghostregs)
397         longjmp(regs->progjmp, pcode);
398 
399     PTT(PTT_CL_PGM,"*PROG",pcode,(U32)(regs->TEA & 0xffffffff),regs->psw.IA_L);
400 
401     /* program_interrupt() may be called with a shadow copy of the
402        regs structure, realregs is the pointer to the real structure
403        which must be used when loading/storing the psw, or backing up
404        the instruction address in case of nullification */
405 #if defined(_FEATURE_SIE)
406         realregs = SIE_MODE(regs)
407                  ? sysblk.regs[regs->cpuad]->guestregs
408                  : sysblk.regs[regs->cpuad];
409 #else /*!defined(_FEATURE_SIE)*/
410     realregs = sysblk.regs[regs->cpuad];
411 #endif /*!defined(_FEATURE_SIE)*/
412 
413     /* Prevent machine check when in (almost) interrupt loop */
414     realregs->instcount++;
415 
416     /* Release any locks */
417     if (sysblk.intowner == realregs->cpuad)
418         RELEASE_INTLOCK(realregs);
419     if (sysblk.mainowner == realregs->cpuad)
420         RELEASE_MAINLOCK(realregs);
421 
422     /* Ensure psw.IA is set and aia invalidated */
423     INVALIDATE_AIA(realregs);
424 #if defined(FEATURE_INTERPRETIVE_EXECUTION)
425     if(realregs->sie_active)
426         INVALIDATE_AIA(realregs->guestregs);
427 #endif /*defined(FEATURE_INTERPRETIVE_EXECUTION)*/
428 
429     /* Set instruction length (ilc) */
430     ilc = realregs->psw.zeroilc ? 0 : REAL_ILC(realregs);
431     if (realregs->psw.ilc == 0 && !realregs->psw.zeroilc)
432     {
433         /* This can happen if BALR, BASR, BASSM or BSM
434            program checks during trace */
435         ilc = realregs->execflag ? realregs->exrl ? 6 : 4 : 2;
436         realregs->ip += ilc;
437         realregs->psw.IA += ilc;
438         realregs->psw.ilc = ilc;
439     }
440 #if defined(FEATURE_INTERPRETIVE_EXECUTION)
441     if(realregs->sie_active)
442     {
443         sie_ilc = realregs->guestregs->psw.zeroilc
444                 ? 0 : REAL_ILC(realregs->guestregs);
445         if (realregs->guestregs->psw.ilc == 0
446          && !realregs->guestregs->psw.zeroilc)
447         {
448             sie_ilc = realregs->guestregs->execflag ?
449                       realregs->guestregs->exrl ? 6 : 4 : 2;
450             realregs->guestregs->psw.IA += sie_ilc; /* IanWorthington regression restored from 20081205 */
451             realregs->guestregs->psw.ilc = sie_ilc;
452         }
453     }
454 #endif /*defined(FEATURE_INTERPRETIVE_EXECUTION)*/
455 
456     /* Set `execflag' to 0 in case EXecuted instruction program-checked */
457     realregs->execflag = 0;
458 #if defined(FEATURE_INTERPRETIVE_EXECUTION)
459     if(realregs->sie_active)
460         realregs->guestregs->execflag = 0;
461 #endif /*defined(FEATURE_INTERPRETIVE_EXECUTION)*/
462 
463     /* Unlock the main storage lock if held */
464     if (realregs->cpuad == sysblk.mainowner)
465         RELEASE_MAINLOCK(realregs);
466 
467     /* Remove PER indication from program interrupt code
468        such that interrupt code specific tests may be done.
469        The PER indication will be stored in the PER handling
470        code */
471     code = pcode & ~PGM_PER_EVENT;
472 
473     /* If this is a concurrent PER event then we must add the PER
474        bit to the interrupts code */
475     if( OPEN_IC_PER(realregs) )
476         pcode |= PGM_PER_EVENT;
477 
478     /* Perform serialization and checkpoint synchronization */
479     PERFORM_SERIALIZATION (realregs);
480     PERFORM_CHKPT_SYNC (realregs);
481 
482 #if defined(FEATURE_INTERPRETIVE_EXECUTION)
483     /* Host protection and addressing exceptions must be
484        reflected to the guest */
485     if(realregs->sie_active &&
486         (code == PGM_PROTECTION_EXCEPTION
487       || code == PGM_ADDRESSING_EXCEPTION
488 #if defined(_FEATURE_MULTIPLE_CONTROLLED_DATA_SPACE)
489       || code == PGM_ALET_SPECIFICATION_EXCEPTION
490       || code == PGM_ALEN_TRANSLATION_EXCEPTION
491       || code == PGM_ALE_SEQUENCE_EXCEPTION
492       || code == PGM_EXTENDED_AUTHORITY_EXCEPTION
493 #endif /*defined(_FEATURE_MULTIPLE_CONTROLLED_DATA_SPACE)*/
494         ) )
495     {
496 #if defined(SIE_DEBUG)
497         logmsg(_("program_int() passing to guest code=%4.4X\n"),pcode);
498 #endif /*defined(SIE_DEBUG)*/
499         realregs->guestregs->TEA = realregs->TEA;
500         realregs->guestregs->excarid = realregs->excarid;
501         realregs->guestregs->opndrid = realregs->opndrid;
502 #if defined(_FEATURE_PROTECTION_INTERCEPTION_CONTROL)
503         realregs->guestregs->hostint = 1;
504 #endif /*defined(_FEATURE_PROTECTION_INTERCEPTION_CONTROL)*/
505         (realregs->guestregs->program_interrupt) (realregs->guestregs, pcode);
506     }
507 #endif /*defined(FEATURE_INTERPRETIVE_EXECUTION)*/
508 
509     /* Back up the PSW for exceptions which cause nullification,
510        unless the exception occurred during instruction fetch */
511     if ((code == PGM_PAGE_TRANSLATION_EXCEPTION
512       || code == PGM_SEGMENT_TRANSLATION_EXCEPTION
513 #if defined(FEATURE_ESAME)
514       || code == PGM_ASCE_TYPE_EXCEPTION
515       || code == PGM_REGION_FIRST_TRANSLATION_EXCEPTION
516       || code == PGM_REGION_SECOND_TRANSLATION_EXCEPTION
517       || code == PGM_REGION_THIRD_TRANSLATION_EXCEPTION
518 #endif /*defined(FEATURE_ESAME)*/
519       || code == PGM_TRACE_TABLE_EXCEPTION
520       || code == PGM_AFX_TRANSLATION_EXCEPTION
521       || code == PGM_ASX_TRANSLATION_EXCEPTION
522       || code == PGM_LX_TRANSLATION_EXCEPTION
523       || code == PGM_LFX_TRANSLATION_EXCEPTION                 /*@ALR*/
524       || code == PGM_LSX_TRANSLATION_EXCEPTION                 /*@ALR*/
525       || code == PGM_LSTE_SEQUENCE_EXCEPTION                   /*@ALR*/
526       || code == PGM_EX_TRANSLATION_EXCEPTION
527       || code == PGM_PRIMARY_AUTHORITY_EXCEPTION
528       || code == PGM_SECONDARY_AUTHORITY_EXCEPTION
529       || code == PGM_ALEN_TRANSLATION_EXCEPTION
530       || code == PGM_ALE_SEQUENCE_EXCEPTION
531       || code == PGM_ASTE_VALIDITY_EXCEPTION
532       || code == PGM_ASTE_SEQUENCE_EXCEPTION
533       || code == PGM_ASTE_INSTANCE_EXCEPTION                   /*@ALR*/
534       || code == PGM_EXTENDED_AUTHORITY_EXCEPTION
535       || code == PGM_STACK_FULL_EXCEPTION
536       || code == PGM_STACK_EMPTY_EXCEPTION
537       || code == PGM_STACK_SPECIFICATION_EXCEPTION
538       || code == PGM_STACK_TYPE_EXCEPTION
539       || code == PGM_STACK_OPERATION_EXCEPTION
540       || code == PGM_VECTOR_OPERATION_EXCEPTION)
541       && !realregs->instinvalid)
542     {
543         realregs->psw.IA -= ilc;
544         realregs->psw.IA &= ADDRESS_MAXWRAP(realregs);
545 #if defined(FEATURE_INTERPRETIVE_EXECUTION)
546         /* When in SIE mode the guest instruction causing this
547            host exception must also be nullified */
548         if(realregs->sie_active && !realregs->guestregs->instinvalid)
549         {
550             realregs->guestregs->psw.IA -= sie_ilc;
551             realregs->guestregs->psw.IA &= ADDRESS_MAXWRAP(realregs->guestregs);
552         }
553 #endif /*defined(FEATURE_INTERPRETIVE_EXECUTION)*/
554     }
555 
556     /* The OLD PSW must be incremented on the following
557        exceptions during instfetch */
558     if(realregs->instinvalid &&
559       (  code == PGM_PROTECTION_EXCEPTION
560       || code == PGM_ADDRESSING_EXCEPTION
561       || code == PGM_SPECIFICATION_EXCEPTION
562       || code == PGM_TRANSLATION_SPECIFICATION_EXCEPTION ))
563     {
564         realregs->psw.IA += ilc;
565         realregs->psw.IA &= ADDRESS_MAXWRAP(realregs);
566     }
567 
568     /* Store the interrupt code in the PSW */
569     realregs->psw.intcode = pcode;
570 
571     /* Call debugger if active */
572     HDC2(debug_program_interrupt, regs, pcode);
573 
574     /* Trace program checks other then PER event */
575     if(code && (CPU_STEPPING_OR_TRACING(realregs, ilc)
576         || sysblk.pgminttr & ((U64)1 << ((code - 1) & 0x3F))))
577     {
578      BYTE *ip;
579 #if defined(OPTION_FOOTPRINT_BUFFER)
580         if(!(sysblk.insttrace || sysblk.inststep))
581             for(n = sysblk.footprptr[realregs->cpuad] + 1 ;
582                 n != sysblk.footprptr[realregs->cpuad];
583                 n++, n &= OPTION_FOOTPRINT_BUFFER - 1)
584                 ARCH_DEP(display_inst)
585                         (&sysblk.footprregs[realregs->cpuad][n],
586                         sysblk.footprregs[realregs->cpuad][n].inst);
587 #endif /*defined(OPTION_FOOTPRINT_BUFFER)*/
588         logmsg(_("HHCCP014I "));
589 #if defined(_FEATURE_SIE)
590         if(SIE_MODE(realregs))
591             logmsg(_("SIE: "));
592 #endif /*defined(_FEATURE_SIE)*/
593 #if defined(SIE_DEBUG)
594         logmsg (MSTRING(_GEN_ARCH) " ");
595 #endif /*defined(SIE_DEBUG)*/
596         if (code == PGM_DATA_EXCEPTION)
597             sprintf(dxcstr, " DXC=%2.2X", regs->dxc);
598         logmsg (_("CPU%4.4X: %s CODE=%4.4X ILC=%d%s\n"), realregs->cpuad,
599                 pgmintname[ (code - 1) & 0x3F], pcode, ilc, dxcstr);
600 
601         /* Calculate instruction pointer */
602         ip = realregs->instinvalid ? NULL
603            : (realregs->ip - ilc < realregs->aip)
604              ? realregs->inst : realregs->ip - ilc;
605 
606         ARCH_DEP(display_inst) (realregs, ip);
607     }
608 
609     realregs->instinvalid = 0;
610 
611 #if defined(FEATURE_INTERPRETIVE_EXECUTION)
612     /* If this is a host exception in SIE state then leave SIE */
613     if(realregs->sie_active)
614         ARCH_DEP(sie_exit) (realregs, SIE_HOST_PGMINT);
615 #endif /*defined(FEATURE_INTERPRETIVE_EXECUTION)*/
616 
617     /* Absolute address of prefix page */
618     px = realregs->PX;
619 
620     /* If under SIE use translated to host absolute prefix */
621 #if defined(_FEATURE_SIE)
622     if(SIE_MODE(regs))
623         px = regs->sie_px;
624 #endif
625 
626 #if defined(_FEATURE_SIE)
627     if(!SIE_MODE(regs) ||
628       /* Interception is mandatory for the following exceptions */
629       (
630 #if defined(_FEATURE_PROTECTION_INTERCEPTION_CONTROL)
631          !(code == PGM_PROTECTION_EXCEPTION
632            && (!SIE_FEATB(regs, EC2, PROTEX)
633              || realregs->hostint))
634 #else /*!defined(_FEATURE_PROTECTION_INTERCEPTION_CONTROL)*/
635          code != PGM_PROTECTION_EXCEPTION
636 #endif /*!defined(_FEATURE_PROTECTION_INTERCEPTION_CONTROL)*/
637 #if defined (_FEATURE_PER2)
638       && !((pcode & PGM_PER_EVENT) && SIE_FEATB(regs, M, GPE))
639 #endif /* defined (_FEATURE_PER2) */
640       && code != PGM_ADDRESSING_EXCEPTION
641       && code != PGM_SPECIFICATION_EXCEPTION
642       && code != PGM_SPECIAL_OPERATION_EXCEPTION
643 #ifdef FEATURE_VECTOR_FACILITY
644       && code != PGM_VECTOR_OPERATION_EXCEPTION
645 #endif /*FEATURE_VECTOR_FACILITY*/
646 #if defined(FEATURE_MULTIPLE_CONTROLLED_DATA_SPACE)
647       && !(code == PGM_ALEN_TRANSLATION_EXCEPTION
648         && SIE_FEATB(regs, MX, XC))
649       && !(code == PGM_ALE_SEQUENCE_EXCEPTION
650         && SIE_FEATB(regs, MX, XC))
651       && !(code == PGM_EXTENDED_AUTHORITY_EXCEPTION
652         && SIE_FEATB(regs, MX, XC))
653 #endif /*defined(FEATURE_MULTIPLE_CONTROLLED_DATA_SPACE)*/
654       /* And conditional for the following exceptions */
655       && !(code == PGM_OPERATION_EXCEPTION
656         && SIE_FEATB(regs, IC0, OPEREX))
657       && !(code == PGM_PRIVILEGED_OPERATION_EXCEPTION
658         && SIE_FEATB(regs, IC0, PRIVOP))
659 #ifdef FEATURE_BASIC_FP_EXTENSIONS
660       && !(code == PGM_DATA_EXCEPTION
661         && (regs->dxc == 1 || regs->dxc == 2)
662         && (regs->CR(0) & CR0_AFP)
663         && !(regs->hostregs->CR(0) & CR0_AFP))
664 #endif /*FEATURE_BASIC_FP_EXTENSIONS*/
665       /* Or all exceptions if requested as such */
666       && !SIE_FEATB(regs, IC0, PGMALL) )
667     )
668     {
669 #endif /*defined(_FEATURE_SIE)*/
670         /* Set the main storage reference and change bits */
671         STORAGE_KEY(px, regs) |= (STORKEY_REF | STORKEY_CHANGE);
672 
673         /* Point to PSA in main storage */
674         psa = (void*)(regs->mainstor + px);
675 #if defined(_FEATURE_SIE)
676 #if defined(FEATURE_ESAME)
677 /** FIXME : SEE ISW20090110-1 */
678         if(code == PGM_MONITOR_EVENT)
679         {
680             zmoncode=psa->moncode;
681         }
682 #endif
683         nointercept = 1;
684     }
685     else
686     {
687         /* This is a guest interruption interception so point to
688            the interruption parm area in the state descriptor
689            rather then the PSA, except for the operation exception */
690         if(code != PGM_OPERATION_EXCEPTION)
691         {
692             psa = (void*)(regs->hostregs->mainstor + SIE_STATE(regs) + SIE_IP_PSA_OFFSET);
693             /* Set the main storage reference and change bits */
694             STORAGE_KEY(SIE_STATE(regs), regs->hostregs) |= (STORKEY_REF | STORKEY_CHANGE);
695 #if defined(FEATURE_ESAME)
696 /** FIXME : SEE ISW20090110-1 */
697             if(code == PGM_MONITOR_EVENT)
698             {
699                 PSA *_psa;
700                 _psa=(void *)(regs->hostregs->mainstor + SIE_STATE(regs) + SIE_II_PSA_OFFSET);
701                 zmoncode=_psa->ioid;
702             }
703 #endif
704         }
705         else
706         {
707             /* Point to PSA in main storage */
708             psa = (void*)(regs->mainstor + px);
709 
710             /* Set the main storage reference and change bits */
711             STORAGE_KEY(px, regs) |= (STORKEY_REF | STORKEY_CHANGE);
712         }
713 
714         nointercept = 0;
715     }
716 #endif /*defined(_FEATURE_SIE)*/
717 
718 #if defined(_FEATURE_PER)
719     /* Handle PER or concurrent PER event */
720 
721     /* Throw out Stor Alter PER if merged with nullified/suppressed rupt */
722     if ( IS_IC_PER_SA(realregs) && !IS_IC_PER_STURA(realregs) &&
723                                    (realregs->ip[0] != 0x0E) &&
724          !(code == 0x00 || code == 0x06 || code == 0x08 || code == 0x0A ||
725            code == 0x0C || code == 0x0D || code == 0x0E || code == 0x1C ||
726            code == 0x40) )
727               OFF_IC_PER_SA(realregs);
728 
729     if( OPEN_IC_PER(realregs) )
730     {
731         if( CPU_STEPPING_OR_TRACING(realregs, ilc) )
732             logmsg(_("HHCCP015I CPU%4.4X PER event: code=%4.4X perc=%2.2X "
733                      "addr=" F_VADR "\n"),
734               regs->cpuad, pcode, IS_IC_PER(realregs) >> 16,
735               (realregs->psw.IA - ilc) & ADDRESS_MAXWRAP(realregs) );
736 
737         realregs->perc |= OPEN_IC_PER(realregs) >> ((32 - IC_CR9_SHIFT) - 16);
738 
739         /* Positions 14 and 15 contain zeros if a storage alteration
740            event was not indicated */
741 //FIXME: is this right??
742         if( !(OPEN_IC_PER_SA(realregs))
743           || (OPEN_IC_PER_STURA(realregs)) )
744             realregs->perc &= 0xFFFC;
745 
746         STORE_HW(psa->perint, realregs->perc);
747 
748         STORE_W(psa->peradr, realregs->peradr);
749 
750         if( IS_IC_PER_SA(realregs) && ACCESS_REGISTER_MODE(&realregs->psw) )
751             psa->perarid = realregs->peraid;
752 
753 #if defined(_FEATURE_SIE)
754         /* Reset PER pending indication */
755         if(nointercept)
756             OFF_IC_PER(realregs);
757 #endif
758     }
759     else
760     {
761         pcode &= 0xFF7F;
762     }
763 #endif /*defined(_FEATURE_PER)*/
764 
765 
766 #if defined(FEATURE_BCMODE)
767     /* For ECMODE, store extended interrupt information in PSA */
768     if ( ECMODE(&realregs->psw) )
769 #endif /*defined(FEATURE_BCMODE)*/
770     {
771         /* Store the program interrupt code at PSA+X'8C' */
772         psa->pgmint[0] = 0;
773         psa->pgmint[1] = ilc;
774         STORE_HW(psa->pgmint + 2, pcode);
775 
776         /* Store the exception access identification at PSA+160 */
777         if ( code == PGM_PAGE_TRANSLATION_EXCEPTION
778           || code == PGM_SEGMENT_TRANSLATION_EXCEPTION
779 #if defined(FEATURE_ESAME)
780           || code == PGM_ASCE_TYPE_EXCEPTION
781           || code == PGM_REGION_FIRST_TRANSLATION_EXCEPTION
782           || code == PGM_REGION_SECOND_TRANSLATION_EXCEPTION
783           || code == PGM_REGION_THIRD_TRANSLATION_EXCEPTION
784 #endif /*defined(FEATURE_ESAME)*/
785           || code == PGM_ALEN_TRANSLATION_EXCEPTION
786           || code == PGM_ALE_SEQUENCE_EXCEPTION
787           || code == PGM_ASTE_VALIDITY_EXCEPTION
788           || code == PGM_ASTE_SEQUENCE_EXCEPTION
789           || code == PGM_ASTE_INSTANCE_EXCEPTION               /*@ALR*/
790           || code == PGM_EXTENDED_AUTHORITY_EXCEPTION
791 #ifdef FEATURE_SUPPRESSION_ON_PROTECTION
792           || code == PGM_PROTECTION_EXCEPTION
793 #endif /*FEATURE_SUPPRESSION_ON_PROTECTION*/
794            )
795         {
796             psa->excarid = regs->excarid;
797             if(regs->TEA | TEA_MVPG)
798                 psa->opndrid = regs->opndrid;
799             realregs->opndrid = 0;
800         }
801 
802 #if defined(FEATURE_ESAME)
803         /* Store the translation exception address at PSA+168 */
804         if ( code == PGM_PAGE_TRANSLATION_EXCEPTION
805           || code == PGM_SEGMENT_TRANSLATION_EXCEPTION
806           || code == PGM_ASCE_TYPE_EXCEPTION
807           || code == PGM_REGION_FIRST_TRANSLATION_EXCEPTION
808           || code == PGM_REGION_SECOND_TRANSLATION_EXCEPTION
809           || code == PGM_REGION_THIRD_TRANSLATION_EXCEPTION
810 #ifdef FEATURE_SUPPRESSION_ON_PROTECTION
811           || code == PGM_PROTECTION_EXCEPTION
812 #endif /*FEATURE_SUPPRESSION_ON_PROTECTION*/
813            )
814         {
815             STORE_DW(psa->TEA_G, regs->TEA);
816         }
817 
818         /* Store the translation exception address at PSA+172 */
819         if ( code == PGM_AFX_TRANSLATION_EXCEPTION
820           || code == PGM_ASX_TRANSLATION_EXCEPTION
821           || code == PGM_PRIMARY_AUTHORITY_EXCEPTION
822           || code == PGM_SECONDARY_AUTHORITY_EXCEPTION
823           || code == PGM_SPACE_SWITCH_EVENT
824           || code == PGM_LX_TRANSLATION_EXCEPTION
825           || code == PGM_LFX_TRANSLATION_EXCEPTION             /*@ALR*/
826           || code == PGM_LSX_TRANSLATION_EXCEPTION             /*@ALR*/
827           || code == PGM_LSTE_SEQUENCE_EXCEPTION               /*@ALR*/
828           || code == PGM_EX_TRANSLATION_EXCEPTION)
829         {
830             STORE_FW(psa->TEA_L, regs->TEA);
831         }
832 #else /*!defined(FEATURE_ESAME)*/
833         /* Store the translation exception address at PSA+144 */
834         if ( code == PGM_PAGE_TRANSLATION_EXCEPTION
835           || code == PGM_SEGMENT_TRANSLATION_EXCEPTION
836           || code == PGM_AFX_TRANSLATION_EXCEPTION
837           || code == PGM_ASX_TRANSLATION_EXCEPTION
838           || code == PGM_PRIMARY_AUTHORITY_EXCEPTION
839           || code == PGM_SECONDARY_AUTHORITY_EXCEPTION
840           || code == PGM_SPACE_SWITCH_EVENT
841           || code == PGM_LX_TRANSLATION_EXCEPTION
842           || code == PGM_EX_TRANSLATION_EXCEPTION
843 #ifdef FEATURE_SUPPRESSION_ON_PROTECTION
844           || code == PGM_PROTECTION_EXCEPTION
845 #endif /*FEATURE_SUPPRESSION_ON_PROTECTION*/
846            )
847         {
848             STORE_FW(psa->tea, regs->TEA);
849         }
850 #endif /*!defined(FEATURE_ESAME)*/
851         realregs->TEA = 0;
852 
853         /* Store Data exception code in PSA */
854         if (code == PGM_DATA_EXCEPTION)
855         {
856             STORE_FW(psa->DXC, regs->dxc);
857 #ifdef FEATURE_BASIC_FP_EXTENSIONS
858             /* Load data exception code into FPC register byte 2 */
859             if(regs->CR(0) & CR0_AFP)
860             {
861                 regs->fpc &= ~(FPC_DXC);
862                 regs->fpc |= ((regs->dxc << 8)) & FPC_DXC;
863             }
864 #endif /*FEATURE_BASIC_FP_EXTENSIONS*/
865         }
866 
867         /* Store the monitor class and event code */
868         if (code == PGM_MONITOR_EVENT)
869         {
870             STORE_HW(psa->monclass, regs->monclass);
871 
872             /* Store the monitor code word at PSA+156 */
873             /* or doubleword at PSA+176               */
874             /* ISW20090110-1 ZSIEMCFIX                */
875             /* In the event of a z/Arch guest being   */
876             /* intercepted during a succesful Monitor */
877             /* call, the monitor code is not stored   */
878             /* at psa->moncode (which is beyond sie2bk->ip */
879             /* but rather at the same location as an  */
880             /* I/O interrupt would store the SSID     */
881             /*    zmoncode points to this location    */
882             /*  **** FIXME **** FIXME  *** FIXME ***  */
883             /* ---- The determination of the location */
884             /*      of the z/Sie Intercept moncode    */
885             /*      should be made more flexible      */
886             /*      and should be put somewhere in    */
887             /*      esa390.h                          */
888             /*  **** FIXME **** FIXME  *** FIXME ***  */
889 #if defined(FEATURE_ESAME)
890             STORE_DW(zmoncode, regs->MONCODE);
891 #else
892             STORE_W(psa->moncode, regs->MONCODE);
893 #endif
894         }
895 
896 #if defined(FEATURE_PER3)
897         /* Store the breaking event address register in the PSA */
898         SET_BEAR_REG(regs, regs->bear_ip);
899         STORE_W(psa->bea, regs->bear);
900 #endif /*defined(FEATURE_PER3)*/
901 
902     } /* end if(ECMODE) */
903 
904 #if defined(_FEATURE_PROTECTION_INTERCEPTION_CONTROL)
905     realregs->hostint = 0;
906 #endif /*defined(_FEATURE_PROTECTION_INTERCEPTION_CONTROL)*/
907 
908 #if defined(_FEATURE_SIE)
909     if(nointercept)
910     {
911 #endif /*defined(_FEATURE_SIE)*/
912 //FIXME: Why are we getting intlock here??
913 //      OBTAIN_INTLOCK(realregs);
914 
915         /* Store current PSW at PSA+X'28' or PSA+X'150' for ESAME */
916         ARCH_DEP(store_psw) (realregs, psa->pgmold);
917 
918         /* Load new PSW from PSA+X'68' or PSA+X'1D0' for ESAME */
919         if ( (code = ARCH_DEP(load_psw) (realregs, psa->pgmnew)) )
920         {
921 #if defined(_FEATURE_SIE)
922             if(SIE_MODE(realregs))
923             {
924 //              RELEASE_INTLOCK(realregs);
925                 longjmp(realregs->progjmp, pcode);
926             }
927             else
928 #endif /*defined(_FEATURE_SIE)*/
929             {
930                 logmsg (_("HHCCP016I CPU%4.4X: Program interrupt loop: "),
931                           realregs->cpuad);
932                 display_psw (realregs);
933                 OBTAIN_INTLOCK(realregs);
934                 realregs->cpustate = CPUSTATE_STOPPING;
935                 ON_IC_INTERRUPT(realregs);
936                 RELEASE_INTLOCK(realregs);
937             }
938         }
939 
940 //      RELEASE_INTLOCK(realregs);
941 
942         longjmp(realregs->progjmp, SIE_NO_INTERCEPT);
943 
944 #if defined(_FEATURE_SIE)
945     }
946 
947     longjmp (realregs->progjmp, pcode);
948 #endif /*defined(_FEATURE_SIE)*/
949 
950 } /* end function ARCH_DEP(program_interrupt) */
951 
952 /*-------------------------------------------------------------------*/
953 /* Load restart new PSW                                              */
954 /*-------------------------------------------------------------------*/
ARCH_DEP(restart_interrupt)955 static void ARCH_DEP(restart_interrupt) (REGS *regs)
956 {
957 int     rc;                             /* Return code               */
958 PSA    *psa;                            /* -> Prefixed storage area  */
959 
960     PTT(PTT_CL_INF,"*RESTART",regs->cpuad,regs->cpustate,regs->psw.IA_L);
961 
962     /* Set the main storage reference and change bits */
963     STORAGE_KEY(regs->PX, regs) |= (STORKEY_REF | STORKEY_CHANGE);
964 
965     /* Zeroize the interrupt code in the PSW */
966     regs->psw.intcode = 0;
967 
968     /* Point to PSA in main storage */
969     psa = (PSA*)(regs->mainstor + regs->PX);
970 
971     /* Store current PSW at PSA+X'8' or PSA+X'120' for ESAME  */
972     ARCH_DEP(store_psw) (regs, psa->RSTOLD);
973 
974     /* Load new PSW from PSA+X'0' or PSA+X'1A0' for ESAME */
975     rc = ARCH_DEP(load_psw) (regs, psa->RSTNEW);
976 
977     if ( rc == 0)
978     {
979         regs->opinterv = 0;
980         regs->cpustate = CPUSTATE_STARTED;
981     }
982 
983     RELEASE_INTLOCK(regs);
984 
985     if ( rc )
986         regs->program_interrupt(regs, rc);
987 
988     longjmp (regs->progjmp, SIE_INTERCEPT_RESTART);
989 } /* end function restart_interrupt */
990 
991 
992 /*-------------------------------------------------------------------*/
993 /* Perform I/O interrupt if pending                                  */
994 /* Note: The caller MUST hold the interrupt lock (sysblk.intlock)    */
995 /*-------------------------------------------------------------------*/
ARCH_DEP(perform_io_interrupt)996 void ARCH_DEP(perform_io_interrupt) (REGS *regs)
997 {
998 int     rc;                             /* Return code               */
999 int     icode;                          /* Intercept code            */
1000 PSA    *psa;                            /* -> Prefixed storage area  */
1001 U32     ioparm;                         /* I/O interruption parameter*/
1002 U32     ioid;                           /* I/O interruption address  */
1003 U32     iointid;                        /* I/O interruption ident    */
1004 RADR    pfx;                            /* Prefix                    */
1005 DBLWRD  csw;                            /* CSW for S/370 channels    */
1006 
1007     /* Test and clear pending I/O interrupt */
1008     icode = ARCH_DEP(present_io_interrupt) (regs, &ioid, &ioparm, &iointid, csw);
1009 
1010     /* Exit if no interrupt was presented */
1011     if (icode == 0) return;
1012 
1013     PTT(PTT_CL_IO,"*IOINT",ioid,ioparm,iointid);
1014 
1015 #if defined(_FEATURE_IO_ASSIST)
1016     if(SIE_MODE(regs) && icode != SIE_NO_INTERCEPT)
1017     {
1018         /* Point to SIE copy of PSA in state descriptor */
1019         psa = (void*)(regs->hostregs->mainstor + SIE_STATE(regs) + SIE_II_PSA_OFFSET);
1020         STORAGE_KEY(SIE_STATE(regs), regs->hostregs) |= (STORKEY_REF | STORKEY_CHANGE);
1021     }
1022     else
1023 #endif
1024     {
1025         /* Point to PSA in main storage */
1026         pfx =
1027 #if defined(_FEATURE_SIE)
1028               SIE_MODE(regs) ? regs->sie_px :
1029 #endif
1030               regs->PX;
1031         psa = (void*)(regs->mainstor + pfx);
1032         STORAGE_KEY(pfx, regs) |= (STORKEY_REF | STORKEY_CHANGE);
1033     }
1034 
1035 #ifdef FEATURE_S370_CHANNEL
1036     /* Store the channel status word at PSA+X'40' */
1037     memcpy (psa->csw, csw, 8);
1038 
1039     /* Set the interrupt code to the I/O device address */
1040     regs->psw.intcode = ioid;
1041 
1042     /* For ECMODE, store the I/O device address at PSA+X'B8' */
1043     if (ECMODE(&regs->psw))
1044         STORE_FW(psa->ioid, ioid);
1045 
1046     /* Trace the I/O interrupt */
1047     if (CPU_STEPPING_OR_TRACING(regs, 0))
1048         logmsg (_("HHCCP044I I/O interrupt code=%4.4X "
1049                 "CSW=%2.2X%2.2X%2.2X%2.2X %2.2X%2.2X%2.2X%2.2X\n"),
1050                 regs->psw.intcode,
1051                 csw[0], csw[1], csw[2], csw[3],
1052                 csw[4], csw[5], csw[6], csw[7]);
1053 #endif /*FEATURE_S370_CHANNEL*/
1054 
1055 #ifdef FEATURE_CHANNEL_SUBSYSTEM
1056     /* Store X'0001' + subchannel number at PSA+X'B8' */
1057     STORE_FW(psa->ioid, ioid);
1058 
1059     /* Store the I/O interruption parameter at PSA+X'BC' */
1060     STORE_FW(psa->ioparm, ioparm);
1061 
1062 #if defined(FEATURE_ESAME) || defined(_FEATURE_IO_ASSIST)
1063     /* Store the I/O interruption identification word at PSA+X'C0' */
1064     STORE_FW(psa->iointid, iointid);
1065 #endif /*defined(FEATURE_ESAME)*/
1066 
1067     /* Trace the I/O interrupt */
1068     if (CPU_STEPPING_OR_TRACING(regs, 0))
1069 #if !defined(FEATURE_ESAME) && !defined(_FEATURE_IO_ASSIST)
1070         logmsg (_("HHCCP045I I/O interrupt code=%8.8X parm=%8.8X\n"),
1071                   ioid, ioparm);
1072 #else /*defined(FEATURE_ESAME)*/
1073         logmsg (_("HHCCP046I I/O interrupt code=%8.8X parm=%8.8X id=%8.8X\n"),
1074           ioid, ioparm, iointid);
1075 #endif /*defined(FEATURE_ESAME)*/
1076 #endif /*FEATURE_CHANNEL_SUBSYSTEM*/
1077 
1078 #if defined(_FEATURE_IO_ASSIST)
1079     if(icode == SIE_NO_INTERCEPT)
1080 #endif
1081     {
1082         /* Store current PSW at PSA+X'38' or PSA+X'170' for ESAME */
1083         ARCH_DEP(store_psw) ( regs, psa->iopold );
1084 
1085         /* Load new PSW from PSA+X'78' or PSA+X'1F0' for ESAME */
1086         rc = ARCH_DEP(load_psw) ( regs, psa->iopnew );
1087 
1088         if ( rc )
1089         {
1090             RELEASE_INTLOCK(regs);
1091             regs->program_interrupt (regs, rc);
1092         }
1093     }
1094 
1095     RELEASE_INTLOCK(regs);
1096 
1097     longjmp(regs->progjmp, icode);
1098 
1099 } /* end function perform_io_interrupt */
1100 
1101 /*-------------------------------------------------------------------*/
1102 /* Perform Machine Check interrupt if pending                        */
1103 /* Note: The caller MUST hold the interrupt lock (sysblk.intlock)    */
1104 /*-------------------------------------------------------------------*/
ARCH_DEP(perform_mck_interrupt)1105 static void ARCH_DEP(perform_mck_interrupt) (REGS *regs)
1106 {
1107 int     rc;                             /* Return code               */
1108 PSA    *psa;                            /* -> Prefixed storage area  */
1109 U64     mcic;                           /* Mach.check interrupt code */
1110 U32     xdmg;                           /* External damage code      */
1111 RADR    fsta;                           /* Failing storage address   */
1112 
1113     /* Test and clear pending machine check interrupt */
1114     rc = ARCH_DEP(present_mck_interrupt) (regs, &mcic, &xdmg, &fsta);
1115 
1116     /* Exit if no machine check was presented */
1117     if (rc == 0) return;
1118 
1119     /* Set the main storage reference and change bits */
1120     STORAGE_KEY(regs->PX, regs) |= (STORKEY_REF | STORKEY_CHANGE);
1121 
1122     /* Point to the PSA in main storage */
1123     psa = (void*)(regs->mainstor + regs->PX);
1124 
1125     /* Store registers in machine check save area */
1126     ARCH_DEP(store_status) (regs, regs->PX);
1127 
1128 #if !defined(FEATURE_ESAME)
1129 // ZZ
1130     /* Set the extended logout area to zeros */
1131     memset(psa->storepsw, 0, 16);
1132 #endif
1133 
1134     /* Store the machine check interrupt code at PSA+232 */
1135     STORE_DW(psa->mckint, mcic);
1136 
1137     /* Trace the machine check interrupt */
1138     if (CPU_STEPPING_OR_TRACING(regs, 0))
1139         logmsg (_("HHCCP022I Machine Check code=%16.16" I64_FMT "u\n"),
1140                   (long long)mcic);
1141 
1142     /* Store the external damage code at PSA+244 */
1143     STORE_FW(psa->xdmgcode, xdmg);
1144 
1145 #if defined(FEATURE_ESAME)
1146     /* Store the failing storage address at PSA+248 */
1147     STORE_DW(psa->mcstorad, fsta);
1148 #else /*!defined(FEATURE_ESAME)*/
1149     /* Store the failing storage address at PSA+248 */
1150     STORE_FW(psa->mcstorad, fsta);
1151 #endif /*!defined(FEATURE_ESAME)*/
1152 
1153     /* Store current PSW at PSA+X'30' */
1154     ARCH_DEP(store_psw) ( regs, psa->mckold );
1155 
1156     /* Load new PSW from PSA+X'70' */
1157     rc = ARCH_DEP(load_psw) ( regs, psa->mcknew );
1158 
1159     RELEASE_INTLOCK(regs);
1160 
1161     if ( rc )
1162         regs->program_interrupt (regs, rc);
1163 
1164     longjmp (regs->progjmp, SIE_INTERCEPT_MCK);
1165 } /* end function perform_mck_interrupt */
1166 
1167 
1168 #if !defined(_GEN_ARCH)
1169 
1170 
1171 REGS *s370_run_cpu (int cpu, REGS *oldregs);
1172 REGS *s390_run_cpu (int cpu, REGS *oldregs);
1173 REGS *z900_run_cpu (int cpu, REGS *oldregs);
1174 static REGS *(* run_cpu[GEN_MAXARCH]) (int cpu, REGS *oldregs) =
1175                 {
1176 #if defined(_370)
1177                     s370_run_cpu,
1178 #endif
1179 #if defined(_390)
1180                     s390_run_cpu,
1181 #endif
1182 #if defined(_900)
1183                     z900_run_cpu
1184 #endif
1185                 };
1186 
1187 /*-------------------------------------------------------------------*/
1188 /* CPU instruction execution thread                                  */
1189 /*-------------------------------------------------------------------*/
cpu_thread(int * ptr)1190 void *cpu_thread (int *ptr)
1191 {
1192 REGS *regs = NULL;
1193 int   cpu  = *ptr;
1194 
1195     OBTAIN_INTLOCK(NULL);
1196 
1197     /* Signal cpu has started */
1198     signal_condition (&sysblk.cpucond);
1199 
1200     /* Increment number of CPUs online */
1201     sysblk.cpus++;
1202 
1203     /* Set hi CPU */
1204     if (cpu >= sysblk.hicpu)
1205         sysblk.hicpu = cpu + 1;
1206 
1207     /* Start the TOD clock and CPU timer thread */
1208     if (!sysblk.todtid)
1209     {
1210         if ( create_thread (&sysblk.todtid, DETACHED,
1211              timer_update_thread, NULL, "timer_update_thread") )
1212         {
1213             logmsg (_("HHCCP006S Cannot create timer thread: %s\n"),
1214                            strerror(errno));
1215             RELEASE_INTLOCK(NULL);
1216             return NULL;
1217         }
1218     }
1219     /* Set root mode in order to set priority */
1220     SETMODE(ROOT);
1221 
1222     /* Set CPU thread priority */
1223     if (setpriority(PRIO_PROCESS, 0, sysblk.cpuprio))
1224         logmsg (_("HHCCP001W CPU%4.4X thread set priority %d failed: %s\n"),
1225                 cpu, sysblk.cpuprio, strerror(errno));
1226 
1227     /* Back to user mode */
1228     SETMODE(USER);
1229 
1230     /* Display thread started message on control panel */
1231     logmsg (_("HHCCP002I CPU%4.4X thread started: tid="TIDPAT", pid=%d, "
1232             "priority=%d\n"),
1233             cpu, thread_id(), getpid(),
1234             getpriority(PRIO_PROCESS,0));
1235 
1236     /* Execute the program in specified mode */
1237     do {
1238         regs = run_cpu[sysblk.arch_mode] (cpu, regs);
1239     } while (regs);
1240 
1241     /* Decrement number of CPUs online */
1242     sysblk.cpus--;
1243 
1244     /* Reset hi cpu */
1245     if (cpu + 1 >= sysblk.hicpu)
1246     {
1247         int i;
1248         for (i = MAX_CPU_ENGINES - 1; i >= 0; i--)
1249             if (IS_CPU_ONLINE(i))
1250                 break;
1251         sysblk.hicpu = i + 1;
1252     }
1253 
1254     /* Signal cpu has terminated */
1255     signal_condition (&sysblk.cpucond);
1256 
1257     /* Display thread ended message on control panel */
1258     logmsg (_("HHCCP008I CPU%4.4X thread ended: tid="TIDPAT", pid=%d\n"),
1259             cpu, thread_id(), getpid());
1260 
1261     RELEASE_INTLOCK(NULL);
1262 
1263     return NULL;
1264 }
1265 
1266 
1267 void s370_set_jump_pointers(REGS *regs, int jump);
1268 void s390_set_jump_pointers(REGS *regs, int jump);
1269 void z900_set_jump_pointers(REGS *regs, int jump);
1270 
1271 /*-------------------------------------------------------------------*/
1272 /* Initialize a CPU                                                  */
1273 /*-------------------------------------------------------------------*/
cpu_init(int cpu,REGS * regs,REGS * hostregs)1274 int cpu_init (int cpu, REGS *regs, REGS *hostregs)
1275 {
1276 int i;
1277 
1278     obtain_lock (&sysblk.cpulock[cpu]);
1279 
1280     regs->cpuad = cpu;
1281     regs->cpubit = CPU_BIT(cpu);
1282     regs->arch_mode = sysblk.arch_mode;
1283     regs->mainstor = sysblk.mainstor;
1284     regs->sysblk = &sysblk;
1285     /*
1286      * ISW20060125 : LINE REMOVED : This is the job of
1287      *               the INITIAL CPU RESET
1288      */
1289 #if 0
1290     regs->psa = (PSA*)regs->mainstor;
1291 #endif
1292     regs->storkeys = sysblk.storkeys;
1293     regs->mainlim = sysblk.mainsize - 1;
1294     regs->tod_epoch = get_tod_epoch();
1295 
1296     initialize_condition (&regs->intcond);
1297     regs->cpulock = &sysblk.cpulock[cpu];
1298 
1299 #if defined(_FEATURE_VECTOR_FACILITY)
1300     regs->vf = &sysblk.vf[cpu];
1301     regs->vf->online = (cpu < sysblk.numvec);
1302 #endif /*defined(_FEATURE_VECTOR_FACILITY)*/
1303     initial_cpu_reset(regs);
1304 
1305     if (hostregs == NULL)
1306     {
1307         regs->cpustate = CPUSTATE_STOPPING;
1308         ON_IC_INTERRUPT(regs);
1309         regs->hostregs = regs;
1310         regs->host = 1;
1311         sysblk.regs[cpu] = regs;
1312         sysblk.config_mask |= regs->cpubit;
1313         sysblk.started_mask |= regs->cpubit;
1314     }
1315     else
1316     {
1317         hostregs->guestregs = regs;
1318         regs->hostregs = hostregs;
1319         regs->guestregs = regs;
1320         regs->guest = 1;
1321         regs->sie_mode = 1;
1322         regs->opinterv = 0;
1323         regs->cpustate = CPUSTATE_STARTED;
1324     }
1325 
1326     /* Initialize accelerated lookup fields */
1327     regs->CR_G(CR_ASD_REAL) = TLB_REAL_ASD;
1328 
1329     for(i = 0; i < 16; i++)
1330         regs->aea_ar[i]               = CR_ASD_REAL;
1331     regs->aea_ar[USE_INST_SPACE]      = CR_ASD_REAL;
1332     regs->aea_ar[USE_REAL_ADDR]       = CR_ASD_REAL;
1333     regs->aea_ar[USE_PRIMARY_SPACE]   =  1;
1334     regs->aea_ar[USE_SECONDARY_SPACE] =  7;
1335     regs->aea_ar[USE_HOME_SPACE]      = 13;
1336 
1337     /* Initialize opcode table pointers */
1338     set_opcode_pointers (regs);
1339 
1340     /* Set multi-byte jump code pointers */
1341 #if defined(_370)
1342     s370_set_jump_pointers(regs, 0);
1343 #endif
1344 #if defined(_390)
1345     s390_set_jump_pointers(regs, 0);
1346 #endif
1347 #if defined(_900)
1348     z900_set_jump_pointers(regs, 0);
1349 #endif
1350 
1351     regs->configured = 1;
1352 
1353     release_lock (&sysblk.cpulock[cpu]);
1354 
1355 #if defined(FEATURE_CONFIGURATION_TOPOLOGY_FACILITY)
1356     /* Set topology-change-report-pending condition */
1357     sysblk.topchnge = 1;
1358 #endif /*defined(FEATURE_CONFIGURATION_TOPOLOGY_FACILITY)*/
1359 
1360     return 0;
1361 }
1362 
1363 
1364 /*-------------------------------------------------------------------*/
1365 /* Uninitialize a CPU                                                */
1366 /*-------------------------------------------------------------------*/
cpu_uninit(int cpu,REGS * regs)1367 void *cpu_uninit (int cpu, REGS *regs)
1368 {
1369     if (regs->host)
1370     {
1371         obtain_lock (&sysblk.cpulock[cpu]);
1372         if (regs->guestregs)
1373         {
1374             cpu_uninit (cpu, regs->guestregs);
1375             free (regs->guestregs);
1376         }
1377     }
1378 
1379     destroy_condition(&regs->intcond);
1380 
1381     if (regs->host)
1382     {
1383 #ifdef FEATURE_VECTOR_FACILITY
1384         /* Mark Vector Facility offline */
1385         regs->vf->online = 0;
1386 #endif /*FEATURE_VECTOR_FACILITY*/
1387 
1388         /* Remove CPU from all CPU bit masks */
1389         sysblk.config_mask &= ~CPU_BIT(cpu);
1390         sysblk.started_mask &= ~CPU_BIT(cpu);
1391         sysblk.waiting_mask &= ~CPU_BIT(cpu);
1392         sysblk.regs[cpu] = NULL;
1393         release_lock (&sysblk.cpulock[cpu]);
1394     }
1395 
1396 #if defined(FEATURE_CONFIGURATION_TOPOLOGY_FACILITY)
1397     /* Set topology-change-report-pending condition */
1398     sysblk.topchnge = 1;
1399 #endif /*defined(FEATURE_CONFIGURATION_TOPOLOGY_FACILITY)*/
1400 
1401     return NULL;
1402 }
1403 
1404 
1405 #endif /*!defined(_GEN_ARCH)*/
1406 
1407 
1408 /*-------------------------------------------------------------------*/
1409 /* Process interrupt                                                 */
1410 /*-------------------------------------------------------------------*/
1411 void (ATTR_REGPARM(1) ARCH_DEP(process_interrupt))(REGS *regs)
1412 {
1413     /* Process PER program interrupts */
1414     if( OPEN_IC_PER(regs) )
1415         regs->program_interrupt (regs, PGM_PER_EVENT);
1416 
1417     /* Obtain the interrupt lock */
1418     OBTAIN_INTLOCK(regs);
1419     OFF_IC_INTERRUPT(regs);
1420     regs->tracing = (sysblk.inststep || sysblk.insttrace);
1421 
1422     /* Ensure psw.IA is set and invalidate the aia */
1423     INVALIDATE_AIA(regs);
1424 
1425     /* Perform invalidation */
1426     if (unlikely(regs->invalidate))
1427         ARCH_DEP(invalidate_tlbe)(regs, regs->invalidate_main);
1428 
1429     /* Take interrupts if CPU is not stopped */
1430     if (likely(regs->cpustate == CPUSTATE_STARTED))
1431     {
1432         /* Process machine check interrupt */
1433         if ( OPEN_IC_MCKPENDING(regs) )
1434         {
1435             PERFORM_SERIALIZATION (regs);
1436             PERFORM_CHKPT_SYNC (regs);
1437             ARCH_DEP (perform_mck_interrupt) (regs);
1438         }
1439 
1440         /* Process external interrupt */
1441         if ( OPEN_IC_EXTPENDING(regs) )
1442         {
1443             PERFORM_SERIALIZATION (regs);
1444             PERFORM_CHKPT_SYNC (regs);
1445             ARCH_DEP (perform_external_interrupt) (regs);
1446         }
1447 
1448         /* Process I/O interrupt */
1449         if (IS_IC_IOPENDING)
1450         {
1451             if ( OPEN_IC_IOPENDING(regs) )
1452             {
1453                 PERFORM_SERIALIZATION (regs);
1454                 PERFORM_CHKPT_SYNC (regs);
1455                 ARCH_DEP (perform_io_interrupt) (regs);
1456             }
1457             else
1458                 WAKEUP_CPU_MASK(sysblk.waiting_mask);
1459         }
1460     } /*CPU_STARTED*/
1461 
1462     /* If CPU is stopping, change status to stopped */
1463     if (unlikely(regs->cpustate == CPUSTATE_STOPPING))
1464     {
1465         /* Change CPU status to stopped */
1466         regs->opinterv = 0;
1467         regs->cpustate = CPUSTATE_STOPPED;
1468 
1469         /* Thread exit (note - intlock still held) */
1470         if (!regs->configured)
1471             longjmp(regs->exitjmp, SIE_NO_INTERCEPT);
1472 
1473         /* If initial CPU reset pending then perform reset */
1474         if (regs->sigpireset)
1475         {
1476             PERFORM_SERIALIZATION (regs);
1477             PERFORM_CHKPT_SYNC (regs);
1478             ARCH_DEP (initial_cpu_reset) (regs);
1479             RELEASE_INTLOCK(regs);
1480             longjmp(regs->progjmp, SIE_NO_INTERCEPT);
1481         }
1482 
1483         /* If a CPU reset is pending then perform the reset */
1484         if (regs->sigpreset)
1485         {
1486             PERFORM_SERIALIZATION (regs);
1487             PERFORM_CHKPT_SYNC (regs);
1488             ARCH_DEP(cpu_reset) (regs);
1489             RELEASE_INTLOCK(regs);
1490             longjmp(regs->progjmp, SIE_NO_INTERCEPT);
1491         }
1492 
1493         /* Store status at absolute location 0 if requested */
1494         if (IS_IC_STORSTAT(regs))
1495         {
1496             OFF_IC_STORSTAT(regs);
1497             ARCH_DEP(store_status) (regs, 0);
1498             logmsg (_("HHCCP010I CPU%4.4X store status completed.\n"),
1499                     regs->cpuad);
1500             /* ISW 20071102 : Do not return via longjmp here. */
1501             /*    process_interrupt needs to finish putting the */
1502             /*    CPU in its manual state                     */
1503             /*
1504             RELEASE_INTLOCK(regs);
1505             longjmp(regs->progjmp, SIE_NO_INTERCEPT);
1506             */
1507         }
1508     } /*CPUSTATE_STOPPING*/
1509 
1510     /* Perform restart interrupt if pending */
1511     if ( IS_IC_RESTART(regs) )
1512     {
1513         PERFORM_SERIALIZATION (regs);
1514         PERFORM_CHKPT_SYNC (regs);
1515         OFF_IC_RESTART(regs);
1516         ARCH_DEP(restart_interrupt) (regs);
1517     } /* end if(restart) */
1518 
1519     /* This is where a stopped CPU will wait */
1520     if (unlikely(regs->cpustate == CPUSTATE_STOPPED))
1521     {
1522         S64 saved_timer = cpu_timer(regs);
1523         regs->ints_state = IC_INITIAL_STATE;
1524         sysblk.started_mask ^= regs->cpubit;
1525         sysblk.intowner = LOCK_OWNER_NONE;
1526 
1527         /* Wait while we are STOPPED */
1528         wait_condition (&regs->intcond, &sysblk.intlock);
1529 
1530         /* Wait while SYNCHRONIZE_CPUS is in progress */
1531         while (sysblk.syncing)
1532             wait_condition (&sysblk.sync_bc_cond, &sysblk.intlock);
1533 
1534         sysblk.intowner = regs->cpuad;
1535         sysblk.started_mask |= regs->cpubit;
1536         regs->ints_state |= sysblk.ints_state;
1537         set_cpu_timer(regs,saved_timer);
1538 
1539         ON_IC_INTERRUPT(regs);
1540 
1541         /* Purge the lookaside buffers */
1542         ARCH_DEP(purge_tlb) (regs);
1543 #if defined(FEATURE_ACCESS_REGISTERS)
1544         ARCH_DEP(purge_alb) (regs);
1545 #endif /*defined(FEATURE_ACCESS_REGISTERS)*/
1546 
1547         /* If the architecture mode has changed we must adapt */
1548         if(sysblk.arch_mode != regs->arch_mode)
1549             longjmp(regs->archjmp,SIE_NO_INTERCEPT);
1550 
1551         RELEASE_INTLOCK(regs);
1552         longjmp(regs->progjmp, SIE_NO_INTERCEPT);
1553     } /*CPUSTATE_STOPPED*/
1554 
1555     /* Test for wait state */
1556     if (WAITSTATE(&regs->psw))
1557     {
1558 #ifdef OPTION_MIPS_COUNTING
1559         regs->waittod = host_tod();
1560 #endif
1561 
1562         /* Test for disabled wait PSW and issue message */
1563         if( IS_IC_DISABLED_WAIT_PSW(regs) )
1564         {
1565             logmsg (_("HHCCP011I CPU%4.4X: Disabled wait state\n"
1566                       "          "),
1567                     regs->cpuad);
1568             display_psw (regs);
1569             regs->cpustate = CPUSTATE_STOPPING;
1570             RELEASE_INTLOCK(regs);
1571             longjmp(regs->progjmp, SIE_NO_INTERCEPT);
1572         }
1573 
1574         /* Indicate we are giving up intlock */
1575         sysblk.intowner = LOCK_OWNER_NONE;
1576         sysblk.waiting_mask |= regs->cpubit;
1577 
1578         /* Wait for interrupt */
1579         wait_condition (&regs->intcond, &sysblk.intlock);
1580 
1581         /* Wait while SYNCHRONIZE_CPUS is in progress */
1582         while (sysblk.syncing)
1583             wait_condition (&sysblk.sync_bc_cond, &sysblk.intlock);
1584 
1585         /* Indicate we now own intlock */
1586         sysblk.waiting_mask ^= regs->cpubit;
1587         sysblk.intowner = regs->cpuad;
1588 
1589 #ifdef OPTION_MIPS_COUNTING
1590         /* Calculate the time we waited */
1591         regs->waittime += host_tod() - regs->waittod;
1592         regs->waittod = 0;
1593 #endif
1594         RELEASE_INTLOCK(regs);
1595         longjmp(regs->progjmp, SIE_NO_INTERCEPT);
1596     } /* end if(wait) */
1597 
1598     /* Release the interrupt lock */
1599     RELEASE_INTLOCK(regs);
1600     return;
1601 
1602 } /* process_interrupt */
1603 
1604 /*-------------------------------------------------------------------*/
1605 /* Run CPU                                                           */
1606 /*-------------------------------------------------------------------*/
ARCH_DEP(run_cpu)1607 REGS *ARCH_DEP(run_cpu) (int cpu, REGS *oldregs)
1608 {
1609 BYTE   *ip;
1610 REGS    regs;
1611 
1612     if (oldregs)
1613     {
1614         memcpy (&regs, oldregs, sizeof(REGS));
1615         free (oldregs);
1616         regs.hostregs = &regs;
1617         if (regs.guestregs)
1618             regs.guestregs->hostregs = &regs;
1619         sysblk.regs[cpu] = &regs;
1620         release_lock(&sysblk.cpulock[cpu]);
1621         logmsg (_("HHCCP007I CPU%4.4X architecture mode set to %s\n"),
1622                 cpu, get_arch_mode_string(&regs));
1623     }
1624     else
1625     {
1626         memset (&regs, 0, sizeof(REGS));
1627 
1628         if (cpu_init (cpu, &regs, NULL))
1629             return NULL;
1630 
1631         logmsg (_("HHCCP003I CPU%4.4X architecture mode %s\n"),
1632                 cpu, get_arch_mode_string(&regs));
1633 
1634 #ifdef FEATURE_VECTOR_FACILITY
1635         if (regs->vf->online)
1636             logmsg (_("HHCCP004I CPU%4.4X Vector Facility online\n"),
1637                     cpu);
1638 #endif /*FEATURE_VECTOR_FACILITY*/
1639     }
1640 
1641     regs.program_interrupt = &ARCH_DEP(program_interrupt);
1642 #if defined(FEATURE_TRACING)
1643     regs.trace_br = (func)&ARCH_DEP(trace_br);
1644 #endif
1645 
1646     regs.tracing = (sysblk.inststep || sysblk.insttrace);
1647     regs.ints_state |= sysblk.ints_state;
1648 
1649     /* Establish longjmp destination for cpu thread exit */
1650     if (setjmp(regs.exitjmp))
1651         return cpu_uninit(cpu, &regs);
1652 
1653     /* Establish longjmp destination for architecture switch */
1654     setjmp(regs.archjmp);
1655 
1656     /* Switch architecture mode if appropriate */
1657     if(sysblk.arch_mode != regs.arch_mode)
1658     {
1659         PTT(PTT_CL_INF,"*SETARCH",regs.arch_mode,sysblk.arch_mode,cpu);
1660         regs.arch_mode = sysblk.arch_mode;
1661         oldregs = malloc (sizeof(REGS));
1662         if (oldregs)
1663         {
1664             memcpy(oldregs, &regs, sizeof(REGS));
1665             obtain_lock(&sysblk.cpulock[cpu]);
1666         }
1667         else
1668         {
1669             logmsg (_("HHCCP080E CPU%4.4X malloc failed for archjmp regs: %s\n"),
1670                     cpu, strerror(errno));
1671             cpu_uninit (cpu, &regs);
1672         }
1673         return oldregs;
1674     }
1675 
1676     RELEASE_INTLOCK(&regs);
1677 
1678     /* Establish longjmp destination for program check */
1679     setjmp(regs.progjmp);
1680 
1681     /* Set `execflag' to 0 in case EXecuted instruction did a longjmp() */
1682     regs.execflag = 0;
1683 
1684     do {
1685         if (INTERRUPT_PENDING(&regs))
1686             ARCH_DEP(process_interrupt)(&regs);
1687 
1688         ip = INSTRUCTION_FETCH(&regs, 0);
1689         regs.instcount++;
1690         EXECUTE_INSTRUCTION(ip, &regs);
1691 
1692         do {
1693             UNROLLED_EXECUTE(&regs);
1694             UNROLLED_EXECUTE(&regs);
1695             UNROLLED_EXECUTE(&regs);
1696             UNROLLED_EXECUTE(&regs);
1697             UNROLLED_EXECUTE(&regs);
1698             UNROLLED_EXECUTE(&regs);
1699 
1700             regs.instcount += 12;
1701 
1702             UNROLLED_EXECUTE(&regs);
1703             UNROLLED_EXECUTE(&regs);
1704             UNROLLED_EXECUTE(&regs);
1705             UNROLLED_EXECUTE(&regs);
1706             UNROLLED_EXECUTE(&regs);
1707             UNROLLED_EXECUTE(&regs);
1708         } while (!INTERRUPT_PENDING(&regs));
1709     } while (1);
1710 
1711     /* Never reached */
1712     return NULL;
1713 
1714 } /* end function cpu_thread */
1715 
1716 /*-------------------------------------------------------------------*/
1717 /* Process Trace                                                     */
1718 /*-------------------------------------------------------------------*/
ARCH_DEP(process_trace)1719 void ARCH_DEP(process_trace)(REGS *regs)
1720 {
1721 int     shouldtrace = 0;                /* 1=Trace instruction       */
1722 int     shouldstep = 0;                 /* 1=Wait for start command  */
1723 
1724     /* Test for trace */
1725     if (CPU_TRACING(regs, 0))
1726         shouldtrace = 1;
1727 
1728     /* Test for step */
1729     if (CPU_STEPPING(regs, 0))
1730         shouldstep = 1;
1731 
1732     /* Display the instruction */
1733     if (shouldtrace || shouldstep)
1734     {
1735         BYTE *ip = regs->ip < regs->aip ? regs->inst : regs->ip;
1736         ARCH_DEP(display_inst) (regs, ip);
1737     }
1738 
1739     /* Stop the CPU */
1740     if (shouldstep)
1741     {
1742         REGS *hostregs = regs->hostregs;
1743         S64 saved_timer[2];
1744 
1745         OBTAIN_INTLOCK(hostregs);
1746 #ifdef OPTION_MIPS_COUNTING
1747         hostregs->waittod = host_tod();
1748 #endif
1749         /* The CPU timer is not decremented for a CPU that is in
1750            the manual state (e.g. stopped in single step mode) */
1751         saved_timer[0] = cpu_timer(regs);
1752         saved_timer[1] = cpu_timer(hostregs);
1753         hostregs->cpustate = CPUSTATE_STOPPED;
1754         sysblk.started_mask &= ~hostregs->cpubit;
1755         hostregs->stepwait = 1;
1756         sysblk.intowner = LOCK_OWNER_NONE;
1757         while (hostregs->cpustate == CPUSTATE_STOPPED)
1758         {
1759             wait_condition (&hostregs->intcond, &sysblk.intlock);
1760         }
1761         sysblk.intowner = hostregs->cpuad;
1762         hostregs->stepwait = 0;
1763         sysblk.started_mask |= hostregs->cpubit;
1764         set_cpu_timer(regs,saved_timer[0]);
1765         set_cpu_timer(hostregs,saved_timer[1]);
1766 #ifdef OPTION_MIPS_COUNTING
1767         hostregs->waittime += host_tod() - hostregs->waittod;
1768         hostregs->waittod = 0;
1769 #endif
1770         RELEASE_INTLOCK(hostregs);
1771     }
1772 } /* process_trace */
1773 
1774 /*-------------------------------------------------------------------*/
1775 /* Set Jump Pointers                                                 */
1776 /*                                                                   */
1777 /* For supported architectures and certain multi-byte instructions,  */
1778 /* EXECUTE_INSTRUCTION and UNROLLED_EXECUTE call a label in this     */
1779 /* function which does a jump to the real instruction.               */
1780 /*                                                                   */
1781 /* The reason why we use labels instead of individual pointers is    */
1782 /* that if -fomit-frame-pointer is omitted then the backframe        */
1783 /* isn't pushed onto the stack.                                      */
1784 /*                                                                   */
1785 /* The reason why this routine is in cpu.c is an attempt to provide  */
1786 /* locality with the corresponding run_cpu function.                 */
1787 /*                                                                   */
1788 /* This routine is called from cpu_init                              */
1789 /*                                                                   */
1790 /*-------------------------------------------------------------------*/
ARCH_DEP(set_jump_pointers)1791 void ARCH_DEP(set_jump_pointers) (REGS *regs, int jump)
1792 {
1793 
1794 #if defined(MULTI_BYTE_ASSIST)
1795 
1796     /* Use `switch' to confuse smart-ass optimizing compilers */
1797     switch (jump) {
1798 
1799  #if defined(MULTI_BYTE_ASSIST_IA32)
1800     case 0xa7:
1801 jump_a7xx:
1802  __asm__ (
1803         "movzbl 1(%%eax),%%ecx\n\t"
1804         "jmp    *%c0(%%edx,%%ecx,4)"
1805         : : "i" (offsetof(REGS,ARCH_DEP(opcode_a7xx)))
1806         );
1807         return;
1808     case 0xb2:
1809 jump_b2xx:
1810  __asm__ (
1811         "movzbl 1(%%eax),%%ecx\n\t"
1812         "jmp    *%c0(%%edx,%%ecx,4)"
1813         : : "i" (offsetof(REGS,ARCH_DEP(opcode_b2xx)))
1814         );
1815         return;
1816     case 0xb9:
1817 jump_b9xx:
1818  __asm__ (
1819         "movzbl 1(%%eax),%%ecx\n\t"
1820         "jmp    *%c0(%%edx,%%ecx,4)"
1821         : : "i" (offsetof(REGS,ARCH_DEP(opcode_b9xx)))
1822         );
1823         return;
1824   #if defined(FEATURE_ESAME) || defined(FEATURE_ESAME_N3_ESA390)
1825     case 0xc0:
1826 jump_c0xx:
1827  __asm__ (
1828         "movzbl 1(%%eax),%%ecx\n\t"
1829         "jmp    *%c0(%%edx,%%ecx,4)"
1830         : : "i" (offsetof(REGS,ARCH_DEP(opcode_c0xx)))
1831         );
1832         return;
1833     case 0xe3:
1834 jump_e3xx:
1835  __asm__ (
1836         "movzbl 5(%%eax),%%ecx\n\t"
1837         "jmp    *%c0(%%edx,%%ecx,4)"
1838         : : "i" (offsetof(REGS,ARCH_DEP(opcode_e3xx)))
1839         );
1840         return;
1841     case 0xeb:
1842   #endif /* defined(FEATURE_ESAME) || defined(FEATURE_ESAME_N3_ESA390) */
1843 jump_ebxx:
1844  __asm__ (
1845         "movzbl 5(%%eax),%%ecx\n\t"
1846         "jmp    *%c0(%%edx,%%ecx,4)"
1847         : : "i" (offsetof(REGS,ARCH_DEP(opcode_ebxx)))
1848         );
1849         return;
1850  #endif /* defined(MULTI_BYTE_ASSIST_IA32) */
1851 
1852     } /* switch(jump) */
1853 
1854     regs->ARCH_DEP(opcode_table)[0xa7] = &&jump_a7xx;
1855     regs->ARCH_DEP(opcode_table)[0xb2] = &&jump_b2xx;
1856     regs->ARCH_DEP(opcode_table)[0xb9] = &&jump_b9xx;
1857  #if defined(FEATURE_ESAME) || defined(FEATURE_ESAME_N3_ESA390)
1858     regs->ARCH_DEP(opcode_table)[0xc0] = &&jump_c0xx;
1859     regs->ARCH_DEP(opcode_table)[0xe3] = &&jump_e3xx;
1860  #endif /* defined(FEATURE_ESAME) || defined(FEATURE_ESAME_N3_ESA390) */
1861     regs->ARCH_DEP(opcode_table)[0xeb] = &&jump_ebxx;
1862 
1863 #else /* !defined(MULTI_BYTE_ASSIST) */
1864     UNREFERENCED(regs);
1865     UNREFERENCED(jump);
1866 #endif /* !defined(MULTI_BYTE_ASSIST) */
1867 
1868 }
1869 
1870 #if !defined(_GEN_ARCH)
1871 
1872 #if defined(_ARCHMODE2)
1873  #define  _GEN_ARCH _ARCHMODE2
1874  #include "cpu.c"
1875 #endif
1876 
1877 #if defined(_ARCHMODE3)
1878  #undef   _GEN_ARCH
1879  #define  _GEN_ARCH _ARCHMODE3
1880  #include "cpu.c"
1881 #endif
1882 
1883 /*-------------------------------------------------------------------*/
1884 /* Copy program status word                                          */
1885 /*-------------------------------------------------------------------*/
copy_psw(REGS * regs,BYTE * addr)1886 DLL_EXPORT void copy_psw (REGS *regs, BYTE *addr)
1887 {
1888 REGS cregs;
1889 int  arch_mode;
1890 
1891     memcpy(&cregs, regs, sysblk.regs_copy_len);
1892 
1893     /* Use the architecture mode from SYSBLK if load indicator
1894        shows IPL in process, otherwise use archmode from REGS */
1895     if (cregs.loadstate)
1896     {
1897         arch_mode = sysblk.arch_mode;
1898     }
1899     else
1900     {
1901         arch_mode = cregs.arch_mode;
1902     }
1903 
1904     /* Call the appropriate store_psw routine based on archmode */
1905     switch(arch_mode) {
1906 #if defined(_370)
1907         case ARCH_370:
1908             s370_store_psw(&cregs, addr);
1909             break;
1910 #endif
1911 #if defined(_390)
1912         case ARCH_390:
1913             s390_store_psw(&cregs, addr);
1914             break;
1915 #endif
1916 #if defined(_900)
1917         case ARCH_900:
1918             z900_store_psw(&cregs, addr);
1919             break;
1920 #endif
1921     }
1922 } /* end function copy_psw */
1923 
1924 /*-------------------------------------------------------------------*/
1925 /* Display program status word                                       */
1926 /*-------------------------------------------------------------------*/
display_psw(REGS * regs)1927 void display_psw (REGS *regs)
1928 {
1929 QWORD   qword;                            /* quadword work area      */
1930 int     arch_mode;                        /* architecture mode       */
1931 
1932     memset(qword, 0, sizeof(qword));
1933 
1934     /* Use the architecture mode from SYSBLK if load indicator
1935        shows IPL in process, otherwise use archmode from REGS */
1936     if (regs->loadstate)
1937     {
1938         arch_mode = sysblk.arch_mode;
1939     }
1940     else
1941     {
1942         arch_mode = regs->arch_mode;
1943     }
1944 
1945     if( arch_mode != ARCH_900 )
1946     {
1947         copy_psw (regs, qword);
1948         logmsg (_("PSW=%2.2X%2.2X%2.2X%2.2X %2.2X%2.2X%2.2X%2.2X\n"),
1949                 qword[0], qword[1], qword[2], qword[3],
1950                 qword[4], qword[5], qword[6], qword[7]);
1951     }
1952     else
1953     {
1954         copy_psw (regs, qword);
1955         logmsg (_("PSW=%2.2X%2.2X%2.2X%2.2X %2.2X%2.2X%2.2X%2.2X "
1956                 "%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X\n"),
1957                 qword[0], qword[1], qword[2], qword[3],
1958                 qword[4], qword[5], qword[6], qword[7],
1959                 qword[8], qword[9], qword[10], qword[11],
1960                 qword[12], qword[13], qword[14], qword[15]);
1961     }
1962 
1963 } /* end function display_psw */
1964 
1965 const char* arch_name[GEN_MAXARCH] =
1966 {
1967 #if defined(_370)
1968         _ARCH_370_NAME,
1969 #endif
1970 #if defined(_390)
1971         _ARCH_390_NAME,
1972 #endif
1973 #if defined(_900)
1974         _ARCH_900_NAME
1975 #endif
1976 };
1977 
get_arch_mode_string(REGS * regs)1978 const char* get_arch_mode_string(REGS* regs)
1979 {
1980     if (!regs) return arch_name[sysblk.arch_mode];
1981     else return arch_name[regs->arch_mode];
1982 }
1983 
1984 #endif /*!defined(_GEN_ARCH)*/
1985