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