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(®s->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(®s->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(®s->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(®s->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(®s->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(®s->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(®s->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(®s->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(®s->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 (®s->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(®s->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 (®s->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(®s->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 (®s->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 (®s, oldregs, sizeof(REGS));
1615 free (oldregs);
1616 regs.hostregs = ®s;
1617 if (regs.guestregs)
1618 regs.guestregs->hostregs = ®s;
1619 sysblk.regs[cpu] = ®s;
1620 release_lock(&sysblk.cpulock[cpu]);
1621 logmsg (_("HHCCP007I CPU%4.4X architecture mode set to %s\n"),
1622 cpu, get_arch_mode_string(®s));
1623 }
1624 else
1625 {
1626 memset (®s, 0, sizeof(REGS));
1627
1628 if (cpu_init (cpu, ®s, NULL))
1629 return NULL;
1630
1631 logmsg (_("HHCCP003I CPU%4.4X architecture mode %s\n"),
1632 cpu, get_arch_mode_string(®s));
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, ®s);
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, ®s, 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, ®s);
1672 }
1673 return oldregs;
1674 }
1675
1676 RELEASE_INTLOCK(®s);
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(®s))
1686 ARCH_DEP(process_interrupt)(®s);
1687
1688 ip = INSTRUCTION_FETCH(®s, 0);
1689 regs.instcount++;
1690 EXECUTE_INSTRUCTION(ip, ®s);
1691
1692 do {
1693 UNROLLED_EXECUTE(®s);
1694 UNROLLED_EXECUTE(®s);
1695 UNROLLED_EXECUTE(®s);
1696 UNROLLED_EXECUTE(®s);
1697 UNROLLED_EXECUTE(®s);
1698 UNROLLED_EXECUTE(®s);
1699
1700 regs.instcount += 12;
1701
1702 UNROLLED_EXECUTE(®s);
1703 UNROLLED_EXECUTE(®s);
1704 UNROLLED_EXECUTE(®s);
1705 UNROLLED_EXECUTE(®s);
1706 UNROLLED_EXECUTE(®s);
1707 UNROLLED_EXECUTE(®s);
1708 } while (!INTERRUPT_PENDING(®s));
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