controlvmchannel.h revision af96e9c058ff620b78292945e24a9d044b0d6f97
1/* Copyright (C) 2010 - 2013 UNISYS CORPORATION
2 * All rights reserved.
3 *
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.
8 *
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
13 * details.
14 */
15
16#ifndef __CONTROLVMCHANNEL_H__
17#define __CONTROLVMCHANNEL_H__
18
19#include <linux/uuid.h>
20#include "commontypes.h"
21#include "channel.h"
22#include "controlframework.h"
23
24typedef u64 GUEST_PHYSICAL_ADDRESS;
25
26enum { INVALID_GUEST_FIRMWARE, SAMPLE_GUEST_FIRMWARE,
27	    TIANO32_GUEST_FIRMWARE, TIANO64_GUEST_FIRMWARE
28};
29
30/* {2B3C2D10-7EF5-4ad8-B966-3448B7386B3D} */
31#define ULTRA_CONTROLVM_CHANNEL_PROTOCOL_GUID	\
32		UUID_LE(0x2b3c2d10, 0x7ef5, 0x4ad8, \
33				0xb9, 0x66, 0x34, 0x48, 0xb7, 0x38, 0x6b, 0x3d)
34
35static const uuid_le UltraControlvmChannelProtocolGuid =
36	ULTRA_CONTROLVM_CHANNEL_PROTOCOL_GUID;
37
38#define ULTRA_CONTROLVM_CHANNEL_PROTOCOL_SIGNATURE \
39	ULTRA_CHANNEL_PROTOCOL_SIGNATURE
40#define CONTROLVM_MESSAGE_MAX     64
41
42/* Must increment this whenever you insert or delete fields within
43* this channel struct.  Also increment whenever you change the meaning
44* of fields within this channel struct so as to break pre-existing
45* software.  Note that you can usually add fields to the END of the
46* channel struct withOUT needing to increment this. */
47#define ULTRA_CONTROLVM_CHANNEL_PROTOCOL_VERSIONID  1
48
49#define ULTRA_CONTROLVM_CHANNEL_OK_CLIENT(pChannel, logCtx)           \
50	(ULTRA_check_channel_client(pChannel, \
51		UltraControlvmChannelProtocolGuid, \
52		"controlvm", \
53		sizeof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL), \
54		ULTRA_CONTROLVM_CHANNEL_PROTOCOL_VERSIONID, \
55		ULTRA_CONTROLVM_CHANNEL_PROTOCOL_SIGNATURE, \
56		__FILE__, __LINE__, logCtx))
57#define ULTRA_CONTROLVM_CHANNEL_OK_SERVER(actualBytes, logCtx)        \
58	(ULTRA_check_channel_server(UltraControlvmChannelProtocolGuid,	\
59				    "controlvm",			\
60				    sizeof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL), \
61				    actualBytes, __FILE__, __LINE__, logCtx))
62
63#define MY_DEVICE_INDEX 0
64#define MAX_MACDATA_LEN 8 /* number of bytes for MAC address in config packet */
65#define MAX_SERIAL_NUM	32
66
67#define DISK_ZERO_PUN_NUMBER	1  /* Target ID on the SCSI bus for LUN 0 */
68#define DISK_ZERO_LUN_NUMBER	3  /* Logical Unit Number */
69
70/* Defines for various channel queues... */
71#define CONTROLVM_QUEUE_REQUEST		0
72#define CONTROLVM_QUEUE_RESPONSE	1
73#define	CONTROLVM_QUEUE_EVENT		2
74#define CONTROLVM_QUEUE_ACK		3
75
76/* Max number of messages stored during IOVM creation to be reused
77 * after crash */
78#define CONTROLVM_CRASHMSG_MAX		2
79
80/** Ids for commands that may appear in either queue of a ControlVm channel.
81 *
82 *  Commands that are initiated by the command partition (CP), by an IO or
83 *  console service partition (SP), or by a guest partition (GP)are:
84 *  - issued on the RequestQueue queue (q #0) in the ControlVm channel
85 *  - responded to on the ResponseQueue queue (q #1) in the ControlVm channel
86 *
87 *  Events that are initiated by an IO or console service partition (SP) or
88 *  by a guest partition (GP) are:
89 *  - issued on the EventQueue queue (q #2) in the ControlVm channel
90 *  - responded to on the EventAckQueue queue (q #3) in the ControlVm channel
91 */
92typedef enum  {
93	CONTROLVM_INVALID = 0,
94	/* SWITCH commands required Parameter: SwitchNumber  */
95	/* BUS commands required Parameter: BusNumber  */
96	CONTROLVM_BUS_CREATE = 0x101,	/* CP --> SP, GP */
97	CONTROLVM_BUS_DESTROY = 0x102,	/* CP --> SP, GP */
98	CONTROLVM_BUS_CONFIGURE = 0x104,	/* CP --> SP */
99	CONTROLVM_BUS_CHANGESTATE = 0x105,	/* CP --> SP, GP */
100	CONTROLVM_BUS_CHANGESTATE_EVENT = 0x106, /* SP, GP --> CP */
101/* DEVICE commands required Parameter: BusNumber, DeviceNumber  */
102
103	CONTROLVM_DEVICE_CREATE = 0x201,	/* CP --> SP, GP */
104	CONTROLVM_DEVICE_DESTROY = 0x202,	/* CP --> SP, GP */
105	CONTROLVM_DEVICE_CONFIGURE = 0x203,	/* CP --> SP */
106	CONTROLVM_DEVICE_CHANGESTATE = 0x204,	/* CP --> SP, GP */
107	CONTROLVM_DEVICE_CHANGESTATE_EVENT = 0x205, /* SP, GP --> CP */
108	CONTROLVM_DEVICE_RECONFIGURE = 0x206,	/* CP --> Boot */
109/* DISK commands required Parameter: BusNumber, DeviceNumber  */
110	CONTROLVM_DISK_CREATE = 0x221,	/* CP --> SP */
111	CONTROLVM_DISK_DESTROY = 0x222,	/* CP --> SP */
112	CONTROLVM_DISK_CONFIGURE = 0x223,	/* CP --> SP */
113	CONTROLVM_DISK_CHANGESTATE = 0x224,	/* CP --> SP */
114/* CHIPSET commands */
115	CONTROLVM_CHIPSET_INIT = 0x301,	/* CP --> SP, GP */
116	CONTROLVM_CHIPSET_STOP = 0x302,	/* CP --> SP, GP */
117	CONTROLVM_CHIPSET_SHUTDOWN = 0x303,	/* CP --> SP */
118	CONTROLVM_CHIPSET_READY = 0x304,	/* CP --> SP */
119	CONTROLVM_CHIPSET_SELFTEST = 0x305,	/* CP --> SP */
120
121} CONTROLVM_ID;
122
123struct InterruptInfo {
124	 /**< specifies interrupt info. It is used to send interrupts
125	  *   for this channel. The peer at the end of this channel
126	  *   who has registered an interrupt (using recv fields
127	  *   above) will receive the interrupt. Passed as a parameter
128	  *   to Issue_VMCALL_IO_QUEUE_TRANSITION, which generates the
129	  *   interrupt.  Currently this is used by IOPart-SP to wake
130	  *   up GP when Data Channel transitions from empty to
131	  *   non-empty.*/
132	u64 sendInterruptHandle;
133
134	 /**< specifies interrupt handle. It is used to retrieve the
135	  *   corresponding interrupt pin from Monitor; and the
136	  *   interrupt pin is used to connect to the corresponding
137	  *   intrrupt.  Used by IOPart-GP only. */
138	u64 recvInterruptHandle;
139
140	 /**< specifies interrupt vector. It, interrupt pin, and shared are
141	  *   used to connect to the corresponding interrupt.  Used by
142	  *   IOPart-GP only. */
143	u32 recvInterruptVector;
144
145    /**< specifies if the recvInterrupt is shared.  It, interrupt pin
146     *   and vector are used to connect to 0 = not shared; 1 = shared.
147     *   the corresponding interrupt.  Used by IOPart-GP only. */
148	u8 recvInterruptShared;
149	u8 reserved[3];	/* Natural alignment purposes */
150};
151
152struct PciId {
153	u16 Domain;
154	u8 Bus;
155	u8 Slot;
156	u8 Func;
157	u8 Reserved[3];	/* Natural alignment purposes */
158};
159
160struct PciConfigHdr {
161	u16 VendorId;
162	u16 SubSysVendor;
163	u16 DeviceId;
164	u16 SubSysDevice;
165	u32 ClassCode;
166	u32 Reserved;		/* Natural alignment purposes */
167};
168
169struct ScsiId {
170	u32 Bus;
171	u32 Target;
172	u32 Lun;
173	u32 Host; /* Command should ignore this for *
174		   * DiskArrival/RemovalEvents */
175};
176
177struct WWID {
178	u32 wwid1;
179	u32 wwid2;
180};
181
182struct virtDiskInfo  {
183	u32 switchNo;		/* defined by SWITCH_CREATE */
184	u32 externalPortNo;	/* 0 for SAS RAID provided (external)
185				 * virtual disks, 1 for virtual disk
186				 * images, 2 for gold disk images */
187	u16 VirtualDiskIndex;	/* Index of disk descriptor in the
188				 * VirtualDisk segment associated with
189				 * externalPortNo */
190	u16 Reserved1;
191	u32 Reserved2;
192};
193
194typedef enum {
195	CONTROLVM_ACTION_NONE = 0,
196	CONTROLVM_ACTION_SET_RESTORE = 0x05E7,
197	CONTROLVM_ACTION_CLEAR_RESTORE = 0x0C18,
198	CONTROLVM_ACTION_RESTORING = 0x08E5,
199	CONTROLVM_ACTION_RESTORE_BUSY = 0x0999,
200	CONTROLVM_ACTION_CLEAR_NVRAM = 0xB01
201} CONTROLVM_ACTION;
202
203typedef enum _ULTRA_TOOL_ACTIONS {
204	    /* enumeration that defines intended action  */
205	    ULTRA_TOOL_ACTION_NONE = 0,	/* normal boot of boot disk */
206	ULTRA_TOOL_ACTION_INSTALL = 1,	/* install source disk(s) to boot
207					 * disk */
208	ULTRA_TOOL_ACTION_CAPTURE = 2,	/* capture boot disk to target disk(s)
209					 * as 'gold image' */
210	ULTRA_TOOL_ACTION_REPAIR = 3,	/* use source disk(s) to repair
211					 * installation on boot disk */
212	ULTRA_TOOL_ACTION_CLEAN = 4,	/* 'scrub' virtual disk before
213					 * releasing back to storage pool */
214	ULTRA_TOOL_ACTION_UPGRADE = 5,	/* upgrade to use content of images
215					 * referenced from newer blueprint */
216	ULTRA_TOOL_ACTION_DIAG = 6,	/* use tool to invoke diagnostic script
217					 * provided by blueprint */
218	ULTRA_TOOL_ACTION_FAILED = 7,	/* used when tool fails installation
219					   and cannot continue */
220	ULTRA_TOOL_ACTION_COUNT = 8
221} ULTRA_TOOL_ACTIONS;
222
223typedef struct _ULTRA_EFI_SPAR_INDICATION  {
224	u64 BootToFirmwareUI:1;	/* Bit 0: Stop in uefi ui */
225	u64 ClearNvram:1;	/* Bit 1: Clear NVRAM */
226	u64 ClearCmos:1;	/* Bit 2: Clear CMOS */
227	u64 BootToTool:1;	/* Bit 3: Run install tool */
228	/* remaining bits are available */
229} ULTRA_EFI_SPAR_INDICATION;
230
231typedef enum {
232	ULTRA_CHIPSET_FEATURE_REPLY = 0x00000001,
233	ULTRA_CHIPSET_FEATURE_PARA_HOTPLUG = 0x00000002,
234	ULTRA_CHIPSET_FEATURE_PCIVBUS = 0x00000004
235} ULTRA_CHIPSET_FEATURE;
236
237/** This is the common structure that is at the beginning of every
238 *  ControlVm message (both commands and responses) in any ControlVm
239 *  queue.  Commands are easily distinguished from responses by
240 *  looking at the flags.response field.
241 */
242typedef struct _CONTROLVM_MESSAGE_HEADER  {
243	u32 Id;		/* See CONTROLVM_ID. */
244	/* For requests, indicates the message type. */
245	/* For responses, indicates the type of message we are responding to. */
246
247	u32 MessageSize;	/* Includes size of this struct + size
248				 * of message */
249	u32 SegmentIndex;	/* Index of segment containing Vm
250				 * message/information */
251	u32 CompletionStatus;	/* Error status code or result of
252				 * message completion */
253	struct  {
254		u32 failed:1;		   /**< =1 in a response to * signify
255					    * failure */
256		u32 responseExpected:1;   /**< =1 in all messages that expect a
257					   * response (Control ignores this
258					   * bit) */
259		u32 server:1;		   /**< =1 in all bus & device-related
260					    * messages where the message
261					    * receiver is to act as the bus or
262					    * device server */
263		u32 testMessage:1;	   /**< =1 for testing use only
264					    * (Control and Command ignore this
265					    * bit) */
266		u32 partialCompletion:1;  /**< =1 if there are forthcoming
267					   * responses/acks associated
268					   * with this message */
269		u32 preserve:1;	       /**< =1 this is to let us know to
270					* preserve channel contents
271					* (for running guests)*/
272		u32 writerInDiag:1;	/**< =1 the DiagWriter is active in the
273					 * Diagnostic Partition*/
274
275		    /* remaining bits in this 32-bit word are available */
276	} Flags;
277	u32 Reserved;		/* Natural alignment */
278	u64 MessageHandle;	/* Identifies the particular message instance,
279				 * and is used to match particular */
280	/* request instances with the corresponding response instance. */
281	u64 PayloadVmOffset;	/* Offset of payload area from start of this
282				 * instance of ControlVm segment */
283	u32 PayloadMaxBytes;	/* Maximum bytes allocated in payload
284				 * area of ControlVm segment */
285	u32 PayloadBytes;	/* Actual number of bytes of payload
286				 * area to copy between IO/Command; */
287	/* if non-zero, there is a payload to copy. */
288} CONTROLVM_MESSAGE_HEADER;
289
290typedef struct _CONTROLVM_PACKET_DEVICE_CREATE  {
291	u32 busNo;	   /**< bus # (0..n-1) from the msg receiver's
292			    * perspective */
293
294	    /* Control uses header SegmentIndex field to access bus number... */
295	u32 devNo;	   /**< bus-relative (0..n-1) device number */
296	u64 channelAddr;  /**< Guest physical address of the channel, which
297			*   can be dereferenced by the receiver
298			*   of this ControlVm command */
299	u64 channelBytes; /**< specifies size of the channel in bytes */
300	uuid_le dataTypeGuid;/**< specifies format of data in channel */
301	uuid_le devInstGuid; /**< instance guid for the device */
302	struct InterruptInfo intr; /**< specifies interrupt information */
303} CONTROLVM_PACKET_DEVICE_CREATE;	/* for CONTROLVM_DEVICE_CREATE */
304
305typedef struct _CONTROLVM_PACKET_DEVICE_CONFIGURE  {
306	u32 busNo;	      /**< bus # (0..n-1) from the msg
307			       * receiver's perspective */
308
309	    /* Control uses header SegmentIndex field to access bus number... */
310	u32 devNo;	      /**< bus-relative (0..n-1) device number */
311} CONTROLVM_PACKET_DEVICE_CONFIGURE;	/* for CONTROLVM_DEVICE_CONFIGURE */
312
313typedef struct _CONTROLVM_MESSAGE_DEVICE_CREATE  {
314	CONTROLVM_MESSAGE_HEADER Header;
315	CONTROLVM_PACKET_DEVICE_CREATE Packet;
316} CONTROLVM_MESSAGE_DEVICE_CREATE;	/* total 128 bytes */
317
318typedef struct _CONTROLVM_MESSAGE_DEVICE_CONFIGURE  {
319	CONTROLVM_MESSAGE_HEADER Header;
320	CONTROLVM_PACKET_DEVICE_CONFIGURE Packet;
321} CONTROLVM_MESSAGE_DEVICE_CONFIGURE;	/* total 56 bytes */
322
323/* This is the format for a message in any ControlVm queue. */
324typedef struct _CONTROLVM_MESSAGE_PACKET  {
325	union  {
326
327		/* BEGIN Request messages */
328		struct  {
329			u32 busNo;	      /*< bus # (0..n-1) from the msg
330					       * receiver's perspective */
331
332	    /* Control uses header SegmentIndex field to access bus number... */
333			u32 deviceCount;      /*< indicates the max number of
334					       * devices on this bus */
335			u64 channelAddr;     /*< Guest physical address of the
336					      *   channel, which can be
337					      *   dereferenced by the receiver
338					      *   of this ControlVm command */
339			u64 channelBytes;    /*< size of the channel in bytes */
340			uuid_le busDataTypeGuid;/*< indicates format of data in
341						    bus channel */
342			uuid_le busInstGuid;    /*< instance guid for the bus */
343		} createBus;	/* for CONTROLVM_BUS_CREATE */
344		struct  {
345			u32 busNo;	      /*< bus # (0..n-1) from the msg
346					       * receiver's perspective */
347
348	    /* Control uses header SegmentIndex field to access bus number... */
349			u32 reserved;	/* Natural alignment purposes */
350		} destroyBus;	/* for CONTROLVM_BUS_DESTROY */
351		struct  {
352			u32 busNo;		    /*< bus # (0..n-1) from the
353						     * msg receiver's
354						     * perspective */
355
356	    /* Control uses header SegmentIndex field to access bus number... */
357			u32 reserved1;		    /* for alignment purposes */
358			u64 guestHandle;	    /* This is used to convert
359					 *  guest physical address to real
360					 *  physical address for DMA, for ex. */
361			u64 recvBusInterruptHandle;/*< specifies interrupt
362					 *   info. It is used by SP to register
363					 *   to receive interrupts from the CP.
364					 *   This interrupt is used for bus
365					 *   level notifications.  The
366					 *   corresponding
367					 *   sendBusInterruptHandle is kept in
368					 *   CP. */
369		} configureBus;	/* for CONTROLVM_BUS_CONFIGURE */
370
371		/* for CONTROLVM_DEVICE_CREATE */
372		CONTROLVM_PACKET_DEVICE_CREATE createDevice;
373		struct  {
374			u32 busNo;	      /*< bus # (0..n-1) from the msg
375					       * receiver's perspective */
376
377	    /* Control uses header SegmentIndex field to access bus number... */
378			u32 devNo;	      /*< bus-relative (0..n-1) device
379					       * number */
380		} destroyDevice;	/* for CONTROLVM_DEVICE_DESTROY */
381
382		/* for CONTROLVM_DEVICE_CONFIGURE */
383		CONTROLVM_PACKET_DEVICE_CONFIGURE configureDevice;
384		struct  {
385			u32 busNo;	      /*< bus # (0..n-1) from the msg
386					       * receiver's perspective */
387
388	    /* Control uses header SegmentIndex field to access bus number... */
389			u32 devNo;	      /*< bus-relative (0..n-1) device
390					       * number */
391		} reconfigureDevice;	/* for CONTROLVM_DEVICE_RECONFIGURE */
392		struct  {
393			u32 busNo;
394			ULTRA_SEGMENT_STATE state;
395			u8 reserved[2];	/* Natural alignment purposes */
396		} busChangeState;	/* for CONTROLVM_BUS_CHANGESTATE */
397		struct  {
398			u32 busNo;
399			u32 devNo;
400			ULTRA_SEGMENT_STATE state;
401			struct  {
402				u32 physicalDevice:1;	/* =1 if message is for
403							 * a physical device */
404			/* remaining bits in this 32-bit word are available */
405			} flags;
406			u8 reserved[2];	/* Natural alignment purposes */
407		} deviceChangeState;	/* for CONTROLVM_DEVICE_CHANGESTATE */
408		struct  {
409			u32 busNo;
410			u32 devNo;
411			ULTRA_SEGMENT_STATE state;
412			u8 reserved[6];	/* Natural alignment purposes */
413		} deviceChangeStateEvent; /* for CONTROLVM_DEVICE_CHANGESTATE_EVENT */
414		struct  {
415			u32 busCount; /*< indicates the max number of busses */
416			u32 switchCount; /*< indicates the max number of
417					  *   switches (applicable for service
418					  *   partition only) */
419			ULTRA_CHIPSET_FEATURE features;
420			u32 platformNumber;	/* Platform Number */
421		} initChipset;	/* for CONTROLVM_CHIPSET_INIT */
422		struct  {
423			u32 Options; /*< reserved */
424			u32 Test;    /*< bit 0 set to run embedded selftest */
425		} chipsetSelftest;	/* for CONTROLVM_CHIPSET_SELFTEST */
426
427		    /* END Request messages */
428
429		    /* BEGIN Response messages */
430
431		    /* END Response messages */
432
433		    /* BEGIN Event messages */
434
435		    /* END Event messages */
436
437		    /* BEGIN Ack messages */
438
439		    /* END Ack messages */
440		u64 addr;	    /*< a physical address of something, that
441				     *   can be dereferenced by the receiver of
442				     *   this ControlVm command (depends on
443				     *   command id) */
444		u64 handle;	    /*< a handle of something (depends on
445				     * command id) */
446	};
447} CONTROLVM_MESSAGE_PACKET;
448
449/* All messages in any ControlVm queue have this layout. */
450typedef struct _CONTROLVM_MESSAGE  {
451	CONTROLVM_MESSAGE_HEADER hdr;
452	CONTROLVM_MESSAGE_PACKET cmd;
453} CONTROLVM_MESSAGE;
454
455typedef struct _DEVICE_MAP  {
456	GUEST_PHYSICAL_ADDRESS DeviceChannelAddress;
457	u64 DeviceChannelSize;
458	u32 CA_Index;
459	u32 Reserved;		/* natural alignment */
460	u64 Reserved2;		/* Align structure on 32-byte boundary */
461} DEVICE_MAP;
462
463typedef struct _GUEST_DEVICES  {
464	DEVICE_MAP VideoChannel;
465	DEVICE_MAP KeyboardChannel;
466	DEVICE_MAP NetworkChannel;
467	DEVICE_MAP StorageChannel;
468	DEVICE_MAP ConsoleChannel;
469	u32 PartitionIndex;
470	u32 Pad;
471} GUEST_DEVICES;
472
473typedef struct _ULTRA_CONTROLVM_CHANNEL_PROTOCOL  {
474	 CHANNEL_HEADER Header;
475	 GUEST_PHYSICAL_ADDRESS gpControlVm;	/* guest physical address of
476						 * this channel */
477	 GUEST_PHYSICAL_ADDRESS gpPartitionTables; /* guest physical address of
478						    * partition tables */
479	 GUEST_PHYSICAL_ADDRESS gpDiagGuest;	/* guest physical address of
480						 * diagnostic channel */
481	 GUEST_PHYSICAL_ADDRESS gpBootRomDisk;	/* guest phys addr of (read
482						 * only) Boot ROM disk */
483	 GUEST_PHYSICAL_ADDRESS gpBootRamDisk;	/* guest phys addr of writable
484						 * Boot RAM disk */
485	 GUEST_PHYSICAL_ADDRESS gpAcpiTable;	/* guest phys addr of acpi
486						 * table */
487	 GUEST_PHYSICAL_ADDRESS gpControlChannel; /* guest phys addr of control
488						   * channel */
489	 GUEST_PHYSICAL_ADDRESS gpDiagRomDisk;	/* guest phys addr of diagnostic
490						 * ROM disk */
491	 GUEST_PHYSICAL_ADDRESS gpNvram;	/* guest phys addr of NVRAM
492						 * channel */
493	 u64 RequestPayloadOffset;	/* Offset to request payload area */
494	 u64 EventPayloadOffset;	/* Offset to event payload area */
495	 u32 RequestPayloadBytes;	/* Bytes available in request payload
496					 * area */
497	 u32 EventPayloadBytes;	/* Bytes available in event payload area */
498	 u32 ControlChannelBytes;
499	 u32 NvramChannelBytes;	/* Bytes in PartitionNvram segment */
500	 u32 MessageBytes;	/* sizeof(CONTROLVM_MESSAGE) */
501	 u32 MessageCount;	/* CONTROLVM_MESSAGE_MAX */
502	 GUEST_PHYSICAL_ADDRESS gpSmbiosTable;	/* guest phys addr of SMBIOS
503						 * tables */
504	 GUEST_PHYSICAL_ADDRESS gpPhysicalSmbiosTable;	/* guest phys addr of
505							 * SMBIOS table  */
506	 /* ULTRA_MAX_GUESTS_PER_SERVICE */
507	 GUEST_DEVICES gpObsoleteGuestDevices[16];
508
509	 /* guest physical address of EFI firmware image base  */
510	 GUEST_PHYSICAL_ADDRESS VirtualGuestFirmwareImageBase;
511
512	 /* guest physical address of EFI firmware entry point  */
513	 GUEST_PHYSICAL_ADDRESS VirtualGuestFirmwareEntryPoint;
514
515	 /* guest EFI firmware image size  */
516	 u64 VirtualGuestFirmwareImageSize;
517
518	 /* GPA = 1MB where EFI firmware image is copied to  */
519	 GUEST_PHYSICAL_ADDRESS VirtualGuestFirmwareBootBase;
520	 GUEST_PHYSICAL_ADDRESS VirtualGuestImageBase;
521	 GUEST_PHYSICAL_ADDRESS VirtualGuestImageSize;
522	 u64 PrototypeControlChannelOffset;
523	 GUEST_PHYSICAL_ADDRESS VirtualGuestPartitionHandle;
524
525	 u16 RestoreAction;	/* Restore Action field to restore the guest
526				 * partition */
527	u16 DumpAction;		/* For Windows guests it shows if the visordisk
528				 * is running in dump mode */
529	u16 NvramFailCount;
530	u16 SavedCrashMsgCount;	/* = CONTROLVM_CRASHMSG_MAX */
531	u32 SavedCrashMsgOffset;	/* Offset to request payload area needed
532					 * for crash dump */
533	u32 InstallationError;	/* Type of error encountered during
534				 * installation */
535	u32 InstallationTextId;	/* Id of string to display */
536	u16 InstallationRemainingSteps;	/* Number of remaining installation
537					 * steps (for progress bars) */
538	u8 ToolAction;		/* ULTRA_TOOL_ACTIONS Installation Action
539				 * field */
540	u8 Reserved;		/* alignment */
541	ULTRA_EFI_SPAR_INDICATION EfiSparIndication;
542	ULTRA_EFI_SPAR_INDICATION EfiSparIndicationSupported;
543	u32 SPReserved;
544	u8 Reserved2[28];	/* Force signals to begin on 128-byte cache
545				 * line */
546	SIGNAL_QUEUE_HEADER RequestQueue;	/* Service or guest partition
547						 * uses this queue to send
548						 * requests to Control */
549	SIGNAL_QUEUE_HEADER ResponseQueue;	/* Control uses this queue to
550						 * respond to service or guest
551						 * partition requests */
552	SIGNAL_QUEUE_HEADER EventQueue;		/* Control uses this queue to
553						 * send events to service or
554						 * guest partition */
555	SIGNAL_QUEUE_HEADER EventAckQueue;	/* Service or guest partition
556						 * uses this queue to ack
557						 * Control events */
558
559	 /* Request fixed-size message pool - does not include payload */
560	 CONTROLVM_MESSAGE RequestMsg[CONTROLVM_MESSAGE_MAX];
561
562	 /* Response fixed-size message pool - does not include payload */
563	 CONTROLVM_MESSAGE ResponseMsg[CONTROLVM_MESSAGE_MAX];
564
565	 /* Event fixed-size message pool - does not include payload */
566	 CONTROLVM_MESSAGE EventMsg[CONTROLVM_MESSAGE_MAX];
567
568	 /* Ack fixed-size message pool - does not include payload */
569	 CONTROLVM_MESSAGE EventAckMsg[CONTROLVM_MESSAGE_MAX];
570
571	 /* Message stored during IOVM creation to be reused after crash */
572	 CONTROLVM_MESSAGE SavedCrashMsg[CONTROLVM_CRASHMSG_MAX];
573} ULTRA_CONTROLVM_CHANNEL_PROTOCOL;
574
575/* Offsets for VM channel attributes... */
576#define VM_CH_REQ_QUEUE_OFFSET \
577	offsetof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL, RequestQueue)
578#define VM_CH_RESP_QUEUE_OFFSET \
579	offsetof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL, ResponseQueue)
580#define VM_CH_EVENT_QUEUE_OFFSET \
581	offsetof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL, EventQueue)
582#define VM_CH_ACK_QUEUE_OFFSET \
583	offsetof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL, EventAckQueue)
584#define VM_CH_REQ_MSG_OFFSET \
585	offsetof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL, RequestMsg)
586#define VM_CH_RESP_MSG_OFFSET \
587	offsetof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL, ResponseMsg)
588#define VM_CH_EVENT_MSG_OFFSET \
589	offsetof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL, EventMsg)
590#define VM_CH_ACK_MSG_OFFSET \
591	offsetof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL, EventAckMsg)
592#define VM_CH_CRASH_MSG_OFFSET \
593	offsetof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL, SavedCrashMsg)
594
595/* The following header will be located at the beginning of PayloadVmOffset for
596 *  various ControlVm commands. The receiver of a ControlVm command with a
597 *  PayloadVmOffset will dereference this address and then use ConnectionOffset,
598 *  InitiatorOffset, and TargetOffset to get the location of UTF-8 formatted
599 *  strings that can be parsed to obtain command-specific information. The value
600 *  of TotalLength should equal PayloadBytes.  The format of the strings at
601 *  PayloadVmOffset will take different forms depending on the message.  See the
602 *  following Wiki page for more information:
603 *  https://ustr-linux-1.na.uis.unisys.com/spar/index.php/ControlVm_Parameters_Area
604 */
605typedef struct _ULTRA_CONTROLVM_PARAMETERS_HEADER  {
606	u32 TotalLength;
607	u32 HeaderLength;
608	u32 ConnectionOffset;
609	u32 ConnectionLength;
610	u32 InitiatorOffset;
611	u32 InitiatorLength;
612	u32 TargetOffset;
613	u32 TargetLength;
614	u32 ClientOffset;
615	u32 ClientLength;
616	u32 NameOffset;
617	u32 NameLength;
618	uuid_le Id;
619	u32 Revision;
620	u32 Reserved;		/* Natural alignment */
621} ULTRA_CONTROLVM_PARAMETERS_HEADER;
622
623#endif				/* __CONTROLVMCHANNEL_H__ */
624