cp/guest: allow IPL of both 31-bit and 64-bit NSS
[hvf.git] / include / channel.h
blob329161c10b487dfd17b001526e99379b0fde6633
1 /*
2 * (C) Copyright 2007-2011 Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
4 * This file is released under the GPLv2. See the COPYING file for more
5 * details.
6 */
8 #ifndef __CHANNEL_H
9 #define __CHANNEL_H
11 #include <errno.h>
14 * We only care about format-1 CCWs
16 struct ccw {
17 u8 cmd; /* Command code */
18 u8 flags; /* Flags */
19 u16 count; /* Count */
20 u32 addr; /* Data Address */
21 } __attribute__((packed,aligned(8)));
23 #define CCW0_ADDR(c) ((((u64)((c)->addr_hi)) << 16) | (((u64)((c)->addr_lo))))
25 struct ccw0 {
26 u8 cmd; /* Command code */
27 u8 addr_hi; /* Data Address (bits 8-15) */
28 u16 addr_lo; /* Data Address (bits 16-31) */
29 u8 flags; /* Flags */
30 u8 _res0;
31 u16 count; /* Count */
32 } __attribute__((packed,aligned(8)));
34 #define CCW_CMD_INVAL 0x00
35 #define CCW_CMD_IPL_READ 0x02
36 #define CCW_CMD_NOP 0x03
37 #define CCW_CMD_BASIC_SENSE 0x04
38 #define CCW_CMD_SENSE_ID 0xe4
39 #define CCW_CMD_TIC 0x08
41 #define IS_CCW_WRITE(op) (((op)&0x03)==0x01)
42 #define IS_CCW_READ(op) (((op)&0x03)==0x02)
43 #define IS_CCW_CONTROL(op) (((op)&0x03)==0x03)
45 #define CCW_FLAG_CD 0x80 /* Chain-Data */
46 #define CCW_FLAG_CC 0x40 /* Chain-Command */
47 #define CCW_FLAG_SLI 0x20 /* Suppress-Length-Indication */
48 #define CCW_FLAG_SKP 0x10 /* Skip */
49 #define CCW_FLAG_PCI 0x08 /* Program-Controlled-Interruption */
50 #define CCW_FLAG_IDA 0x04 /* Indirect-Data-Address */
51 #define CCW_FLAG_S 0x02 /* Suspend */
52 #define CCW_FLAG_MIDA 0x01 /* Modified-Indirect-Data-Address */
54 static inline void ccw0_to_ccw1(struct ccw *out, struct ccw0 *in)
56 /* 0x08 is TIC; format-0 CCWs allow upper nibble to be non-zero */
57 out->cmd = ((in->cmd & 0x0f) == CCW_CMD_TIC) ?
58 CCW_CMD_TIC : in->cmd;
59 out->flags = in->flags;
60 out->count = in->count;
61 out->addr = CCW0_ADDR(in);
65 * ORB
67 struct orb {
68 /* word 0 */
69 u32 param; /* Interruption Parameter */
71 /* word 1 */
72 u8 key:4, /* Subchannel Key */
73 s:1, /* Suspend */
74 c:1, /* Streaming-Mode Control */
75 m:1, /* Modification Control */
76 y:1; /* Synchronization Control */
77 u8 f:1, /* Format Control */
78 p:1, /* Prefetch Control */
79 i:1, /* Initial-Status-Interruption Control */
80 a:1, /* Address-Limit-Checking control */
81 u:1, /* Suppress-Suspend-Interruption Control */
82 b:1, /* Channel-Program Type Control */
83 h:1, /* Format-2-IDAW Control */
84 t:1; /* 2K-IDAW Control */
85 u8 lpm; /* Logical-Path Mask */
86 u8 l:1, /* Incorrect-Length-Suppression Mode */
87 d:1, /* Modified-CCW-Indirect-Data-Addressing Control */
88 __zero1:5,
89 x:1; /* ORB-Extension Control */
91 /* word 2 */
92 u32 addr; /* Channel-Program Address */
94 /* word 3 */
95 u8 css_prio; /* Channel-Subsystem Priority */
96 u8 __reserved1;
97 u8 cu_prio; /* Control-Unit Priority */
98 u8 __reserved2;
100 /* word 4 - 7 */
101 u32 __reserved3;
102 u32 __reserved4;
103 u32 __reserved5;
104 u32 __reserved6;
105 } __attribute__((packed,aligned(4)));
107 enum SCSW_FC {
108 FC_CLEAR = 0x1,
109 FC_HALT = 0x2,
110 FC_START = 0x4,
113 enum SCSW_AC {
114 AC_RESUME = 0x40,
115 AC_START = 0x20,
116 AC_HALT = 0x10,
117 AC_CLEAR = 0x08,
118 AC_SCH_ACT = 0x04,
119 AC_DEV_ACT = 0x02,
120 AC_SUSP = 0x01,
123 enum SCSW_SC {
124 SC_STATUS = 0x01,
125 SC_SECONDARY = 0x02,
126 SC_PRIMARY = 0x04,
127 SC_INTERMED = 0x08,
128 SC_ALERT = 0x10,
131 struct scsw {
132 /* word 0 */
133 u16 key:4, /* Subchannel key */
134 s:1, /* Suspend control */
135 l:1, /* ESW format */
136 cc:2, /* Deferred condition code */
137 f:1, /* Format */
138 p:1, /* Prefetch */
139 i:1, /* Initial-status interruption control */
140 a:1, /* Address-limit-checking control */
141 u:1, /* Supress-suspended interruption */
142 z:1, /* Zero condition code */
143 e:1, /* Extended control */
144 n:1; /* Path no operational */
145 u16 __zero:1,
146 fc:3, /* Function control */
147 ac:7, /* Activity control */
148 sc:5; /* Status control */
150 /* word 1 */
151 u32 addr; /* CCW Address */
153 /* word 2 */
154 u8 dev_status; /* Device status */
155 u8 sch_status; /* Subchannel status */
156 u16 count; /* Count */
157 } __attribute__((packed));
159 /* needed by IRB */
160 struct irb_ext_status {
161 /* TODO: not implemented */
162 u32 w0, w1, w2, w3, w4;
163 } __attribute__((packed));
165 /* needed by IRB */
166 struct irb_ext_control {
167 /* TODO: not implemented */
168 u32 w0, w1, w2, w3, w4, w5, w6, w7;
169 } __attribute__((packed));
171 /* needed by IRB */
172 struct irb_ext_measurement {
173 /* TODO: not implemented */
174 u32 w0, w1, w2, w3, w4, w5, w6, w7;
175 } __attribute__((packed));
177 struct irb {
178 struct scsw scsw; /* Subchannel-Status */
179 struct irb_ext_status ext_status; /* Extended-Status */
180 struct irb_ext_control ext_control; /* Extended-Control */
181 struct irb_ext_measurement ext_measure; /* Extended-Measurement */
182 } __attribute__((packed,aligned(4)));
184 /* Path Management Control Word */
185 struct pmcw {
186 /* word 0 */
187 u32 interrupt_param; /* Interruption Parameter */
189 /* word 1*/
190 u8 __zero1:2,
191 isc:3, /* I/O-Interruption-Subclass Code */
192 __zero2:3;
193 u8 e:1, /* Enabled */
194 lm:2, /* Limit Mode */
195 mm:2, /* Measurement-Mode Enable */
196 d:1, /* Multipath Mode */
197 t:1, /* Timing Facility */
198 v:1; /* Device Number Valid */
199 u16 dev_num; /* Device Number */
201 /* word 2 */
202 u8 lpm; /* Logical-Path Mask */
203 u8 pnom; /* Path-Not-Operational Mask */
204 u8 lpum; /* Last-Path-Used Mask */
205 u8 pim; /* Path-Installed Mask */
207 /* word 3 */
208 u16 mbi; /* Measurement-Block Index */
209 u8 pom; /* Path-Operational Mask */
210 u8 pam; /* Path-Available Mask */
212 /* word 4 & 5 */
213 u8 chpid[8]; /* Channel-Path Identifiers */
215 /* word 6 */
216 u16 __zero3;
217 u16 __zero4:13,
218 f:1, /* Measurement Block Format Control */
219 x:1, /* Extended Measurement Word Mode Enable */
220 s:1; /* Concurrent Sense */
223 /* needed by schib */
224 struct schib_measurement_block {
225 /* TODO: not implemented */
226 u32 w0, w1;
229 struct schib {
230 struct pmcw pmcw; /* Path Management Control Word */
231 struct scsw scsw; /* Subchannel Status Word */
232 union {
233 struct schib_measurement_block measure_block;
235 u32 model_dep_area;
236 } __attribute__((packed,aligned(4)));
238 struct senseid_struct {
239 u8 __reserved;
240 u16 cu_type;
241 u8 cu_model;
242 u16 dev_type;
243 u8 dev_model;
244 } __attribute__((packed));
246 enum {
247 SC_STATUS_ATTN = 0x80, /* Attention */
248 SC_STATUS_MOD = 0x40, /* Status Modifier */
249 SC_STATUS_CUE = 0x20, /* Control-Unit End */
250 SC_STATUS_BUSY = 0x10, /* Busy */
251 SC_STATUS_CE = 0x08, /* Channel End */
252 SC_STATUS_DE = 0x04, /* Device End */
253 SC_STATUS_UC = 0x02, /* Unit-check */
254 SC_STATUS_UE = 0x01, /* Unit-exception */
257 enum {
258 SC_PROG_CI = 0x80, /* Program-Controlled Interruption */
259 SC_INC_LEN = 0x40, /* Incorrect Length */
260 SC_PROG_CHK = 0x20, /* Program Check */
261 SC_PROT_CHK = 0x10, /* Protection Check */
262 SC_CHD_CHK = 0x08, /* Channel-Data Check */
263 SC_CHC_CHK = 0x04, /* Channel-Control Check */
264 SC_IC_CHK = 0x02, /* Interface-Control Check */
265 SC_CHAIN_CHK= 0x01, /* Chaining Check */
268 enum {
269 SENSE_CMDREJ = 0x00,
272 static inline int store_sch(u32 sch, struct schib *schib)
274 int cc;
276 asm volatile(
277 "lr %%r1,%2\n"
278 "stsch %1\n"
279 "ipm %0\n"
280 "srl %0,28\n"
281 : /* output */
282 "=d" (cc),
283 "=Q" (*schib)
284 : /* input */
285 "d" (sch)
286 : /* clobbered */
287 "cc", "r1", "memory"
290 if (cc == 3)
291 return -EINVAL;
292 return 0;
295 static inline int modify_sch(u32 sch, struct schib *schib)
297 int cc;
299 asm volatile(
300 "lr %%r1,%1\n"
301 "msch 0(%2)\n"
302 "ipm %0\n"
303 "srl %0,28\n"
304 : /* output */
305 "=d" (cc)
306 : /* input */
307 "d" (sch),
308 "a" (schib)
309 : /* clobbered */
310 "cc", "r1"
313 if (cc == 1 || cc == 2)
314 return -EBUSY;
315 if (cc == 3)
316 return -EINVAL;
317 return 0;
320 static inline int start_sch(u32 sch, struct orb *orb)
322 int cc;
324 asm volatile(
325 " lr %%r1,%1\n"
326 " ssch 0(%2)\n"
327 " ipm %0\n"
328 " srl %0,28\n"
329 : /* output */
330 "=d" (cc)
331 : /* input */
332 "d" (sch),
333 "a" (orb)
334 : /* clobbered */
335 "cc", "r1"
338 if (cc == 1 || cc == 2)
339 return -EBUSY;
340 if (cc == 3)
341 return -EINVAL;
343 return 0;
346 static inline int test_sch(u32 sch, struct irb *irb)
348 int cc;
350 asm volatile(
351 " lr %%r1,%1\n"
352 " tsch 0(%2)\n"
353 " ipm %0\n"
354 " srl %0,28\n"
355 : /* output */
356 "=d" (cc)
357 : /* input */
358 "d" (sch),
359 "a" (irb)
360 : /* clobbered */
361 "cc", "r1"
364 if (cc == 3)
365 return -EINVAL;
367 return 0;
370 #endif