1 /* VM.C         (c) Copyright Roger Bowler, 2000-2009                */
2 /*              ESA/390 VM Diagnose calls and IUCV instruction       */
3 
4 /* Interpretive Execution - (c) Copyright Jan Jaeger, 1999-2009      */
5 
6 /*-------------------------------------------------------------------*/
7 /* This module implements miscellaneous diagnose functions           */
8 /* described in SC24-5670 VM/ESA CP Programming Services             */
9 /* and SC24-5855 VM/ESA CP Diagnosis Reference                       */
10 /* and SC24-6084 z/VM 5.4 CP Programming Services.                   */
11 /*      Modifications for Interpretive Execution (SIE) by Jan Jaeger */
12 /* z/Architecture support - (c) Copyright Jan Jaeger, 1999-2009      */
13 /*-------------------------------------------------------------------*/
14 
15 #include "hstdinc.h"
16 
17 #if !defined(_HENGINE_DLL_)
18 #define _HENGINE_DLL_
19 #endif /*_HENGINE_DLL_*/
20 
21 #if !defined(_VM_C_)
22 #define _VM_C_
23 #endif /* _VM_C_ */
24 
25 #include "hercules.h"
26 #include "opcode.h"
27 #include "inline.h"
28 #include "commadpt.h"
29 
30 #if defined(FEATURE_EMULATE_VM)
31 
32 #if !defined(_VM_C)
33 #define _VM_C
34 
35 /*-------------------------------------------------------------------*/
36 /* Internal macro definitions                                        */
37 /*-------------------------------------------------------------------*/
38 #define DEV024(_type,_cls,_typ) \
39        { _type,_cls,_typ,0xC0 }
40 #define DEV210(_type,_cls,_typ) \
41        { _type,_cls,_typ,0x40 }
42 
43 /*-------------------------------------------------------------------*/
44 /* Synchronous Block I/O Parameter List                              */
45 /*-------------------------------------------------------------------*/
46 typedef struct _HCPSBIOP {
47         HWORD   devnum;                 /* Device number             */
48         BYTE    akey;                   /* Bits 0-3=key, 4-7=zeroes  */
49         BYTE    type;                   /* I/O request type          */
50         FWORD   blksize;                /* Fixed block size          */
51         FWORD   sbiaddr;                /* Address of SBILIST        */
52         FWORD   sbicount;               /* Number of SBILIST entries */
53         FWORD   blkcount;               /* Number of blocks processed*/
54         BYTE    unitstat;               /* Device status             */
55         BYTE    chanstat;               /* Subchannel status         */
56         HWORD   residual;               /* Residual byte count       */
57         BYTE    lpm;                    /* Logical path mask         */
58         BYTE    resv1[5];               /* Reserved bytes, must be 0 */
59         HWORD   sensecount;             /* Number of sense bytes     */
60         BYTE    resv2[24];              /* Reserved bytes, must be 0 */
61         BYTE    sense[32];              /* Sense bytes               */
62     } HCPSBIOP;
63 
64 /* Definitions for I/O request type */
65 #define HCPSBIOP_WRITE        0x01
66 #define HCPSBIOP_READ         0x02
67 
68 /*-------------------------------------------------------------------*/
69 /* Synchronous General I/O Parameter List                            */
70 /*-------------------------------------------------------------------*/
71 typedef struct _HCPSGIOP {
72         HWORD   devnum;                 /* Device number             */
73         BYTE    akey;                   /* Bits 0-3=key, 4-7=zeroes  */
74         BYTE    flag;                   /* Flags                     */
75         FWORD   resv1;                  /* Reserved word, must be 0  */
76         FWORD   ccwaddr;                /* Address of channel program*/
77         FWORD   resv2;                  /* Reserved word, must be 0  */
78         FWORD   lastccw;                /* CCW address at interrupt  */
79         BYTE    unitstat;               /* Device status             */
80         BYTE    chanstat;               /* Subchannel status         */
81         HWORD   residual;               /* Residual byte count       */
82         BYTE    lpm;                    /* Logical path mask         */
83         BYTE    resv3[5];               /* Reserved bytes, must be 0 */
84         HWORD   sensecount;             /* Number of sense bytes     */
85         BYTE    resv4[24];              /* Reserved bytes, must be 0 */
86         BYTE    sense[32];              /* Sense bytes               */
87     } HCPSGIOP;
88 
89 /* Bit definitions for flags */
90 #define HCPSGIOP_FORMAT1_CCW  0x80      /* 1=Format-1 CCW            */
91 #define HCPSGIOP_FLAG_RESV    0x7F      /* Reserved bits, must be 0  */
92 
93 /*-------------------------------------------------------------------*/
94 /* DIAGNOSE X'24' and DIAGNOSE X'210' Structures and Table           */
95 /*-------------------------------------------------------------------*/
96 
97 /* VM Device Class Definitions */
98 #define DC_TERM 0x80
99 #define DC_GRAF 0x40
100 #define DC_URI  0x20
101 #define DC_URO  0x10
102 #define DC_TAPE 0x08
103 #define DC_DASD 0x04
104 #define DC_SPEC 0x02
105 #define DC_FBA  0x01
106 
107 /* VM Device Type Definitions */
108 #define DT_CTCA 0x80
109 #define DT_FBA  0x00
110 #define DT_OSA  0x20 /* Not yet supported */
111 #define DT_UNKN 0x01
112 #define DT_0671 0x20
113 #define DT_1052 0x00
114 #define DT_1403 0x41
115 #define DT_1442 0x88
116 #define DT_2305 0x02
117 #define DT_2311 0x80
118 #define DT_2314 0x40
119 #define DT_2501 0x81
120 #define DT_2703 0x40
121 #define DT_3211 0x42
122 #define DT_3215 0x00
123 #define DT_3277 0x04
124 #define DT_3287 0x02
125 #define DT_3310 0x01
126 #define DT_3330 0x10
127 #define DT_3340 0x01
128 #define DT_3350 0x08
129 #define DT_3370 0x02
130 #define DT_3375 0x04
131 #define DT_3380 0x20
132 #define DT_3390 0x82
133 #define DT_3410 0x08
134 #define DT_3420 0x10
135 #define DT_3422 0x82
136 #define DT_3430 0x02
137 #define DT_3480 0x01
138 #define DT_3490 0x81
139 #define DT_3505 0x84
140 #define DT_3525 0x84
141 #define DT_3590 0x83
142 #define DT_370x 0x40
143 #define DT_8809 0x04
144 #define DT_9332 0x08
145 #define DT_9335 0x04
146 #define DT_9336 0x40
147 #define DT_9345 0x81
148 #define DT_9347 0x84
149 
150 /* VM Virtual Device Status Definitions */
151 #define DS_DED    0x01    /* Dedicated device          */
152 #define DS_BUSY   0x20    /* Device is busy            */
153 
154 /* VM Virtual Device Flag Definitions */
155 #define DF_ENA     0x80   /* 270x line enabled         */
156 #define DF_CONN    0x40   /* 270x line connected       */
157 #define DF_RSRL    0x02   /* Reserve/Release supported */
158 #define DF_MIDAW   0x01   /* MIDAW's supported         */
159 
160 /* VM Real Device Features */
161 #define DRF_RPS    0x80  /* Device has RPS             */
162 #define DRF_EXTSNS 0x40  /* Extended Sense             */
163 #define DRF_CTCA   0x40  /* CTCA device                */
164 #define DRF_35M    0x08  /* 3340 has 35M data module   */
165 #define DRF_70M    0x04  /* 3340 has 70M data module   */
166 #define DRF_RSRL   0x02  /* Reserve/Release valid      */
167 
168 /*-------------------------------------------------------------------*/
169 /* Hercules-to-VM Device Table                                       */
170 /*-------------------------------------------------------------------*/
171 typedef struct _VMDEVTBL {
172         U16     vmhtype;                /* Hercules device type      */
173         BYTE    vmdevcls;               /* VM Device Class           */
174         BYTE    vmdevtyp;               /* VM Device Type            */
175         BYTE    vmdiags;                /* DIAGS recognizing device  */
176 #define VMDIAG024 0x80   /* Device recognized by DIAGNOSE X'24'      */
177 #define VMDIAG210 0x40   /* Device recognized by DIAGNOSE X'210'     */
178     } VMDEVTBL;
179 #define VMDEV_SIZE sizeof(VMDEVTBL)
180 
181 static VMDEVTBL vmdev[] = {
182    DEV024(0x0671,DC_FBA, DT_0671),
183    DEV024(0x1052,DC_TERM,DT_1052),
184    DEV024(0x1403,DC_URO, DT_1403),
185    DEV024(0x1442,DC_URI, DT_1442),
186    DEV024(0x2305,DC_DASD,DT_2305),
187    DEV024(0x2311,DC_DASD,DT_2311),
188    DEV024(0x2314,DC_DASD,DT_2314),
189    DEV024(0x2501,DC_URI, DT_2501),
190    DEV024(0x2703,DC_TERM,DT_2703),
191    DEV024(0x3088,DC_SPEC,DT_CTCA),
192    DEV024(0x3211,DC_URI, DT_3211),
193    DEV024(0x3215,DC_TERM,DT_3215),
194    DEV024(0x3270,DC_GRAF,DT_3277),
195    DEV024(0x3287,DC_GRAF,DT_3287),
196    DEV024(0x3310,DC_FBA, DT_3310),
197    DEV024(0x3330,DC_DASD,DT_3330),
198    DEV024(0x3340,DC_DASD,DT_3340),
199    DEV024(0x3350,DC_DASD,DT_3350),
200    DEV024(0x3370,DC_FBA, DT_3370),
201    DEV024(0x3375,DC_DASD,DT_3375),
202    DEV024(0x3380,DC_DASD,DT_3380),
203    DEV210(0x3390,DC_DASD,DT_3390),
204    DEV024(0x3410,DC_TAPE,DT_3410),
205    DEV024(0x3420,DC_TAPE,DT_3420),
206    DEV024(0x3422,DC_TAPE,DT_3422),
207    DEV024(0x3430,DC_TAPE,DT_3430),
208    DEV024(0x3480,DC_TAPE,DT_3480),
209    DEV210(0x3490,DC_TAPE,DT_3490),
210    DEV024(0x3505,DC_URI, DT_3505),
211    DEV024(0x3525,DC_URO, DT_3525),
212    DEV024(0x3590,DC_TAPE,DT_3590),
213    DEV024(0x3705,DC_SPEC,DT_370x),
214    DEV024(0x8809,DC_TAPE,DT_8809),
215    DEV024(0x9332,DC_FBA, DT_9332),
216    DEV024(0x9335,DC_FBA, DT_9335),
217    DEV024(0x9336,DC_FBA, DT_9336),
218    DEV210(0x9345,DC_DASD,DT_9345),
219    DEV024(0x9347,DC_TAPE,DT_9347)
220 };
221 #define VMDEV_NUM (sizeof(vmdev)/VMDEV_SIZE)
222 
223 /*-------------------------------------------------------------------*/
224 /* Virtual Device Data                                               */
225 /*-------------------------------------------------------------------*/
226 typedef struct _VRDCVDAT {
227         BYTE    vdevcls;                /* Virtual device class      */
228         BYTE    vdevtyp;                /* Virtual device type       */
229         BYTE    vdevstat;               /* Virtual device status     */
230         BYTE    vdevflag;               /* Virtual device flag       */
231     } VRDCVDAT;
232 
233 /*-------------------------------------------------------------------*/
234 /* Real Device Data                                                  */
235 /*-------------------------------------------------------------------*/
236 typedef struct _VRDCRCDT {
237         BYTE    rdevcls;                /* Real device class         */
238         BYTE    rdevtyp;                /* Real device type          */
239         BYTE    rdevmodl;               /* Real device model         */
240         BYTE    rdevfeat;               /* Real device features      */
241     } VRDCRCDT;
242 
243 /*-------------------------------------------------------------------*/
244 /* Virtual/Real Device Characteristics Block                         */
245 /*-------------------------------------------------------------------*/
246 typedef struct _VRDCBLOK {
247 /*00*/  HWORD    vrdcdvno;       /* Device number                    */
248 /*02*/  HWORD    vrdclen;        /* VRDCBLOK length                  */
249 /*04*/  VRDCVDAT vrdcvdat;       /* Virtual device data              */
250 /*08*/  VRDCRCDT vrdcrcdt;       /* Real device data                 */
251 /*0C*/  BYTE     vrdcundv;       /* Real underlying device           */
252 /*0D*/  BYTE     vrdcrdaf;       /* Real device additional features  */
253 #define VRDCEMRD 0x02            /* No emulated real device          */
254 /*0E*/  HWORD    vrdcrsvd;       /* Reserved - must be zeros         */
255 /*10*/  BYTE     vrdcrdc[64];    /* READ DEVICE CHARACTERISTICS data */
256 /*50*/  BYTE     vrdcpgid[11];   /* Path Group Identifier            */
257 /*5B*/  BYTE     resv5[5];       /* reserved                         */
258 /*60*/  BYTE     vrdcvers;       /* version                          */
259 /*61*/  BYTE     vrdcrsio[31];   /* reserved for Input/Output        */
260 /*80*/  HWORD    vrdcrdev;       /* Real device number               */
261 /*82*/  BYTE     vrdcrsve[126];  /* reserverd                        */
262 /*100*/
263    } VRDCBLOK;
264 #define VRDCBLOK_SIZE sizeof(VRDCBLOK)
265 
266 #endif /*!defined(_VM_C)*/
267 
268 /*-------------------------------------------------------------------*/
269 /* Internal Function Prototypes                                      */
270 /*-------------------------------------------------------------------*/
271 DEVBLK* ARCH_DEP(vmdevice_data)(int, U16, VRDCVDAT *, VRDCRCDT *);
272 
273 /*-------------------------------------------------------------------*/
274 /* Provide VM Virtual and Real Device Data based upon device number  */
275 /*-------------------------------------------------------------------*/
ARCH_DEP(vmdevice_data)276 DEVBLK* ARCH_DEP(vmdevice_data)(int code, U16 devnum, VRDCVDAT *vdat, VRDCRCDT *rdat)
277 {
278 U32      i;                      /* loop index                      */
279 VMDEVTBL *vmentry;               /* -> VMDEVTBL entry found         */
280 DEVBLK   *dev;                   /* -> DEVBLK                       */
281 
282     /* Clear vdat and rdat */
283     memset (vdat, 0x00, sizeof(*vdat));
284     memset (rdat, 0x00, sizeof(*rdat));
285 
286     /* Locate the device block */
287     dev = find_device_by_devnum (0,devnum);
288 
289     /* Return 0 if device is not found */
290     if (!dev)
291        return 0;
292 
293     /* Indicate the device is dedicated - all Hercules devices are */
294     vdat->vdevstat = DS_DED;
295 
296     /* Find the device in the VM table */
297     vmentry=NULL;
298     for (i = 0; i < (int)VMDEV_NUM; i++)
299        {
300 #if 0
301            logmsg ("vmdevice_data: i=%i %4.4X %2.2X %2.2X %2.2X\n",i,
302                    vmdev[i].vmhtype,vmdev[i].vmdevcls,vmdev[i].vmdevtyp,vmdev[i].vmdiags);
303 #endif
304            if (dev->devtype == vmdev[i].vmhtype)
305            {
306                vmentry = &vmdev[i];
307                break;
308            }
309        }
310 #if 0
311     logmsg ("FOUND: %4.4X %2.2X %2.2X %2.2X\n",
312             vmentry->vmhtype,vmentry->vmdevcls,vmentry->vmdevtyp,vmentry->vmdiags);
313 #endif
314 
315     /* If device is not in the table or it isn't recognized by DIAG X'24' */
316     if ( !vmentry || ( code==0x24 && !(vmentry->vmdiags & VMDIAG024 ) ) )
317     {
318         /* Set the real and virtual data to an unsupported device */
319         vdat->vdevcls = DC_SPEC;
320         vdat->vdevtyp = DT_UNKN;
321         rdat->rdevcls = DC_SPEC;
322         rdat->rdevtyp = DT_UNKN;
323         return dev;
324     }
325 
326     /* Set the virtual and real data to the device's VM class and type */
327     vdat->vdevcls = vmentry->vmdevcls;
328     vdat->vdevtyp = vmentry->vmdevtyp;
329     rdat->rdevcls = vmentry->vmdevcls;
330     rdat->rdevtyp = vmentry->vmdevtyp;
331 
332     /* Indicate if the device is busy */
333     if ( (dev->busy && dev->ioactive == DEV_SYS_LOCAL) || dev->startpending )
334         vdat->vdevstat |= DS_BUSY;
335 
336     /* Set virtual device flags, and real device model and features */
337     vdat->vdevflag = 0x00;
338     rdat->rdevmodl = 0x00;
339     rdat->rdevfeat = 0x00;
340 
341     if (dev->hnd->reserve)           /* Indicate if RESERVE/RELEASE supported */
342         vdat->vdevflag |= DF_RSRL;
343 
344 #if defined(FEATURE_MIDAW)
345     /* If DIAGNOSE X'210', indicate if MIDAW's are supported */
346     if (code==0x210)
347         vdat->vdevflag |= DF_MIDAW;
348 #endif /* FEATURE_MIDAW */
349 
350     switch (rdat->rdevcls) {
351     case DC_DASD:
352          if (dev->hnd->reserve)
353             rdat->rdevfeat |= DRF_RSRL;
354          if (dev->numsense==24)
355             rdat->rdevfeat |= DRF_EXTSNS;
356          if (dev->ckdtab->sectors)
357             rdat->rdevfeat |= DRF_RPS;
358          if (dev->devtype == 0x3340)
359          {
360             if (dev->ckdtab->model==0x01)
361                rdat->rdevfeat |= DRF_35M;
362             else
363                rdat->rdevfeat |= DRF_70M;
364          }
365          if ( dev->devtype == 0x3380  && code == 0x24)
366             rdat->rdevmodl = (dev->ckdtab->model & 0x0F) | (dev->ckdcu->model & 0xF0);
367          else
368             rdat->rdevmodl = dev->ckdtab->model;
369          break;
370      case DC_FBA:
371          rdat->rdevmodl = dev->fbatab->model;
372          break;
373      case DC_TERM:
374          if (dev->devtype==0x3215)
375          {
376             rdat->rdevfeat = 0x50;
377             /* Note: 0x50 is carried forward from the previous version of       */
378             /* DIAGNOSE X'24'. The actual meaning was not previously documented */
379          }
380          else
381          {
382             if (dev->devtype==0x2703 && dev->commadpt)
383             {
384                 if (dev->commadpt->enabled)
385                    vdat->vdevflag |= DF_ENA;
386                 if (dev->commadpt->connect)
387                    vdat->vdevflag |= DF_CONN;
388             }
389          }
390          break;
391      case DC_SPEC:
392          if (rdat->rdevtyp==DT_CTCA)
393             rdat->rdevfeat = DRF_CTCA;
394      }
395 
396      /* Return the located DEVBLK to the caller */
397      return dev;
398 
399 } /* end function vmdevice_data */
400 
401 /*-------------------------------------------------------------------*/
402 /* Device Type and Features (Function code 0x024)                    */
403 /*-------------------------------------------------------------------*/
ARCH_DEP(diag_devtype)404 int ARCH_DEP(diag_devtype) (int r1, int r2, REGS *regs)
405 {
406 DEVBLK         *dev;                    /* -> Device block           */
407 U16             devnum;                 /* Device number             */
408 VRDCVDAT        vdat;                   /* Virtual device data       */
409 VRDCRCDT        rdat;                   /* Real device data          */
410 
411 #if defined(FEATURE_ESAME)
412      /* Program check if 64-bit addressing is being used. */
413      if (regs->psw.amode64)
414      {
415          ARCH_DEP(program_interrupt) (regs, PGM_SPECIFICATION_EXCEPTION);
416      }
417 #endif /* FEATURE_ESAME */
418 
419     /* Return console information if R1 register is all ones */
420     if (regs->GR_L(r1) == 0xFFFFFFFF)
421     {
422         for (dev = sysblk.firstdev; dev != NULL; dev = dev->nextdev)
423             if ( dev->allocated
424                  && ( dev->devtype == 0x3215 || dev->devtype == 0x1503 )
425                )
426             {
427                 regs->GR_L(r1) = dev->devnum;
428                 break;
429             }
430     }
431 
432     /* Extract the device number from the R1 register */
433     devnum = regs->GR_L(r1);
434 
435     /* Locate the device block and set the virtual and real device information */
436     dev = ARCH_DEP(vmdevice_data) (0x24,devnum,&vdat,&rdat);
437 
438     /* Return condition code 3 if device does not exist */
439     if (!dev)
440         return 3;
441 
442     /* Return virtual device information in the R2 register */
443     FETCH_FW(regs->GR_L(r2),&vdat);
444 
445     /* Return real device information in the R2+1 register */
446     if (r2 != 15)
447         FETCH_FW(regs->GR_L(r2+1),&rdat);
448 #if 0
449     logmsg ("Diagnose X\'024\':"
450             "devnum=%4.4X VRDCVDAT=%8.8X VRDCRCDT=%8.8X\n",
451             devnum, vdat, rdat);
452 #endif
453 
454     /* Return condition code 0 */
455     return 0;
456 
457 } /* end function diag_devtype */
458 
459 /*-------------------------------------------------------------------*/
460 /* Process Synchronous Fixed Block I/O call (Function code 0x0A4)    */
461 /*-------------------------------------------------------------------*/
ARCH_DEP(syncblk_io)462 int ARCH_DEP(syncblk_io) (int r1, int r2, REGS *regs)
463 {
464 U32             i;                      /* Array subscript           */
465 U32             numsense;               /* Number of sense bytes     */
466 U32             iopaddr;                /* Address of HCPSBIOP       */
467 HCPSBIOP        ioparm;                 /* I/O parameter list        */
468 DEVBLK         *dev;                    /* -> Device block           */
469 U16             devnum;                 /* Device number             */
470 U16             residual;               /* Residual byte count       */
471 U32             blksize;                /* Fixed block size          */
472 U32             sbiaddr;                /* Addr of SBILIST           */
473 U32             sbicount;               /* Number of SBILIST entries */
474 U32             blkcount;               /* Number of blocks processed*/
475 U32             blknum;                 /* Block number              */
476 U32             absadr;                 /* Absolute storage address  */
477 BYTE            accum;                  /* Work area                 */
478 BYTE            unitstat = 0;           /* Device status             */
479 BYTE            chanstat = 0;           /* Subchannel status         */
480 BYTE            skey1, skey2;           /* Storage keys of first and
481                                            last byte of I/O buffer   */
482 //FIXME: code not right for shared devices
483 
484     UNREFERENCED(r2);
485 
486     /* Register R1 contains the real address of the parameter list */
487     iopaddr = regs->GR_L(r1);
488 
489     /* Program check if parameter list not on fullword boundary */
490     if (iopaddr & 0x00000003)
491     {
492         ARCH_DEP(program_interrupt) (regs, PGM_SPECIFICATION_EXCEPTION);
493         return 0;
494     }
495 
496     /* Ensure that parameter list operand is addressable */
497     ARCH_DEP(validate_operand) (iopaddr, USE_REAL_ADDR, sizeof(ioparm)-1,
498                         ACCTYPE_WRITE, regs);
499 
500     /* Fetch the parameter list from real storage */
501     ARCH_DEP(vfetchc) (&ioparm, sizeof(ioparm)-1, iopaddr, USE_REAL_ADDR, regs);
502 
503     /* Load numeric fields from the parameter list */
504     devnum = (ioparm.devnum[0] << 8) | ioparm.devnum[1];
505     blksize = (ioparm.blksize[0] << 24)
506                 | (ioparm.blksize[1] << 16)
507                 | (ioparm.blksize[2] << 8)
508                 | ioparm.blksize[3];
509     sbiaddr = (ioparm.sbiaddr[0] << 24)
510                 | (ioparm.sbiaddr[1] << 16)
511                 | (ioparm.sbiaddr[2] << 8)
512                 | ioparm.sbiaddr[3];
513     sbicount = (ioparm.sbicount[0] << 24)
514                 | (ioparm.sbicount[1] << 16)
515                 | (ioparm.sbicount[2] << 8)
516                 | ioparm.sbicount[3];
517 
518     /* Locate the device block */
519     dev = find_device_by_devnum (0,devnum);
520 
521     /* Set return code 2 and cond code 1 if device does not exist
522        or does not support the synchronous I/O call */
523     if (dev == NULL || dev->devtype != 0x3370)
524     {
525         regs->GR_L(15) = 2;
526         return 1;
527     }
528 
529     /* Program check if protect key bits 4-7 are not zero
530        or if I/O request type is not read or write */
531     if ((ioparm.akey & 0x0F)
532         || !(ioparm.type == HCPSBIOP_WRITE
533             || ioparm.type == HCPSBIOP_READ))
534     {
535         ARCH_DEP(program_interrupt) (regs, PGM_OPERAND_EXCEPTION);
536         return 0;
537     }
538 
539     /* Set return code 8 and cond code 2 if blocksize is invalid */
540     if (!(blksize == 512 || blksize == 1024
541             || blksize == 2048 || blksize == 4096))
542     {
543         regs->GR_L(15) = 8;
544         return 2;
545     }
546 
547     /* Program check if SBILIST is not on a doubleword boundary */
548     if (sbiaddr & 0x00000007)
549     {
550         ARCH_DEP(program_interrupt) (regs, PGM_OPERAND_EXCEPTION);
551         return 0;
552     }
553 
554     /* Program check if reserved fields are not zero */
555     for (accum = 0, i = 0; i < sizeof(ioparm.resv1); i++)
556         accum |= ioparm.resv1[i];
557     for (i = 0; i < sizeof(ioparm.resv2); i++)
558         accum |= ioparm.resv2[i];
559     if (accum != 0)
560     {
561         ARCH_DEP(program_interrupt) (regs, PGM_OPERAND_EXCEPTION);
562         return 0;
563     }
564 
565     /* Set return code 11 and cond code 2 if SBI count is invalid */
566     if (sbicount < 1 || sbicount > 500)
567     {
568         regs->GR_L(15) = 11;
569         return 2;
570     }
571 
572     /* Obtain the device lock */
573     obtain_lock (&dev->lock);
574 
575 #ifdef FEATURE_CHANNEL_SUBSYSTEM
576     /* Return code 5 and condition code 1 if status pending */
577     if ((dev->scsw.flag3 & SCSW3_SC_PEND)
578         || (dev->pciscsw.flag3 & SCSW3_SC_PEND))
579     {
580         release_lock (&dev->lock);
581         regs->GR_L(15) = 5;
582         return 1;
583     }
584 #endif /*FEATURE_CHANNEL_SUBSYSTEM*/
585 
586     /* Return code 5 and condition code 1 if device is busy */
587     if (dev->busy || IOPENDING(dev))
588     {
589         release_lock (&dev->lock);
590         regs->GR_L(15) = 5;
591         return 1;
592     }
593 
594     /* Set the device busy indicator */
595     dev->busy = 1;
596 
597     /* Release the device lock */
598     release_lock (&dev->lock);
599 
600     /* Process each entry in the SBILIST */
601     for (blkcount = 0; blkcount < sbicount; blkcount++)
602     {
603         /* Return code 10 and cond code 2 if SBILIST entry
604            is outside main storage or is fetch protected.
605            Note that the SBI address is an absolute address
606            and is not subject to fetch-protection override
607            or storage-protection override mechanisms, and
608            an SBILIST entry cannot cross a page boundary */
609         if (sbiaddr > regs->mainlim
610             || ((STORAGE_KEY(sbiaddr, regs) & STORKEY_FETCH)
611                 && (STORAGE_KEY(sbiaddr, regs) & STORKEY_KEY) != ioparm.akey
612                 && ioparm.akey != 0))
613         {
614             regs->GR_L(15) = 10;
615             return 2;
616         }
617 
618         /* Load block number and data address from SBILIST */
619         blknum = ARCH_DEP(fetch_fullword_absolute)(sbiaddr, regs);
620         absadr = ARCH_DEP(fetch_fullword_absolute)(sbiaddr+4, regs);
621 
622         if (dev->ccwtrace || dev->ccwstep)
623         {
624             logmsg ("%4.4X:Diagnose X\'0A4\':%s "
625                     "blk=%8.8X adr=%8.8X len=%8.8X\n",
626                     dev->devnum,
627                     (ioparm.type == HCPSBIOP_WRITE ? "WRITE" : "READ"),
628                     blknum, absadr, blksize);
629         }
630 
631         /* Return code 12 and cond code 2 if buffer exceeds storage */
632         if (absadr > regs->mainlim - blksize)
633         {
634             regs->GR_L(15) = 12;
635             return 2;
636         }
637 
638         /* Channel protection check if access key does not match
639            storage keys of buffer.  Note that the buffer address is
640            an absolute address, the buffer cannot span more than two
641            pages, and the access is not subject to fetch-protection
642            override, storage-protection override, or low-address
643            protection */
644         skey1 = STORAGE_KEY(absadr, regs);
645         skey2 = STORAGE_KEY(absadr + blksize - 1, regs);
646         if (ioparm.akey != 0
647             && (
648                    ((skey1 & STORKEY_KEY) != ioparm.akey
649                     && ((skey1 & STORKEY_FETCH)
650                         || ioparm.type == HCPSBIOP_READ))
651                 || ((skey2 & STORKEY_KEY) != ioparm.akey
652                     && ((skey2 & STORKEY_FETCH)
653                         || ioparm.type == HCPSBIOP_READ))
654             ))
655         {
656             chanstat |= CSW_PROTC;
657             break;
658         }
659 
660         /* Call device handler to read or write one block */
661         fbadasd_syncblk_io (dev, ioparm.type, blknum, blksize,
662                             regs->mainstor + absadr,
663                             &unitstat, &residual);
664 
665         /* Set incorrect length if residual count is non-zero */
666         if (residual != 0)
667             chanstat |= CSW_IL;
668 
669         /* Exit if any unusual status */
670         if (unitstat != (CSW_CE | CSW_DE) || chanstat != 0)
671             break;
672 
673         /* Point to next SBILIST entry */
674         sbiaddr += 8;
675 
676     } /* end for(blkcount) */
677 
678     /* Reset the device busy indicator */
679     dev->busy = 0;
680 
681     /* Store the block count in the parameter list */
682     ioparm.blkcount[0] = (blkcount >> 24) & 0xFF;
683     ioparm.blkcount[1] = (blkcount >> 16) & 0xFF;
684     ioparm.blkcount[2] = (blkcount >> 8) & 0xFF;
685     ioparm.blkcount[3] = blkcount & 0xFF;
686 
687     /* Store the device and subchannel status in the parameter list */
688     ioparm.unitstat = unitstat;
689     ioparm.chanstat = chanstat;
690 
691     /* Store the residual byte count in the parameter list */
692     ioparm.residual[0] = (residual >> 8) & 0xFF;
693     ioparm.residual[1] = residual & 0xFF;
694 
695     /* Return sense data if unit check occurred */
696     if (unitstat & CSW_UC)
697     {
698         numsense = dev->numsense;
699         if (numsense > sizeof(ioparm.sense))
700             numsense = sizeof(ioparm.sense);
701         ioparm.sensecount[0] = (numsense >> 8) & 0xFF;
702         ioparm.sensecount[1] = numsense & 0xFF;
703         memcpy (ioparm.sense, dev->sense, numsense);
704     }
705 
706     /* Store the updated parameter list in real storage */
707     ARCH_DEP(vstorec) (&ioparm, sizeof(ioparm)-1, iopaddr, USE_REAL_ADDR, regs);
708 
709     /* If I/O error occurred, set return code 13 and cond code 3 */
710     if (unitstat != (CSW_CE | CSW_DE) || chanstat != 0)
711     {
712         regs->GR_L(15) = 13;
713         return 3;
714     }
715 
716     /* Set return code 0 and cond code 0 */
717     regs->GR_L(15) = 0;
718     return 0;
719 
720 } /* end function syncblk_io */
721 
722 /*-------------------------------------------------------------------*/
723 /* Process Synchronous General I/O call (Function code 0x0A8)        */
724 /*-------------------------------------------------------------------*/
ARCH_DEP(syncgen_io)725 int ARCH_DEP(syncgen_io) (int r1, int r2, REGS *regs)
726 {
727 U32             i;                      /* Array subscript           */
728 U32             numsense;               /* Number of sense bytes     */
729 U32             iopaddr;                /* Address of HCPSGIOP       */
730 HCPSGIOP        ioparm;                 /* I/O parameter list        */
731 DEVBLK         *dev;                    /* -> Device block           */
732 U16             devnum;                 /* Device number             */
733 U16             residual;               /* Residual byte count       */
734 U32             ccwaddr;                /* Address of channel program*/
735 U32             lastccw;                /* CCW address at interrupt  */
736 BYTE            accum;                  /* Work area                 */
737 BYTE            unitstat = 0;           /* Device status             */
738 BYTE            chanstat = 0;           /* Subchannel status         */
739 
740 //FIXME: code not right for shared devices
741 
742     UNREFERENCED(r2);
743 
744     /* Register R1 contains the real address of the parameter list */
745     iopaddr = regs->GR_L(r1);
746 
747     /* Program check if parameter list not on fullword boundary */
748     if (iopaddr & 0x00000003)
749     {
750         ARCH_DEP(program_interrupt) (regs, PGM_SPECIFICATION_EXCEPTION);
751         return 0;
752     }
753 
754     /* Ensure that parameter list operand is addressable */
755     ARCH_DEP(validate_operand) (iopaddr, USE_REAL_ADDR, sizeof(ioparm)-1,
756                         ACCTYPE_WRITE, regs);
757 
758     /* Fetch the parameter list from real storage */
759     ARCH_DEP(vfetchc) (&ioparm, sizeof(ioparm)-1, iopaddr, USE_REAL_ADDR, regs);
760 
761     /* Load numeric fields from the parameter list */
762     devnum = (ioparm.devnum[0] << 8) | ioparm.devnum[1];
763     ccwaddr = (ioparm.ccwaddr[0] << 24)
764                 | (ioparm.ccwaddr[1] << 16)
765                 | (ioparm.ccwaddr[2] << 8)
766                 | ioparm.ccwaddr[3];
767 
768     /* Locate the device block */
769     dev = find_device_by_devnum (0,devnum);
770 
771     /* Set return code 1 and cond code 1 if device does not exist */
772     if (dev == NULL)
773     {
774         regs->GR_L(15) = 1;
775         return 1;
776     }
777 
778     /* Program check if protect key bits 4-7 are not zero
779        or if the reserved bits in the flag byte are not zero */
780     if ((ioparm.akey & 0x0F) || (ioparm.flag & HCPSGIOP_FLAG_RESV))
781     {
782         ARCH_DEP(program_interrupt) (regs, PGM_OPERAND_EXCEPTION);
783         return 0;
784     }
785 
786 #ifdef FEATURE_S370_CHANNEL
787     /* Program check if flag byte specifies format-1 CCW */
788     if (ioparm.flag & HCPSGIOP_FORMAT1_CCW)
789     {
790         ARCH_DEP(program_interrupt) (regs, PGM_OPERAND_EXCEPTION);
791         return 0;
792     }
793 #endif /*FEATURE_S370_CHANNEL*/
794 
795     /* Program check if CCW is not on a doubleword boundary,
796        or if CCW address exceeds maximum according to CCW format */
797     if ((ccwaddr & 0x00000007) || ccwaddr >
798            ((ioparm.flag & HCPSGIOP_FORMAT1_CCW) ?
799                         (U32)0x7FFFFFFF : (U32)0x00FFFFFF))
800     {
801         ARCH_DEP(program_interrupt) (regs, PGM_OPERAND_EXCEPTION);
802         return 0;
803     }
804 
805     /* Program check if reserved fields are not zero */
806     for (accum = 0, i = 0; i < sizeof(ioparm.resv1); i++)
807         accum |= ioparm.resv1[i];
808     for (i = 0; i < sizeof(ioparm.resv2); i++)
809         accum |= ioparm.resv2[i];
810     for (i = 0; i < sizeof(ioparm.resv3); i++)
811         accum |= ioparm.resv3[i];
812     for (i = 0; i < sizeof(ioparm.resv4); i++)
813         accum |= ioparm.resv4[i];
814     if (accum != 0)
815     {
816         ARCH_DEP(program_interrupt) (regs, PGM_OPERAND_EXCEPTION);
817         return 0;
818     }
819 
820     /* Obtain the interrupt lock */
821     obtain_lock (&dev->lock);
822 
823 #ifdef FEATURE_CHANNEL_SUBSYSTEM
824     /* Return code 5 and condition code 1 if status pending */
825     if ((dev->scsw.flag3 & SCSW3_SC_PEND)
826         || (dev->pciscsw.flag3 & SCSW3_SC_PEND))
827     {
828         release_lock (&dev->lock);
829         regs->GR_L(15) = 5;
830         return 1;
831     }
832 #endif /*FEATURE_CHANNEL_SUBSYSTEM*/
833 
834     /* Return code 5 and condition code 1 if device is busy */
835     if (dev->busy || IOPENDING(dev))
836     {
837         release_lock (&dev->lock);
838         regs->GR_L(15) = 5;
839         return 1;
840     }
841 
842     /* Set the device busy indicator */
843     dev->busy = 1;
844 
845     /* Release the device lock */
846     release_lock (&dev->lock);
847 
848     /* Build the operation request block */                    /*@IWZ*/
849     memset (&dev->orb, 0, sizeof(ORB));                        /*@IWZ*/
850     STORE_FW(dev->orb.ccwaddr, ccwaddr);                       /*@IWZ*/
851     dev->orb.flag4 = ioparm.akey & ORB4_KEY;                   /*@IWZ*/
852     if (ioparm.flag & HCPSGIOP_FORMAT1_CCW)                    /*@IWZ*/
853         dev->orb.flag5 |= ORB5_F;                              /*@IWZ*/
854 
855     /* Execute the channel program synchronously */
856     ARCH_DEP(execute_ccw_chain) (dev);
857 
858     /* Obtain status, CCW address, and residual byte count */
859 #ifdef FEATURE_S370_CHANNEL
860     lastccw = (dev->csw[1] << 16) || (dev->csw[2] << 8)
861                 || dev->csw[3];
862     unitstat = dev->csw[4];
863     chanstat = dev->csw[5];
864     residual = (dev->csw[6] << 8) || dev->csw[7];
865 #endif /*FEATURE_S370_CHANNEL*/
866 
867 #ifdef FEATURE_CHANNEL_SUBSYSTEM
868     lastccw = (dev->scsw.ccwaddr[0] << 24)
869                 || (dev->scsw.ccwaddr[1] << 16)
870                 || (dev->scsw.ccwaddr[2] << 8)
871                 || dev->scsw.ccwaddr[3];
872     unitstat = dev->scsw.unitstat;
873     chanstat = dev->scsw.chanstat;
874     residual = (dev->scsw.count[0] << 8) || dev->scsw.count[1];
875 #endif /*FEATURE_CHANNEL_SUBSYSTEM*/
876 
877     /* Clear the interrupt pending and device busy conditions */
878     obtain_lock (&dev->lock);
879     dev->busy = dev->pending = 0;
880     dev->scsw.flag2 = 0;
881     dev->scsw.flag3 = 0;
882     release_lock (&dev->lock);
883 
884     /* Store the last CCW address in the parameter list */
885     ioparm.lastccw[0] = (lastccw >> 24) & 0xFF;
886     ioparm.lastccw[1] = (lastccw >> 16) & 0xFF;
887     ioparm.lastccw[2] = (lastccw >> 8) & 0xFF;
888     ioparm.lastccw[3] = lastccw & 0xFF;
889 
890     /* Store the device and subchannel status in the parameter list */
891     ioparm.unitstat = unitstat;
892     ioparm.chanstat = chanstat;
893 
894     /* Store the residual byte count in the parameter list */
895     ioparm.residual[0] = (residual >> 8) & 0xFF;
896     ioparm.residual[1] = residual & 0xFF;
897 
898     /* Return sense data if unit check occurred */
899     if (unitstat & CSW_UC)
900     {
901         numsense = dev->numsense;
902         if (numsense > sizeof(ioparm.sense))
903             numsense = sizeof(ioparm.sense);
904         ioparm.sensecount[0] = (numsense >> 8) & 0xFF;
905         ioparm.sensecount[1] = numsense & 0xFF;
906         memcpy (ioparm.sense, dev->sense, numsense);
907     }
908 
909     /* Store the updated parameter list in real storage */
910     ARCH_DEP(vstorec) (&ioparm, sizeof(ioparm)-1, iopaddr, USE_REAL_ADDR, regs);
911 
912     /* If I/O error occurred, set return code 13 and cond code 3 */
913     if (unitstat != (CSW_CE | CSW_DE) || chanstat != 0)
914     {
915         regs->GR_L(15) = 13;
916         return 3;
917     }
918 
919     /* Return with condition code 0 and register 15 unchanged */
920     return 0;
921 
922 } /* end function syncgen_io */
923 
924 /*-------------------------------------------------------------------*/
925 /* Store Extended Identification Code (Function code 0x000)          */
926 /*-------------------------------------------------------------------*/
ARCH_DEP(extid_call)927 void ARCH_DEP(extid_call) (int r1, int r2, REGS *regs)
928 {
929 int        i;                           /* Array subscript           */
930 int        ver, rel;                    /* Version and release number*/
931 U32        idaddr;                      /* Address of storage operand*/
932 U32        idlen;                       /* Length of storage operand */
933 BYTE       buf[40];                     /* Extended identification   */
934 #if defined( HAVE_GETLOGIN_R )
935   #if !defined(LOGIN_NAME_MAX)
936     #define LOGIN_NAME_MAX 100
937   #endif
938 char       unam[LOGIN_NAME_MAX+1];      /* User name                 */
939 #endif
940 char      *puser;                       /* Pointer to user name      */
941 BYTE       c;                           /* Character work area       */
942 
943     /* Load storage operand address from R1 register */
944     idaddr = regs->GR_L(r1);
945 
946     /* Program check if operand is not on a doubleword boundary */
947     if (idaddr & 0x00000007)
948     {
949         ARCH_DEP(program_interrupt) (regs, PGM_SPECIFICATION_EXCEPTION);
950         return;
951     }
952 
953     /* Load storage operand length from R2 register */
954     idlen = regs->GR_L(r2);
955 
956     /* Program check if operand length is invalid */
957     if (idlen < 1)
958     {
959         ARCH_DEP(program_interrupt) (regs, PGM_SPECIFICATION_EXCEPTION);
960         return;
961     }
962 
963     /* Bytes 0-7 contain the system name ("HERCULES" in EBCDIC) */
964     get_lparname(buf);
965 
966     /* Bytes 8-9 contain the execution environment bits */
967     buf[8] = 0x00;
968     buf[9] = 0x00;
969 
970     /* Byte 10 contains the system product version number */
971     sscanf (MSTRING(VERSION), "%d.%d", &ver, &rel);
972     buf[10] = ver;
973 
974     /* Byte 11 contains version number from STIDP */
975     buf[11] = sysblk.cpuid >> 56;
976 
977     /* Bytes 12-13 contain MCEL length from STIDP */
978     buf[12] = (sysblk.cpuid >> 8) & 0xFF;
979     buf[13] = sysblk.cpuid & 0xFF;
980 
981     /* Bytes 14-15 contain the CP address */
982     buf[14] = (regs->cpuad >> 8) & 0xFF;
983     buf[15] = regs->cpuad & 0xFF;
984 
985     /* Bytes 16-23 contain the userid in EBCDIC */
986 #if defined( HAVE_GETLOGIN_R )
987     memset( unam, 0, sizeof(unam) );
988     VERIFY( getlogin_r ( unam, sizeof(unam) ) == 0 );
989     puser = unam;
990 #else
991     puser = "";
992 #endif
993     for (i = 0; i < 8; i++)
994     {
995         c = (*puser == '\0' ? SPACE : *(puser++));
996         buf[16+i] = host_to_guest(toupper(c));
997     }
998 
999     /* Bytes 24-31 contain the program product bitmap */
1000     memcpy (buf+24, "\x7F\xFE\x00\x00\x00\x00\x00\x00", 8);
1001 
1002     /* Bytes 32-35 contain the time zone differential */
1003     memset (buf+32, '\0', 4);
1004 
1005     /* Bytes 36-39 contain version, level, and service level */
1006     buf[36] = ver;
1007     buf[37] = rel;
1008     buf[38] = 0x00;
1009     buf[39] = 0x00;
1010 
1011 #if 0
1012     logmsg ("Diagnose X\'000\':"
1013             "%2.2X%2.2X%2.2X%2.2X %2.2X%2.2X%2.2X%2.2X "
1014             "%2.2X%2.2X%2.2X%2.2X %2.2X%2.2X%2.2X%2.2X\n\t\t"
1015             "%2.2X%2.2X%2.2X%2.2X %2.2X%2.2X%2.2X%2.2X "
1016             "%2.2X%2.2X%2.2X%2.2X %2.2X%2.2X%2.2X%2.2X\n\t\t"
1017             "%2.2X%2.2X%2.2X%2.2X %2.2X%2.2X%2.2X%2.2X\n",
1018             buf[0], buf[1], buf[2], buf[3],
1019             buf[4], buf[5], buf[6], buf[7],
1020             buf[8], buf[9], buf[10], buf[11],
1021             buf[12], buf[13], buf[14], buf[15],
1022             buf[16], buf[17], buf[18], buf[19],
1023             buf[20], buf[21], buf[22], buf[23],
1024             buf[24], buf[25], buf[26], buf[27],
1025             buf[28], buf[29], buf[30], buf[31],
1026             buf[32], buf[33], buf[34], buf[35],
1027             buf[36], buf[37], buf[38], buf[39]);
1028 #endif
1029 
1030     /* Enforce maximum length to store */
1031     if (idlen > sizeof(buf))
1032         idlen = sizeof(buf);
1033 
1034     /* Store the extended identification code at operand address */
1035     ARCH_DEP(vstorec) (buf, idlen-1, idaddr, USE_REAL_ADDR, regs);
1036 
1037     /* Deduct number of bytes from the R2 register */
1038     regs->GR_L(r2) -= idlen;
1039 
1040 } /* end function extid_call */
1041 
1042 /*-------------------------------------------------------------------*/
1043 /* Process CP command (Function code 0x008)                          */
1044 /*-------------------------------------------------------------------*/
ARCH_DEP(cpcmd_call)1045 int ARCH_DEP(cpcmd_call) (int r1, int r2, REGS *regs)
1046 {
1047 U32     i;                              /* Array subscript           */
1048 U32     cc = 0;                         /* Condition code            */
1049 U32     cmdaddr;                        /* Address of command string */
1050 U32     cmdlen;                         /* Length of command string  */
1051 U32     respadr;                        /* Address of response buffer*/
1052 U32     maxrlen;                        /* Length of response buffer */
1053 U32     resplen;                        /* Length of actual response */
1054 BYTE    cmdflags;                       /* Command flags             */
1055 #define CMDFLAGS_REJPASSW       0x80    /* Reject password in command*/
1056 #define CMDFLAGS_RESPONSE       0x40    /* Return response in buffer */
1057 #define CMDFLAGS_REQPASSW       0x20    /* Prompt for password       */
1058 #define CMDFLAGS_RESERVED       0x1F    /* Reserved bits, must be 0  */
1059 char    bufi[256];                      /* Command buffer (ASCIIZ)   */
1060 char    bufo[257];                      /* Command buffer (ASCIIZ)   */
1061 char    resp[256];                      /* Response buffer (ASCIIZ)  */
1062 char    *dresp;                         /* Default response (ASCIIZ) */
1063 int     freeresp;                       /* Flag to free resp bfr     */
1064 U32     j,k;
1065 
1066     /* Obtain command address from R1 register */
1067     cmdaddr = regs->GR_L(r1);
1068 
1069     /* Obtain command length and flags from R2 register */
1070     cmdflags = regs->GR_L(r2) >> 24;
1071     cmdlen = regs->GR_L(r2) & 0x00FFFFFF;
1072 
1073     /* Program check if invalid flags, or if command string
1074        is too long, or if response buffer is specified and
1075        registers are consecutive or either register
1076        specifies register 15 */
1077     if ((cmdflags & CMDFLAGS_RESERVED) || cmdlen > sizeof(bufi)-1
1078         || ((cmdflags & CMDFLAGS_RESPONSE)
1079             && (r1 == 15 || r2 == 15 || r1 == r2 + 1 || r2 == r1 + 1)))
1080     {
1081         ARCH_DEP(program_interrupt) (regs, PGM_SPECIFICATION_EXCEPTION);
1082         return 0;
1083     }
1084 
1085     /* Put machine into stopped state if command length is zero */
1086     if (cmdlen == 0)
1087     {
1088         regs->opinterv = 0;
1089         regs->cpustate = CPUSTATE_STOPPED;
1090         ON_IC_INTERRUPT(regs);
1091         return 0;
1092     }
1093 
1094     /* Obtain the command string from storage */
1095     ARCH_DEP(vfetchc) (bufi, cmdlen-1, cmdaddr, USE_REAL_ADDR, regs);
1096 
1097     /* Prepend '-' if noecho is requested */
1098     i=0;
1099     if(!(sysblk.diag8cmd & DIAG8CMD_ECHO))
1100     {
1101         bufo[0]='-';
1102         i=1;
1103     }
1104     /* Translate EBCDIC command to ASCII */
1105     for (j=0; j < cmdlen; i++,j++)
1106     {
1107         bufo[i] = guest_to_host(bufi[j]);
1108     }
1109     bufo[i] = '\0';
1110     dresp="";
1111     freeresp=0;
1112 
1113     if(*bufo)
1114     {
1115 #ifdef FEATURE_HERCULES_DIAGCALLS
1116         int shcmd = 0;
1117         {
1118             char* p = bufo;
1119             while (*p && isspace(*p)) p++;
1120             if ((*(p+0) == 's' || *(p+0) == 'S') &&
1121                 (*(p+1) == 'h' || *(p+1) == 'H') &&
1122                 isspace(*(p+2))) shcmd = 1;
1123         }
1124         if ((sysblk.diag8cmd & DIAG8CMD_ENABLE)
1125             && (!shcmd || !(sysblk.shcmdopt & (SHCMDOPT_DISABLE | SHCMDOPT_NODIAG8)))
1126         )
1127         {
1128             if(sysblk.diag8cmd & DIAG8CMD_ECHO)
1129                 logmsgp (_("HHCVM001I *%s* panel command issued by guest\n"), bufo);
1130             if (cmdflags & CMDFLAGS_RESPONSE)
1131             {
1132                 dresp=log_capture(panel_command,bufo);
1133                 if(dresp!=NULL)
1134                 {
1135                     freeresp=1;
1136                 }
1137                 else
1138                 {
1139                     dresp="";
1140                 }
1141             }
1142             else
1143             {
1144                 panel_command(bufo);
1145                 if(sysblk.diag8cmd & DIAG8CMD_ECHO)
1146                     logmsgp (_("HHCVM002I *%s* command complete\n"), bufo);
1147             }
1148         }
1149         else
1150         {
1151             if(sysblk.diag8cmd & DIAG8CMD_ECHO)
1152             {
1153                 logmsgp (_("HHCVM005W *%s* panel command issued by guest (but disabled)\n"), bufo);
1154             }
1155             dresp=_("HHCVM003I Host command processing disabled by configuration statement");
1156         }
1157 #else
1158             dresp=_("HHCVM004E Host command processing not included in engine build");
1159 #endif
1160     }
1161 
1162     /* Store the response and set length if response requested */
1163     if (cmdflags & CMDFLAGS_RESPONSE)
1164     {
1165         if(!freeresp)
1166         {
1167                 strlcpy (resp, dresp, sizeof(resp));
1168                 dresp=resp;
1169         }
1170         resplen = strlen(dresp);
1171         for (i = 0; i < resplen; i++)
1172             dresp[i] = host_to_guest(dresp[i]);
1173 
1174         respadr = regs->GR_L(r1+1);
1175         maxrlen = regs->GR_L(r2+1);
1176 
1177         i=(resplen<=maxrlen) ? resplen : maxrlen;
1178         j=0;
1179         while(i>0)
1180         {
1181             k=(i<255 ? i : 255);
1182             ARCH_DEP(vstorec) (&dresp[j], k-1 , respadr+j, USE_REAL_ADDR, regs);
1183             i-=k;
1184             j+=k;
1185         }
1186         regs->GR_L(r2+1) = (resplen<=maxrlen) ? resplen : resplen-maxrlen;
1187         cc = (resplen<=maxrlen) ? 0 : 1;
1188     }
1189     if(freeresp)
1190     {
1191         free(dresp);
1192     }
1193 
1194     /* Set R2 register to CP completion code */
1195     regs->GR_L(r2) = 0;
1196 
1197     /* Return condition code */
1198     return cc;
1199 
1200 } /* end function cpcmd_call */
1201 
1202 /*-------------------------------------------------------------------*/
1203 /* Access Re-IPL data (Function code 0x0B0)                          */
1204 /*-------------------------------------------------------------------*/
ARCH_DEP(access_reipl_data)1205 void ARCH_DEP(access_reipl_data) (int r1, int r2, REGS *regs)
1206 {
1207 U32     bufadr;                         /* Real addr of data buffer  */
1208 U32     buflen;                         /* Length of data buffer     */
1209 
1210     /* Obtain buffer address and length from R1 and R2 registers */
1211     bufadr = regs->GR_L(r1);
1212     buflen = regs->GR_L(r2);
1213 
1214     /* Program check if buffer length is negative */
1215     if ((S32)buflen < 0)
1216     {
1217         ARCH_DEP(program_interrupt) (regs, PGM_SPECIFICATION_EXCEPTION);
1218         return;
1219     }
1220 
1221     /* Store IPL information if buffer length is non-zero */
1222     if (buflen > 0)
1223     {
1224         /* Store one byte of zero to indicate no IPL information */
1225         ARCH_DEP(vstoreb) (0, bufadr, USE_REAL_ADDR, regs);
1226     }
1227 
1228     PTT(PTT_CL_ERR,"*DIAG0B0",regs->GR_L(r1),regs->GR_L(r2),regs->psw.IA_L);
1229 
1230     /* Return code 4 means no re-IPL information available */
1231     regs->GR_L(r2) = 4;
1232 
1233 } /* end function access_reipl_data */
1234 
1235 /*-------------------------------------------------------------------*/
1236 /* Access Device Information (Function code 0x210)                   */
1237 /*-------------------------------------------------------------------*/
1238 /* Note: This implementation emulates z/VM 5.4                       */
ARCH_DEP(device_info)1239 int  ARCH_DEP(device_info) (int r1, int r2, REGS *regs)
1240 {
1241 DEVBLK   *dev;             /* -> Device block                        */
1242 VRDCBLOK vrdc;             /* VRDCBLOK                               */
1243 RADR     blokaddr;         /* Location of the VRDCBLOK               */
1244 U16      bloklen;          /* Length from the VRDCBLOK               */
1245 #if 0
1246 /* Only required if implementation is for the z/VM 5.3 level */
1247 U16      reserved;         /* Bytes 14 and 15                        */
1248 #endif
1249 U16      devnum;           /* Device number from the VRDCBLOK        */
1250 
1251 
1252     UNREFERENCED(r2);
1253 
1254     if (regs->GR_L(r1) & 0x3
1255 #if defined(FEATURE_ESAME)
1256         || (regs->psw.amode64)
1257 #endif /* FEATURE_ESAME */
1258        )
1259     {
1260         ARCH_DEP(program_interrupt) (regs, PGM_SPECIFICATION_EXCEPTION);
1261     }
1262 
1263     blokaddr = regs->GR_L(r1);
1264 
1265     /* Fetch the first 4 bytes of the VRDCBLOK */
1266     ARCH_DEP(vfetchc) (&vrdc, 3, blokaddr, USE_REAL_ADDR, regs);
1267 
1268     /* Get the VRDCBLOK length from the working VRDC */
1269     FETCH_HW(bloklen,&vrdc.vrdclen);
1270 
1271     /* VRDCBLOK length must be at least 8 bytes */
1272     if (bloklen<8)
1273     {
1274         ARCH_DEP(program_interrupt) (regs, PGM_SPECIFICATION_EXCEPTION);
1275     }
1276 
1277     /* Fetch remainder of supplied VRDCBLOK, but no more */
1278     if (bloklen>VRDCBLOK_SIZE)
1279        bloklen=VRDCBLOK_SIZE;
1280     ARCH_DEP(vfetchc) (&vrdc.vrdcvdat,bloklen-5,blokaddr+4, USE_REAL_ADDR, regs);
1281 
1282 #if 0
1283     /* If length is 16 or greater, bytes 14 and 15 must be zero on z/VM 5.3.0 or earlier */
1284     if ( bloklen>=16)
1285     {
1286          FETCH_HW(reserved,&vrdc.vrdcrsvd);
1287          if (reserved != 0)
1288          {
1289               ARCH_DEP(program_interrupt) (regs, PGM_SPECIFICATION_EXCEPTION);
1290          }
1291     }
1292 #endif
1293 
1294     /* Get the device number from the working VRDC */
1295     FETCH_HW(devnum,&vrdc.vrdcdvno);
1296 
1297     /* Locate the device block and set the virtual and real device information */
1298     dev = ARCH_DEP(vmdevice_data) (0x210,devnum,&vrdc.vrdcvdat,&vrdc.vrdcrcdt);
1299 
1300     /* Return condition code 3 if device does not exist */
1301     if (!dev)
1302     {
1303         PTT(PTT_CL_ERR,"*DIAG210",regs->GR_L(r1),regs->GR_L(r2),regs->psw.IA_L);
1304         return 3;
1305     }
1306 
1307     /* Set the underlying device and real device features */
1308     vrdc.vrdcundv=0x00;
1309     vrdc.vrdcrdaf=0x00;
1310 
1311     /* Create device dependent mappings */
1312     if (vrdc.vrdcvdat.vdevcls == DC_DASD)
1313     {
1314         memcpy(&vrdc.vrdcrdc,dev->devchar,42);
1315         switch (dev->devtype)
1316         {
1317              case 0x2311:
1318              case 0x2314:
1319              case 0x2305:
1320              case 0x3330:
1321              case 0x3340:
1322              case 0x3350:
1323                   /* Set non-keyed overhead */
1324                   STORE_HW(&vrdc.vrdcrdc[0x18],dev->ckdtab->f2);
1325                   /* Set keyed overhead */
1326                   STORE_HW(&vrdc.vrdcrdc[0x1A],dev->ckdtab->f1);
1327              /* Note: for all other DASD devices these fields contain bytes 24-27 of the RDC */
1328         }
1329         /* Set Control Unit ID */
1330         vrdc.vrdcrdc[0x2A]=dev->devchar[56];
1331     }
1332     else if (vrdc.vrdcvdat.vdevcls == DC_FBA)
1333         memcpy(&vrdc.vrdcrdc,dev->devchar,32);
1334 
1335     /* Set Path Group ID */
1336     memcpy(&vrdc.vrdcpgid,dev->pgid,11);
1337 
1338     /* Set version */
1339     if (bloklen>0x60)
1340        vrdc.vrdcvers=0x01;
1341 
1342     /* Set underlying real device */
1343     if (!(vrdc.vrdcrdaf & VRDCEMRD))
1344        memcpy(&vrdc.vrdcrdev,&vrdc.vrdcdvno,2);
1345 
1346     /* Update the VRDC in main storage */
1347     ARCH_DEP(vstorec) (&vrdc, bloklen-1, blokaddr, USE_REAL_ADDR, regs);
1348 
1349     /* Return condition code 0 for success */
1350     return 0;
1351 
1352 } /* end function device_info */
1353 
1354 
1355 /*-------------------------------------------------------------------*/
1356 /* Access Certain Virtual Machine Information (Function code 0x260)  */
1357 /*-------------------------------------------------------------------*/
1358 /* Note: This implementation emulates z/VM 5.4                       */
ARCH_DEP(vm_info)1359 void ARCH_DEP(vm_info) (int r1, int r2, REGS *regs)
1360 {
1361 DEVBLK  *dev;                          /* -> Device block            */
1362 U16     devnum;                        /* Device number              */
1363 #if defined(FEATURE_ESAME)
1364 RADR    stgarea;                       /* Storage extent area        */
1365 S64     stglen;                        /* Storage extent area length */
1366 #endif /* FEATURE_ESAME */
1367 
1368     /* Ry contains the subcode */
1369     switch(regs->GR_L(r2))
1370     {
1371     case 0x00000000: /* Highest addressable byte */
1372 #if defined(FEATURE_ESAME)
1373 
1374         /* Program check if running in z/Architecture mode and */
1375         /* 64-bit addressing is being used.                    */
1376         if (regs->psw.amode64)
1377         {
1378             ARCH_DEP(program_interrupt) (regs, PGM_SPECIFICATION_EXCEPTION);
1379         }
1380 #endif /* FEATURE_ESAME */
1381         regs->GR_L(r1) = regs->mainlim; /* provide highest addressable byte */
1382         return;
1383 
1384     case 0x00000004: /* Provide BYUSER ID value */
1385 
1386         /* Program check if Rx and Ry are the same registers or        */
1387         /* or Ry is not an even register or the address provided       */
1388         /* in Rx is not on a doubleword boundary or if running         */
1389         /* in z/Architecture mode and 64-bit addressing is being used. */
1390         if ( r1 == r2 || r2 & 0x1 || regs->GR_L(r1) & 0x7
1391 #if defined(FEATURE_ESAME)
1392              || (regs->psw.amode64)
1393 #endif /* FEATURE_ESAME */
1394            )
1395         {
1396             ARCH_DEP(program_interrupt) (regs, PGM_SPECIFICATION_EXCEPTION);
1397         }
1398         regs->GR_L(r2+1)=0x4; /* Indicate no BYUSER ID for Hercules */
1399         return;
1400 
1401     case 0x00000008: /* Return number of lines per page */
1402 #if defined(FEATURE_ESAME)
1403 
1404         /* Program check if running in z/Architecture mode and */
1405         /* 64-bit addressing is being used.                    */
1406         if (regs->psw.amode64)
1407         {
1408             ARCH_DEP(program_interrupt) (regs, PGM_SPECIFICATION_EXCEPTION);
1409         }
1410 #endif /* FEATURE_ESAME */
1411 
1412         /* Get the device number from the Rx register */
1413         devnum=regs->GR_LHL(r1);
1414 
1415         /* Locate the device block */
1416         dev = find_device_by_devnum(0,devnum);
1417 
1418         /* Set 0 lines per page for a valid printer or console (meaning SPOOL is OFF) */
1419         if (dev != NULL &&
1420               (dev->devtype == 0x1403 ||
1421                dev->devtype == 0x3211 ||
1422                dev->devtype == 0x1052 ||
1423                dev->devtype == 0x3215 )
1424             )
1425         {
1426            regs->GR_L(r1) = 0; /* Set zero lines per page */
1427            regs->GR_L(r2) = 0; /* Set return code to indicate a valid device */
1428         }
1429         else
1430         {
1431            regs->GR_L(r2) = 4; /* Set return code to indicate an invalid device */
1432         }
1433         return;
1434 
1435 #if defined(FEATURE_ESAME)
1436     case 0x0000000C: /* Return highest addressable byte for z/Architecture machine */
1437          regs->GR_G(r1) = regs->mainlim;
1438          regs->GR_G(r2) = regs->mainlim;
1439          return;
1440 
1441     case 0x00000010: /* Set storage extent */
1442 
1443          /* Obtain the storage extent area real address from Rx */
1444          /* and its length from Rx+1                            */
1445          stgarea=regs->GR_G(r1);
1446          stglen=regs->GR_G(r1+1); /* Length is treated as a signed value */
1447 
1448          /* Program check if Rx is not an even register or the address */
1449          /* provided in Rx is not on a quadword boundary or the length */
1450          /* provided in Rx+1 is not positive or not a multiple of 16   */
1451          if ( r1 & 1 || stgarea & 0xF || stglen <= 0 || stglen & 0xF )
1452          {
1453              ARCH_DEP(program_interrupt) (regs, PGM_SPECIFICATION_EXCEPTION);
1454          }
1455 
1456          /* Convert real addres to absolute address */
1457          stgarea=APPLY_PREFIXING(stgarea,regs->PX );
1458 
1459          /* Check to ensure extent information can be stored */
1460          if (stgarea > regs->mainlim - 16)
1461          {
1462              regs->program_interrupt (regs, PGM_ADDRESSING_EXCEPTION);
1463          }
1464          /* Set start of storage extent to zero */
1465          ARCH_DEP(store_doubleword_absolute)(0,stgarea,regs);
1466          /* Set end of storage extent to last addressable byte of main storage */
1467          ARCH_DEP(store_doubleword_absolute)(regs->mainlim,stgarea+8,regs);
1468          /* Set number of extents to 1 in Ry */
1469          regs->GR_G(r2) = 1;
1470          /* Indicate all extents returned */
1471          regs->psw.cc = 0;
1472          return;
1473 #endif /* FEATURE_ESAME */
1474 
1475     default: /* Invalid subcode */
1476         ARCH_DEP(program_interrupt) (regs, PGM_SPECIFICATION_EXCEPTION);
1477     }
1478 }
1479 
1480 
1481 /*-------------------------------------------------------------------*/
1482 /* Pseudo Timer Extended (Function code 0x270)                       */
1483 /* Pseudo Timer (Function code 0x00C)                                */
1484 /*-------------------------------------------------------------------*/
ARCH_DEP(pseudo_timer)1485 void ARCH_DEP(pseudo_timer) (U32 code, int r1, int r2, REGS *regs)
1486 {
1487 int     i;                              /* Array subscript           */
1488 time_t  timeval;                        /* Current time              */
1489 struct  tm *tmptr;                      /* -> Current time structure */
1490 U32     bufadr;                         /* Real addr of data buffer  */
1491 U32     buflen;                         /* Length of data buffer     */
1492 char    buf[64];                        /* Response buffer           */
1493 BYTE    dattim[64];                     /* Date and time (EBCDIC)    */
1494 #define DIAG_DATEFMT_SHORT      0x80    /* Date format mm/dd/yy      */
1495 #define DIAG_DATEFMT_FULL       0x40    /* Date format mm/dd/yyyy    */
1496 #define DIAG_DATEFMT_ISO        0x20    /* Date format yyyy-mm-dd    */
1497 #define DIAG_DATEFMT_SYSDFLT    0x10    /* System-wide default format*/
1498 static  char timefmt[]="%m/%d/%y%H:%M:%S%m/%d/%Y%Y-%m-%d";
1499 
1500     /* Get the current date and time in EBCDIC */
1501     timeval = time(NULL);
1502     tmptr = localtime(&timeval);
1503     strftime((char *)dattim, sizeof(dattim), timefmt, tmptr);
1504     for (i = 0; dattim[i] != '\0'; i++)
1505         dattim[i] = host_to_guest(dattim[i]);
1506 
1507     /* Obtain buffer address and length from R1 and R2 registers */
1508     bufadr = regs->GR_L(r1);
1509     buflen = regs->GR_L(r2);
1510 
1511     /* Use length 32 if R2 is zero or function code is 00C */
1512     if (r2 == 0 || code == 0x00C)
1513         buflen = 32;
1514 
1515     /* Program check if R1 and R2 specify the same non-zero
1516        register number, or if buffer length is less than or
1517        equal to zero, or if buffer address is zero, or if
1518        buffer is not on a doubleword boundary */
1519     if ((r2 != 0 && r2 == r1)
1520         || (S32)buflen <= 0
1521         || bufadr == 0
1522         || (bufadr & 0x00000007))
1523     {
1524         ARCH_DEP(program_interrupt) (regs, PGM_SPECIFICATION_EXCEPTION);
1525         return;
1526     }
1527 
1528     /* Build the response buffer */
1529     memset (buf, 0x00, sizeof(buf));
1530     /* Bytes 0-7 contain the date as EBCDIC MM/DD/YY */
1531     memcpy (buf, dattim, 8);
1532     /* Bytes 8-15 contain the time as EBCDIC HH:MM:SS */
1533     memcpy (buf+8, dattim+8, 8);
1534     /* Bytes 16-23 contain the virtual CPU time used in microseconds */
1535     /* Bytes 24-31 contain the total CPU time used in microseconds */
1536     /* Bytes 32-41 contain the date as EBCDIC MM/DD/YYYY */
1537     memcpy (buf+32, dattim+16, 10);
1538     /* Bytes 42-47 contain binary zeroes */
1539     /* Bytes 48-57 contain the date as EBCDIC YYYY-MM-DD */
1540     memcpy (buf+48, dattim+26, 10);
1541     /* Byte 58 contains the diagnose 270 version code */
1542     buf[58] = 0x01;
1543     /* Byte 59 contains the user's default date format */
1544     buf[59] = DIAG_DATEFMT_ISO;
1545     /* Byte 60 contains the system default date format */
1546     buf[60] = DIAG_DATEFMT_ISO;
1547     /* Bytes 61-63 contain binary zeroes */
1548 
1549 #if 0
1550     logmsg ("Diagnose X\'%3.3X\':"
1551             "%2.2X%2.2X%2.2X%2.2X %2.2X%2.2X%2.2X%2.2X "
1552             "%2.2X%2.2X%2.2X%2.2X %2.2X%2.2X%2.2X%2.2X\n\t\t"
1553             "%2.2X%2.2X%2.2X%2.2X %2.2X%2.2X%2.2X%2.2X "
1554             "%2.2X%2.2X%2.2X%2.2X %2.2X%2.2X%2.2X%2.2X\n\t\t"
1555             "%2.2X%2.2X%2.2X%2.2X %2.2X%2.2X%2.2X%2.2X "
1556             "%2.2X%2.2X%2.2X%2.2X %2.2X%2.2X%2.2X%2.2X\n\t\t"
1557             "%2.2X%2.2X%2.2X%2.2X %2.2X%2.2X%2.2X%2.2X "
1558             "%2.2X%2.2X%2.2X%2.2X %2.2X%2.2X%2.2X%2.2X\n",
1559             code, buf[0], buf[1], buf[2], buf[3],
1560             buf[4], buf[5], buf[6], buf[7],
1561             buf[8], buf[9], buf[10], buf[11],
1562             buf[12], buf[13], buf[14], buf[15],
1563             buf[16], buf[17], buf[18], buf[19],
1564             buf[20], buf[21], buf[22], buf[23],
1565             buf[24], buf[25], buf[26], buf[27],
1566             buf[28], buf[29], buf[30], buf[31],
1567             buf[32], buf[33], buf[34], buf[35],
1568             buf[36], buf[37], buf[38], buf[39],
1569             buf[40], buf[41], buf[42], buf[43],
1570             buf[44], buf[45], buf[46], buf[47],
1571             buf[48], buf[49], buf[50], buf[51],
1572             buf[52], buf[53], buf[54], buf[55],
1573             buf[56], buf[57], buf[58], buf[59],
1574             buf[60], buf[61], buf[63], buf[63]);
1575 #endif
1576 
1577     /* Enforce maximum length to store */
1578     if (buflen > sizeof(buf))
1579         buflen = sizeof(buf);
1580 
1581     /* Store the response buffer at the operand location */
1582     ARCH_DEP(vstorec) (buf, buflen-1, bufadr, USE_REAL_ADDR, regs);
1583 
1584 } /* end function pseudo_timer */
1585 
1586 /*-------------------------------------------------------------------*/
1587 /* Pending Page Release (Function code 0x214)                        */
1588 /*-------------------------------------------------------------------*/
ARCH_DEP(diag_ppagerel)1589 int ARCH_DEP(diag_ppagerel) (int r1, int r2, REGS *regs)
1590 {
1591 U32     abs, start, end;                /* Absolute frame addresses  */
1592 BYTE    skey;                           /* Specified storage key     */
1593 BYTE    func;                           /* Function code...          */
1594 #define DIAG214_EPR             0x00    /* Establish pending release */
1595 #define DIAG214_CPR             0x01    /* Cancel pending release    */
1596 #define DIAG214_CAPR            0x02    /* Cancel all pending release*/
1597 #define DIAG214_CPRV            0x03    /* Cancel and validate       */
1598 
1599     /* Program check if R1 is not an even-numbered register */
1600     if (r1 & 1)
1601     {
1602         ARCH_DEP(program_interrupt) (regs, PGM_SPECIFICATION_EXCEPTION);
1603         return 0;
1604     }
1605 
1606     /* Extract the function code from R1+1 register bits 24-31 */
1607     func = regs->GR_L(r1+1) & 0xFF;
1608 
1609     /* Extract the start/end addresses from R1 and R1+1 registers */
1610     start = regs->GR_L(r1) & STORAGE_KEY_PAGEMASK;
1611     end = regs->GR_L(r1+1) & STORAGE_KEY_PAGEMASK;
1612 
1613     /* Validate start/end addresses if function is not CAPR */
1614     if (func != DIAG214_CAPR
1615         && (start > end || end > regs->mainlim))
1616     {
1617         ARCH_DEP(program_interrupt) (regs, PGM_SPECIFICATION_EXCEPTION);
1618         return 0;
1619     }
1620 
1621     /* Process depending on function code */
1622     switch (func)
1623     {
1624     case DIAG214_EPR:  /* Establish Pending Release */
1625         break;
1626 
1627     case DIAG214_CPR:  /* Cancel Pending Release */
1628     case DIAG214_CPRV: /* Cancel Pending Release and Validate */
1629 
1630         /* Do not set storage keys if R2 is register 0 */
1631         if (r2 == 0) break;
1632 
1633         /* Obtain key from R2 register bits 24-28 */
1634         skey = regs->GR_L(r2) & (STORKEY_KEY | STORKEY_FETCH);
1635 
1636         /* Set storage key for each frame within specified range */
1637         for (abs = start; abs <= end; abs += STORAGE_KEY_PAGESIZE)
1638         {
1639             STORAGE_KEY(abs, regs) &= ~(STORKEY_KEY | STORKEY_FETCH);
1640             STORAGE_KEY(abs, regs) |= skey;
1641         } /* end for(abs) */
1642 
1643         break;
1644 
1645     case DIAG214_CAPR:  /* Cancel All Pending Releases */
1646         break;
1647 
1648     default:            /* Invalid function code */
1649         ARCH_DEP(program_interrupt) (regs, PGM_SPECIFICATION_EXCEPTION);
1650         return 0;
1651     } /* end switch(func) */
1652 
1653     /* Return condition code zero */
1654     return 0;
1655 
1656 } /* end function diag_ppagerel */
1657 
1658 
1659 /*-------------------------------------------------------------------*/
1660 /* B2F0 IUCV  - Inter User Communications Vehicle                [S] */
1661 /*-------------------------------------------------------------------*/
DEF_INST(inter_user_communication_vehicle)1662 DEF_INST(inter_user_communication_vehicle)
1663 {
1664 int     b2;                             /* Effective addr base       */
1665 VADR    effective_addr2;                /* Effective address         */
1666 
1667     S(inst, regs, b2, effective_addr2);
1668 #if defined(FEATURE_ECPSVM)
1669     if(ecpsvm_doiucv(regs,b2,effective_addr2)==0)
1670     {
1671         return;
1672     }
1673 #endif
1674 
1675 
1676     /* Program check if in problem state,
1677        the IUCV instruction generates an operation exception
1678        rather then a priviliged operation exception when
1679        executed in problem state                                 *JJ */
1680     if ( PROBSTATE(&regs->psw) )
1681         ARCH_DEP(program_interrupt) (regs, PGM_OPERATION_EXCEPTION);
1682 
1683     SIE_INTERCEPT(regs);
1684 
1685     if( HDC3(debug_iucv, b2, effective_addr2, regs) )
1686         return;
1687 
1688     PTT(PTT_CL_ERR,"*IUCV",b2,effective_addr2,regs->psw.IA_L);
1689 
1690     /* Set condition code to indicate IUCV not available */
1691     regs->psw.cc = 3;
1692 
1693 }
1694 
1695 #endif /*FEATURE_EMULATE_VM*/
1696 
1697 
1698 #if !defined(_GEN_ARCH)
1699 
1700 #if defined(_ARCHMODE2)
1701  #define  _GEN_ARCH _ARCHMODE2
1702  #include "vm.c"
1703 #endif
1704 
1705 #if defined(_ARCHMODE3)
1706  #undef   _GEN_ARCH
1707  #define  _GEN_ARCH _ARCHMODE3
1708  #include "vm.c"
1709 #endif
1710 
1711 #endif /*!defined(_GEN_ARCH)*/
1712