1 /* CHSC.C       (c) Copyright Jan Jaeger, 2002-2009                  */
2 /*              Channel Subsystem Call                               */
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 channel subsystem interface functions      */
9 /* for the Hercules ESA/390 emulator.                                */
10 /*-------------------------------------------------------------------*/
11 
12 #include "hstdinc.h"
13 
14 #if !defined(_HENGINE_DLL_)
15 #define _HENGINE_DLL_
16 #endif
17 
18 #if !defined(_CHSC_C_)
19 #define _CHSC_C_
20 #endif
21 
22 #include "hercules.h"
23 
24 #include "opcode.h"
25 
26 #include "inline.h"
27 
28 #include "chsc.h"
29 
30 
31 #if defined(FEATURE_CHSC)
32 
ARCH_DEP(chsc_get_sch_desc)33 int ARCH_DEP(chsc_get_sch_desc) (CHSC_REQ *chsc_req, CHSC_RSP *chsc_rsp)
34 {
35     U16 req_len, sch, f_sch, l_sch, rsp_len;
36 
37     CHSC_REQ4 *chsc_req4 = (CHSC_REQ4 *)(chsc_req);
38     CHSC_RSP4 *chsc_rsp4 = (CHSC_RSP4 *)(chsc_rsp);
39 
40 #if 0
41 { U16 resv1, resv2, resv3;
42     FETCH_HW(resv1,chsc_req4->resv1);
43     FETCH_HW(resv2,chsc_req4->resv2);
44     FETCH_HW(resv3,chsc_req4->resv3);
45     logmsg(D_("chsc_get_sch_desc: resv1=%4.4X resv2=%4.4X resv3=%4.4X\n"),resv1,resv2,resv3);
46 }
47 #endif
48 
49     FETCH_HW(f_sch,chsc_req4->f_sch);
50     FETCH_HW(l_sch,chsc_req4->l_sch);
51 
52     /* Fetch length of request field */
53     FETCH_HW(req_len, chsc_req4->length);
54 
55     rsp_len = sizeof(CHSC_RSP) + ((1 + l_sch - f_sch) * sizeof(CHSC_RSP4));
56 
57     if(l_sch < f_sch
58       || rsp_len > (0x1000 - req_len)) {
59         /* Set response field length */
60         STORE_HW(chsc_rsp->length,sizeof(CHSC_RSP));
61         /* Store request error */
62         STORE_HW(chsc_rsp->rsp,CHSC_REQ_ERRREQ);
63         /* No reaon code */
64         STORE_FW(chsc_rsp->info,0);
65         return 0;
66     }
67 
68     for(sch = f_sch; sch <= l_sch; sch++, chsc_rsp4++)
69     {
70     DEVBLK *dev;
71         memset(chsc_rsp4, 0x00, sizeof(CHSC_RSP4) );
72 // ZZ FIXME:  Dunno how to put the proper lcss id in here...
73         if((dev = find_device_by_subchan(0x00010000|sch)))
74         {
75             chsc_rsp4->sch_val = 1;
76             if(dev->pmcw.flag5 & PMCW5_V)
77                 chsc_rsp4->dev_val = 1;
78             chsc_rsp4->st = (dev->pmcw.flag25 & PMCW25_TYPE) >> 5;
79             chsc_rsp4->unit_addr = dev->devnum & 0xff;
80             STORE_HW(chsc_rsp4->devno,dev->devnum);
81             chsc_rsp4->path_mask = dev->pmcw.pim;
82             STORE_HW(chsc_rsp4->sch, sch);
83             memcpy(chsc_rsp4->chpid, dev->pmcw.chpid, 8);
84         }
85     }
86 
87     /* Store response length */
88     STORE_HW(chsc_rsp->length,rsp_len);
89 
90     /* Store request OK */
91     STORE_HW(chsc_rsp->rsp,CHSC_REQ_OK);
92 
93     /* No reaon code */
94     STORE_FW(chsc_rsp->info,0);
95 
96     return 0;
97 
98 }
99 
100 
ARCH_DEP(chsc_get_css_info)101 int ARCH_DEP(chsc_get_css_info) (CHSC_REQ *chsc_req, CHSC_RSP *chsc_rsp)
102 {
103 CHSC_RSP10 *chsc_rsp10;
104 U16 req_len, rsp_len;
105 
106     UNREFERENCED(chsc_req);
107 
108     chsc_rsp10 = (CHSC_RSP10 *)(chsc_rsp + 1);
109 
110     /* Fetch length of request field */
111     FETCH_HW(req_len, chsc_req->length);
112 
113     rsp_len = sizeof(CHSC_RSP) + sizeof(CHSC_RSP10);
114 
115     if(rsp_len > (0x1000 - req_len)) {
116         /* Set response field length */
117         STORE_HW(chsc_rsp->length,sizeof(CHSC_RSP));
118         /* Store request error */
119         STORE_HW(chsc_rsp->rsp,CHSC_REQ_ERRREQ);
120         /* No reaon code */
121         STORE_FW(chsc_rsp->info,0);
122         return 0;
123     }
124 
125     STORE_HW(chsc_rsp->length,rsp_len);
126 
127     memset(chsc_rsp10->general_char, 0x00, sizeof(chsc_rsp10->general_char));
128     memset(chsc_rsp10->chsc_char, 0x00, sizeof(chsc_rsp10->chsc_char));
129 
130     chsc_rsp10->general_char[0][0] = 0
131 #if defined(FEATURE_REGION_RELOCATE)
132                                    | 0x24
133 #endif
134 #if defined(FEATURE_CANCEL_IO_FACILITY)
135                                    | 0x02
136 #endif
137                                        ;
138 
139 #if defined(FEATURE_QUEUED_DIRECT_IO)
140     chsc_rsp10->general_char[1][1] = 0
141                                    | 0x40  /* Adapter Interruption Facility */
142                                    ;
143 
144     chsc_rsp10->chsc_char[3][1] = 0
145                                 | 0x10 /* Set Channel Subsystem Char */
146                                 | 0x08 /* Fast CHSCs */
147                                 ;
148 
149     chsc_rsp10->general_char[2][0] = 0
150 //                                 | 0x10 /* OSA/FCP Thin interrupts */
151                                    ;
152 
153     chsc_rsp10->general_char[1][3] = 0
154 //                                 | 0x80 /* AIF Time Delay Disablement Fac */
155                                    ;
156 #endif /*defined(FEATURE_QUEUED_DIRECT_IO)*/
157 
158     /* Store request OK */
159     STORE_HW(chsc_rsp->rsp,CHSC_REQ_OK);
160 
161     /* No reaon code */
162     STORE_FW(chsc_rsp->info,0);
163 
164     return 0;
165 }
166 
167 
168 /*-------------------------------------------------------------------*/
169 /* B25F CHSC  - Channel Subsystem Call                         [RRE] */
170 /*-------------------------------------------------------------------*/
DEF_INST(channel_subsystem_call)171 DEF_INST(channel_subsystem_call)
172 {
173 int     r1, r2;                                 /* register values   */
174 VADR    n;                                      /* Unsigned work     */
175 BYTE   *mn;                                     /* Unsigned work     */
176 U16     req_len;                                /* Length of request */
177 U16     req;                                    /* Request code      */
178 CHSC_REQ *chsc_req;                             /* Request structure */
179 CHSC_RSP *chsc_rsp;                             /* Response structure*/
180 
181     RRE(inst, regs, r1, r2);
182 
183     PRIV_CHECK(regs);
184 
185     SIE_INTERCEPT(regs);
186 
187     PTT(PTT_CL_INF,"CHSC",regs->GR_L(r1),regs->GR_L(r2),regs->psw.IA_L);
188 
189     n = regs->GR(r1) & ADDRESS_MAXWRAP(regs);
190 
191     if(n & 0xFFF)
192         ARCH_DEP(program_interrupt) (regs, PGM_SPECIFICATION_EXCEPTION);
193 
194     mn = MADDR(n, r1, regs, ACCTYPE_READ, regs->psw.pkey);
195     chsc_req = (CHSC_REQ*)(mn);
196 
197     /* Fetch length of request field */
198     FETCH_HW(req_len, chsc_req->length);
199 
200     chsc_rsp = (CHSC_RSP*)((BYTE*)chsc_req + req_len);
201 
202     if((req_len < sizeof(CHSC_REQ))
203       || (req_len > (0x1000 - sizeof(CHSC_RSP))))
204         ARCH_DEP(program_interrupt) (regs, PGM_OPERAND_EXCEPTION);
205 
206     FETCH_HW(req,chsc_req->req);
207 
208     ARCH_DEP(validate_operand) (n, r1, 0, ACCTYPE_WRITE, regs);
209 
210     switch(req) {
211 
212         case CHSC_REQ_SCHDESC:
213             regs->psw.cc = ARCH_DEP(chsc_get_sch_desc) (chsc_req, chsc_rsp);
214             break;
215 #if 0
216         case CHSC_REQ_CSSINFO:
217             regs->psw.cc = ARCH_DEP(chsc_get_css_info) (chsc_req, chsc_rsp);
218             break;
219 #endif
220         default:
221 
222             PTT(PTT_CL_ERR,"*CHSC",regs->GR_L(r1),regs->GR_L(r2),regs->psw.IA_L);
223 
224             if( HDC3(debug_chsc_unknown_request, chsc_rsp, chsc_req, regs) )
225                 break;
226 
227             /* Set response field length */
228             STORE_HW(chsc_rsp->length,sizeof(CHSC_RSP));
229             /* Store unsupported command code */
230             STORE_HW(chsc_rsp->rsp,CHSC_REQ_INVALID);
231             /* No reaon code */
232             STORE_FW(chsc_rsp->info,0);
233 
234             regs->psw.cc = 0;
235     }
236 
237 }
238 #endif /*defined(FEATURE_CHSC)*/
239 
240 
241 #if !defined(_GEN_ARCH)
242 
243 #if defined(_ARCHMODE2)
244  #define  _GEN_ARCH _ARCHMODE2
245  #include "chsc.c"
246 #endif
247 
248 #if defined(_ARCHMODE3)
249  #undef   _GEN_ARCH
250  #define  _GEN_ARCH _ARCHMODE3
251  #include "chsc.c"
252 #endif
253 
254 #endif /*!defined(_GEN_ARCH)*/
255