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