1 /* SERVICE.C    (c) Copyright Roger Bowler, 1999-2009                */
2 /*              ESA/390 Service Processor                            */
3 
4 /* Interpretive Execution - (c) Copyright Jan Jaeger, 1999-2009      */
5 /* z/Architecture support - (c) Copyright Jan Jaeger, 1999-2009      */
6 
7 /*-------------------------------------------------------------------*/
8 /* This module implements service processor functions                */
9 /* for the Hercules ESA/390 emulator.                                */
10 /*-------------------------------------------------------------------*/
11 
12 /*-------------------------------------------------------------------*/
13 /* Additional credits:                                               */
14 /*      Corrections contributed by Jan Jaeger                        */
15 /*      HMC system console functions by Jan Jaeger 2000-02-08        */
16 /*      Expanded storage support by Jan Jaeger                       */
17 /*      Dynamic CPU reconfiguration - Jan Jaeger                     */
18 /*      Suppress superflous HHC701I/HHC702I messages - Jan Jaeger    */
19 /*      Break syscons output if too long - Jan Jaeger                */
20 /*      Added CPI - Control Program Information ev. - JJ 2001-11-19  */
21 /*-------------------------------------------------------------------*/
22 
23 #include "hstdinc.h"
24 
25 #if !defined(_HENGINE_DLL_)
26 #define _HENGINE_DLL_
27 #endif
28 
29 #if !defined(_SERVICE_C_)
30 #define _SERVICE_C_
31 #endif
32 
33 #include "hercules.h"
34 #include "opcode.h"
35 #include "inline.h"
36 #include "sr.h"
37 
38 #if !defined(_SERVICE_C)
39 
40 #define _SERVICE_C
41 
42 /*-------------------------------------------------------------------*/
43 /* Service processor state data                                      */
44 /*-------------------------------------------------------------------*/
45 static  U32     servc_cp_recv_mask;     /* Syscons CP receive mask   */
46 static  U32     servc_cp_send_mask;     /* Syscons CP send mask      */
47 static  U32     servc_attn_pending;     /* Attention pending mask    */
48 static  char    servc_scpcmdstr[123+1]; /* Operator command string   */
49 static  U16     servc_signal_quiesce_count;
50 static  BYTE    servc_signal_quiesce_unit;
51 static  BYTE    servc_sysg_cmdcode;     /* Pending SYSG read command */
52 
53 #define SCLP_RECV_ENABLED(_type) \
54     (servc_cp_recv_mask & (0x80000000 >> ((_type)-1)))
55 
56 /*-------------------------------------------------------------------*/
57 /* Reset the service processor to its initial state                  */
58 /*-------------------------------------------------------------------*/
sclp_reset()59 void sclp_reset()
60 {
61     servc_cp_recv_mask = 0;
62     servc_cp_send_mask = 0;
63     servc_attn_pending = 0;
64     servc_signal_quiesce_count = 0;
65     servc_signal_quiesce_unit = 0;
66     servc_sysg_cmdcode = 0;
67 
68     sysblk.servparm = 0;
69 }
70 
71 
72 // #ifdef FEATURE_SYSTEM_CONSOLE
73 /*-------------------------------------------------------------------*/
74 /* Raise service signal external interrupt                           */
75 /* (the caller is expected to hold the interrupt lock)               */
76 /*-------------------------------------------------------------------*/
sclp_attention(U16 type)77 void sclp_attention(U16 type)
78 {
79     /* Set pending mask */
80     servc_attn_pending |= 0x80000000 >> (type -1);
81 
82     /* Ignore request if already pending */
83     if (!(IS_IC_SERVSIG && (sysblk.servparm & SERVSIG_PEND)))
84     {
85         /* Set event pending flag in service parameter */
86         sysblk.servparm |= SERVSIG_PEND;
87 
88         /* Set service signal interrupt pending for read event data */
89         ON_IC_SERVSIG;
90         WAKEUP_CPUS_MASK (sysblk.waiting_mask);
91     }
92 }
93 
94 
sclp_attn_thread(U16 * type)95 void sclp_attn_thread(U16 *type)
96 {
97 
98     OBTAIN_INTLOCK(NULL);
99 
100     // The VM boys appear to have made an error in not
101     // allowing for asyncronous attentions to be merged
102     // with pending interrupts as such we will wait here
103     // until a pending interrupt has been cleared. *JJ
104     while(IS_IC_SERVSIG)
105     {
106         RELEASE_INTLOCK(NULL);
107         sched_yield();
108         OBTAIN_INTLOCK(NULL);
109     }
110 
111     sclp_attention(*type);
112 
113     free(type);
114 
115     RELEASE_INTLOCK(NULL);
116 }
117 
118 
sclp_attn_async(U16 type)119 void sclp_attn_async(U16 type)
120 {
121     if(!IS_IC_SERVSIG)
122         sclp_attention(type);
123     else
124     {
125     TID sclp_attn_tid;
126     U16 *typ;
127         typ=malloc(sizeof(U16));
128         *typ=type;
129         create_thread(&sclp_attn_tid, &sysblk.detattr, sclp_attn_thread, typ, "attn_thread");
130     }
131 }
132 
133 
sclp_attn_pending(U16 type)134 static U32 sclp_attn_pending(U16 type)
135 {
136 U32 pending;
137 
138     if(type)
139     {
140         pending = servc_attn_pending & (0x80000000 >> (type -1));
141         servc_attn_pending &= ~pending;
142         return pending;
143     }
144     else
145         return servc_attn_pending;
146 }
147 
148 
149 /*-------------------------------------------------------------------*/
150 /* Issue SCP command                                                 */
151 /*                                                                   */
152 /* This function is called from the control panel when the operator  */
153 /* enters an HMC system console SCP command or SCP priority message. */
154 /* The command is queued for processing by the SCLP_READ_EVENT_DATA  */
155 /* service call, and a service signal interrupt is made pending.     */
156 /*                                                                   */
157 /* Input:                                                            */
158 /*      command Null-terminated ASCII command string                 */
159 /*      priomsg 0=SCP command, 1=SCP priority message                */
160 /*-------------------------------------------------------------------*/
scp_command(char * command,int priomsg)161 void scp_command (char *command, int priomsg)
162 {
163     /* Error if disabled for priority messages */
164     if (priomsg && !SCLP_RECV_ENABLED(SCCB_EVD_TYPE_PRIOR))
165     {
166         logmsg (_("HHCCP036E SCP not receiving priority messages\n"));
167         return;
168     }
169 
170     /* Error if disabled for commands */
171     if (!priomsg && !SCLP_RECV_ENABLED(SCCB_EVD_TYPE_OPCMD))
172     {
173         logmsg (_("HHCCP037E SCP not receiving commands\n"));
174         return;
175     }
176 
177     /* Error if command string is missing */
178     if (strlen(command) < 1)
179     {
180         logmsg (_("HHCCP038E No SCP command\n"));
181         return;
182     }
183 
184     /* Obtain the interrupt lock */
185     OBTAIN_INTLOCK(NULL);
186 
187     /* Save command string and message type for read event data */
188     strncpy (servc_scpcmdstr, command, sizeof(servc_scpcmdstr));
189 
190     /* Ensure termination of the command string */
191     servc_scpcmdstr[sizeof(servc_scpcmdstr)-1] = '\0';
192 
193     /* Raise attention service signal */
194     sclp_attention( priomsg ? SCCB_EVD_TYPE_PRIOR : SCCB_EVD_TYPE_OPCMD );
195 
196     /* Release the interrupt lock */
197     RELEASE_INTLOCK(NULL);
198 
199 } /* end function scp_command */
200 
201 
sclp_opcmd_event(SCCB_HEADER * sccb,U16 type)202 static void sclp_opcmd_event(SCCB_HEADER *sccb, U16 type)
203 {
204 static BYTE     const1_template[] = {
205         0x13,0x10,                      /* MDS message unit          */
206         0x00,0x25,0x13,0x11,            /* MDS routine info          */
207              0x0E,0x81,                 /* origin location name      */
208                   0x03,0x01,0x00,       /* Net ID                    */
209                   0x03,0x02,0x00,       /* NAU Name                  */
210                   0x06,0x03,0x00,0x00,0x00,0x00,  /* Appl id         */
211              0x0E,0x82,                 /* Destinition location name */
212                   0x03,0x01,0x00,       /* Net ID                    */
213                   0x03,0x02,0x00,       /* NAU Name                  */
214                   0x06,0x03,0x00,0x00,0x00,0x00,  /* Appl id         */
215              0x05,0x90,0x00,0x00,0x00,  /* Flags (MDS type = req)    */
216         0x00,0x0C,0x15,0x49,            /* Agent unit-of-work        */
217              0x08,0x01,                 /* Requestor loc name        */
218                   0x03,0x01,0x00,       /* Requestor Net ID          */
219                   0x03,0x02,0x00        /* Requestor Node ID         */
220         };
221 
222 static BYTE    const2_template[] = {
223         0x12,0x12,                      /* CP-MSU                    */
224         0x00,0x12,0x15,0x4D,            /* RTI                       */
225              0x0E,0x06,                 /* Name List                 */
226                   0x06,0x10,0x00,0x03,0x00,0x00,  /* Cascaded
227                                                        resource list */
228                   0x06,0x60,0xD6,0xC3,0xC6,0xC1,  /* OAN (C'OCFA')   */
229         0x00,0x04,0x80,0x70             /* Operate request           */
230         };
231 
232 static BYTE    const3_template[] = {
233         0x13,0x20                       /* Text data                 */
234         };
235 
236 static BYTE    const4_template = {
237         0x31                            /* Self-defining             */
238         };
239 
240 static BYTE    const5_template = {
241         0x30                            /* Text data                 */
242         };
243 
244 U16 sccb_len;
245 U16 evd_len;
246 int event_msglen;
247 int i;
248 
249 SCCB_EVD_HDR *evd_hdr = (SCCB_EVD_HDR*)(sccb+1);
250 SCCB_EVD_BK *evd_bk = (SCCB_EVD_BK*)(evd_hdr+1);
251 BYTE *event_msg = (BYTE*)(evd_bk+1);
252 
253     /* Get SCCB length */
254     FETCH_HW(sccb_len, sccb->length);
255 
256     /* Command length */
257     event_msglen = strlen(servc_scpcmdstr);
258 
259     /* Calculate required EVD length */
260     evd_len = event_msglen + sizeof(SCCB_EVD_HDR) + sizeof(SCCB_EVD_BK);
261 
262     /* Set response code X'75F0' if SCCB length exceeded */
263     if ((evd_len + sizeof(SCCB_HEADER)) > sccb_len)
264     {
265         sccb->reas = SCCB_REAS_EXCEEDS_SCCB;
266         sccb->resp = SCCB_RESP_EXCEEDS_SCCB;
267         return;
268     }
269 
270     /* Zero all fields */
271     memset (evd_hdr, 0, evd_len);
272 
273     /* Update SCCB length field if variable request */
274     if (sccb->type & SCCB_TYPE_VARIABLE)
275     {
276         /* Set new SCCB length */
277         sccb_len = evd_len + sizeof(SCCB_HEADER);
278         STORE_HW(sccb->length, sccb_len);
279         sccb->type &= ~SCCB_TYPE_VARIABLE;
280     }
281 
282     /* Set length in event header */
283     STORE_HW(evd_hdr->totlen, evd_len);
284 
285     /* Set type in event header */
286     evd_hdr->type = type;
287 
288     /* Set message length in event data block */
289     i = evd_len - sizeof(SCCB_EVD_HDR);
290     STORE_HW(evd_bk->msglen, i);
291     memcpy (evd_bk->const1, const1_template,
292                             sizeof(const1_template));
293     i -= sizeof(const1_template) + 2;
294     STORE_HW(evd_bk->cplen, i);
295     memcpy (evd_bk->const2, const2_template,
296                             sizeof(const2_template));
297     i -= sizeof(const2_template) + 2;
298     STORE_HW(evd_bk->tdlen, i);
299     memcpy (evd_bk->const3, const3_template,
300                             sizeof(const3_template));
301     i -= sizeof(const3_template) + 2;
302     evd_bk->sdtlen = i;
303     evd_bk->const4 = const4_template;
304     i -= 2;
305     evd_bk->tmlen = i;
306     evd_bk->const5 = const5_template;
307 
308     /* Copy and translate command */
309     for (i = 0; i < event_msglen; i++)
310             event_msg[i] = host_to_guest(servc_scpcmdstr[i]);
311 
312     /* Set response code X'0020' in SCCB header */
313     sccb->reas = SCCB_REAS_NONE;
314     sccb->resp = SCCB_RESP_COMPLETE;
315 }
316 
317 
sclp_cpident(SCCB_HEADER * sccb)318 void sclp_cpident(SCCB_HEADER *sccb)
319 {
320 SCCB_EVD_HDR *evd_hdr = (SCCB_EVD_HDR*)(sccb + 1);
321 SCCB_CPI_BK  *cpi_bk  = (SCCB_CPI_BK*)(evd_hdr + 1);
322 int i;
323 char systype[9], sysname[9], sysplex[9];
324 U64  syslevel;
325 
326     if(*(cpi_bk->system_type))
327         set_systype(cpi_bk->system_type);
328     if(*(cpi_bk->system_name))
329         set_sysname(cpi_bk->system_name);
330     if(*(cpi_bk->sysplex_name))
331         set_sysplex(cpi_bk->sysplex_name);
332 
333     for(i = 0; i < 8; i++)
334     {
335         systype[i] = guest_to_host(cpi_bk->system_type[i]);
336         sysname[i] = guest_to_host(cpi_bk->system_name[i]);
337         sysplex[i] = guest_to_host(cpi_bk->sysplex_name[i]);
338     }
339     systype[8] = sysname[8] = sysplex[8] = 0;
340     FETCH_DW(syslevel,cpi_bk->system_level);
341 
342 #if 1
343     logmsg(_("HHCCP040I CPI: System Type: %s Name: %s "
344              "Sysplex: %s\n"),
345         systype,sysname,sysplex);
346 #else
347     logmsg(_("HHC770I Control Program Information:\n"));
348     logmsg(_("HHC771I System Type  = %s\n",systype));
349     logmsg(_("HHC772I System Name  = %s\n",sysname));
350     logmsg(_("HHC773I Sysplex Name = %s\n",sysplex));
351     logmsg(_("HHC774I System Level = %16.16" I64_FMT "X\n"),syslevel);
352 #endif
353 
354     losc_check(systype);
355 
356     /* Indicate Event Processed */
357     evd_hdr->flag |= SCCB_EVD_FLAG_PROC;
358 
359     /* Set response code X'0020' in SCCB header */
360     sccb->reas = SCCB_REAS_NONE;
361     sccb->resp = SCCB_RESP_COMPLETE;
362 }
363 
364 
365 /*-------------------------------------------------------------------*/
366 /* Test whether SCP is enabled for QUIESCE signal                    */
367 /*                                                                   */
368 /* This function tests whether the SCP is willing to be notified     */
369 /* of a system shutdown via the SCLP_READ_EVENT_DATA service call.   */
370 /*                                                                   */
371 /* Return code:                                                      */
372 /*      Zero = SCP not receiving quiesce event notification          */
373 /*      Non-zero = SCP ready to receive quiesce event notification   */
374 /*-------------------------------------------------------------------*/
can_signal_quiesce()375 int can_signal_quiesce()
376 {
377     return SCLP_RECV_ENABLED(SCCB_EVD_TYPE_SIGQ);
378 }
379 
380 
381 /*-------------------------------------------------------------------*/
382 /* Send QUIESCE signal to SCP                                        */
383 /*                                                                   */
384 /* This function is called during system shutdown to notify the SCP  */
385 /* that a shutdown event is occurring. The shutdown event is queued  */
386 /* for processing by the SCLP_READ_EVENT_DATA service call, and a    */
387 /* service signal interrupt is made pending.                         */
388 /*                                                                   */
389 /* Input:                                                            */
390 /*      count and unit values to be returned by SCLP_READ_EVENT_DATA */
391 /*-------------------------------------------------------------------*/
signal_quiesce(U16 count,BYTE unit)392 int signal_quiesce (U16 count, BYTE unit)
393 {
394     /* Error if disabled for commands */
395     if (!SCLP_RECV_ENABLED(SCCB_EVD_TYPE_SIGQ))
396     {
397         logmsg (_("HHCCP081E SCP not receiving quiesce signals\n"));
398         return -1;
399     }
400 
401     /* Obtain the interrupt lock */
402     OBTAIN_INTLOCK(NULL);
403 
404     /* Save delay values for signal shutdown event read */
405     servc_signal_quiesce_count = count;
406     servc_signal_quiesce_unit = unit;
407 
408     sclp_attention(SCCB_EVD_TYPE_SIGQ);
409 
410     /* Release the interrupt lock */
411     RELEASE_INTLOCK(NULL);
412 
413     return 0;
414 } /* end function signal_quiesce */
415 
416 
sclp_sigq_event(SCCB_HEADER * sccb)417 static void sclp_sigq_event(SCCB_HEADER *sccb)
418 {
419 U16 sccb_len;
420 U16 evd_len;
421 SCCB_EVD_HDR *evd_hdr = (SCCB_EVD_HDR*)(sccb+1);
422 SCCB_SGQ_BK *sgq_bk = (SCCB_SGQ_BK*)(evd_hdr+1);
423 
424     FETCH_HW(sccb_len, sccb->length);
425     evd_len = sizeof(SCCB_EVD_HDR) + sizeof(SCCB_SGQ_BK);
426 
427     /* Set response code X'75F0' if SCCB length exceeded */
428     if ((evd_len + sizeof(SCCB_HEADER)) > sccb_len)
429     {
430         sccb->reas = SCCB_REAS_EXCEEDS_SCCB;
431         sccb->resp = SCCB_RESP_EXCEEDS_SCCB;
432         return;
433     }
434 
435     /* Zero all fields */
436     memset (evd_hdr, 0, evd_len);
437 
438     /* Update SCCB length field if variable request */
439     if (sccb->type & SCCB_TYPE_VARIABLE)
440     {
441         /* Set new SCCB length */
442         sccb_len = evd_len + sizeof(SCCB_HEADER);
443         STORE_HW(sccb->length, sccb_len);
444         sccb->type &= ~SCCB_TYPE_VARIABLE;
445     }
446 
447     /* Set length in event header */
448     STORE_HW(evd_hdr->totlen, evd_len);
449 
450     /* Set type in event header */
451     evd_hdr->type = SCCB_EVD_TYPE_SIGQ;
452 
453     STORE_HW(sgq_bk->count, servc_signal_quiesce_count);
454     sgq_bk->unit = servc_signal_quiesce_unit;
455 
456     /* Set response code X'0020' in SCCB header */
457     sccb->reas = SCCB_REAS_NONE;
458     sccb->resp = SCCB_RESP_COMPLETE;
459 }
460 
461 
462 #if defined(_FEATURE_INTEGRATED_3270_CONSOLE)
463 /*-------------------------------------------------------------------*/
464 /* Write data to the SYSG console                                    */
465 /*                                                                   */
466 /* The datastream to be written to the SYSG console is in the SCCB   */
467 /* immediately following the Event Data Header. It consists of a     */
468 /* one-byte local 3270 CCW command code, followed by a 3270 WCC,     */
469 /* followed by 3270 orders and data.                                 */
470 /*                                                                   */
471 /* Input:                                                            */
472 /*      sccb    Address of SCCB                                      */
473 /*      evd_hdr Address of event data header within SCCB             */
474 /* Output:                                                           */
475 /*      Reason and response codes are set in the SCCB                */
476 /*                                                                   */
477 /*-------------------------------------------------------------------*/
sclp_sysg_write(SCCB_HEADER * sccb)478 void sclp_sysg_write(SCCB_HEADER *sccb)
479 {
480 SCCB_EVD_HDR *evd_hdr = (SCCB_EVD_HDR*)(sccb+1);
481 U16             evd_len;                /* SCCB event data length    */
482 U16             sysg_len;               /* SYSG output data length   */
483 DEVBLK         *dev;                    /* -> SYSG console devblk    */
484 BYTE           *sysg_data;              /* -> SYSG output data       */
485 BYTE            unitstat;               /* Unit status               */
486 BYTE            more = 0;               /* Flag for device handler   */
487 U16             residual;               /* Residual data count       */
488 BYTE            cmdcode;                /* 3270 read/write command   */
489 
490     /* Calculate the address and length of the 3270 datastream */
491     FETCH_HW(evd_len,evd_hdr->totlen);
492     sysg_data = (BYTE*)(evd_hdr+1);
493     sysg_len = evd_len - sizeof(SCCB_EVD_HDR);
494 
495     /* The first data byte is the 3270 command code */
496     cmdcode = *sysg_data;
497 
498     /* Look for the SYSG console device block */
499     dev = sysblk.sysgdev;
500     if (dev == NULL)
501     {
502         PTT(PTT_CL_ERR,"*SERVC",(U32)cmdcode,(U32)sysg_len,0);
503 
504         /* Set response code X'05F0' in SCCB header */
505         sccb->reas = SCCB_REAS_IMPROPER_RSC;
506         sccb->resp = SCCB_RESP_REJECT;
507         return;
508     }
509 
510     /* If it is a read CCW then save the command until READ_EVENT_DATA */
511     if (IS_CCW_READ(cmdcode))
512     {
513 
514         servc_sysg_cmdcode = cmdcode;
515 
516         /* Indicate Event Processed */
517         evd_hdr->flag |= SCCB_EVD_FLAG_PROC;
518 
519         /* Generate a service call interrupt to trigger READ_EVENT_DATA */
520         sclp_attn_async(SCCB_EVD_TYPE_SYSG);
521 
522         /* Set response code X'0020' in SCCB header */
523         sccb->reas = SCCB_REAS_NONE;
524         sccb->resp = SCCB_RESP_COMPLETE;
525         return;
526     }
527     else
528     {
529         servc_sysg_cmdcode = 0x00;
530 
531         /* Execute the 3270 command in data block */
532         /* dev->hnd->exec points to loc3270_execute_ccw */
533         (dev->hnd->exec) (dev, /*ccw opcode*/ cmdcode,
534             /*flags*/ CCW_FLAGS_SLI, /*chained*/0,
535             /*count*/ sysg_len - 1,
536             /*prevcode*/ 0, /*ccwseq*/ 0, /*iobuf*/ sysg_data+1,
537             &more, &unitstat, &residual);
538 
539         /* Indicate Event Processed */
540         evd_hdr->flag |= SCCB_EVD_FLAG_PROC;
541 
542         /* If unit check occured, set response code X'0040' */
543         if (unitstat & CSW_UC)
544         {
545             PTT(PTT_CL_ERR,"*SERVC",(U32)more,(U32)unitstat,residual);
546 
547             /* Set response code X'0040' in SCCB header */
548             sccb->reas = SCCB_REAS_NONE;
549             sccb->resp = SCCB_RESP_BACKOUT;
550             return;
551         }
552 
553         /* Set response code X'0020' in SCCB header */
554         sccb->reas = SCCB_REAS_NONE;
555         sccb->resp = SCCB_RESP_COMPLETE;
556     }
557 }
558 
559 /*-------------------------------------------------------------------*/
560 /* Read data from the SYSG console                                   */
561 /*                                                                   */
562 /* If the SYSG console has data to send, copy it into the SCCB       */
563 /* immediately following the Event Data Header. The data consists    */
564 /* of a 3270 AID byte, followed by a two-byte 3270 cursor address,   */
565 /* followed by 3270 orders and data.                                 */
566 /*                                                                   */
567 /* Output:                                                           */
568 /*      Data, reason and response codes are set in the SCCB          */
569 /*                                                                   */
570 /*-------------------------------------------------------------------*/
sclp_sysg_poll(SCCB_HEADER * sccb)571 void sclp_sysg_poll(SCCB_HEADER *sccb)
572 {
573 SCCB_EVD_HDR *evd_hdr = (SCCB_EVD_HDR*)(sccb+1);
574 U16             sccblen;                /* SCCB total length         */
575 U16             evd_len;                /* SCCB event data length    */
576 U16             sysg_len;               /* SYSG input data length    */
577 DEVBLK         *dev;                    /* -> SYSG console devblk    */
578 BYTE           *sysg_data;              /* -> SYSG input data        */
579 BYTE           *sysg_cmd;               /* -> SYSG input data        */
580 BYTE            unitstat;               /* Unit status               */
581 BYTE            more = 0;               /* Flag for device handler   */
582 U16             residual;               /* Residual data count       */
583 
584     dev = sysblk.sysgdev;
585     if (dev != NULL)
586     {
587         /* Zeroize the event data header */
588         memset (evd_hdr, 0, sizeof(SCCB_EVD_HDR));
589 
590         /* Calculate maximum data length */
591         FETCH_HW(sccblen, sccb->length);
592         evd_len = sccblen - sizeof(SCCB_HEADER);
593         sysg_data = (BYTE*)(evd_hdr+1);
594         sysg_len = evd_len - sizeof(SCCB_EVD_HDR);
595 
596         /* Insert flag byte before the 3270 input data */
597         sysg_cmd = sysg_data;
598         sysg_len-=1;
599         sysg_data+=1;
600 
601         /* Execute previously saved 3270 read command */
602         if (servc_sysg_cmdcode)
603         {
604             *sysg_cmd = 0x00;
605 
606             /* Execute a 3270 read-modified command */
607             /* dev->hnd->exec points to loc3270_execute_ccw */
608             (dev->hnd->exec) (dev, /*ccw opcode*/ servc_sysg_cmdcode,
609                 /*flags*/ CCW_FLAGS_SLI, /*chained*/0,
610                 /*count*/ sysg_len,
611                 /*prevcode*/ 0, /*ccwseq*/ 0, /*iobuf*/ sysg_data,
612                 &more, &unitstat, &residual);
613 
614             servc_sysg_cmdcode = 0;
615 
616             /* Set response code X'0040' if unit check occurred */
617             if (unitstat & CSW_UC)
618             {
619                 PTT(PTT_CL_ERR,"*SERVC",(U32)more,(U32)unitstat,residual);
620 
621                 /* Set response code X'0040' in SCCB header */
622                 sccb->reas = SCCB_REAS_NONE;
623                 sccb->resp = SCCB_RESP_BACKOUT;
624                 return;
625             }
626 
627             /* Set response code X'75F0' if SCCB length exceeded */
628             if (more)
629             {
630                 PTT(PTT_CL_ERR,"*SERVC",(U32)more,(U32)unitstat,residual);
631 
632                 sccb->reas = SCCB_REAS_EXCEEDS_SCCB;
633                 sccb->resp = SCCB_RESP_EXCEEDS_SCCB;
634                 return;
635             }
636 
637             /* Calculate actual length read */
638             sysg_len -= residual;
639             evd_len = sizeof(SCCB_EVD_HDR) + sysg_len + 1;
640 
641             /* Set response code X'0020' in SCCB header */
642             sccb->reas = SCCB_REAS_NONE;
643             sccb->resp = SCCB_RESP_COMPLETE;
644         }
645         else
646         {
647             evd_len = sizeof(SCCB_EVD_HDR) + 1;
648             *sysg_cmd = 0x80;
649 
650             /* Set response code X'0020' in SCCB header */
651             sccb->reas = SCCB_REAS_NONE;
652             sccb->resp = SCCB_RESP_COMPLETE;
653         }
654 
655         /* Update SCCB length field if variable request */
656         if (sccb->type & SCCB_TYPE_VARIABLE)
657         {
658             /* Set new SCCB length */
659             sccblen = evd_len + sizeof(SCCB_HEADER);
660             STORE_HW(sccb->length, sccblen);
661             sccb->type &= ~SCCB_TYPE_VARIABLE;
662         }
663 
664         /* Set length in event header */
665         STORE_HW(evd_hdr->totlen, evd_len);
666 
667         /* Set type in event header */
668         evd_hdr->type = SCCB_EVD_TYPE_SYSG;
669     }
670 }
671 
672 /*-------------------------------------------------------------------*/
673 /* Handle attention interrupt from the SYSG console                  */
674 /*                                                                   */
675 /* This function is called by console.c when it receives input       */
676 /* from the SYSG console. It sets the SYSG read flag and raises      */
677 /* a service signal external interrupt, which should prompt the      */
678 /* SCP to issue a SCLP_READ_EVENT_DATA service call to retrieve      */
679 /* the input data.                                                   */
680 /*-------------------------------------------------------------------*/
681 SERV_DLL_IMPORT
sclp_sysg_attention()682 void sclp_sysg_attention()
683 {
684 
685     OBTAIN_INTLOCK(NULL);
686 
687     sclp_attn_async(SCCB_EVD_TYPE_SYSG);
688 
689     RELEASE_INTLOCK(NULL);
690 }
691 #endif /*defined(_FEATURE_INTEGRATED_3270_CONSOLE)*/
692 
693 
694 #if defined(_FEATURE_INTEGRATED_ASCII_CONSOLE)
sclp_sysa_write(SCCB_HEADER * sccb)695 int sclp_sysa_write(SCCB_HEADER *sccb)
696 {
697 SCCB_EVD_HDR *evd_hdr = (SCCB_EVD_HDR*)(sccb+1);
698 U16 evd_len;
699 U16 sysa_len;
700 BYTE *sysa_data;
701 int i;
702     logmsg(D_("SYSA write:"));
703     FETCH_HW(evd_len,evd_hdr->totlen);
704     sysa_data = (BYTE*)(evd_hdr+1);
705     sysa_len = evd_len - sizeof(SCCB_EVD_HDR);
706     for(i = 0; i < sysa_len; i++)
707     {
708         if(!(i & 15))
709             logmsg("\n          %4.4X:", i);
710         logmsg(" %2.2X", sysa_data[i]);
711     }
712 
713     if(i & 15)
714         logmsg("\n");
715 
716     /* Indicate Event Processed */
717     evd_hdr->flag |= SCCB_EVD_FLAG_PROC;
718 
719     /* Set response code X'0020' in SCCB header */
720     sccb->reas = SCCB_REAS_NONE;
721     sccb->resp = SCCB_RESP_COMPLETE;  // maybe this needs to be INFO
722 
723     //sclp_attention(SCCB_EVD_TYPE_VT220);
724 
725     return 0; // write ok
726 }
727 
sclp_sysa_poll(SCCB_HEADER * sccb)728 int sclp_sysa_poll(SCCB_HEADER *sccb)
729 {
730 SCCB_EVD_HDR *evd_hdr = (SCCB_EVD_HDR*)(sccb+1);
731 
732     UNREFERENCED(sccb);
733     UNREFERENCED(evd_hdr);
734 
735     logmsg(D_("VT220 poll\n"));
736 }
737 #endif /*defined(_FEATURE_INTEGRATED_ASCII_CONSOLE)*/
738 
739 
740 /*-------------------------------------------------------------------*/
741 /* Suspend and resume functions                                      */
742 /*-------------------------------------------------------------------*/
743 
744 #define SR_SYS_SERVC_RECVMASK    ( SR_SYS_SERVC | 0x001 )
745 #define SR_SYS_SERVC_SENDMASK    ( SR_SYS_SERVC | 0x002 )
746 #define SR_SYS_SERVC_PENDING     ( SR_SYS_SERVC | 0x003 )
747 #define SR_SYS_SERVC_SCPCMD      ( SR_SYS_SERVC | 0x004 )
748 #define SR_SYS_SERVC_SQC         ( SR_SYS_SERVC | 0x005 )
749 #define SR_SYS_SERVC_SQU         ( SR_SYS_SERVC | 0x006 )
750 #define SR_SYS_SERVC_PARM        ( SR_SYS_SERVC | 0x007 )
751 
servc_hsuspend(void * file)752 int servc_hsuspend(void *file)
753 {
754     SR_WRITE_VALUE(file, SR_SYS_SERVC_RECVMASK, servc_cp_recv_mask, sizeof(servc_cp_recv_mask));
755     SR_WRITE_VALUE(file, SR_SYS_SERVC_SENDMASK, servc_cp_send_mask, sizeof(servc_cp_send_mask));
756     SR_WRITE_VALUE(file, SR_SYS_SERVC_PENDING, servc_attn_pending, sizeof(servc_attn_pending));
757     SR_WRITE_STRING(file, SR_SYS_SERVC_SCPCMD,  servc_scpcmdstr);
758     SR_WRITE_VALUE(file, SR_SYS_SERVC_SQC,      servc_signal_quiesce_count,
759                                          sizeof(servc_signal_quiesce_count));
760     SR_WRITE_VALUE(file, SR_SYS_SERVC_SQU,      servc_signal_quiesce_unit,
761                                          sizeof(servc_signal_quiesce_unit));
762     SR_WRITE_VALUE(file, SR_SYS_SERVC_PARM,     sysblk.servparm,
763                                          sizeof(sysblk.servparm));
764     return 0;
765 }
766 
servc_hresume(void * file)767 int servc_hresume(void *file)
768 {
769     size_t key, len;
770 
771     sclp_reset();
772     do {
773         SR_READ_HDR(file, key, len);
774         switch (key) {
775         case SR_SYS_SERVC_RECVMASK:
776             SR_READ_VALUE(file, len, &servc_cp_recv_mask, sizeof(servc_cp_recv_mask));
777             break;
778         case SR_SYS_SERVC_SENDMASK:
779             SR_READ_VALUE(file, len, &servc_cp_send_mask, sizeof(servc_cp_send_mask));
780             break;
781         case SR_SYS_SERVC_PENDING:
782             SR_READ_VALUE(file, len, &servc_attn_pending, sizeof(servc_attn_pending));
783             break;
784         case SR_SYS_SERVC_SCPCMD:
785             if ( len <= sizeof(servc_scpcmdstr) )
786                 SR_READ_STRING(file, servc_scpcmdstr, sizeof(servc_scpcmdstr));
787             else
788                 SR_READ_SKIP(file, len);
789             break;
790         case SR_SYS_SERVC_SQC:
791             SR_READ_VALUE(file, len, &servc_signal_quiesce_count,
792                               sizeof(servc_signal_quiesce_count));
793             break;
794         case SR_SYS_SERVC_SQU:
795             SR_READ_VALUE(file, len, &servc_signal_quiesce_unit,
796                               sizeof(servc_signal_quiesce_unit));
797             break;
798         case SR_SYS_SERVC_PARM:
799             SR_READ_VALUE(file, len, &sysblk.servparm, sizeof(sysblk.servparm));
800             break;
801         default:
802             SR_READ_SKIP(file, len);
803             break;
804         }
805     } while ((key & SR_SYS_MASK) == SR_SYS_SERVC);
806     return 0;
807 }
808 
809 #endif /*!defined(_SERVICE_C)*/
810 
811 // #endif /*FEATURE_SYSTEM_CONSOLE*/
812 
813 #if defined(FEATURE_SERVICE_PROCESSOR)
814 /*-------------------------------------------------------------------*/
815 /* Architecture-dependent service processor bit strings              */
816 /*-------------------------------------------------------------------*/
817 BYTE ARCH_DEP(scpinfo_ifm)[8] = {
818                         0
819                         | SCCB_IFM0_CHANNEL_PATH_INFORMATION
820                         | SCCB_IFM0_CHANNEL_PATH_SUBSYSTEM_COMMAND
821 //                      | SCCB_IFM0_CHANNEL_PATH_RECONFIG
822 //                      | SCCB_IFM0_CPU_INFORMATION
823 #ifdef FEATURE_CPU_RECONFIG
824                         | SCCB_IFM0_CPU_RECONFIG
825 #endif /*FEATURE_CPU_RECONFIG*/
826                         ,
827                         0
828 //                      | SCCB_IFM1_SIGNAL_ALARM
829 //                      | SCCB_IFM1_WRITE_OPERATOR_MESSAGE
830 //                      | SCCB_IFM1_STORE_STATUS_ON_LOAD
831 //                      | SCCB_IFM1_RESTART_REASONS
832 //                      | SCCB_IFM1_INSTRUCTION_ADDRESS_TRACE_BUFFER
833                         | SCCB_IFM1_LOAD_PARAMETER
834                         ,
835                         0
836 //                      | SCCB_IFM2_REAL_STORAGE_INCREMENT_RECONFIG
837 //                      | SCCB_IFM2_REAL_STORAGE_ELEMENT_INFO
838 //                      | SCCB_IFM2_REAL_STORAGE_ELEMENT_RECONFIG
839 //                      | SCCB_IFM2_COPY_AND_REASSIGN_STORAGE
840 #ifdef FEATURE_EXPANDED_STORAGE
841                         | SCCB_IFM2_EXTENDED_STORAGE_USABILITY_MAP
842 #endif /*FEATURE_EXPANDED_STORAGE*/
843 //                      | SCCB_IFM2_EXTENDED_STORAGE_ELEMENT_INFO
844 //                      | SCCB_IFM2_EXTENDED_STORAGE_ELEMENT_RECONFIG
845                         ,
846                         0
847 #if defined(FEATURE_VECTOR_FACILITY) && defined(FEATURE_CPU_RECONFIG)
848                         | SCCB_IFM3_VECTOR_FEATURE_RECONFIG
849 #endif /*FEATURE_VECTOR_FACILITY*/
850 #ifdef FEATURE_SYSTEM_CONSOLE
851                         | SCCB_IFM3_READ_WRITE_EVENT_FEATURE
852 #endif /*FEATURE_SYSTEM_CONSOLE*/
853 //                      | SCCB_IFM3_READ_RESOURCE_GROUP_INFO
854                         ,
855                         0, 0, 0, 0 };
856 
857 BYTE ARCH_DEP(scpinfo_cfg)[6] = {
858                         0
859 #if defined(FEATURE_HYPERVISOR)
860                         | SCCB_CFG0_LOGICALLY_PARTITIONED
861 #endif /*defined(FEATURE_HYPERVISOR)*/
862 #ifdef FEATURE_SUPPRESSION_ON_PROTECTION
863                         | SCCB_CFG0_SUPPRESSION_ON_PROTECTION
864 #endif /*FEATURE_SUPPRESSION_ON_PROTECTION*/
865 //                      | SCCB_CFG0_INITIATE_RESET
866 #if defined(FEATURE_CHSC)
867                         | SCCB_CFG0_STORE_CHANNEL_SUBSYS_CHARACTERISTICS
868 #endif /*defined(FEATURE_CHSC)*/
869 #if defined(FEATURE_MOVE_PAGE_FACILITY_2)
870                         | SCCB_CFG0_MVPG_FOR_ALL_GUESTS
871 #endif /*defined(FEATURE_MOVE_PAGE_FACILITY_2)*/
872 #if defined(FEATURE_FAST_SYNC_DATA_MOVER)
873     /* The Fast Sync Data Mover facility is simply a flag which
874        indicates that the MVPG instruction performs faster than
875        the Asynchronous Data Mover facility (see GA22-1030-03) */
876                         | SCCB_CFG0_FAST_SYNCHRONOUS_DATA_MOVER
877 #endif /*defined(FEATURE_FAST_SYNC_DATA_MOVER)*/
878                         ,
879                         0
880 //                      | SCCB_CFG1_CSLO
881                         ,
882                         0
883 //                      | SCCB_CFG2_DEVICE_ACTIVE_ONLY_MEASUREMENT
884 #ifdef FEATURE_CALLED_SPACE_IDENTIFICATION
885                         | SCCB_CFG2_CALLED_SPACE_IDENTIFICATION
886 #endif /*FEATURE_CALLED_SPACE_IDENTIFICATION*/
887 #ifdef FEATURE_CHECKSUM_INSTRUCTION
888                         | SCCB_CFG2_CHECKSUM_INSTRUCTION
889 #endif /*FEATURE_CHECKSUM_INSTRUCTION*/
890                         ,
891                         0
892 #if defined(FEATURE_RESUME_PROGRAM)
893                         | SCCB_CFG3_RESUME_PROGRAM
894 #endif /*defined(FEATURE_RESUME_PROGRAM)*/
895 #if defined(FEATURE_PERFORM_LOCKED_OPERATION)
896                         | SCCB_CFG3_PERFORM_LOCKED_OPERATION
897 #endif /*defined(FEATURE_PERFORM_LOCKED_OPERATION)*/
898 #ifdef FEATURE_IMMEDIATE_AND_RELATIVE
899                         | SCCB_CFG3_IMMEDIATE_AND_RELATIVE
900 #endif /*FEATURE_IMMEDIATE_AND_RELATIVE*/
901 #ifdef FEATURE_COMPARE_AND_MOVE_EXTENDED
902                         | SCCB_CFG3_COMPARE_AND_MOVE_EXTENDED
903 #endif /*FEATURE_COMPARE_AND_MOVE_EXTENDED*/
904 #ifdef FEATURE_BRANCH_AND_SET_AUTHORITY
905                         | SCCB_CFG3_BRANCH_AND_SET_AUTHORITY
906 #endif /*FEATURE_BRANCH_AND_SET_AUTHORITY*/
907 #if defined(FEATURE_BASIC_FP_EXTENSIONS)
908                         | SCCB_CFG3_EXTENDED_FLOATING_POINT
909 #endif /*defined(FEATURE_BASIC_FP_EXTENSIONS)*/
910 /*ZZ*/                  | SCCB_CFG3_EXTENDED_LOGICAL_COMPUTATION_FACILITY
911                         ,
912                         0
913 #ifdef FEATURE_EXTENDED_TOD_CLOCK
914                         | SCCB_CFG4_EXTENDED_TOD_CLOCK
915 #endif /*FEATURE_EXTENDED_TOD_CLOCK*/
916 #if defined(FEATURE_EXTENDED_TRANSLATION)
917                         | SCCB_CFG4_EXTENDED_TRANSLATION
918 #endif /*defined(FEATURE_EXTENDED_TRANSLATION)*/
919 #if defined(FEATURE_LOAD_REVERSED)
920                         | SCCB_CFG4_LOAD_REVERSED_FACILITY
921 #endif /*defined(FEATURE_LOAD_REVERSED)*/
922 #if defined(FEATURE_EXTENDED_TRANSLATION_FACILITY_2)
923                         | SCCB_CFG4_EXTENDED_TRANSLATION_FACILITY2
924 #endif /*defined(FEATURE_EXTENDED_TRANSLATION_FACILITY_2)*/
925 #if defined(FEATURE_STORE_SYSTEM_INFORMATION)
926                         | SCCB_CFG4_STORE_SYSTEM_INFORMATION
927 #endif /*FEATURE_STORE_SYSTEM_INFORMATION*/
928 //                      | SCCB_CFG4_LPAR_CLUSTERING
929                         | SCCB_CFG4_IFA_FACILITY
930                         ,
931                         0
932 #if defined(FEATURE_SENSE_RUNNING_STATUS)
933                         | SCCB_CFG5_SENSE_RUNNING_STATUS
934 #endif /*FEATURE_SENSE_RUNNING_STATUS*/
935                         };
936 
937 BYTE ARCH_DEP(scpinfo_cfg11) =
938     0
939 #if defined(FEATURE_PER3)
940         | SCCB_CFGB_PER_3
941 #endif
942         | SCCB_CFGB_LIST_DIRECTED_IPL;
943 
944 BYTE ARCH_DEP(scpinfo_cpf)[12] = {
945                             0
946 #if defined(FEATURE_INTERPRETIVE_EXECUTION)
947 #if defined(_370) && !defined(FEATURE_ESAME)
948                             | SCCB_CPF0_SIE_370_MODE
949 #endif /*defined(_370) && !defined(FEATURE_ESAME)*/
950                             | SCCB_CPF0_SIE_XA_MODE
951 #endif /*defined(FEATURE_INTERPRETIVE_EXECUTION)*/
952 //                          | SCCB_CPF0_SIE_SET_II_370_MODE
953 #if defined(FEATURE_IO_ASSIST)
954                             | SCCB_CPF0_SIE_SET_II_XA_MODE
955 #endif /*defined(FEATURE_IO_ASSIST)*/
956 #if defined(FEATURE_INTERPRETIVE_EXECUTION)
957                             | SCCB_CPF0_SIE_NEW_INTERCEPT_FORMAT
958 #endif /*defined(FEATURE_INTERPRETIVE_EXECUTION)*/
959 #if defined(FEATURE_STORAGE_KEY_ASSIST)
960                             | SCCB_CPF0_STORAGE_KEY_ASSIST
961 #endif /*defined(FEATURE_STORAGE_KEY_ASSIST)*/
962 #if defined(_FEATURE_MULTIPLE_CONTROLLED_DATA_SPACE)
963                             | SCCB_CPF0_MULTIPLE_CONTROLLED_DATA_SPACE
964 #endif /*defined(_FEATURE_MULTIPLE_CONTROLLED_DATA_SPACE)*/
965                             ,
966                             0
967 #if defined(FEATURE_IO_ASSIST)
968                             | SCCB_CPF1_IO_INTERPRETATION_LEVEL_2
969 #endif /*defined(FEATURE_IO_ASSIST)*/
970 #if defined(FEATURE_INTERPRETIVE_EXECUTION)
971                             | SCCB_CPF1_GUEST_PER_ENHANCED
972 #endif /*defined(FEATURE_INTERPRETIVE_EXECUTION)*/
973 //                          | SCCB_CPF1_SIGP_INTERPRETATION_ASSIST
974 #if defined(FEATURE_STORAGE_KEY_ASSIST)
975                             | SCCB_CPF1_RCP_BYPASS_FACILITY
976 #endif /*defined(FEATURE_STORAGE_KEY_ASSIST)*/
977 #if defined(FEATURE_REGION_RELOCATE)
978                             | SCCB_CPF1_REGION_RELOCATE_FACILITY
979 #endif /*defined(FEATURE_REGION_RELOCATE)*/
980 #if defined(FEATURE_EXPEDITED_SIE_SUBSET)
981                             | SCCB_CPF1_EXPEDITE_TIMER_PROCESSING
982 #endif /*defined(FEATURE_EXPEDITED_SIE_SUBSET)*/
983                             ,
984                             0
985 #if defined(FEATURE_CRYPTO)
986                             | SCCB_CPF2_CRYPTO_FEATURE_ACCESSED
987 #endif /*defined(FEATURE_CRYPTO)*/
988 #if defined(FEATURE_EXPEDITED_SIE_SUBSET)
989                             | SCCB_CPF2_EXPEDITE_RUN_PROCESSING
990 #endif /*defined(FEATURE_EXPEDITED_SIE_SUBSET)*/
991                             ,
992                             0
993 #ifdef FEATURE_PRIVATE_SPACE
994                             | SCCB_CPF3_PRIVATE_SPACE_FEATURE
995                             | SCCB_CPF3_FETCH_ONLY_BIT
996 #endif /*FEATURE_PRIVATE_SPACE*/
997 #if defined(FEATURE_PER2)
998                             | SCCB_CPF3_PER2_INSTALLED
999 #endif /*defined(FEATURE_PER2)*/
1000                             ,
1001                             0
1002 #if defined(FEATURE_PER2)
1003                             | SCCB_CPF4_OMISION_GR_ALTERATION_370
1004 #endif /*defined(FEATURE_PER2)*/
1005                             ,
1006                             0
1007 #if defined(FEATURE_WAITSTATE_ASSIST)
1008                             | SCCB_CPF5_GUEST_WAIT_STATE_ASSIST
1009 #endif /*defined(FEATURE_WAITSTATE_ASSIST)*/
1010                             ,
1011                             0, 0, 0, 0, 0, 0
1012                             } ;
1013 
1014 U32  ARCH_DEP(sclp_recv_mask) =
1015         (0x80000000 >> (SCCB_EVD_TYPE_MSG-1)) |
1016         (0x80000000 >> (SCCB_EVD_TYPE_PRIOR-1)) |
1017 #if defined(FEATURE_SCEDIO)
1018         (0x80000000 >> (SCCB_EVD_TYPE_SCEDIO-1)) |
1019 #endif /*defined(FEATURE_SCEDIO)*/
1020 #if defined(FEATURE_INTEGRATED_ASCII_CONSOLE)
1021         (0x80000000 >> (SCCB_EVD_TYPE_VT220-1)) |
1022 #endif /*defined(FEATURE_INTEGRATED_ASCII_CONSOLE)*/
1023 #if defined(FEATURE_INTEGRATED_3270_CONSOLE)
1024         (0x80000000 >> (SCCB_EVD_TYPE_SYSG-1)) |
1025 #endif /*defined(FEATURE_INTEGRATED_3270_CONSOLE)*/
1026         (0x80000000 >> (SCCB_EVD_TYPE_CPIDENT-1)) ;
1027 
1028 U32  ARCH_DEP(sclp_send_mask) =
1029         (0x80000000 >> (SCCB_EVD_TYPE_OPCMD-1)) |
1030         (0x80000000 >> (SCCB_EVD_TYPE_STATECH-1)) |
1031         (0x80000000 >> (SCCB_EVD_TYPE_PRIOR-1)) |
1032         (0x80000000 >> (SCCB_EVD_TYPE_SIGQ-1)) |
1033 #if defined(FEATURE_SCEDIO)
1034         (0x80000000 >> (SCCB_EVD_TYPE_SCEDIO-1)) |
1035 #endif /*defined(FEATURE_SCEDIO)*/
1036 #if defined(FEATURE_INTEGRATED_ASCII_CONSOLE)
1037         (0x80000000 >> (SCCB_EVD_TYPE_VT220-1)) |
1038 #endif /*defined(FEATURE_INTEGRATED_ASCII_CONSOLE)*/
1039 #if defined(FEATURE_INTEGRATED_3270_CONSOLE)
1040         (0x80000000 >> (SCCB_EVD_TYPE_SYSG-1)) |
1041 #endif /*defined(FEATURE_INTEGRATED_3270_CONSOLE)*/
1042         (0x80000000 >> (SCCB_EVD_TYPE_CPCMD-1)) ;
1043 
1044 
1045 /*-------------------------------------------------------------------*/
1046 /* B220 SERVC - Service Call                                   [RRE] */
1047 /*-------------------------------------------------------------------*/
DEF_INST(service_call)1048 DEF_INST(service_call)
1049 {
1050 U32             r1, r2;                 /* Values of R fields        */
1051 U32             sclp_command;           /* SCLP command code         */
1052 U32             sccb_real_addr;         /* SCCB real address         */
1053 int             i;                      /* Array subscripts          */
1054 U32             realinc;                /* Storage size in increments*/
1055 U32             incsizemb;              /* Increment size in MB      */
1056 U32             sccb_absolute_addr;     /* Absolute address of SCCB  */
1057 U32             sccblen;                /* Length of SCCB            */
1058 SCCB_HEADER    *sccb;                   /* -> SCCB header            */
1059 SCCB_SCP_INFO  *sccbscp;                /* -> SCCB SCP information   */
1060 SCCB_CPU_INFO  *sccbcpu;                /* -> SCCB CPU information   */
1061 #if defined(FEATURE_MPF_INFO)
1062 SCCB_MPF_INFO  *sccbmpf;                /* -> SCCB MPF information   */
1063 #endif /*defined(FEATURE_MPF_INFO)*/
1064 #ifdef FEATURE_CHANNEL_SUBSYSTEM
1065 SCCB_CHP_INFO  *sccbchp;                /* -> SCCB channel path info */
1066 #else
1067 SCCB_CHSET_INFO *sccbchp;               /* -> SCCB channel path info */
1068 #endif
1069 SCCB_CSI_INFO  *sccbcsi;                /* -> SCCB channel subsys inf*/
1070 U16             offset;                 /* Offset from start of SCCB */
1071 #ifdef FEATURE_CHANNEL_SUBSYSTEM
1072 DEVBLK         *dev;                    /* Used to find CHPIDs       */
1073 U32             chpbyte;                /* Offset to byte for CHPID  */
1074 U32             chpbit;                 /* Bit number for CHPID      */
1075 #endif /*FEATURE_CHANNEL_SUBSYSTEM*/
1076 #ifdef FEATURE_SYSTEM_CONSOLE
1077 SCCB_EVENT_MASK*evd_mask;               /* Event mask                */
1078 SCCB_EVD_HDR   *evd_hdr;                /* Event header              */
1079 U16             evd_len;                /* Length of event data      */
1080 SCCB_MCD_BK    *mcd_bk;                 /* Message Control Data      */
1081 U16             mcd_len;                /* Length of MCD             */
1082 SCCB_OBJ_HDR   *obj_hdr;                /* Object Header             */
1083 U16             obj_len;                /* Length of Object          */
1084 U16             obj_type;               /* Object type               */
1085 SCCB_MTO_BK    *mto_bk;                 /* Message Text Object       */
1086 BYTE           *event_msg;              /* Message Text pointer      */
1087 int             event_msglen;           /* Message Text length       */
1088 BYTE            message[4089];          /* Maximum event data buffer
1089                                            length plus one for \0    */
1090 U32             masklen;                /* Length of event mask      */
1091 U32             old_cp_recv_mask;       /* Masks before write event  */
1092 U32             old_cp_send_mask;       /*              mask command */
1093 #endif /*FEATURE_SYSTEM_CONSOLE*/
1094 
1095 
1096 #ifdef FEATURE_EXPANDED_STORAGE
1097 SCCB_XST_MAP    *sccbxmap;              /* Xstore usability map      */
1098 U32             xstincnum;              /* Number of expanded storage
1099                                                          increments  */
1100 U32             xstblkinc;              /* Number of expanded storage
1101                                                blocks per increment  */
1102 BYTE            *xstmap;                /* Xstore bitmap, zero means
1103                                                            available */
1104 #endif /*FEATURE_EXPANDED_STORAGE*/
1105 
1106     RRE(inst, regs, r1, r2);
1107 
1108     PRIV_CHECK(regs);
1109 
1110     SIE_INTERCEPT(regs);
1111 
1112     PTT(PTT_CL_INF,"SERVC",regs->GR_L(r1),regs->GR_L(r2),regs->psw.IA_L);
1113 
1114     /* R1 is SCLP command word */
1115     sclp_command = regs->GR_L(r1);
1116 
1117     /* R2 is real address of service call control block */
1118     sccb_real_addr = regs->GR_L(r2);
1119 
1120     /* Obtain the absolute address of the SCCB */
1121     sccb_absolute_addr = APPLY_PREFIXING(sccb_real_addr, regs->PX);
1122 
1123     /* Program check if SCCB is not on a doubleword boundary */
1124     if ( sccb_absolute_addr & 0x00000007 )
1125         ARCH_DEP(program_interrupt) (regs, PGM_SPECIFICATION_EXCEPTION);
1126 
1127     /* Program check if SCCB is outside main storage */
1128     if ( sccb_absolute_addr > regs->mainlim )
1129         ARCH_DEP(program_interrupt) (regs, PGM_ADDRESSING_EXCEPTION);
1130 
1131     /* Point to service call control block */
1132     sccb = (SCCB_HEADER*)(regs->mainstor + sccb_absolute_addr);
1133 
1134     /* Load SCCB length from header */
1135     FETCH_HW(sccblen, sccb->length);
1136 
1137     /* Set the main storage reference bit */
1138     STORAGE_KEY(sccb_absolute_addr, regs) |= STORKEY_REF;
1139 
1140     /* Program check if end of SCCB falls outside main storage */
1141     if ( sccb_absolute_addr + sccblen > regs->mainlim + 1)
1142         ARCH_DEP(program_interrupt) (regs, PGM_ADDRESSING_EXCEPTION);
1143 
1144     /* Obtain lock if immediate response is not requested */
1145     if (!(sccb->flag & SCCB_FLAG_SYNC)
1146         || (sclp_command & SCLP_COMMAND_CLASS) == 0x01)
1147     {
1148         /* Obtain the interrupt lock */
1149         OBTAIN_INTLOCK(regs);
1150 
1151         /* If a service signal is pending then return condition
1152            code 2 to indicate that service processor is busy */
1153         if (IS_IC_SERVSIG && (sysblk.servparm & SERVSIG_ADDR))
1154         {
1155             RELEASE_INTLOCK(regs);
1156             regs->psw.cc = 2;
1157             return;
1158         }
1159     }
1160 
1161     /* Test SCLP command word */
1162     switch (sclp_command & SCLP_COMMAND_MASK) {
1163 
1164     case SCLP_READ_IFL_INFO:
1165         /* READ_IFL_INFO is only valid for processor type IFL */
1166         if(sysblk.ptyp[regs->cpuad] != SCCB_PTYP_IFL)
1167             goto invalidcmd;
1168         else
1169             goto read_scpinfo;
1170 
1171     case SCLP_READ_SCP_INFO:
1172         /* READ_SCP_INFO is only valid for processor type CP */
1173         if(sysblk.ptyp[regs->cpuad] != SCCB_PTYP_CP)
1174         {
1175 #ifdef OPTION_MSGCLR
1176             logmsg("<pnl,color(lightred,black)>");
1177 #endif
1178             logmsg("HHCCP090W The configuration has been placed into a system check-stop state because of an incompatible service call\n\n");
1179             goto docheckstop;
1180             /*
1181              * Replace the following 2 lines with
1182              * goto invalidcmd
1183              * if this behavior is not satisfactory
1184              * ISW 20081221
1185              */
1186         }
1187 
1188     read_scpinfo:
1189 
1190         /* Set the main storage change bit */
1191         STORAGE_KEY(sccb_absolute_addr, regs) |= STORKEY_CHANGE;
1192 
1193         /* Set response code X'0100' if SCCB crosses a page boundary */
1194         if ((sccb_absolute_addr & STORAGE_KEY_PAGEMASK) !=
1195             ((sccb_absolute_addr + sccblen - 1) & STORAGE_KEY_PAGEMASK))
1196         {
1197             sccb->reas = SCCB_REAS_NOT_PGBNDRY;
1198             sccb->resp = SCCB_RESP_BLOCK_ERROR;
1199             break;
1200         }
1201 
1202         /* Set response code X'0300' if SCCB length
1203            is insufficient to contain SCP info */
1204         if ( sccblen < sizeof(SCCB_HEADER) + sizeof(SCCB_SCP_INFO)
1205                 + (sizeof(SCCB_CPU_INFO) * MAX_CPU))
1206         {
1207             sccb->reas = SCCB_REAS_TOO_SHORT;
1208             sccb->resp = SCCB_RESP_BLOCK_ERROR;
1209             break;
1210         }
1211 
1212         /* Point to SCCB data area following SCCB header */
1213         sccbscp = (SCCB_SCP_INFO*)(sccb+1);
1214         memset (sccbscp, 0, sizeof(SCCB_SCP_INFO));
1215 
1216         /* Set main storage size in SCCB */
1217         incsizemb = (sysblk.mainsize + (0xFFFF00000ULL - 1)) / 0xFFFF00000ULL;
1218         realinc = sysblk.mainsize / (incsizemb << 20);
1219         STORE_HW(sccbscp->realinum, realinc);
1220         sccbscp->realiszm = (incsizemb & 0xFF);
1221         sccbscp->realbszk = 4;
1222         STORE_HW(sccbscp->realiint, 1);
1223 
1224 #if defined(_900) || defined(FEATURE_ESAME)
1225         /* SIE supports the full address range */
1226         sccbscp->maxvm = 0;
1227         /* realiszm is valid */
1228         STORE_FW(sccbscp->grzm, 0);
1229         /* Number of storage increments installed in esame mode */
1230         STORE_DW(sccbscp->grnmx, realinc);
1231 #endif /*defined(_900) || defined(FEATURE_ESAME)*/
1232 
1233 #ifdef FEATURE_EXPANDED_STORAGE
1234         /* Set expanded storage size in SCCB */
1235         xstincnum = sysblk.xpndsize /
1236                     (XSTORE_INCREMENT_SIZE >> XSTORE_PAGESHIFT);
1237         STORE_FW(sccbscp->xpndinum, xstincnum);
1238         xstblkinc = XSTORE_INCREMENT_SIZE >> XSTORE_PAGESHIFT;
1239         STORE_FW(sccbscp->xpndsz4K, xstblkinc);
1240 #endif /*FEATURE_EXPANDED_STORAGE*/
1241 
1242 #ifdef FEATURE_VECTOR_FACILITY
1243         /* Set the Vector section size in the SCCB */
1244         STORE_HW(sccbscp->vectssiz, VECTOR_SECTION_SIZE);
1245         /* Set the Vector partial sum number in the SCCB */
1246         STORE_HW(sccbscp->vectpsum, VECTOR_PARTIAL_SUM_NUMBER);
1247 #endif /*FEATURE_VECTOR_FACILITY*/
1248 
1249         /* Set CPU array count and offset in SCCB */
1250         STORE_HW(sccbscp->numcpu, MAX_CPU);
1251         offset = sizeof(SCCB_HEADER) + sizeof(SCCB_SCP_INFO);
1252         STORE_HW(sccbscp->offcpu, offset);
1253 
1254 #if defined(FEATURE_MPF_INFO)
1255         /* Set MPF array count and offset in SCCB */
1256         STORE_HW(sccbscp->nummpf, MAX_CPU-1);
1257 #endif /*defined(FEATURE_MPF_INFO)*/
1258         offset += sizeof(SCCB_CPU_INFO) * MAX_CPU;
1259         STORE_HW(sccbscp->offmpf, offset);
1260 
1261         /* Set HSA array count and offset in SCCB */
1262         STORE_HW(sccbscp->numhsa, 0);
1263 #if defined(FEATURE_MPF_INFO)
1264         offset += sizeof(SCCB_MPF_INFO) * MAX_CPU-1;
1265 #endif /*defined(FEATURE_MPF_INFO)*/
1266         STORE_HW(sccbscp->offhsa, offset);
1267 
1268         /* Build the MPF information array after the CPU info */
1269         /* Move IPL load parameter to SCCB */
1270         get_loadparm (sccbscp->loadparm);
1271 
1272         /* Set installed features bit mask in SCCB */
1273         memcpy(sccbscp->ifm, ARCH_DEP(scpinfo_ifm), sizeof(sccbscp->ifm));
1274 
1275         memcpy(sccbscp->cfg, ARCH_DEP(scpinfo_cfg), sizeof(sccbscp->cfg));
1276         /* sccbscp->cfg11 = ARCH_DEP(scpinfo_cfg11); */
1277 #if defined(_900) || defined(FEATURE_ESAME)
1278         if(sysblk.arch_z900)
1279             sccbscp->cfg[5] |= SCCB_CFG5_ESAME;
1280 #endif /*defined(_900) || defined(FEATURE_ESAME)*/
1281                         ;
1282 
1283         /* Build the CPU information array after the SCP info */
1284         sccbcpu = (SCCB_CPU_INFO*)(sccbscp+1);
1285         for (i = 0; i < MAX_CPU; i++, sccbcpu++)
1286         {
1287             memset (sccbcpu, 0, sizeof(SCCB_CPU_INFO));
1288             sccbcpu->cpa = i;
1289             sccbcpu->tod = 0;
1290             memcpy(sccbcpu->cpf, ARCH_DEP(scpinfo_cpf), sizeof(sccbcpu->cpf));
1291             sccbcpu->ptyp = sysblk.ptyp[i];
1292 
1293 #if defined(FEATURE_CRYPTO)
1294 //          sccbcpu->ksid = SCCB_KSID_CRYPTO_UNIT_ID;
1295 #endif /*defined(FEATURE_CRYPTO)*/
1296 
1297 #ifdef FEATURE_VECTOR_FACILITY
1298             if(IS_CPU_ONLINE(i) && sysblk.regs[i]->vf->online)
1299                 sccbcpu->cpf[2] |= SCCB_CPF2_VECTOR_FEATURE_INSTALLED;
1300             if(IS_CPU_ONLINE(i) && sysblk.regs[i]->vf->online)
1301                 sccbcpu->cpf[2] |= SCCB_CPF2_VECTOR_FEATURE_CONNECTED;
1302             if(!IS_CPU_ONLINE(i))
1303                 sccbcpu->cpf[2] |= SCCB_CPF2_VECTOR_FEATURE_STANDBY_STATE;
1304 #endif /*FEATURE_VECTOR_FACILITY*/
1305 
1306         }
1307 
1308 #if defined(FEATURE_MPF_INFO)
1309         /* Define machine capacity */
1310         STORE_FW(sccbscp->rcci, 10000);
1311         /* Fill in the MP Factors array */
1312         sccbmpf = (SCCB_MPF_INFO*)(sccbcpu);
1313         get_mpfactors((BYTE*)sccbmpf);
1314 #endif /*defined(FEATURE_MPF_INFO)*/
1315 
1316         /* Set response code X'0010' in SCCB header */
1317         sccb->reas = SCCB_REAS_NONE;
1318         sccb->resp = SCCB_RESP_INFO;
1319 
1320         break;
1321         docheckstop:
1322             ARCH_DEP(checkstop_config)();
1323             RELEASE_INTLOCK(regs);
1324             longjmp(regs->progjmp,SIE_NO_INTERCEPT);
1325             break;
1326 
1327     case SCLP_READ_CHP_INFO:
1328 
1329         /* Set the main storage change bit */
1330         STORAGE_KEY(sccb_absolute_addr, regs) |= STORKEY_CHANGE;
1331 
1332         /* Set response code X'0100' if SCCB crosses a page boundary */
1333         if ((sccb_absolute_addr & STORAGE_KEY_PAGEMASK) !=
1334             ((sccb_absolute_addr + sccblen - 1) & STORAGE_KEY_PAGEMASK))
1335         {
1336             sccb->reas = SCCB_REAS_NOT_PGBNDRY;
1337             sccb->resp = SCCB_RESP_BLOCK_ERROR;
1338             break;
1339         }
1340 
1341         /* Set response code X'0300' if SCCB length
1342            is insufficient to contain channel path info */
1343         if ( sccblen < sizeof(SCCB_HEADER) + sizeof(SCCB_CHP_INFO))
1344         {
1345             sccb->reas = SCCB_REAS_TOO_SHORT;
1346             sccb->resp = SCCB_RESP_BLOCK_ERROR;
1347             break;
1348         }
1349 
1350 #ifdef FEATURE_S370_CHANNEL
1351         /* Point to SCCB data area following SCCB header */
1352         sccbchp = (SCCB_CHSET_INFO*)(sccb+1);
1353         memset (sccbchp, 0, sizeof(SCCB_CHSET_INFO));
1354 #else
1355         /* Point to SCCB data area following SCCB header */
1356         sccbchp = (SCCB_CHP_INFO*)(sccb+1);
1357         memset (sccbchp, 0, sizeof(SCCB_CHP_INFO));
1358 #endif
1359 
1360 #ifdef FEATURE_CHANNEL_SUBSYSTEM
1361         /* Identify CHPIDs installed, standby, and online */
1362         for (dev = sysblk.firstdev; dev != NULL; dev = dev->nextdev)
1363         {
1364             chpbyte = dev->devnum >> 11;
1365             chpbit = (dev->devnum >> 8) & 7;
1366 
1367             sccbchp->installed[chpbyte] |= 0x80 >> chpbit;
1368             if (dev->pmcw.flag5 & PMCW5_V)
1369                 sccbchp->online[chpbyte] |= 0x80 >> chpbit;
1370             else
1371                 sccbchp->standby[chpbyte] |= 0x80 >> chpbit;
1372         }
1373 #endif /*FEATURE_CHANNEL_SUBSYSTEM*/
1374 
1375 #ifdef FEATURE_S370_CHANNEL
1376         /* For S/370, initialize identifiers for channel set 0A */
1377         for (i = 0; i < 16; i++)
1378         {
1379             sccbchp->chanset0a[2*i] = 0x80;
1380             sccbchp->chanset0a[2*i+1] = i;
1381         } /* end for(i) */
1382 
1383         /* Set the channel set configuration byte */
1384         sccbchp->csconfig = 0xC0;
1385 #endif /*FEATURE_S370_CHANNEL*/
1386 
1387         /* Set response code X'0010' in SCCB header */
1388         sccb->reas = SCCB_REAS_NONE;
1389         sccb->resp = SCCB_RESP_INFO;
1390 
1391         break;
1392 
1393     case SCLP_READ_CSI_INFO:
1394 
1395         /* Set the main storage change bit */
1396         STORAGE_KEY(sccb_absolute_addr, regs) |= STORKEY_CHANGE;
1397 
1398         /* Set response code X'0100' if SCCB crosses a page boundary */
1399         if ((sccb_absolute_addr & STORAGE_KEY_PAGEMASK) !=
1400             ((sccb_absolute_addr + sccblen - 1) & STORAGE_KEY_PAGEMASK))
1401         {
1402             sccb->reas = SCCB_REAS_NOT_PGBNDRY;
1403             sccb->resp = SCCB_RESP_BLOCK_ERROR;
1404             break;
1405         }
1406 
1407         /* Set response code X'0300' if SCCB length
1408            is insufficient to contain channel path info */
1409         if ( sccblen < sizeof(SCCB_HEADER) + sizeof(SCCB_CSI_INFO))
1410         {
1411             sccb->reas = SCCB_REAS_TOO_SHORT;
1412             sccb->resp = SCCB_RESP_BLOCK_ERROR;
1413             break;
1414         }
1415 
1416         /* Point to SCCB data area following SCCB header */
1417         sccbcsi = (SCCB_CSI_INFO*)(sccb+1);
1418         memset (sccbcsi, 0, sizeof(SCCB_CSI_INFO));
1419 
1420         sccbcsi->csif[0] = 0
1421 #if defined(FEATURE_CANCEL_IO_FACILITY)
1422                         | SCCB_CSI0_CANCEL_IO_REQUEST_FACILITY
1423 #endif /*defined(FEATURE_CANCEL_IO_FACILITY)*/
1424                         | SCCB_CSI0_CONCURRENT_SENSE_FACILITY
1425                         ;
1426 
1427         /* Set response code X'0010' in SCCB header */
1428         sccb->reas = SCCB_REAS_NONE;
1429         sccb->resp = SCCB_RESP_INFO;
1430 
1431         break;
1432 
1433 #ifdef FEATURE_SYSTEM_CONSOLE
1434     case SCLP_WRITE_EVENT_DATA:
1435 
1436         /* Set the main storage change bit */
1437         STORAGE_KEY(sccb_absolute_addr, regs) |= STORKEY_CHANGE;
1438 
1439         /* Set response code X'0100' if SCCB crosses a page boundary */
1440         if ((sccb_absolute_addr & STORAGE_KEY_PAGEMASK) !=
1441             ((sccb_absolute_addr + sccblen - 1) & STORAGE_KEY_PAGEMASK))
1442         {
1443             sccb->reas = SCCB_REAS_NOT_PGBNDRY;
1444             sccb->resp = SCCB_RESP_BLOCK_ERROR;
1445             break;
1446         }
1447 
1448         /* Point to SCCB data area following SCCB header */
1449         evd_hdr = (SCCB_EVD_HDR*)(sccb+1);
1450         FETCH_HW(evd_len,evd_hdr->totlen);
1451 
1452         switch(evd_hdr->type) {
1453 
1454         case SCCB_EVD_TYPE_MSG:
1455         case SCCB_EVD_TYPE_PRIOR:
1456 
1457             /* Point to the Message Control Data Block */
1458             mcd_bk = (SCCB_MCD_BK*)(evd_hdr+1);
1459             FETCH_HW(mcd_len,mcd_bk->length);
1460 
1461             obj_hdr = (SCCB_OBJ_HDR*)(mcd_bk+1);
1462 
1463             while (mcd_len > sizeof(SCCB_MCD_BK))
1464             {
1465                 FETCH_HW(obj_len,obj_hdr->length);
1466                 if (obj_len == 0)
1467                 {
1468                     sccb->reas = SCCB_REAS_BUFF_LEN_ERR;
1469                     sccb->resp = SCCB_RESP_BUFF_LEN_ERR;
1470                     break;
1471                 }
1472                 FETCH_HW(obj_type,obj_hdr->type);
1473                 if (obj_type == SCCB_OBJ_TYPE_MESSAGE)
1474                 {
1475                     mto_bk = (SCCB_MTO_BK*)(obj_hdr+1);
1476                     event_msg = (BYTE*)(mto_bk+1);
1477                     event_msglen = obj_len -
1478                             (sizeof(SCCB_OBJ_HDR) + sizeof(SCCB_MTO_BK));
1479                     if (event_msglen < 0)
1480                     {
1481                         sccb->reas = SCCB_REAS_BUFF_LEN_ERR;
1482                         sccb->resp = SCCB_RESP_BUFF_LEN_ERR;
1483                         break;
1484                     }
1485 
1486                     /* Print line unless it is a response prompt */
1487                     if (!(mto_bk->ltflag[0] & SCCB_MTO_LTFLG0_PROMPT))
1488                     {
1489                         for (i = 0; i < event_msglen; i++)
1490                         {
1491                             message[i] = isprint(guest_to_host(event_msg[i])) ?
1492                                 guest_to_host(event_msg[i]) : 0x20;
1493                         }
1494                         message[i] = '\0';
1495 #ifdef OPTION_MSGCLR
1496                         if(evd_hdr->type == SCCB_EVD_TYPE_MSG)
1497                         {
1498                           if(mto_bk->presattr[3] == SCCB_MTO_PRATTR3_HIGH)
1499                             logmsg("<pnl,color(lightyellow,black),keep>%s\n", message);
1500                           else
1501                             logmsg ("<pnl,color(green,black)>%s\n", message);
1502                         }
1503                         else
1504                           logmsg ("<pnl,color(lightred,black),keep>%s\n", message);
1505 #else
1506                         logmsg ("%s\n", message);
1507 #endif
1508                     }
1509                 }
1510                 mcd_len -= obj_len;
1511                 obj_hdr=(SCCB_OBJ_HDR *)((BYTE*)obj_hdr + obj_len);
1512             }
1513 
1514             /* Indicate Event Processed */
1515             evd_hdr->flag |= SCCB_EVD_FLAG_PROC;
1516 
1517             /* Set response code X'0020' in SCCB header */
1518             sccb->reas = SCCB_REAS_NONE;
1519             sccb->resp = SCCB_RESP_COMPLETE;
1520 
1521             break;
1522 
1523 
1524         case SCCB_EVD_TYPE_CPIDENT:
1525             sclp_cpident(sccb);
1526             break;
1527 
1528 #if defined(FEATURE_SCEDIO)
1529         case SCCB_EVD_TYPE_SCEDIO:
1530             ARCH_DEP(sclp_scedio_request)(sccb);
1531             break;
1532 #endif /*defined(FEATURE_SCEDIO)*/
1533 
1534 #if defined(FEATURE_INTEGRATED_3270_CONSOLE)
1535         case SCCB_EVD_TYPE_SYSG:
1536             sclp_sysg_write(sccb);
1537             break;
1538 #endif /*defined(FEATURE_INTEGRATED_3270_CONSOLE)*/
1539 
1540 
1541 #if defined(FEATURE_INTEGRATED_ASCII_CONSOLE)
1542         case SCCB_EVD_TYPE_VT220:
1543             sclp_sysa_write(sccb);
1544             break;
1545 #endif /*defined(FEATURE_INTEGRATED_ASCII_CONSOLE)*/
1546 
1547 
1548         default:
1549 
1550             PTT(PTT_CL_ERR,"*SERVC",regs->GR_L(r1),regs->GR_L(r2),evd_hdr->type);
1551 
1552             if( HDC3(debug_sclp_unknown_event, evd_hdr, sccb, regs) )
1553                 break;
1554 
1555             /* Set response code X'73F0' in SCCB header */
1556             sccb->reas = SCCB_REAS_SYNTAX_ERROR;
1557             sccb->resp = SCCB_RESP_SYNTAX_ERROR;
1558 
1559             break;
1560 
1561         }
1562 
1563         break;
1564 
1565     case SCLP_READ_EVENT_DATA:
1566 
1567         /* Set the main storage change bit */
1568         STORAGE_KEY(sccb_absolute_addr, regs) |= STORKEY_CHANGE;
1569 
1570         /* Set response code X'0100' if SCCB crosses a page boundary */
1571         if ((sccb_absolute_addr & STORAGE_KEY_PAGEMASK) !=
1572             ((sccb_absolute_addr + sccblen - 1) & STORAGE_KEY_PAGEMASK))
1573         {
1574             sccb->reas = SCCB_REAS_NOT_PGBNDRY;
1575             sccb->resp = SCCB_RESP_BLOCK_ERROR;
1576             break;
1577         }
1578 
1579         /* Point to SCCB data area following SCCB header */
1580         evd_hdr = (SCCB_EVD_HDR*)(sccb+1);
1581 
1582         if(SCLP_RECV_ENABLED(SCCB_EVD_TYPE_PRIOR) && sclp_attn_pending(SCCB_EVD_TYPE_PRIOR))
1583         {
1584             sclp_opcmd_event(sccb, SCCB_EVD_TYPE_PRIOR);
1585             break;
1586         }
1587 
1588         if(SCLP_RECV_ENABLED(SCCB_EVD_TYPE_OPCMD) && sclp_attn_pending(SCCB_EVD_TYPE_OPCMD))
1589         {
1590             sclp_opcmd_event(sccb, SCCB_EVD_TYPE_OPCMD);
1591             break;
1592         }
1593 
1594 
1595 #if defined(FEATURE_SCEDIO)
1596         if(SCLP_RECV_ENABLED(SCCB_EVD_TYPE_SCEDIO) && sclp_attn_pending(SCCB_EVD_TYPE_SCEDIO))
1597         {
1598             ARCH_DEP(sclp_scedio_event)(sccb);
1599             break;
1600         }
1601 #endif /*defined(FEATURE_SCEDIO)*/
1602 
1603 
1604 #if defined(FEATURE_INTEGRATED_3270_CONSOLE)
1605         if(SCLP_RECV_ENABLED(SCCB_EVD_TYPE_SYSG) && sclp_attn_pending(SCCB_EVD_TYPE_SYSG))
1606         {
1607             sclp_sysg_poll(sccb);
1608             break;
1609         }
1610 #endif /*defined(FEATURE_INTEGRATED_3270_CONSOLE)*/
1611 
1612 
1613 #if defined(FEATURE_INTEGRATED_ASCII_CONSOLE)
1614         if(SCLP_RECV_ENABLED(SCCB_EVD_TYPE_VT220) && sclp_attn_pending(SCCB_EVD_TYPE_VT220))
1615         {
1616             sclp_sysa_poll(sccb);
1617             break;
1618         }
1619 #endif /*defined(FEATURE_INTEGRATED_ASCII_CONSOLE)*/
1620 
1621         if(SCLP_RECV_ENABLED(SCCB_EVD_TYPE_SIGQ) && sclp_attn_pending(SCCB_EVD_TYPE_SIGQ))
1622         {
1623             sclp_sigq_event(sccb);
1624             break;
1625         }
1626 
1627         PTT(PTT_CL_ERR,"*SERVC",regs->GR_L(r1),regs->GR_L(r2),regs->psw.IA_L);
1628 
1629         if( HDC3(debug_sclp_event_data, evd_hdr, sccb, regs) )
1630             break;
1631 
1632         /* Set response code X'62F0' if events are pending but suppressed */
1633         if(sclp_attn_pending(0))
1634         {
1635             sccb->reas = SCCB_REAS_EVENTS_SUP;
1636             sccb->resp = SCCB_RESP_EVENTS_SUP;
1637             break;
1638         }
1639         else
1640         {
1641             /* Set response code X'60F0' if no outstanding events */
1642             sccb->reas = SCCB_REAS_NO_EVENTS;
1643             sccb->resp = SCCB_RESP_NO_EVENTS;
1644         }
1645 
1646         break;
1647 
1648 
1649     case SCLP_WRITE_EVENT_MASK:
1650 
1651         /* Set the main storage change bit */
1652         STORAGE_KEY(sccb_absolute_addr, regs) |= STORKEY_CHANGE;
1653 
1654         /* Set response code X'0100' if SCCB crosses a page boundary */
1655         if ((sccb_absolute_addr & STORAGE_KEY_PAGEMASK) !=
1656             ((sccb_absolute_addr + sccblen - 1) & STORAGE_KEY_PAGEMASK))
1657         {
1658             sccb->reas = SCCB_REAS_NOT_PGBNDRY;
1659             sccb->resp = SCCB_RESP_BLOCK_ERROR;
1660             break;
1661         }
1662 
1663         /* Point to SCCB data area following SCCB header */
1664         evd_mask = (SCCB_EVENT_MASK*)(sccb+1);
1665 
1666         /* Get length of single mask field */
1667         FETCH_HW(masklen, evd_mask->length);
1668 
1669         /* Save old mask settings in order to suppress superflous messages */
1670         old_cp_recv_mask = servc_cp_recv_mask & ARCH_DEP(sclp_send_mask) & SCCB_EVENT_CONS_RECV_MASK;
1671         old_cp_send_mask = servc_cp_send_mask & ARCH_DEP(sclp_recv_mask) & SCCB_EVENT_CONS_SEND_MASK;
1672 
1673         for (i = 0; i < 4; i++)
1674         {
1675             servc_cp_recv_mask <<= 8;
1676             servc_cp_send_mask <<= 8;
1677             if ((U32)i < masklen)
1678             {
1679                 servc_cp_recv_mask |= evd_mask->masks[i+(0*masklen)];
1680                 servc_cp_send_mask |= evd_mask->masks[i+(1*masklen)];
1681             }
1682         }
1683 
1684         if((servc_cp_recv_mask & ~ARCH_DEP(sclp_recv_mask))
1685           || (servc_cp_send_mask & ~ARCH_DEP(sclp_send_mask)))
1686             HDC3(debug_sclp_unknown_event_mask, evd_mask, sccb, regs);
1687 
1688         /* Write the events that we support back */
1689         memset (&evd_mask->masks[2 * masklen], 0, 2 * masklen);
1690         for (i = 0; (i < 4) && ((U32)i < masklen); i++)
1691         {
1692             evd_mask->masks[i+(2*masklen)] |= (ARCH_DEP(sclp_recv_mask) >> ((3-i)*8)) & 0xFF;
1693             evd_mask->masks[i+(3*masklen)] |= (ARCH_DEP(sclp_send_mask) >> ((3-i)*8)) & 0xFF;
1694         }
1695 
1696         /* Issue message only when supported mask has changed */
1697         if ((servc_cp_recv_mask & ARCH_DEP(sclp_send_mask) & SCCB_EVENT_CONS_RECV_MASK) != old_cp_recv_mask
1698          || (servc_cp_send_mask & ARCH_DEP(sclp_recv_mask) & SCCB_EVENT_CONS_SEND_MASK) != old_cp_send_mask)
1699         {
1700             if ((servc_cp_recv_mask & SCCB_EVENT_CONS_RECV_MASK) != 0
1701                 || (servc_cp_send_mask & SCCB_EVENT_CONS_SEND_MASK) != 0)
1702                 logmsg (_("HHCCP041I SYSCONS interface active\n"));
1703             else
1704                 logmsg (_("HHCCP042I SYSCONS interface inactive\n"));
1705         }
1706 
1707         /* Set response code X'0020' in SCCB header */
1708         sccb->reas = SCCB_REAS_NONE;
1709         sccb->resp = SCCB_RESP_COMPLETE;
1710 
1711         break;
1712 #endif /*FEATURE_SYSTEM_CONSOLE*/
1713 
1714 #ifdef FEATURE_EXPANDED_STORAGE
1715    case SCLP_READ_XST_MAP:
1716 
1717         /* Set the main storage change bit */
1718         STORAGE_KEY(sccb_absolute_addr, regs) |= STORKEY_CHANGE;
1719 
1720         /* Set response code X'0100' if SCCB crosses a page boundary */
1721         if ((sccb_absolute_addr & STORAGE_KEY_PAGEMASK) !=
1722             ((sccb_absolute_addr + sccblen - 1) & STORAGE_KEY_PAGEMASK))
1723         {
1724             sccb->reas = SCCB_REAS_NOT_PGBNDRY;
1725             sccb->resp = SCCB_RESP_BLOCK_ERROR;
1726             break;
1727         }
1728 
1729         /* Calculate number of blocks per increment */
1730         xstblkinc = XSTORE_INCREMENT_SIZE / XSTORE_PAGESIZE;
1731 
1732         /* Set response code X'0300' if SCCB length
1733            is insufficient to contain xstore info */
1734         if ( sccblen < sizeof(SCCB_HEADER) + sizeof(SCCB_XST_MAP)
1735                 + xstblkinc/8)
1736         {
1737             sccb->reas = SCCB_REAS_TOO_SHORT;
1738             sccb->resp = SCCB_RESP_BLOCK_ERROR;
1739             break;
1740         }
1741 
1742         /* Point to SCCB data area following SCCB header */
1743         sccbxmap = (SCCB_XST_MAP*)(sccb+1);
1744 
1745         /* Verify expanded storage increment number */
1746         xstincnum = sysblk.xpndsize /
1747                     (XSTORE_INCREMENT_SIZE >> XSTORE_PAGESHIFT);
1748         FETCH_FW(i, sccbxmap->incnum);
1749         if ( i < 1 || (U32)i > xstincnum )
1750         {
1751             sccb->reas = SCCB_REAS_INVALID_RSC;
1752             sccb->resp = SCCB_RESP_REJECT;
1753             break;
1754         }
1755 
1756         /* Point to bitmap */
1757         xstmap = (BYTE*)(sccbxmap+1);
1758 
1759         /* Set all blocks available */
1760         memset (xstmap, 0x00, xstblkinc/8);
1761 
1762         /* Set response code X'0010' in SCCB header */
1763         sccb->reas = SCCB_REAS_NONE;
1764         sccb->resp = SCCB_RESP_INFO;
1765 
1766         break;
1767 
1768 #endif /*FEATURE_EXPANDED_STORAGE*/
1769 
1770 #ifdef FEATURE_CPU_RECONFIG
1771 
1772     case SCLP_CONFIGURE_CPU:
1773 
1774         i = (sclp_command & SCLP_RESOURCE_MASK) >> SCLP_RESOURCE_SHIFT;
1775 
1776         /* Return invalid resource in parm if target does not exist */
1777         if(i >= MAX_CPU)
1778         {
1779             sccb->reas = SCCB_REAS_INVALID_RSCP;
1780             sccb->resp = SCCB_RESP_REJECT;
1781             break;
1782         }
1783 
1784         /* Add cpu to the configuration */
1785         configure_cpu(i);
1786 
1787         /* Set response code X'0020' in SCCB header */
1788         sccb->reas = SCCB_REAS_NONE;
1789         sccb->resp = SCCB_RESP_COMPLETE;
1790         break;
1791 
1792     case SCLP_DECONFIGURE_CPU:
1793 
1794         i = (sclp_command & SCLP_RESOURCE_MASK) >> SCLP_RESOURCE_SHIFT;
1795 
1796         /* Return invalid resource in parm if target does not exist */
1797         if(i >= MAX_CPU)
1798         {
1799             sccb->reas = SCCB_REAS_INVALID_RSCP;
1800             sccb->resp = SCCB_RESP_REJECT;
1801             break;
1802         }
1803 
1804         /* Take cpu out of the configuration */
1805         deconfigure_cpu(i);
1806 
1807         /* Set response code X'0020' in SCCB header */
1808         sccb->reas = SCCB_REAS_NONE;
1809         sccb->resp = SCCB_RESP_COMPLETE;
1810         break;
1811 
1812 #ifdef FEATURE_VECTOR_FACILITY
1813 
1814     case SCLP_DISCONNECT_VF:
1815 
1816         i = (sclp_command & SCLP_RESOURCE_MASK) >> SCLP_RESOURCE_SHIFT;
1817 
1818         /* Return invalid resource in parm if target does not exist */
1819         if(i >= MAX_CPU || !IS_CPU_ONLINE(i))
1820         {
1821             sccb->reas = SCCB_REAS_INVALID_RSCP;
1822             sccb->resp = SCCB_RESP_REJECT;
1823             break;
1824         }
1825 
1826         if(sysblk.regs[i]->vf->online)
1827             logmsg(_("CPU%4.4X: Vector Facility configured offline\n"),i);
1828 
1829         /* Take the VF out of the configuration */
1830         sysblk.regs[i]->vf->online = 0;
1831 
1832         /* Set response code X'0020' in SCCB header */
1833         sccb->reas = SCCB_REAS_NONE;
1834         sccb->resp = SCCB_RESP_COMPLETE;
1835         break;
1836 
1837     case SCLP_CONNECT_VF:
1838 
1839         i = (sclp_command & SCLP_RESOURCE_MASK) >> SCLP_RESOURCE_SHIFT;
1840 
1841         /* Return invalid resource in parm if target does not exist */
1842         if(i >= MAX_CPU)
1843         {
1844             sccb->reas = SCCB_REAS_INVALID_RSCP;
1845             sccb->resp = SCCB_RESP_REJECT;
1846             break;
1847         }
1848 
1849         /* Return improper state if associated cpu is offline */
1850         if(!IS_CPU_ONLINE(i))
1851         {
1852             sccb->reas = SCCB_REAS_IMPROPER_RSC;
1853             sccb->resp = SCCB_RESP_REJECT;
1854             break;
1855         }
1856 
1857         if(!sysblk.regs[i]->vf->online)
1858             logmsg(_("CPU%4.4X: Vector Facility configured online\n"),i);
1859 
1860         /* Mark the VF online to the CPU */
1861         sysblk.regs[i]->vf->online = 1;
1862 
1863         /* Set response code X'0020' in SCCB header */
1864         sccb->reas = SCCB_REAS_NONE;
1865         sccb->resp = SCCB_RESP_COMPLETE;
1866         break;
1867 
1868 #endif /*FEATURE_VECTOR_FACILITY*/
1869 
1870 #endif /*FEATURE_CPU_RECONFIG*/
1871 
1872     default:
1873     invalidcmd:
1874 
1875         PTT(PTT_CL_INF|PTT_CL_ERR,"*SERVC",regs->GR_L(r1),regs->GR_L(r2),regs->psw.IA_L);
1876 
1877         if( HDC3(debug_sclp_unknown_command, sclp_command, sccb, regs) )
1878             break;
1879 
1880         /* Set response code X'01F0' for invalid SCLP command */
1881         sccb->reas = SCCB_REAS_INVALID_CMD;
1882         sccb->resp = SCCB_RESP_REJECT;
1883 
1884         break;
1885 
1886     } /* end switch(sclp_command) */
1887 
1888     /* If immediate response is requested, return condition code 1 */
1889     if ((sccb->flag & SCCB_FLAG_SYNC)
1890         && (sclp_command & SCLP_COMMAND_CLASS) != 0x01)
1891     {
1892         regs->psw.cc = 1;
1893         return;
1894     }
1895 
1896     /* Set service signal external interrupt pending */
1897     sysblk.servparm &= ~SERVSIG_ADDR;
1898     sysblk.servparm |= sccb_absolute_addr;
1899     ON_IC_SERVSIG;
1900 
1901     /* Release the interrupt lock */
1902     RELEASE_INTLOCK(regs);
1903 
1904     /* Set condition code 0 */
1905     regs->psw.cc = 0;
1906 
1907 } /* end function service_call */
1908 
1909 
1910 #endif /*defined(FEATURE_SERVICE_PROCESSOR)*/
1911 
1912 
1913 #if !defined(_GEN_ARCH)
1914 
1915 #if defined(_ARCHMODE2)
1916  #define  _GEN_ARCH _ARCHMODE2
1917  #include "service.c"
1918 #endif
1919 
1920 #if defined(_ARCHMODE3)
1921  #undef   _GEN_ARCH
1922  #define  _GEN_ARCH _ARCHMODE3
1923  #include "service.c"
1924 #endif
1925 
1926 #endif /*!defined(_GEN_ARCH)*/
1927