1 /* HSCMISC.C (c) Copyright Roger Bowler, 1999-2009 */
2 /* (c) Copyright Jan Jaeger, 1999-2009 */
3 /* Miscellaneous System Command Routines */
4
5 #include "hstdinc.h"
6
7 #if !defined(_HENGINE_DLL_)
8 #define _HENGINE_DLL_
9 #endif
10
11 #if !defined(_HSCMISC_C_)
12 #define _HSCMISC_C_
13 #endif
14
15 #include "hercules.h"
16 #include "devtype.h"
17 #include "opcode.h"
18 #include "inline.h"
19
20 #define DISPLAY_INSTRUCTION_OPERANDS
21
22 #if !defined(_HSCMISC_C)
23 #define _HSCMISC_C
24
25 /*-------------------------------------------------------------------*/
26 /* System Shutdown Processing */
27 /*-------------------------------------------------------------------*/
28
29 /* The following 'sigq' functions are responsible for ensuring all of
30 the CPUs are stopped ("quiesced") before continuing with Hercules
31 shutdown processing, and should NEVER be called directly. Instead,
32 they are called by the main 'do_shutdown' (or 'do_shutdown_wait')
33 function(s) (defined further below) as needed and/or appropriate.
34 */
35 static int wait_sigq_pending = 0;
36
is_wait_sigq_pending()37 static int is_wait_sigq_pending()
38 {
39 int pending;
40
41 OBTAIN_INTLOCK(NULL);
42 pending = wait_sigq_pending;
43 RELEASE_INTLOCK(NULL);
44
45 return pending;
46 }
47
wait_sigq_resp()48 static void wait_sigq_resp()
49 {
50 int pending, i;
51 /* Wait for all CPU's to stop */
52 do
53 {
54 OBTAIN_INTLOCK(NULL);
55 wait_sigq_pending = 0;
56 for (i = 0; i < MAX_CPU_ENGINES; i++)
57 if (IS_CPU_ONLINE(i)
58 && sysblk.regs[i]->cpustate != CPUSTATE_STOPPED)
59 wait_sigq_pending = 1;
60 pending = wait_sigq_pending;
61 RELEASE_INTLOCK(NULL);
62
63 if(pending)
64 SLEEP(1);
65 }
66 while(is_wait_sigq_pending());
67 }
68
cancel_wait_sigq()69 static void cancel_wait_sigq()
70 {
71 OBTAIN_INTLOCK(NULL);
72 wait_sigq_pending = 0;
73 RELEASE_INTLOCK(NULL);
74 }
75
76 /* do_shutdown_now
77
78 This is the main shutdown processing function. It is NEVER called
79 directly, but is instead ONLY called by either the 'do_shutdown'
80 or 'do_shutdown_wait' functions after all CPUs have been stopped.
81
82 It is responsible for releasing the device configuration and then
83 calling the Hercules Dynamic Loader "hdl_shut" function to invoke
84 all registered "Hercules at-exit/termination functions" (similar
85 to 'atexit' but unique to Hercules) (to perform any other needed
86 miscellaneous shutdown related processing).
87
88 Only after the above three tasks have been completed (stopping the
89 CPUs, releasing the device configuration, calling registered term-
90 ination routines/functions) can Hercules then be safely terminated.
91
92 Note too that, *technically*, this function *should* wait for *all*
93 other threads to finish terminating first before either exiting or
94 returning back to the caller, but we don't currently enforce that
95 (since that's *really* what hdl_adsc + hdl_shut is designed for!).
96
97 At the moment, as long as the three previously mentioned three most
98 important shutdown tasks have been completed (stop cpus, release
99 device config, call term funcs), then we consider the brunt of our
100 shutdown processing to be completed and thus exit (or return back
101 to the caller to let them exit instead). If there happen to be any
102 threads still running when that happens, they will be automatically
103 terminated by the operating sytem as normal when a process exits.
104
105 SO... If there are any threads that must be terminated completely
106 and cleanly before Hercules can safely terminate, then you better
107 add code to this function to ENSURE that your thread is terminated
108 properly! (and/or add a call to 'hdl_adsc' at the appropriate place
109 in the startup sequence). For this purpose, the use of "join_thread"
110 is *strongly* encouraged as it *ensures* that your thread will not
111 continue until the thread in question has completely exited first.
112 */
do_shutdown_now()113 static void do_shutdown_now()
114 {
115 logmsg("HHCIN900I Begin Hercules shutdown\n");
116
117 ASSERT( !sysblk.shutfini ); // (sanity check)
118
119 sysblk.shutfini = 0; // (shutdown NOT finished yet)
120 sysblk.shutdown = 1; // (system shutdown initiated)
121
122 logmsg("HHCIN901I Releasing configuration\n");
123 {
124 release_config();
125 }
126 logmsg("HHCIN902I Configuration release complete\n");
127
128 logmsg("HHCIN903I Calling termination routines\n");
129 {
130 hdl_shut();
131 }
132 logmsg("HHCIN904I All termination routines complete\n");
133
134 /*
135 logmsg("HHCIN905I Terminating threads\n");
136 {
137 // (none we really care about at the moment...)
138 }
139 logmsg("HHCIN906I Threads terminations complete\n");
140 */
141
142 logmsg("HHCIN909I Hercules shutdown complete\n");
143 sysblk.shutfini = 1; // (shutdown is now complete)
144
145 // PROGRAMMING NOTE
146
147 // If we're NOT in "daemon_mode" (i.e. panel_display in control),
148 // -OR- if a daemon_task DOES exist, then THEY are in control of
149 // shutdown; THEY are responsible for exiting the system whenever
150 // THEY feel it's proper to do so (by simply returning back to the
151 // caller thereby allowing 'main' to return back to the operating
152 // system).
153
154 // OTHEWRWISE we ARE in "daemon_mode", but a daemon_task does NOT
155 // exist, which means the main thread (tail end of 'impl.c') is
156 // stuck in a loop reading log messages and writing them to the
157 // logfile, so we need to do the exiting here since it obviously
158 // cannot.
159
160 if ( sysblk.daemon_mode
161 #if defined(OPTION_DYNAMIC_LOAD)
162 && !daemon_task
163 #endif /*defined(OPTION_DYNAMIC_LOAD)*/
164 )
165 {
166 #ifdef _MSVC_
167 socket_deinit();
168 #endif
169 #ifdef DEBUG
170 fprintf(stdout, _("DO_SHUTDOWN_NOW EXIT\n"));
171 #endif
172 fprintf(stdout, _("HHCIN099I Hercules terminated\n"));
173 fflush(stdout);
174 exit(0);
175 }
176 }
177
178 /* do_shutdown_wait
179
180 This function simply waits for the CPUs to stop and then calls
181 the above do_shutdown_now function to perform the actual shutdown
182 (which releases the device configuration, etc)
183 */
do_shutdown_wait()184 static void do_shutdown_wait()
185 {
186 logmsg(_("HHCIN098I Shutdown initiated\n"));
187 wait_sigq_resp();
188 do_shutdown_now();
189 }
190
191 /* ***** do_shutdown *****
192
193 This is the main system shutdown function, and the ONLY function
194 that should EVER be called to shut the system down. It calls one
195 or more of the above static helper functions as needed.
196 */
do_shutdown()197 void do_shutdown()
198 {
199 TID tid;
200 #if defined(_MSVC_)
201 if ( sysblk.shutimmed )
202 do_shutdown_now();
203 else
204 {
205 #endif // defined(_MSVC_)
206 if(is_wait_sigq_pending())
207 cancel_wait_sigq();
208 else
209 if(can_signal_quiesce() && !signal_quiesce(0,0))
210 create_thread(&tid, DETACHED, do_shutdown_wait,
211 NULL, "do_shutdown_wait");
212 else
213 do_shutdown_now();
214 #if defined(_MSVC_)
215 }
216 #endif // defined(_MSVC_)
217 }
218 /*-------------------------------------------------------------------*/
219 /* The following 2 routines display an array of 32/64 registers */
220 /* 1st parameter is the register type (GR, CR, AR, etc..) */
221 /* 2nd parameter is the CPU Address involved */
222 /* 3rd parameter is an array of 32/64 bit regs */
223 /* NOTE : 32 bit regs are displayed 4 by 4, while 64 bit regs are */
224 /* displayed 2 by 2. Change the modulo if to change this */
225 /* behaviour. */
226 /* These routines are intended to be invoked by display_regs, */
227 /* display_cregs and display_aregs */
228 /* Ivan Warren 2005/11/07 */
229 /*-------------------------------------------------------------------*/
display_regs32(char * hdr,U16 cpuad,U32 * r,int numcpus)230 static void display_regs32(char *hdr,U16 cpuad,U32 *r,int numcpus)
231 {
232 int i;
233 for(i=0;i<16;i++)
234 {
235 if(!(i%4))
236 {
237 if(i)
238 {
239 logmsg("\n");
240 }
241 if(numcpus>1)
242 {
243 logmsg("CPU%4.4X: ",cpuad);
244 }
245 }
246 if(i%4)
247 {
248 logmsg(" ");
249 }
250 logmsg("%s%2.2d=%8.8"I32_FMT"X",hdr,i,r[i]);
251 }
252 logmsg("\n");
253 }
254
255 #if defined(_900)
256
display_regs64(char * hdr,U16 cpuad,U64 * r,int numcpus)257 static void display_regs64(char *hdr,U16 cpuad,U64 *r,int numcpus)
258 {
259 int i;
260 int rpl;
261 if(numcpus>1)
262 {
263 rpl=2;
264 }
265 else
266 {
267 rpl=4;
268 }
269 for(i=0;i<16;i++)
270 {
271 if(!(i%rpl))
272 {
273 if(i)
274 {
275 logmsg("\n");
276 }
277 if(numcpus>1)
278 {
279 logmsg("CPU%4.4X: ",cpuad);
280 }
281 }
282 if(i%rpl)
283 {
284 logmsg(" ");
285 }
286 logmsg("%s%1.1X=%16.16"I64_FMT"X",hdr,i,r[i]);
287 }
288 logmsg("\n");
289 }
290
291 #endif
292
293 /*-------------------------------------------------------------------*/
294 /* Display registers for the instruction display */
295 /*-------------------------------------------------------------------*/
display_inst_regs(REGS * regs,BYTE * inst,BYTE opcode)296 void display_inst_regs (REGS *regs, BYTE *inst, BYTE opcode)
297 {
298 /* Display the general purpose registers */
299 if (!(opcode == 0xB3 || (opcode >= 0x20 && opcode <= 0x3F))
300 || (opcode == 0xB3 && (
301 (inst[1] >= 0x80 && inst[1] <= 0xCF)
302 || (inst[1] >= 0xE1 && inst[1] <= 0xFE)
303 )))
304 {
305 display_regs (regs);
306 if (sysblk.showregsfirst) logmsg("\n");
307 }
308
309 /* Display control registers if appropriate */
310 if (!REAL_MODE(®s->psw) || opcode == 0xB2)
311 {
312 display_cregs (regs);
313 if (sysblk.showregsfirst) logmsg("\n");
314 }
315
316 /* Display access registers if appropriate */
317 if (!REAL_MODE(®s->psw) && ACCESS_REGISTER_MODE(®s->psw))
318 {
319 display_aregs (regs);
320 if (sysblk.showregsfirst) logmsg("\n");
321 }
322
323 /* Display floating-point registers if appropriate */
324 if (opcode == 0xB3 || opcode == 0xED
325 || (opcode >= 0x20 && opcode <= 0x3F)
326 || (opcode >= 0x60 && opcode <= 0x70)
327 || (opcode >= 0x78 && opcode <= 0x7F)
328 || (opcode == 0xB2 && inst[1] == 0x2D) /*DXR*/
329 || (opcode == 0xB2 && inst[1] == 0x44) /*SQDR*/
330 || (opcode == 0xB2 && inst[1] == 0x45) /*SQER*/
331 )
332 {
333 display_fregs (regs);
334 if (sysblk.showregsfirst) logmsg("\n");
335 }
336 }
337
338 /*-------------------------------------------------------------------*/
339 /* Display general purpose registers */
340 /*-------------------------------------------------------------------*/
display_regs(REGS * regs)341 void display_regs (REGS *regs)
342 {
343 int i;
344 U32 gprs[16];
345 #if defined(_900)
346 U64 ggprs[16];
347 #endif
348
349 #if defined(_900)
350 if(regs->arch_mode != ARCH_900)
351 {
352 #endif
353 for(i=0;i<16;i++)
354 {
355 gprs[i]=regs->GR_L(i);
356 }
357 display_regs32("GR",regs->cpuad,gprs,sysblk.cpus);
358 #if defined(_900)
359 }
360 else
361 {
362 for(i=0;i<16;i++)
363 {
364 ggprs[i]=regs->GR_G(i);
365 }
366 display_regs64("R",regs->cpuad,ggprs,sysblk.cpus);
367 }
368 #endif
369
370 } /* end function display_regs */
371
372
373 /*-------------------------------------------------------------------*/
374 /* Display control registers */
375 /*-------------------------------------------------------------------*/
display_cregs(REGS * regs)376 void display_cregs (REGS *regs)
377 {
378 int i;
379 U32 crs[16];
380 #if defined(_900)
381 U64 gcrs[16];
382 #endif
383
384 #if defined(_900)
385 if(regs->arch_mode != ARCH_900)
386 {
387 #endif
388 for(i=0;i<16;i++)
389 {
390 crs[i]=regs->CR_L(i);
391 }
392 display_regs32("CR",regs->cpuad,crs,sysblk.cpus);
393 #if defined(_900)
394 }
395 else
396 {
397 for(i=0;i<16;i++)
398 {
399 gcrs[i]=regs->CR_G(i);
400 }
401 display_regs64("C",regs->cpuad,gcrs,sysblk.cpus);
402 }
403 #endif
404
405 } /* end function display_cregs */
406
407
408 /*-------------------------------------------------------------------*/
409 /* Display access registers */
410 /*-------------------------------------------------------------------*/
display_aregs(REGS * regs)411 void display_aregs (REGS *regs)
412 {
413 int i;
414 U32 ars[16];
415
416 for(i=0;i<16;i++)
417 {
418 ars[i]=regs->AR(i);
419 }
420 display_regs32("AR",regs->cpuad,ars,sysblk.cpus);
421
422 } /* end function display_aregs */
423
424
425 /*-------------------------------------------------------------------*/
426 /* Display floating point registers */
427 /*-------------------------------------------------------------------*/
display_fregs(REGS * regs)428 void display_fregs (REGS *regs)
429 {
430 char cpustr[10] = {0}; /* "CPU:nnnn " or "" */
431
432 if(sysblk.cpus>1)
433 sprintf(cpustr, "CPU%4.4X: ", regs->cpuad);
434
435 if(regs->CR(0) & CR0_AFP)
436 logmsg
437 (
438 "%sFPR0=%8.8X %8.8X FPR2=%8.8X %8.8X\n"
439 "%sFPR1=%8.8X %8.8X FPR3=%8.8X %8.8X\n"
440 "%sFPR4=%8.8X %8.8X FPR6=%8.8X %8.8X\n"
441 "%sFPR5=%8.8X %8.8X FPR7=%8.8X %8.8X\n"
442 "%sFPR8=%8.8X %8.8X FP10=%8.8X %8.8X\n"
443 "%sFPR9=%8.8X %8.8X FP11=%8.8X %8.8X\n"
444 "%sFP12=%8.8X %8.8X FP14=%8.8X %8.8X\n"
445 "%sFP13=%8.8X %8.8X FP15=%8.8X %8.8X\n"
446 ,cpustr, regs->fpr[0], regs->fpr[1], regs->fpr[4], regs->fpr[5]
447 ,cpustr, regs->fpr[2], regs->fpr[3], regs->fpr[6], regs->fpr[7]
448 ,cpustr, regs->fpr[8], regs->fpr[9], regs->fpr[12], regs->fpr[13]
449 ,cpustr, regs->fpr[10], regs->fpr[11], regs->fpr[14], regs->fpr[15]
450 ,cpustr, regs->fpr[16], regs->fpr[17], regs->fpr[20], regs->fpr[21]
451 ,cpustr, regs->fpr[18], regs->fpr[19], regs->fpr[22], regs->fpr[23]
452 ,cpustr, regs->fpr[24], regs->fpr[25], regs->fpr[28], regs->fpr[29]
453 ,cpustr, regs->fpr[26], regs->fpr[27], regs->fpr[30], regs->fpr[31]
454 );
455 else
456 logmsg
457 (
458 "%sFPR0=%8.8X %8.8X FPR2=%8.8X %8.8X\n"
459 "%sFPR4=%8.8X %8.8X FPR6=%8.8X %8.8X\n"
460 ,cpustr, regs->fpr[0], regs->fpr[1], regs->fpr[2], regs->fpr[3]
461 ,cpustr, regs->fpr[4], regs->fpr[5], regs->fpr[6], regs->fpr[7]
462 );
463
464 } /* end function display_fregs */
465
466
467 /*-------------------------------------------------------------------*/
468 /* Display subchannel */
469 /*-------------------------------------------------------------------*/
display_subchannel(DEVBLK * dev)470 void display_subchannel (DEVBLK *dev)
471 {
472 logmsg ("%4.4X:D/T=%4.4X",
473 dev->devnum, dev->devtype);
474 if (ARCH_370 == sysblk.arch_mode)
475 {
476 logmsg (" CSW=Flags:%2.2X CCW:%2.2X%2.2X%2.2X "
477 "Stat:%2.2X%2.2X Count:%2.2X%2.2X\n",
478 dev->csw[0], dev->csw[1], dev->csw[2], dev->csw[3],
479 dev->csw[4], dev->csw[5], dev->csw[6], dev->csw[7]);
480 } else {
481 logmsg (" Subchannel_Number=%4.4X\n", dev->subchan);
482 logmsg (" PMCW=IntParm:%2.2X%2.2X%2.2X%2.2X Flags:%2.2X%2.2X"
483 " Dev:%2.2X%2.2X"
484 " LPM:%2.2X PNOM:%2.2X LPUM:%2.2X PIM:%2.2X\n"
485 " MBI:%2.2X%2.2X POM:%2.2X PAM:%2.2X"
486 " CHPIDs:%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X"
487 " Misc:%2.2X%2.2X%2.2X%2.2X\n",
488 dev->pmcw.intparm[0], dev->pmcw.intparm[1],
489 dev->pmcw.intparm[2], dev->pmcw.intparm[3],
490 dev->pmcw.flag4, dev->pmcw.flag5,
491 dev->pmcw.devnum[0], dev->pmcw.devnum[1],
492 dev->pmcw.lpm, dev->pmcw.pnom, dev->pmcw.lpum, dev->pmcw.pim,
493 dev->pmcw.mbi[0], dev->pmcw.mbi[1],
494 dev->pmcw.pom, dev->pmcw.pam,
495 dev->pmcw.chpid[0], dev->pmcw.chpid[1],
496 dev->pmcw.chpid[2], dev->pmcw.chpid[3],
497 dev->pmcw.chpid[4], dev->pmcw.chpid[5],
498 dev->pmcw.chpid[6], dev->pmcw.chpid[7],
499 dev->pmcw.zone, dev->pmcw.flag25,
500 dev->pmcw.flag26, dev->pmcw.flag27);
501
502 logmsg (" SCSW=Flags:%2.2X%2.2X SCHC:%2.2X%2.2X "
503 "Stat:%2.2X%2.2X Count:%2.2X%2.2X "
504 "CCW:%2.2X%2.2X%2.2X%2.2X\n",
505 dev->scsw.flag0, dev->scsw.flag1,
506 dev->scsw.flag2, dev->scsw.flag3,
507 dev->scsw.unitstat, dev->scsw.chanstat,
508 dev->scsw.count[0], dev->scsw.count[1],
509 dev->scsw.ccwaddr[0], dev->scsw.ccwaddr[1],
510 dev->scsw.ccwaddr[2], dev->scsw.ccwaddr[3]);
511 }
512
513 } /* end function display_subchannel */
514
515
516 /*-------------------------------------------------------------------*/
517 /* Parse a storage range or storage alteration operand */
518 /* */
519 /* Valid formats for a storage range operand are: */
520 /* startaddr */
521 /* startaddr-endaddr */
522 /* startaddr.length */
523 /* where startaddr, endaddr, and length are hexadecimal values. */
524 /* */
525 /* Valid format for a storage alteration operand is: */
526 /* startaddr=hexstring (up to 32 pairs of digits) */
527 /* */
528 /* Return values: */
529 /* 0 = operand contains valid storage range display syntax; */
530 /* start/end of range is returned in saddr and eaddr */
531 /* >0 = operand contains valid storage alteration syntax; */
532 /* return value is number of bytes to be altered; */
533 /* start/end/value are returned in saddr, eaddr, newval */
534 /* -1 = error message issued */
535 /*-------------------------------------------------------------------*/
parse_range(char * operand,U64 maxadr,U64 * sadrp,U64 * eadrp,BYTE * newval)536 static int parse_range (char *operand, U64 maxadr, U64 *sadrp,
537 U64 *eadrp, BYTE *newval)
538 {
539 U64 opnd1, opnd2; /* Address/length operands */
540 U64 saddr, eaddr; /* Range start/end addresses */
541 int rc; /* Return code */
542 int n; /* Number of bytes altered */
543 int h1, h2; /* Hexadecimal digits */
544 char *s; /* Alteration value pointer */
545 BYTE delim; /* Operand delimiter */
546 BYTE c; /* Character work area */
547
548 rc = sscanf(operand, "%"I64_FMT"x%c%"I64_FMT"x%c",
549 &opnd1, &delim, &opnd2, &c);
550
551 /* Process storage alteration operand */
552 if (rc > 2 && delim == '=' && newval)
553 {
554 s = strchr (operand, '=');
555 for (n = 0; n < 32;)
556 {
557 h1 = *(++s);
558 if (h1 == '\0' || h1 == '#' ) break;
559 if (h1 == SPACE || h1 == '\t') continue;
560 h1 = toupper(h1);
561 h2 = *(++s);
562 h2 = toupper(h2);
563 h1 = (h1 >= '0' && h1 <= '9') ? h1 - '0' :
564 (h1 >= 'A' && h1 <= 'F') ? h1 - 'A' + 10 : -1;
565 h2 = (h2 >= '0' && h2 <= '9') ? h2 - '0' :
566 (h2 >= 'A' && h2 <= 'F') ? h2 - 'A' + 10 : -1;
567 if (h1 < 0 || h2 < 0 || n >= 32)
568 {
569 logmsg (_("HHCPN143E Invalid value: %s\n"), s);
570 return -1;
571 }
572 newval[n++] = (h1 << 4) | h2;
573 } /* end for(n) */
574 saddr = opnd1;
575 eaddr = saddr + n - 1;
576 }
577 else
578 {
579 /* Process storage range operand */
580 saddr = opnd1;
581 if (rc == 1)
582 {
583 /* If only starting address is specified, default to
584 64 byte display, or less if near end of storage */
585 eaddr = saddr + 0x3F;
586 if (eaddr > maxadr) eaddr = maxadr;
587 }
588 else
589 {
590 /* Ending address or length is specified */
591 if (rc != 3 || !(delim == '-' || delim == '.'))
592 {
593 logmsg (_("HHCPN144E Invalid operand: %s\n"), operand);
594 return -1;
595 }
596 eaddr = (delim == '.') ? saddr + opnd2 - 1 : opnd2;
597 }
598 /* Set n=0 to indicate storage display only */
599 n = 0;
600 }
601
602 /* Check for valid range */
603 if (saddr > maxadr || eaddr > maxadr || eaddr < saddr)
604 {
605 logmsg (_("HHCPN145E Invalid range: %s\n"), operand);
606 return -1;
607 }
608
609 /* Return start/end addresses and number of bytes altered */
610 *sadrp = saddr;
611 *eadrp = eaddr;
612 return n;
613
614 } /* end function parse_range */
615
616
617 /*-------------------------------------------------------------------*/
618 /* get_connected_client return IP address and hostname of the */
619 /* client that is connected to this device */
620 /*-------------------------------------------------------------------*/
get_connected_client(DEVBLK * dev,char ** pclientip,char ** pclientname)621 void get_connected_client (DEVBLK* dev, char** pclientip, char** pclientname)
622 {
623 *pclientip = NULL;
624 *pclientname = NULL;
625
626 obtain_lock (&dev->lock);
627
628 if (dev->bs /* if device is a socket device, */
629 && dev->fd != -1) /* and a client is connected to it */
630 {
631 *pclientip = strdup(dev->bs->clientip);
632 *pclientname = strdup(dev->bs->clientname);
633 }
634
635 release_lock (&dev->lock);
636 }
637
638 /*-------------------------------------------------------------------*/
639 /* Return the address of a regs structure to be used for address */
640 /* translation. This address should be freed by the caller. */
641 /*-------------------------------------------------------------------*/
copy_regs(REGS * regs)642 static REGS *copy_regs (REGS *regs)
643 {
644 REGS *newregs, *hostregs;
645 size_t size;
646
647 size = (SIE_MODE(regs) || SIE_ACTIVE(regs)) ? 2*sizeof(REGS) : sizeof(REGS);
648 newregs = malloc(size);
649 if (newregs == NULL)
650 {
651 logmsg(_("HHCMS001E malloc failed for REGS copy: %s\n"),
652 strerror(errno));
653 return NULL;
654 }
655
656 /* Perform partial copy and clear the TLB */
657 memcpy(newregs, regs, sysblk.regs_copy_len);
658 memset(&newregs->tlb.vaddr, 0, TLBN * sizeof(DW));
659 newregs->tlbID = 1;
660 newregs->ghostregs = 1;
661 newregs->hostregs = newregs;
662 newregs->guestregs = NULL;
663 newregs->sie_active=0;
664
665 /* Copy host regs if in SIE mode */
666 /* newregs is a SIE Guest REGS */
667 if(SIE_MODE(newregs))
668 {
669 hostregs = newregs + 1;
670 memcpy(hostregs, regs->hostregs, sysblk.regs_copy_len);
671 memset(&hostregs->tlb.vaddr, 0, TLBN * sizeof(DW));
672 hostregs->tlbID = 1;
673 hostregs->ghostregs = 1;
674 hostregs->hostregs = hostregs;
675 hostregs->guestregs = newregs;
676 newregs->hostregs = hostregs;
677 newregs->guestregs = newregs;
678 }
679
680 return newregs;
681 }
682
683 #endif /*!defined(_HSCMISC_C)*/
684
685
686 /*-------------------------------------------------------------------*/
687 /* Convert virtual address to absolute address */
688 /* */
689 /* Input: */
690 /* vaddr Virtual address to be translated */
691 /* arn Access register number */
692 /* regs CPU register context */
693 /* acctype Type of access (ACCTYPE_INSTFETCH, ACCTYPE_READ, */
694 /* or ACCTYPE_LRA) */
695 /* Output: */
696 /* aaptr Points to word in which abs address is returned */
697 /* siptr Points to word to receive indication of which */
698 /* STD or ASCE was used to perform the translation */
699 /* Return value: */
700 /* 0=translation successful, non-zero=exception code */
701 /* Note: */
702 /* To avoid unwanted alteration of the CPU register context */
703 /* during translation (for example, the TEA will be updated */
704 /* if a translation exception occurs), the translation is */
705 /* performed using a temporary copy of the CPU registers. */
706 /*-------------------------------------------------------------------*/
ARCH_DEP(virt_to_abs)707 static U16 ARCH_DEP(virt_to_abs) (RADR *raptr, int *siptr, VADR vaddr,
708 volatile int arn, REGS *regs, int acctype)
709 {
710 int icode;
711
712 if( !(icode = setjmp(regs->progjmp)) )
713 {
714 int temp_arn = arn; // bypass longjmp clobber warning
715 if (acctype == ACCTYPE_INSTFETCH)
716 temp_arn = USE_INST_SPACE;
717 if (SIE_MODE(regs))
718 memcpy(regs->hostregs->progjmp, regs->progjmp,
719 sizeof(jmp_buf));
720 ARCH_DEP(logical_to_main) (vaddr, temp_arn, regs, acctype, 0);
721 }
722
723 *siptr = regs->dat.stid;
724 *raptr = regs->hostregs->dat.raddr;
725
726 return icode;
727
728 } /* end function virt_to_abs */
729
730
731 /*-------------------------------------------------------------------*/
732 /* Display real storage (up to 16 bytes, or until end of page) */
733 /* Prefixes display by Rxxxxx: if draflag is 1 */
734 /* Returns number of characters placed in display buffer */
735 /*-------------------------------------------------------------------*/
ARCH_DEP(display_real)736 static int ARCH_DEP(display_real) (REGS *regs, RADR raddr, char *buf,
737 int draflag)
738 {
739 RADR aaddr; /* Absolute storage address */
740 int i, j; /* Loop counters */
741 int n = 0; /* Number of bytes in buffer */
742 char hbuf[40]; /* Hexadecimal buffer */
743 BYTE cbuf[17]; /* Character buffer */
744 BYTE c; /* Character work area */
745
746 #if defined(FEATURE_INTERVAL_TIMER)
747 if(ITIMER_ACCESS(raddr,16))
748 ARCH_DEP(store_int_timer)(regs);
749 #endif
750
751 if (draflag)
752 {
753 n = sprintf (buf, "R:"F_RADR":", raddr);
754 }
755
756 aaddr = APPLY_PREFIXING (raddr, regs->PX);
757 if (aaddr > regs->mainlim)
758 {
759 n += sprintf (buf+n, " Real address is not valid");
760 return n;
761 }
762
763 n += sprintf (buf+n, "K:%2.2X=", STORAGE_KEY(aaddr, regs));
764
765 memset (hbuf, SPACE, sizeof(hbuf));
766 memset (cbuf, SPACE, sizeof(cbuf));
767
768 for (i = 0, j = 0; i < 16; i++)
769 {
770 c = regs->mainstor[aaddr++];
771 j += sprintf (hbuf+j, "%2.2X", c);
772 if ((aaddr & 0x3) == 0x0) hbuf[j++] = SPACE;
773 c = guest_to_host(c);
774 if (!isprint(c)) c = '.';
775 cbuf[i] = c;
776 if ((aaddr & PAGEFRAME_BYTEMASK) == 0x000) break;
777 } /* end for(i) */
778
779 n += sprintf (buf+n, "%36.36s %16.16s", hbuf, cbuf);
780 return n;
781
782 } /* end function display_real */
783
784
785 /*-------------------------------------------------------------------*/
786 /* Display virtual storage (up to 16 bytes, or until end of page) */
787 /* Returns number of characters placed in display buffer */
788 /*-------------------------------------------------------------------*/
ARCH_DEP(display_virt)789 static int ARCH_DEP(display_virt) (REGS *regs, VADR vaddr, char *buf,
790 int ar, int acctype)
791 {
792 RADR raddr; /* Real address */
793 int n; /* Number of bytes in buffer */
794 int stid; /* Segment table indication */
795 U16 xcode; /* Exception code */
796
797 n = sprintf (buf, "%c:"F_VADR":", ar == USE_REAL_ADDR ? 'R' : 'V',
798 vaddr);
799 xcode = ARCH_DEP(virt_to_abs) (&raddr, &stid,
800 vaddr, ar, regs, acctype);
801 if (xcode == 0)
802 {
803 n += ARCH_DEP(display_real) (regs, raddr, buf+n, 0);
804 }
805 else
806 n += sprintf (buf+n," Translation exception %4.4hX",xcode);
807
808 return n;
809
810 } /* end function display_virt */
811
812
813 /*-------------------------------------------------------------------*/
814 /* Disassemble real */
815 /*-------------------------------------------------------------------*/
ARCH_DEP(disasm_stor)816 static void ARCH_DEP(disasm_stor) (REGS *regs, char *opnd)
817 {
818 U64 saddr, eaddr; /* Range start/end addresses */
819 U64 maxadr; /* Highest real storage addr */
820 RADR raddr; /* Real storage address */
821 RADR aaddr; /* Absolute storage address */
822 int stid = -1;
823 int len; /* Number of bytes to alter */
824 int i; /* Loop counter */
825 int ilc;
826 BYTE inst[6]; /* Storage alteration value */
827 BYTE opcode;
828 U16 xcode;
829 char type;
830 char buf[80];
831
832 /* Set limit for address range */
833 #if defined(FEATURE_ESAME)
834 maxadr = 0xFFFFFFFFFFFFFFFFULL;
835 #else /*!defined(FEATURE_ESAME)*/
836 maxadr = 0x7FFFFFFF;
837 #endif /*!defined(FEATURE_ESAME)*/
838
839 while((opnd && *opnd != '\0') &&
840 (*opnd == ' ' || *opnd == '\t'))
841 opnd++;
842
843 if(REAL_MODE(®s->psw))
844 type = 'R';
845 else
846 type = 'V';
847
848 switch(toupper(*opnd)) {
849 case 'R': /* real */
850 case 'V': /* virtual */
851 case 'P': /* primary */
852 case 'H': /* home */
853 type = toupper(*opnd);
854 opnd++;
855 }
856
857 /* Parse the range or alteration operand */
858 len = parse_range (opnd, maxadr, &saddr, &eaddr, NULL);
859 if (len < 0) return;
860
861 /* Display real storage */
862 for (i = 0; i < 999 && saddr <= eaddr; i++)
863 {
864
865 if(type == 'R')
866 raddr = saddr;
867 else
868 {
869 if((xcode = ARCH_DEP(virt_to_abs) (&raddr, &stid, saddr, 0, regs, ACCTYPE_INSTFETCH) ))
870 {
871 logmsg(_("Storage not accessible code = %4.4X\n"), xcode);
872 return;
873 }
874 }
875
876 aaddr = APPLY_PREFIXING (raddr, regs->PX);
877 if (aaddr > regs->mainlim)
878 {
879 logmsg(_("Addressing exception\n"));
880 return;
881 }
882
883 opcode = regs->mainstor[aaddr];
884 ilc = ILC(opcode);
885
886 if (aaddr + ilc > regs->mainlim)
887 {
888 logmsg(_("Addressing exception\n"));
889 return;
890 }
891
892 memcpy(inst, regs->mainstor + aaddr, ilc);
893 logmsg("%c" F_RADR ": %2.2X%2.2X",
894 stid == TEA_ST_PRIMARY ? 'P' :
895 stid == TEA_ST_HOME ? 'H' :
896 stid == TEA_ST_SECNDRY ? 'S' : 'R',
897 raddr, inst[0], inst[1]);
898 if(ilc > 2)
899 {
900 logmsg("%2.2X%2.2X", inst[2], inst[3]);
901 if(ilc > 4)
902 logmsg("%2.2X%2.2X ", inst[4], inst[5]);
903 else
904 logmsg(" ");
905 }
906 else
907 logmsg(" ");
908 DISASM_INSTRUCTION(inst, buf);
909 logmsg("%s\n", buf);
910 saddr += ilc;
911 } /* end for(i) */
912
913 } /* end function disasm_stor */
914
915
916 /*-------------------------------------------------------------------*/
917 /* Process real storage alter/display command */
918 /*-------------------------------------------------------------------*/
ARCH_DEP(alter_display_real)919 static void ARCH_DEP(alter_display_real) (char *opnd, REGS *regs)
920 {
921 U64 saddr, eaddr; /* Range start/end addresses */
922 U64 maxadr; /* Highest real storage addr */
923 RADR raddr; /* Real storage address */
924 RADR aaddr; /* Absolute storage address */
925 int len; /* Number of bytes to alter */
926 int i; /* Loop counter */
927 BYTE newval[32]; /* Storage alteration value */
928 char buf[100]; /* Message buffer */
929
930 /* Set limit for address range */
931 #if defined(FEATURE_ESAME)
932 maxadr = 0xFFFFFFFFFFFFFFFFULL;
933 #else /*!defined(FEATURE_ESAME)*/
934 maxadr = 0x7FFFFFFF;
935 #endif /*!defined(FEATURE_ESAME)*/
936
937 /* Parse the range or alteration operand */
938 len = parse_range (opnd, maxadr, &saddr, &eaddr, newval);
939 if (len < 0) return;
940 raddr = saddr;
941
942 /* Alter real storage */
943 if (len > 0)
944 {
945 for (i = 0; i < len && raddr+i <= regs->mainlim; i++)
946 {
947 aaddr = raddr + i;
948 aaddr = APPLY_PREFIXING (aaddr, regs->PX);
949 regs->mainstor[aaddr] = newval[i];
950 STORAGE_KEY(aaddr, regs) |= (STORKEY_REF | STORKEY_CHANGE);
951 } /* end for(i) */
952
953 }
954
955 /* Display real storage */
956 for (i = 0; i < 999 && raddr <= eaddr; i++)
957 {
958 ARCH_DEP(display_real) (regs, raddr, buf, 1);
959 logmsg ("%s\n", buf);
960 raddr += 16;
961 } /* end for(i) */
962
963 } /* end function alter_display_real */
964
965
966 /*-------------------------------------------------------------------*/
967 /* Process virtual storage alter/display command */
968 /*-------------------------------------------------------------------*/
ARCH_DEP(alter_display_virt)969 static void ARCH_DEP(alter_display_virt) (char *opnd, REGS *regs)
970 {
971 U64 saddr, eaddr; /* Range start/end addresses */
972 U64 maxadr; /* Highest virt storage addr */
973 VADR vaddr; /* Virtual storage address */
974 RADR raddr; /* Real storage address */
975 RADR aaddr; /* Absolute storage address */
976 int stid; /* Segment table indication */
977 int len; /* Number of bytes to alter */
978 int i; /* Loop counter */
979 int n; /* Number of bytes in buffer */
980 int arn = 0; /* Access register number */
981 U16 xcode; /* Exception code */
982 BYTE newval[32]; /* Storage alteration value */
983 char buf[100]; /* Message buffer */
984
985 /* Set limit for address range */
986 #if defined(FEATURE_ESAME)
987 maxadr = 0xFFFFFFFFFFFFFFFFULL;
988 #else /*!defined(FEATURE_ESAME)*/
989 maxadr = 0x7FFFFFFF;
990 #endif /*!defined(FEATURE_ESAME)*/
991
992 while((opnd && *opnd != '\0') &&
993 (*opnd == ' ' || *opnd == '\t'))
994 opnd++;
995
996 switch(toupper(*opnd))
997 {
998 case 'P': /* primary */
999 arn = USE_PRIMARY_SPACE;
1000 opnd++;
1001 break;
1002 case 'S': /* secondary */
1003 arn = USE_SECONDARY_SPACE;
1004 opnd++;
1005 break;
1006 case 'H': /* home */
1007 arn = USE_HOME_SPACE;
1008 opnd++;
1009 break;
1010 }
1011
1012 /* Parse the range or alteration operand */
1013 len = parse_range (opnd, maxadr, &saddr, &eaddr, newval);
1014 if (len < 0) return;
1015 vaddr = saddr;
1016
1017 /* Alter virtual storage */
1018 if (len > 0
1019 && ARCH_DEP(virt_to_abs) (&raddr, &stid, vaddr, arn,
1020 regs, ACCTYPE_LRA) == 0
1021 && ARCH_DEP(virt_to_abs) (&raddr, &stid, eaddr, arn,
1022 regs, ACCTYPE_LRA) == 0)
1023 {
1024 for (i = 0; i < len && raddr+i <= regs->mainlim; i++)
1025 {
1026 ARCH_DEP(virt_to_abs) (&raddr, &stid, vaddr+i, arn,
1027 regs, ACCTYPE_LRA);
1028 aaddr = APPLY_PREFIXING (raddr, regs->PX);
1029 regs->mainstor[aaddr] = newval[i];
1030 STORAGE_KEY(aaddr, regs) |= (STORKEY_REF | STORKEY_CHANGE);
1031 } /* end for(i) */
1032 }
1033
1034 /* Display virtual storage */
1035 for (i = 0; i < 999 && vaddr <= eaddr; i++)
1036 {
1037 if (i == 0 || (vaddr & PAGEFRAME_BYTEMASK) < 16)
1038 {
1039 xcode = ARCH_DEP(virt_to_abs) (&raddr, &stid, vaddr, arn,
1040 regs, ACCTYPE_LRA);
1041 n = sprintf (buf, "V:"F_VADR" ", vaddr);
1042 if (REAL_MODE(®s->psw))
1043 n += sprintf (buf+n, "(dat off)");
1044 else if (stid == TEA_ST_PRIMARY)
1045 n += sprintf (buf+n, "(primary)");
1046 else if (stid == TEA_ST_SECNDRY)
1047 n += sprintf (buf+n, "(secondary)");
1048 else if (stid == TEA_ST_HOME)
1049 n += sprintf (buf+n, "(home)");
1050 else
1051 n += sprintf (buf+n, "(AR%2.2d)", arn);
1052 if (xcode == 0)
1053 n += sprintf (buf+n, " R:"F_RADR, raddr);
1054 logmsg ("%s\n", buf);
1055 }
1056 ARCH_DEP(display_virt) (regs, vaddr, buf, arn, ACCTYPE_LRA);
1057 logmsg ("%s\n", buf);
1058 vaddr += 16;
1059 } /* end for(i) */
1060
1061 } /* end function alter_display_virt */
1062
1063
1064 /*-------------------------------------------------------------------*/
1065 /* Display instruction */
1066 /*-------------------------------------------------------------------*/
ARCH_DEP(display_inst)1067 void ARCH_DEP(display_inst) (REGS *iregs, BYTE *inst)
1068 {
1069 QWORD qword; /* Doubleword work area */
1070 BYTE opcode; /* Instruction operation code*/
1071 int ilc; /* Instruction length */
1072 #ifdef DISPLAY_INSTRUCTION_OPERANDS
1073 int b1=-1, b2=-1, x1; /* Register numbers */
1074 VADR addr1 = 0, addr2 = 0; /* Operand addresses */
1075 #endif /*DISPLAY_INSTRUCTION_OPERANDS*/
1076 char buf[256]; /* Message buffer */
1077 int n; /* Number of bytes in buffer */
1078 REGS *regs; /* Copied regs */
1079
1080 if (iregs->ghostregs)
1081 regs = iregs;
1082 else if ((regs = copy_regs(iregs)) == NULL)
1083 return;
1084
1085 #if defined(_FEATURE_SIE)
1086 if(SIE_MODE(regs))
1087 logmsg(_("SIE: "));
1088 #endif /*defined(_FEATURE_SIE)*/
1089
1090 #if 0
1091 #if _GEN_ARCH == 370
1092 logmsg("S/370 ");
1093 #elif _GEN_ARCH == 390
1094 logmsg("ESA/390 ");
1095 #else
1096 logmsg("Z/Arch ");
1097 #endif
1098 #endif
1099
1100 /* Display the PSW */
1101 memset (qword, 0x00, sizeof(qword));
1102 copy_psw (regs, qword);
1103 if(sysblk.cpus>1)
1104 {
1105 n=sprintf(buf,"CPU%4.4X: ",regs->cpuad);
1106 }
1107 else
1108 {
1109 n=0;
1110 }
1111 n += sprintf (buf+n,
1112 "PSW=%2.2X%2.2X%2.2X%2.2X %2.2X%2.2X%2.2X%2.2X ",
1113 qword[0], qword[1], qword[2], qword[3],
1114 qword[4], qword[5], qword[6], qword[7]);
1115 #if defined(FEATURE_ESAME)
1116 n += sprintf (buf + n,
1117 "%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X ",
1118 qword[8], qword[9], qword[10], qword[11],
1119 qword[12], qword[13], qword[14], qword[15]);
1120 #endif /*defined(FEATURE_ESAME)*/
1121
1122 /* Exit if instruction is not valid */
1123 if (inst == NULL)
1124 {
1125 logmsg (_("%sInstruction fetch error\n"), buf);
1126 display_regs (regs);
1127 if (!iregs->ghostregs) free(regs);
1128 return;
1129 }
1130
1131 /* Extract the opcode and determine the instruction length */
1132 opcode = inst[0];
1133 ilc = ILC(opcode);
1134
1135 /* Show registers associated with the instruction */
1136 if (sysblk.showregsfirst)
1137 display_inst_regs (regs, inst, opcode);
1138
1139 /* Display the instruction */
1140 n += sprintf (buf+n, "INST=%2.2X%2.2X", inst[0], inst[1]);
1141 if (ilc > 2) n += sprintf (buf+n, "%2.2X%2.2X", inst[2], inst[3]);
1142 if (ilc > 4) n += sprintf (buf+n, "%2.2X%2.2X", inst[4], inst[5]);
1143 logmsg ("%s %s", buf,(ilc<4) ? " " : (ilc<6) ? " " : "");
1144 DISASM_INSTRUCTION(inst, buf);
1145 logmsg("%s\n", buf);
1146
1147 #ifdef DISPLAY_INSTRUCTION_OPERANDS
1148
1149 /* Process the first storage operand */
1150 if (ilc > 2
1151 && opcode != 0x84 && opcode != 0x85
1152 && opcode != 0xA5 && opcode != 0xA7
1153 && opcode != 0xB3
1154 && opcode != 0xC0 && opcode != 0xC4 && opcode != 0xC6
1155 && opcode != 0xEC)
1156 {
1157 /* Calculate the effective address of the first operand */
1158 b1 = inst[2] >> 4;
1159 addr1 = ((inst[2] & 0x0F) << 8) | inst[3];
1160 if (b1 != 0)
1161 {
1162 addr1 += regs->GR(b1);
1163 addr1 &= ADDRESS_MAXWRAP(regs);
1164 }
1165
1166 /* Apply indexing for RX/RXE/RXF instructions */
1167 if ((opcode >= 0x40 && opcode <= 0x7F) || opcode == 0xB1
1168 || opcode == 0xE3 || opcode == 0xED)
1169 {
1170 x1 = inst[1] & 0x0F;
1171 if (x1 != 0)
1172 {
1173 addr1 += regs->GR(x1);
1174 addr1 &= ADDRESS_MAXWRAP(regs);
1175 }
1176 }
1177 }
1178
1179 /* Process the second storage operand */
1180 if (ilc > 4
1181 && opcode != 0xC0 && opcode != 0xC4 && opcode != 0xC6
1182 && opcode != 0xE3 && opcode != 0xEB
1183 && opcode != 0xEC && opcode != 0xED)
1184 {
1185 /* Calculate the effective address of the second operand */
1186 b2 = inst[4] >> 4;
1187 addr2 = ((inst[4] & 0x0F) << 8) | inst[5];
1188 if (b2 != 0)
1189 {
1190 addr2 += regs->GR(b2);
1191 addr2 &= ADDRESS_MAXWRAP(regs);
1192 }
1193 }
1194
1195 /* Calculate the operand addresses for MVCL(E) and CLCL(E) */
1196 if (opcode == 0x0E || opcode == 0x0F
1197 || opcode == 0xA8 || opcode == 0xA9)
1198 {
1199 b1 = inst[1] >> 4;
1200 addr1 = regs->GR(b1) & ADDRESS_MAXWRAP(regs);
1201 b2 = inst[1] & 0x0F;
1202 addr2 = regs->GR(b2) & ADDRESS_MAXWRAP(regs);
1203 }
1204
1205 /* Calculate the operand addresses for RRE instructions */
1206 if ((opcode == 0xB2 &&
1207 ((inst[1] >= 0x20 && inst[1] <= 0x2F)
1208 || (inst[1] >= 0x40 && inst[1] <= 0x6F)
1209 || (inst[1] >= 0xA0 && inst[1] <= 0xAF)))
1210 || opcode == 0xB9)
1211 {
1212 b1 = inst[3] >> 4;
1213 addr1 = regs->GR(b1) & ADDRESS_MAXWRAP(regs);
1214 b2 = inst[3] & 0x0F;
1215 if (inst[1] >= 0x29 && inst[1] <= 0x2C)
1216 addr2 = regs->GR(b2) & ADDRESS_MAXWRAP_E(regs);
1217 else
1218 if (inst[1] >= 0x29 && inst[1] <= 0x2C)
1219 addr2 = regs->GR(b2) & ADDRESS_MAXWRAP(regs);
1220 else
1221 addr2 = regs->GR(b2) & ADDRESS_MAXWRAP(regs);
1222 }
1223
1224 /* Calculate the operand address for RIL_A instructions */
1225 if ((opcode == 0xC0 &&
1226 ((inst[1] & 0x0F) == 0x00
1227 || (inst[1] & 0x0F) == 0x04
1228 || (inst[1] & 0x0F) == 0x05))
1229 || opcode == 0xC4
1230 || opcode == 0xC6)
1231 {
1232 S64 offset = 2LL*(S32)(fetch_fw(inst+2));
1233 addr1 = (likely(!regs->execflag)) ?
1234 PSW_IA(regs, offset) : \
1235 (regs->ET + offset) & ADDRESS_MAXWRAP(regs);
1236 b1 = 0;
1237 }
1238
1239 /* Display storage at first storage operand location */
1240 if (b1 >= 0)
1241 {
1242 if(REAL_MODE(®s->psw))
1243 n = ARCH_DEP(display_virt) (regs, addr1, buf, USE_REAL_ADDR,
1244 ACCTYPE_READ);
1245 else
1246 n = ARCH_DEP(display_virt) (regs, addr1, buf, b1,
1247 (opcode == 0x44
1248 #if defined(FEATURE_EXECUTE_EXTENSIONS_FACILITY)
1249 || (opcode == 0xc6 && !(inst[1] & 0x0f))
1250 #endif /*defined(FEATURE_EXECUTE_EXTENSIONS_FACILITY)*/
1251 ? ACCTYPE_INSTFETCH :
1252 opcode == 0xB1 ? ACCTYPE_LRA :
1253 ACCTYPE_READ));
1254 if(sysblk.cpus>1)
1255 {
1256 logmsg ("CPU%4.4X: ", regs->cpuad);
1257 }
1258 logmsg ("%s\n", buf);
1259 }
1260
1261 /* Display storage at second storage operand location */
1262 if (b2 >= 0)
1263 {
1264 if(
1265 (REAL_MODE(®s->psw)
1266 || (opcode == 0xB2 && inst[1] == 0x4B) /*LURA*/
1267 || (opcode == 0xB2 && inst[1] == 0x46) /*STURA*/
1268 || (opcode == 0xB9 && inst[1] == 0x05) /*LURAG*/
1269 || (opcode == 0xB9 && inst[1] == 0x25))) /*STURG*/
1270 n = ARCH_DEP(display_virt) (regs, addr2, buf, USE_REAL_ADDR,
1271 ACCTYPE_READ);
1272 else
1273 n = ARCH_DEP(display_virt) (regs, addr2, buf, b2,
1274 ACCTYPE_READ);
1275
1276 if(sysblk.cpus>1)
1277 {
1278 logmsg ("CPU%4.4X: ", regs->cpuad);
1279 }
1280 logmsg ("%s\n", buf);
1281 }
1282
1283 #endif /*DISPLAY_INSTRUCTION_OPERANDS*/
1284
1285 /* Show registers associated with the instruction */
1286 if (!sysblk.showregsfirst && !sysblk.showregsnone)
1287 display_inst_regs (regs, inst, opcode);
1288
1289 if (!iregs->ghostregs)
1290 free (regs);
1291
1292 } /* end function display_inst */
1293
1294
1295 #if !defined(_GEN_ARCH)
1296
1297 #if defined(_ARCHMODE2)
1298 #define _GEN_ARCH _ARCHMODE2
1299 #include "hscmisc.c"
1300 #endif
1301
1302 #if defined(_ARCHMODE3)
1303 #undef _GEN_ARCH
1304 #define _GEN_ARCH _ARCHMODE3
1305 #include "hscmisc.c"
1306 #endif
1307
1308
1309 /*-------------------------------------------------------------------*/
1310 /* Wrappers for architecture-dependent functions */
1311 /*-------------------------------------------------------------------*/
alter_display_real(char * opnd,REGS * regs)1312 void alter_display_real (char *opnd, REGS *regs)
1313 {
1314 switch(sysblk.arch_mode) {
1315 #if defined(_370)
1316 case ARCH_370:
1317 s370_alter_display_real (opnd, regs); break;
1318 #endif
1319 #if defined(_390)
1320 case ARCH_390:
1321 s390_alter_display_real (opnd, regs); break;
1322 #endif
1323 #if defined(_900)
1324 case ARCH_900:
1325 z900_alter_display_real (opnd, regs); break;
1326 #endif
1327 }
1328
1329 } /* end function alter_display_real */
1330
1331
alter_display_virt(char * opnd,REGS * iregs)1332 void alter_display_virt (char *opnd, REGS *iregs)
1333 {
1334 REGS *regs;
1335
1336 if (iregs->ghostregs)
1337 regs = iregs;
1338 else if ((regs = copy_regs(iregs)) == NULL)
1339 return;
1340
1341 switch(sysblk.arch_mode) {
1342 #if defined(_370)
1343 case ARCH_370:
1344 s370_alter_display_virt (opnd, regs); break;
1345 #endif
1346 #if defined(_390)
1347 case ARCH_390:
1348 s390_alter_display_virt (opnd, regs); break;
1349 #endif
1350 #if defined(_900)
1351 case ARCH_900:
1352 z900_alter_display_virt (opnd, regs); break;
1353 #endif
1354 }
1355
1356 if (!iregs->ghostregs)
1357 free(regs);
1358 } /* end function alter_display_virt */
1359
1360
display_inst(REGS * iregs,BYTE * inst)1361 void display_inst(REGS *iregs, BYTE *inst)
1362 {
1363 REGS *regs;
1364
1365 if (iregs->ghostregs)
1366 regs = iregs;
1367 else if ((regs = copy_regs(iregs)) == NULL)
1368 return;
1369
1370 switch(regs->arch_mode) {
1371 #if defined(_370)
1372 case ARCH_370:
1373 s370_display_inst(regs,inst);
1374 break;
1375 #endif
1376 #if defined(_390)
1377 case ARCH_390:
1378 s390_display_inst(regs,inst);
1379 break;
1380 #endif
1381 #if defined(_900)
1382 case ARCH_900:
1383 z900_display_inst(regs,inst);
1384 break;
1385 #endif
1386 }
1387
1388 if (!iregs->ghostregs)
1389 free (regs);
1390 }
1391
1392
disasm_stor(REGS * iregs,char * opnd)1393 void disasm_stor(REGS *iregs, char *opnd)
1394 {
1395 REGS *regs;
1396
1397 if (iregs->ghostregs)
1398 regs = iregs;
1399 else if ((regs = copy_regs(iregs)) == NULL)
1400 return;
1401
1402 switch(regs->arch_mode) {
1403 #if defined(_370)
1404 case ARCH_370:
1405 s370_disasm_stor(regs,opnd);
1406 break;
1407 #endif
1408 #if defined(_390)
1409 case ARCH_390:
1410 s390_disasm_stor(regs,opnd);
1411 break;
1412 #endif
1413 #if defined(_900)
1414 case ARCH_900:
1415 z900_disasm_stor(regs,opnd);
1416 break;
1417 #endif
1418 }
1419
1420 if (!iregs->ghostregs)
1421 free(regs);
1422 }
1423
1424 /*-------------------------------------------------------------------*/
1425 /* Execute a Unix or Windows command */
1426 /* Returns the system command status code */
1427 /*-------------------------------------------------------------------*/
herc_system(char * command)1428 int herc_system (char* command)
1429 {
1430
1431 #if HOW_TO_IMPLEMENT_SH_COMMAND == USE_ANSI_SYSTEM_API_FOR_SH_COMMAND
1432
1433 return system(command);
1434
1435 #elif HOW_TO_IMPLEMENT_SH_COMMAND == USE_W32_POOR_MANS_FORK
1436
1437 #define SHELL_CMD_SHIM_PGM "conspawn "
1438
1439 int rc = (int)(strlen(SHELL_CMD_SHIM_PGM) + strlen(command) + 1);
1440 char* pszNewCommandLine = malloc( rc );
1441 strlcpy( pszNewCommandLine, SHELL_CMD_SHIM_PGM, rc );
1442 strlcat( pszNewCommandLine, command, rc );
1443 rc = w32_poor_mans_fork( pszNewCommandLine, NULL );
1444 free( pszNewCommandLine );
1445 return rc;
1446
1447 #elif HOW_TO_IMPLEMENT_SH_COMMAND == USE_FORK_API_FOR_SH_COMMAND
1448
1449 extern char **environ;
1450 int pid, status;
1451
1452 if (command == 0)
1453 return 1;
1454
1455 pid = fork();
1456
1457 if (pid == -1)
1458 return -1;
1459
1460 if (pid == 0)
1461 {
1462 char *argv[4];
1463
1464 /* Redirect stderr (screen) to hercules log task */
1465 dup2(STDOUT_FILENO, STDERR_FILENO);
1466
1467 /* Drop ROOT authority (saved uid) */
1468 SETMODE(TERM);
1469 DROP_ALL_CAPS();
1470
1471 argv[0] = "sh";
1472 argv[1] = "-c";
1473 argv[2] = command;
1474 argv[3] = 0;
1475 execve("/bin/sh", argv, environ);
1476
1477 exit(127);
1478 }
1479
1480 do
1481 {
1482 if (waitpid(pid, &status, 0) == -1)
1483 {
1484 if (errno != EINTR)
1485 return -1;
1486 } else
1487 return status;
1488 } while(1);
1489 #else
1490 #error 'HOW_TO_IMPLEMENT_SH_COMMAND' not #defined correctly
1491 #endif
1492 } /* end function herc_system */
1493
1494 #endif /*!defined(_GEN_ARCH)*/
1495