1 /* Copyright (C) 2010 - 2013 UNISYS CORPORATION
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or (at
7 * your option) any later version.
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
12 * NON INFRINGEMENT. See the GNU General Public License for more
19 #include <linux/types.h>
21 #include <linux/uuid.h>
24 * Whenever this file is changed a corresponding change must be made in
25 * the Console/ServicePart/visordiag_early/supervisor_channel.h file
26 * which is needed for Linux kernel compiles. These two files must be
30 /* define the following to prevent include nesting in kernel header
31 * files of similar abbreviated content
33 #define __SUPERVISOR_CHANNEL_H__
35 #define SIGNATURE_16(A, B) ((A) | (B << 8))
36 #define SIGNATURE_32(A, B, C, D) \
37 (SIGNATURE_16(A, B) | (SIGNATURE_16(C, D) << 16))
38 #define SIGNATURE_64(A, B, C, D, E, F, G, H) \
39 (SIGNATURE_32(A, B, C, D) | ((u64)(SIGNATURE_32(E, F, G, H)) << 32))
42 #define lengthof(TYPE, MEMBER) (sizeof(((TYPE *)0)->MEMBER))
45 #define COVERQ(v, d) (((v) + (d) - 1) / (d))
48 #define COVER(v, d) ((d) * COVERQ(v, d))
51 #define ULTRA_CHANNEL_PROTOCOL_SIGNATURE SIGNATURE_32('E', 'C', 'N', 'L')
53 enum channel_serverstate {
54 CHANNELSRV_UNINITIALIZED = 0, /* channel is in an undefined state */
55 CHANNELSRV_READY = 1 /* channel has been initialized by server */
58 enum channel_clientstate {
59 CHANNELCLI_DETACHED = 0,
60 CHANNELCLI_DISABLED = 1, /* client can see channel but is NOT
61 * allowed to use it unless given TBD
62 * explicit request (should actually be
64 CHANNELCLI_ATTACHING = 2, /* legacy EFI client request
65 * for EFI server to attach */
66 CHANNELCLI_ATTACHED = 3, /* idle, but client may want
67 * to use channel any time */
68 CHANNELCLI_BUSY = 4, /* client either wants to use or is
70 CHANNELCLI_OWNED = 5 /* "no worries" state - client can
71 * access channel anytime */
74 static inline const u8 *
75 ULTRA_CHANNELCLI_STRING(u32 v)
78 case CHANNELCLI_DETACHED:
79 return (const u8 *)("DETACHED");
80 case CHANNELCLI_DISABLED:
81 return (const u8 *)("DISABLED");
82 case CHANNELCLI_ATTACHING:
83 return (const u8 *)("ATTACHING");
84 case CHANNELCLI_ATTACHED:
85 return (const u8 *)("ATTACHED");
87 return (const u8 *)("BUSY");
88 case CHANNELCLI_OWNED:
89 return (const u8 *)("OWNED");
93 return (const u8 *)("?");
96 #define SPAR_CHANNEL_SERVER_READY(ch) \
97 (readl(&(ch)->srv_state) == CHANNELSRV_READY)
99 #define ULTRA_VALID_CHANNELCLI_TRANSITION(o, n) \
100 (((((o) == CHANNELCLI_DETACHED) && ((n) == CHANNELCLI_DISABLED)) || \
101 (((o) == CHANNELCLI_ATTACHING) && ((n) == CHANNELCLI_DISABLED)) || \
102 (((o) == CHANNELCLI_ATTACHED) && ((n) == CHANNELCLI_DISABLED)) || \
103 (((o) == CHANNELCLI_ATTACHING) && ((n) == CHANNELCLI_DETACHED)) || \
104 (((o) == CHANNELCLI_ATTACHED) && ((n) == CHANNELCLI_DETACHED)) || \
105 (((o) == CHANNELCLI_DETACHED) && ((n) == CHANNELCLI_ATTACHING)) || \
106 (((o) == CHANNELCLI_ATTACHING) && ((n) == CHANNELCLI_ATTACHED)) || \
107 (((o) == CHANNELCLI_DETACHED) && ((n) == CHANNELCLI_ATTACHED)) || \
108 (((o) == CHANNELCLI_BUSY) && ((n) == CHANNELCLI_ATTACHED)) || \
109 (((o) == CHANNELCLI_ATTACHED) && ((n) == CHANNELCLI_BUSY)) || \
110 (((o) == CHANNELCLI_DETACHED) && ((n) == CHANNELCLI_OWNED)) || \
111 (((o) == CHANNELCLI_DISABLED) && ((n) == CHANNELCLI_OWNED)) || \
112 (((o) == CHANNELCLI_ATTACHING) && ((n) == CHANNELCLI_OWNED)) || \
113 (((o) == CHANNELCLI_ATTACHED) && ((n) == CHANNELCLI_OWNED)) || \
114 (((o) == CHANNELCLI_BUSY) && ((n) == CHANNELCLI_OWNED)) || (0)) \
117 /* Values for ULTRA_CHANNEL_PROTOCOL.CliErrorBoot: */
118 /* throttling invalid boot channel statetransition error due to client
120 #define ULTRA_CLIERRORBOOT_THROTTLEMSG_DISABLED 0x01
122 /* throttling invalid boot channel statetransition error due to client
124 #define ULTRA_CLIERRORBOOT_THROTTLEMSG_NOTATTACHED 0x02
126 /* throttling invalid boot channel statetransition error due to busy channel */
127 #define ULTRA_CLIERRORBOOT_THROTTLEMSG_BUSY 0x04
129 /* Values for ULTRA_CHANNEL_PROTOCOL.CliErrorOS: */
130 /* throttling invalid guest OS channel statetransition error due to
132 #define ULTRA_CLIERROROS_THROTTLEMSG_DISABLED 0x01
134 /* throttling invalid guest OS channel statetransition error due to
135 * client not attached */
136 #define ULTRA_CLIERROROS_THROTTLEMSG_NOTATTACHED 0x02
138 /* throttling invalid guest OS channel statetransition error due to
140 #define ULTRA_CLIERROROS_THROTTLEMSG_BUSY 0x04
142 /* Values for ULTRA_CHANNEL_PROTOCOL.Features: This define exists so
143 * that windows guest can look at the FeatureFlags in the io channel,
144 * and configure the windows driver to use interrupts or not based on
145 * this setting. This flag is set in uislib after the
146 * ULTRA_VHBA_init_channel is called. All feature bits for all
147 * channels should be defined here. The io channel feature bits are
148 * defined right here */
149 #define ULTRA_IO_DRIVER_ENABLES_INTS (0x1ULL << 1)
150 #define ULTRA_IO_CHANNEL_IS_POLLING (0x1ULL << 3)
151 #define ULTRA_IO_IOVM_IS_OK_WITH_DRIVER_DISABLING_INTS (0x1ULL << 4)
152 #define ULTRA_IO_DRIVER_DISABLES_INTS (0x1ULL << 5)
153 #define ULTRA_IO_DRIVER_SUPPORTS_ENHANCED_RCVBUF_CHECKING (0x1ULL << 6)
155 /* Common Channel Header */
156 struct channel_header {
157 u64 signature; /* Signature */
158 u32 legacy_state; /* DEPRECATED - being replaced by */
159 /* / SrvState, CliStateBoot, and CliStateOS below */
160 u32 header_size; /* sizeof(struct channel_header) */
161 u64 size; /* Total size of this channel in bytes */
162 u64 features; /* Flags to modify behavior */
163 uuid_le chtype; /* Channel type: data, bus, control, etc. */
164 u64 partition_handle; /* ID of guest partition */
165 u64 handle; /* Device number of this channel in client */
166 u64 ch_space_offset; /* Offset in bytes to channel specific area */
167 u32 version_id; /* struct channel_header Version ID */
168 u32 partition_index; /* Index of guest partition */
169 uuid_le zone_uuid; /* Guid of Channel's zone */
170 u32 cli_str_offset; /* offset from channel header to
171 * nul-terminated ClientString (0 if
172 * ClientString not present) */
173 u32 cli_state_boot; /* CHANNEL_CLIENTSTATE of pre-boot
174 * EFI client of this channel */
175 u32 cmd_state_cli; /* CHANNEL_COMMANDSTATE (overloaded in
176 * Windows drivers, see ServerStateUp,
177 * ServerStateDown, etc) */
178 u32 cli_state_os; /* CHANNEL_CLIENTSTATE of Guest OS
179 * client of this channel */
180 u32 ch_characteristic; /* CHANNEL_CHARACTERISTIC_<xxx> */
181 u32 cmd_state_srv; /* CHANNEL_COMMANDSTATE (overloaded in
182 * Windows drivers, see ServerStateUp,
183 * ServerStateDown, etc) */
184 u32 srv_state; /* CHANNEL_SERVERSTATE */
185 u8 cli_error_boot; /* bits to indicate err states for
186 * boot clients, so err messages can
188 u8 cli_error_os; /* bits to indicate err states for OS
189 * clients, so err messages can be
191 u8 filler[1]; /* Pad out to 128 byte cacheline */
192 /* Please add all new single-byte values below here */
196 #define ULTRA_CHANNEL_ENABLE_INTS (0x1ULL << 0)
198 /* Subheader for the Signal Type variation of the Common Channel */
199 struct signal_queue_header {
201 u32 version; /* SIGNAL_QUEUE_HEADER Version ID */
202 u32 chtype; /* Queue type: storage, network */
203 u64 size; /* Total size of this queue in bytes */
204 u64 sig_base_offset; /* Offset to signal queue area */
205 u64 features; /* Flags to modify behavior */
206 u64 num_sent; /* Total # of signals placed in this queue */
207 u64 num_overflows; /* Total # of inserts failed due to
209 u32 signal_size; /* Total size of a signal for this queue */
210 u32 max_slots; /* Max # of slots in queue, 1 slot is
212 u32 max_signals; /* Max # of signals in queue
213 * (MaxSignalSlots-1) */
214 u32 head; /* Queue head signal # */
216 u64 num_received; /* Total # of signals removed from this queue */
217 u32 tail; /* Queue tail signal # (on separate
219 u32 reserved1; /* Reserved field */
220 u64 reserved2; /* Reserved field */
222 u64 num_irq_received; /* Total # of Interrupts received. This
223 * is incremented by the ISR in the
224 * guest windows driver */
225 u64 num_empty; /* Number of times that visor_signal_remove
226 * is called and returned Empty
228 u32 errorflags; /* Error bits set during SignalReinit
229 * to denote trouble with client's
231 u8 filler[12]; /* Pad out to 64 byte cacheline */
234 #define spar_signal_init(chan, QHDRFLD, QDATAFLD, QDATATYPE, ver, typ) \
236 memset(&chan->QHDRFLD, 0, sizeof(chan->QHDRFLD)); \
237 chan->QHDRFLD.version = ver; \
238 chan->QHDRFLD.chtype = typ; \
239 chan->QHDRFLD.size = sizeof(chan->QDATAFLD); \
240 chan->QHDRFLD.signal_size = sizeof(QDATATYPE); \
241 chan->QHDRFLD.sig_base_offset = (u64)(chan->QDATAFLD) - \
242 (u64)(&chan->QHDRFLD); \
243 chan->QHDRFLD.max_slots = \
244 sizeof(chan->QDATAFLD) / sizeof(QDATATYPE); \
245 chan->QHDRFLD.max_signals = chan->QHDRFLD.max_slots - 1;\
248 /* Generic function useful for validating any type of channel when it is
249 * received by the client that will be accessing the channel.
250 * Note that <logCtx> is only needed for callers in the EFI environment, and
251 * is used to pass the EFI_DIAG_CAPTURE_PROTOCOL needed to log messages.
254 spar_check_channel_client(void __iomem *ch,
255 uuid_le expected_uuid,
257 u64 expected_min_bytes,
258 u32 expected_version,
259 u64 expected_signature)
261 if (uuid_le_cmp(expected_uuid, NULL_UUID_LE) != 0) {
265 &((struct channel_header __iomem *)(ch))->chtype,
267 /* caller wants us to verify type GUID */
268 if (uuid_le_cmp(guid, expected_uuid) != 0) {
269 pr_err("Channel mismatch on channel=%s(%pUL) field=type expected=%pUL actual=%pUL\n",
270 chname, &expected_uuid,
271 &expected_uuid, &guid);
275 if (expected_min_bytes > 0) { /* caller wants us to verify
277 unsigned long long bytes =
278 readq(&((struct channel_header __iomem *)
280 if (bytes < expected_min_bytes) {
281 pr_err("Channel mismatch on channel=%s(%pUL) field=size expected=0x%-8.8Lx actual=0x%-8.8Lx\n",
282 chname, &expected_uuid,
283 (unsigned long long)expected_min_bytes, bytes);
287 if (expected_version > 0) { /* caller wants us to verify
289 unsigned long ver = readl(&((struct channel_header __iomem *)
291 if (ver != expected_version) {
292 pr_err("Channel mismatch on channel=%s(%pUL) field=version expected=0x%-8.8lx actual=0x%-8.8lx\n",
293 chname, &expected_uuid,
294 (unsigned long)expected_version, ver);
298 if (expected_signature > 0) { /* caller wants us to verify
299 * channel signature */
300 unsigned long long sig =
301 readq(&((struct channel_header __iomem *)
303 if (sig != expected_signature) {
304 pr_err("Channel mismatch on channel=%s(%pUL) field=signature expected=0x%-8.8llx actual=0x%-8.8llx\n",
305 chname, &expected_uuid,
306 expected_signature, sig);
313 /* Generic function useful for validating any type of channel when it is about
314 * to be initialized by the server of the channel.
315 * Note that <logCtx> is only needed for callers in the EFI environment, and
316 * is used to pass the EFI_DIAG_CAPTURE_PROTOCOL needed to log messages.
318 static inline int spar_check_channel_server(uuid_le typeuuid, char *name,
319 u64 expected_min_bytes,
322 if (expected_min_bytes > 0) /* caller wants us to verify
324 if (actual_bytes < expected_min_bytes) {
325 pr_err("Channel mismatch on channel=%s(%pUL) field=size expected=0x%-8.8llx actual=0x%-8.8llx\n",
326 name, &typeuuid, expected_min_bytes,
333 /* Given a file pathname <s> (with '/' or '\' separating directory nodes),
334 * returns a pointer to the beginning of a node within that pathname such
335 * that the number of nodes from that pointer to the end of the string is
336 * NOT more than <n>. Note that if the pathname has less than <n> nodes
337 * in it, the return pointer will be to the beginning of the string.
340 pathname_last_n_nodes(u8 *s, unsigned int n)
343 unsigned int node_count = 0;
346 if ((*p == '/') || (*p == '\\'))
355 break; /* should never happen, unless someone
356 * is changing the string while we are
358 if ((*p == '/') || (*p == '\\'))
365 spar_channel_client_acquire_os(void __iomem *ch, u8 *id)
367 struct channel_header __iomem *hdr = ch;
369 if (readl(&hdr->cli_state_os) == CHANNELCLI_DISABLED) {
370 if ((readb(&hdr->cli_error_os)
371 & ULTRA_CLIERROROS_THROTTLEMSG_DISABLED) == 0) {
372 /* we are NOT throttling this message */
373 writeb(readb(&hdr->cli_error_os) |
374 ULTRA_CLIERROROS_THROTTLEMSG_DISABLED,
376 /* throttle until acquire successful */
378 pr_info("%s Channel StateTransition INVALID! - acquire failed because OS client DISABLED\n",
383 if ((readl(&hdr->cli_state_os) != CHANNELCLI_OWNED) &&
384 (readl(&hdr->cli_state_boot) == CHANNELCLI_DISABLED)) {
385 /* Our competitor is DISABLED, so we can transition to OWNED */
386 pr_info("%s Channel StateTransition (%s) %s(%d)-->%s(%d)\n",
388 ULTRA_CHANNELCLI_STRING(readl(&hdr->cli_state_os)),
389 readl(&hdr->cli_state_os),
390 ULTRA_CHANNELCLI_STRING(CHANNELCLI_OWNED),
392 writel(CHANNELCLI_OWNED, &hdr->cli_state_os);
393 mb(); /* required for channel synch */
395 if (readl(&hdr->cli_state_os) == CHANNELCLI_OWNED) {
396 if (readb(&hdr->cli_error_os) != 0) {
397 /* we are in an error msg throttling state;
399 pr_info("%s Channel OS client acquire now successful\n",
401 writeb(0, &hdr->cli_error_os);
406 /* We have to do it the "hard way". We transition to BUSY,
407 * and can use the channel iff our competitor has not also
408 * transitioned to BUSY. */
409 if (readl(&hdr->cli_state_os) != CHANNELCLI_ATTACHED) {
410 if ((readb(&hdr->cli_error_os)
411 & ULTRA_CLIERROROS_THROTTLEMSG_NOTATTACHED) == 0) {
412 /* we are NOT throttling this message */
413 writeb(readb(&hdr->cli_error_os) |
414 ULTRA_CLIERROROS_THROTTLEMSG_NOTATTACHED,
416 /* throttle until acquire successful */
417 pr_info("%s Channel StateTransition INVALID! - acquire failed because OS client NOT ATTACHED (state=%s(%d))\n",
418 id, ULTRA_CHANNELCLI_STRING(
419 readl(&hdr->cli_state_os)),
420 readl(&hdr->cli_state_os));
424 writel(CHANNELCLI_BUSY, &hdr->cli_state_os);
425 mb(); /* required for channel synch */
426 if (readl(&hdr->cli_state_boot) == CHANNELCLI_BUSY) {
427 if ((readb(&hdr->cli_error_os)
428 & ULTRA_CLIERROROS_THROTTLEMSG_BUSY) == 0) {
429 /* we are NOT throttling this message */
430 writeb(readb(&hdr->cli_error_os) |
431 ULTRA_CLIERROROS_THROTTLEMSG_BUSY,
433 /* throttle until acquire successful */
434 pr_info("%s Channel StateTransition failed - host OS acquire failed because boot BUSY\n",
438 writel(CHANNELCLI_ATTACHED, &hdr->cli_state_os);
439 mb(); /* required for channel synch */
442 if (readb(&hdr->cli_error_os) != 0) {
443 /* we are in an error msg throttling state; come out of it */
444 pr_info("%s Channel OS client acquire now successful\n", id);
445 writeb(0, &hdr->cli_error_os);
451 spar_channel_client_release_os(void __iomem *ch, u8 *id)
453 struct channel_header __iomem *hdr = ch;
455 if (readb(&hdr->cli_error_os) != 0) {
456 /* we are in an error msg throttling state; come out of it */
457 pr_info("%s Channel OS client error state cleared\n", id);
458 writeb(0, &hdr->cli_error_os);
460 if (readl(&hdr->cli_state_os) == CHANNELCLI_OWNED)
462 if (readl(&hdr->cli_state_os) != CHANNELCLI_BUSY) {
463 pr_info("%s Channel StateTransition INVALID! - release failed because OS client NOT BUSY (state=%s(%d))\n",
464 id, ULTRA_CHANNELCLI_STRING(
465 readl(&hdr->cli_state_os)),
466 readl(&hdr->cli_state_os));
469 writel(CHANNELCLI_ATTACHED, &hdr->cli_state_os); /* release busy */
473 * Routine Description:
474 * Tries to insert the prebuilt signal pointed to by pSignal into the nth
475 * Queue of the Channel pointed to by pChannel
478 * pChannel: (IN) points to the IO Channel
479 * Queue: (IN) nth Queue of the IO Channel
480 * pSignal: (IN) pointer to the signal
483 * - pChannel, Queue and pSignal are valid.
484 * - If insertion fails due to a full queue, the caller will determine the
485 * retry policy (e.g. wait & try again, report an error, etc.).
487 * Return value: 1 if the insertion succeeds, 0 if the queue was
491 unsigned char spar_signal_insert(struct channel_header __iomem *ch, u32 queue,
495 * Routine Description:
496 * Removes one signal from Channel pChannel's nth Queue at the
497 * time of the call and copies it into the memory pointed to by
501 * pChannel: (IN) points to the IO Channel
502 * Queue: (IN) nth Queue of the IO Channel
503 * pSignal: (IN) pointer to where the signals are to be copied
506 * - pChannel and Queue are valid.
507 * - pSignal points to a memory area large enough to hold queue's SignalSize
509 * Return value: 1 if the removal succeeds, 0 if the queue was
513 unsigned char spar_signal_remove(struct channel_header __iomem *ch, u32 queue,
517 * Routine Description:
518 * Removes all signals present in Channel pChannel's nth Queue at the
519 * time of the call and copies them into the memory pointed to by
520 * pSignal. Returns the # of signals copied as the value of the routine.
523 * pChannel: (IN) points to the IO Channel
524 * Queue: (IN) nth Queue of the IO Channel
525 * pSignal: (IN) pointer to where the signals are to be copied
528 * - pChannel and Queue are valid.
529 * - pSignal points to a memory area large enough to hold Queue's MaxSignals
530 * # of signals, each of which is Queue's SignalSize.
533 * # of signals copied.
535 unsigned int spar_signal_remove_all(struct channel_header *ch, u32 queue,
539 * Routine Description:
540 * Determine whether a signal queue is empty.
543 * pChannel: (IN) points to the IO Channel
544 * Queue: (IN) nth Queue of the IO Channel
547 * 1 if the signal queue is empty, 0 otherwise.
549 unsigned char spar_signalqueue_empty(struct channel_header __iomem *ch,