1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0 */ 2*4882a593Smuzhiyun /* 3*4882a593Smuzhiyun * Copyright (C) 2010 - 2015 UNISYS CORPORATION 4*4882a593Smuzhiyun * All rights reserved. 5*4882a593Smuzhiyun */ 6*4882a593Smuzhiyun 7*4882a593Smuzhiyun #ifndef __CONTROLVMCHANNEL_H__ 8*4882a593Smuzhiyun #define __CONTROLVMCHANNEL_H__ 9*4882a593Smuzhiyun 10*4882a593Smuzhiyun #include <linux/uuid.h> 11*4882a593Smuzhiyun #include <linux/visorbus.h> 12*4882a593Smuzhiyun 13*4882a593Smuzhiyun /* {2B3C2D10-7EF5-4ad8-B966-3448B7386B3D} */ 14*4882a593Smuzhiyun #define VISOR_CONTROLVM_CHANNEL_GUID \ 15*4882a593Smuzhiyun GUID_INIT(0x2b3c2d10, 0x7ef5, 0x4ad8, \ 16*4882a593Smuzhiyun 0xb9, 0x66, 0x34, 0x48, 0xb7, 0x38, 0x6b, 0x3d) 17*4882a593Smuzhiyun 18*4882a593Smuzhiyun #define CONTROLVM_MESSAGE_MAX 64 19*4882a593Smuzhiyun 20*4882a593Smuzhiyun /* 21*4882a593Smuzhiyun * Must increment this whenever you insert or delete fields within this channel 22*4882a593Smuzhiyun * struct. Also increment whenever you change the meaning of fields within this 23*4882a593Smuzhiyun * channel struct so as to break pre-existing software. Note that you can 24*4882a593Smuzhiyun * usually add fields to the END of the channel struct withOUT needing to 25*4882a593Smuzhiyun * increment this. 26*4882a593Smuzhiyun */ 27*4882a593Smuzhiyun #define VISOR_CONTROLVM_CHANNEL_VERSIONID 1 28*4882a593Smuzhiyun 29*4882a593Smuzhiyun /* Defines for various channel queues */ 30*4882a593Smuzhiyun #define CONTROLVM_QUEUE_REQUEST 0 31*4882a593Smuzhiyun #define CONTROLVM_QUEUE_RESPONSE 1 32*4882a593Smuzhiyun #define CONTROLVM_QUEUE_EVENT 2 33*4882a593Smuzhiyun #define CONTROLVM_QUEUE_ACK 3 34*4882a593Smuzhiyun 35*4882a593Smuzhiyun /* Max num of messages stored during IOVM creation to be reused after crash */ 36*4882a593Smuzhiyun #define CONTROLVM_CRASHMSG_MAX 2 37*4882a593Smuzhiyun 38*4882a593Smuzhiyun /* 39*4882a593Smuzhiyun * struct visor_segment_state 40*4882a593Smuzhiyun * @enabled: May enter other states. 41*4882a593Smuzhiyun * @active: Assigned to active partition. 42*4882a593Smuzhiyun * @alive: Configure message sent to service/server. 43*4882a593Smuzhiyun * @revoked: Similar to partition state ShuttingDown. 44*4882a593Smuzhiyun * @allocated: Memory (device/port number) has been selected by Command. 45*4882a593Smuzhiyun * @known: Has been introduced to the service/guest partition. 46*4882a593Smuzhiyun * @ready: Service/Guest partition has responded to introduction. 47*4882a593Smuzhiyun * @operating: Resource is configured and operating. 48*4882a593Smuzhiyun * @reserved: Natural alignment. 49*4882a593Smuzhiyun * 50*4882a593Smuzhiyun * Note: Don't use high bit unless we need to switch to ushort which is 51*4882a593Smuzhiyun * non-compliant. 52*4882a593Smuzhiyun */ 53*4882a593Smuzhiyun struct visor_segment_state { 54*4882a593Smuzhiyun u16 enabled:1; 55*4882a593Smuzhiyun u16 active:1; 56*4882a593Smuzhiyun u16 alive:1; 57*4882a593Smuzhiyun u16 revoked:1; 58*4882a593Smuzhiyun u16 allocated:1; 59*4882a593Smuzhiyun u16 known:1; 60*4882a593Smuzhiyun u16 ready:1; 61*4882a593Smuzhiyun u16 operating:1; 62*4882a593Smuzhiyun u16 reserved:8; 63*4882a593Smuzhiyun } __packed; 64*4882a593Smuzhiyun 65*4882a593Smuzhiyun static const struct visor_segment_state segment_state_running = { 66*4882a593Smuzhiyun 1, 1, 1, 0, 1, 1, 1, 1 67*4882a593Smuzhiyun }; 68*4882a593Smuzhiyun 69*4882a593Smuzhiyun static const struct visor_segment_state segment_state_paused = { 70*4882a593Smuzhiyun 1, 1, 1, 0, 1, 1, 1, 0 71*4882a593Smuzhiyun }; 72*4882a593Smuzhiyun 73*4882a593Smuzhiyun static const struct visor_segment_state segment_state_standby = { 74*4882a593Smuzhiyun 1, 1, 0, 0, 1, 1, 1, 0 75*4882a593Smuzhiyun }; 76*4882a593Smuzhiyun 77*4882a593Smuzhiyun /* 78*4882a593Smuzhiyun * enum controlvm_id 79*4882a593Smuzhiyun * @CONTROLVM_INVALID: 80*4882a593Smuzhiyun * @CONTROLVM_BUS_CREATE: CP --> SP, GP. 81*4882a593Smuzhiyun * @CONTROLVM_BUS_DESTROY: CP --> SP, GP. 82*4882a593Smuzhiyun * @CONTROLVM_BUS_CONFIGURE: CP --> SP. 83*4882a593Smuzhiyun * @CONTROLVM_BUS_CHANGESTATE: CP --> SP, GP. 84*4882a593Smuzhiyun * @CONTROLVM_BUS_CHANGESTATE_EVENT: SP, GP --> CP. 85*4882a593Smuzhiyun * @CONTROLVM_DEVICE_CREATE: CP --> SP, GP. 86*4882a593Smuzhiyun * @CONTROLVM_DEVICE_DESTROY: CP --> SP, GP. 87*4882a593Smuzhiyun * @CONTROLVM_DEVICE_CONFIGURE: CP --> SP. 88*4882a593Smuzhiyun * @CONTROLVM_DEVICE_CHANGESTATE: CP --> SP, GP. 89*4882a593Smuzhiyun * @CONTROLVM_DEVICE_CHANGESTATE_EVENT: SP, GP --> CP. 90*4882a593Smuzhiyun * @CONTROLVM_DEVICE_RECONFIGURE: CP --> Boot. 91*4882a593Smuzhiyun * @CONTROLVM_CHIPSET_INIT: CP --> SP, GP. 92*4882a593Smuzhiyun * @CONTROLVM_CHIPSET_STOP: CP --> SP, GP. 93*4882a593Smuzhiyun * @CONTROLVM_CHIPSET_READY: CP --> SP. 94*4882a593Smuzhiyun * @CONTROLVM_CHIPSET_SELFTEST: CP --> SP. 95*4882a593Smuzhiyun * 96*4882a593Smuzhiyun * Ids for commands that may appear in either queue of a ControlVm channel. 97*4882a593Smuzhiyun * 98*4882a593Smuzhiyun * Commands that are initiated by the command partition (CP), by an IO or 99*4882a593Smuzhiyun * console service partition (SP), or by a guest partition (GP) are: 100*4882a593Smuzhiyun * - issued on the RequestQueue queue (q #0) in the ControlVm channel 101*4882a593Smuzhiyun * - responded to on the ResponseQueue queue (q #1) in the ControlVm channel 102*4882a593Smuzhiyun * 103*4882a593Smuzhiyun * Events that are initiated by an IO or console service partition (SP) or 104*4882a593Smuzhiyun * by a guest partition (GP) are: 105*4882a593Smuzhiyun * - issued on the EventQueue queue (q #2) in the ControlVm channel 106*4882a593Smuzhiyun * - responded to on the EventAckQueue queue (q #3) in the ControlVm channel 107*4882a593Smuzhiyun */ 108*4882a593Smuzhiyun enum controlvm_id { 109*4882a593Smuzhiyun CONTROLVM_INVALID = 0, 110*4882a593Smuzhiyun /* 111*4882a593Smuzhiyun * SWITCH commands required Parameter: SwitchNumber. 112*4882a593Smuzhiyun * BUS commands required Parameter: BusNumber 113*4882a593Smuzhiyun */ 114*4882a593Smuzhiyun CONTROLVM_BUS_CREATE = 0x101, 115*4882a593Smuzhiyun CONTROLVM_BUS_DESTROY = 0x102, 116*4882a593Smuzhiyun CONTROLVM_BUS_CONFIGURE = 0x104, 117*4882a593Smuzhiyun CONTROLVM_BUS_CHANGESTATE = 0x105, 118*4882a593Smuzhiyun CONTROLVM_BUS_CHANGESTATE_EVENT = 0x106, 119*4882a593Smuzhiyun /* DEVICE commands required Parameter: BusNumber, DeviceNumber */ 120*4882a593Smuzhiyun CONTROLVM_DEVICE_CREATE = 0x201, 121*4882a593Smuzhiyun CONTROLVM_DEVICE_DESTROY = 0x202, 122*4882a593Smuzhiyun CONTROLVM_DEVICE_CONFIGURE = 0x203, 123*4882a593Smuzhiyun CONTROLVM_DEVICE_CHANGESTATE = 0x204, 124*4882a593Smuzhiyun CONTROLVM_DEVICE_CHANGESTATE_EVENT = 0x205, 125*4882a593Smuzhiyun CONTROLVM_DEVICE_RECONFIGURE = 0x206, 126*4882a593Smuzhiyun /* CHIPSET commands */ 127*4882a593Smuzhiyun CONTROLVM_CHIPSET_INIT = 0x301, 128*4882a593Smuzhiyun CONTROLVM_CHIPSET_STOP = 0x302, 129*4882a593Smuzhiyun CONTROLVM_CHIPSET_READY = 0x304, 130*4882a593Smuzhiyun CONTROLVM_CHIPSET_SELFTEST = 0x305, 131*4882a593Smuzhiyun }; 132*4882a593Smuzhiyun 133*4882a593Smuzhiyun /* 134*4882a593Smuzhiyun * struct irq_info 135*4882a593Smuzhiyun * @reserved1: Natural alignment purposes 136*4882a593Smuzhiyun * @recv_irq_handle: Specifies interrupt handle. It is used to retrieve the 137*4882a593Smuzhiyun * corresponding interrupt pin from Monitor; and the interrupt 138*4882a593Smuzhiyun * pin is used to connect to the corresponding interrupt. 139*4882a593Smuzhiyun * Used by IOPart-GP only. 140*4882a593Smuzhiyun * @recv_irq_vector: Specifies interrupt vector. It, interrupt pin, and shared 141*4882a593Smuzhiyun * are used to connect to the corresponding interrupt. 142*4882a593Smuzhiyun * Used by IOPart-GP only. 143*4882a593Smuzhiyun * @recv_irq_shared: Specifies if the recvInterrupt is shared. It, interrupt 144*4882a593Smuzhiyun * pin and vector are used to connect to 0 = not shared; 145*4882a593Smuzhiyun * 1 = shared the corresponding interrupt. 146*4882a593Smuzhiyun * Used by IOPart-GP only. 147*4882a593Smuzhiyun * @reserved: Natural alignment purposes 148*4882a593Smuzhiyun */ 149*4882a593Smuzhiyun struct irq_info { 150*4882a593Smuzhiyun u64 reserved1; 151*4882a593Smuzhiyun u64 recv_irq_handle; 152*4882a593Smuzhiyun u32 recv_irq_vector; 153*4882a593Smuzhiyun u8 recv_irq_shared; 154*4882a593Smuzhiyun u8 reserved[3]; 155*4882a593Smuzhiyun } __packed; 156*4882a593Smuzhiyun 157*4882a593Smuzhiyun /* 158*4882a593Smuzhiyun * struct efi_visor_indication 159*4882a593Smuzhiyun * @boot_to_fw_ui: Stop in UEFI UI 160*4882a593Smuzhiyun * @clear_nvram: Clear NVRAM 161*4882a593Smuzhiyun * @clear_cmos: Clear CMOS 162*4882a593Smuzhiyun * @boot_to_tool: Run install tool 163*4882a593Smuzhiyun * @reserved: Natural alignment 164*4882a593Smuzhiyun */ 165*4882a593Smuzhiyun struct efi_visor_indication { 166*4882a593Smuzhiyun u64 boot_to_fw_ui:1; 167*4882a593Smuzhiyun u64 clear_nvram:1; 168*4882a593Smuzhiyun u64 clear_cmos:1; 169*4882a593Smuzhiyun u64 boot_to_tool:1; 170*4882a593Smuzhiyun /* Remaining bits are available */ 171*4882a593Smuzhiyun u64 reserved:60; 172*4882a593Smuzhiyun } __packed; 173*4882a593Smuzhiyun 174*4882a593Smuzhiyun enum visor_chipset_feature { 175*4882a593Smuzhiyun VISOR_CHIPSET_FEATURE_REPLY = 0x00000001, 176*4882a593Smuzhiyun VISOR_CHIPSET_FEATURE_PARA_HOTPLUG = 0x00000002, 177*4882a593Smuzhiyun }; 178*4882a593Smuzhiyun 179*4882a593Smuzhiyun /* 180*4882a593Smuzhiyun * struct controlvm_message_header 181*4882a593Smuzhiyun * @id: See CONTROLVM_ID. 182*4882a593Smuzhiyun * @message_size: Includes size of this struct + size of message. 183*4882a593Smuzhiyun * @segment_index: Index of segment containing Vm message/information. 184*4882a593Smuzhiyun * @completion_status: Error status code or result of message completion. 185*4882a593Smuzhiyun * @struct flags: 186*4882a593Smuzhiyun * @failed: =1 in a response to signify failure. 187*4882a593Smuzhiyun * @response_expected: =1 in all messages that expect a response. 188*4882a593Smuzhiyun * @server: =1 in all bus & device-related messages where the 189*4882a593Smuzhiyun * message receiver is to act as the bus or device 190*4882a593Smuzhiyun * server. 191*4882a593Smuzhiyun * @test_message: =1 for testing use only (Control and Command 192*4882a593Smuzhiyun * ignore this). 193*4882a593Smuzhiyun * @partial_completion: =1 if there are forthcoming responses/acks 194*4882a593Smuzhiyun * associated with this message. 195*4882a593Smuzhiyun * @preserve: =1 this is to let us know to preserve channel 196*4882a593Smuzhiyun * contents. 197*4882a593Smuzhiyun * @writer_in_diag: =1 the DiagWriter is active in the Diagnostic 198*4882a593Smuzhiyun * Partition. 199*4882a593Smuzhiyun * @reserve: Natural alignment. 200*4882a593Smuzhiyun * @reserved: Natural alignment. 201*4882a593Smuzhiyun * @message_handle: Identifies the particular message instance. 202*4882a593Smuzhiyun * @payload_vm_offset: Offset of payload area from start of this instance. 203*4882a593Smuzhiyun * @payload_max_bytes: Maximum bytes allocated in payload area of ControlVm 204*4882a593Smuzhiyun * segment. 205*4882a593Smuzhiyun * @payload_bytes: Actual number of bytes of payload area to copy between 206*4882a593Smuzhiyun * IO/Command. If non-zero, there is a payload to copy. 207*4882a593Smuzhiyun * 208*4882a593Smuzhiyun * This is the common structure that is at the beginning of every 209*4882a593Smuzhiyun * ControlVm message (both commands and responses) in any ControlVm 210*4882a593Smuzhiyun * queue. Commands are easily distinguished from responses by 211*4882a593Smuzhiyun * looking at the flags.response field. 212*4882a593Smuzhiyun */ 213*4882a593Smuzhiyun struct controlvm_message_header { 214*4882a593Smuzhiyun u32 id; 215*4882a593Smuzhiyun /* 216*4882a593Smuzhiyun * For requests, indicates the message type. For responses, indicates 217*4882a593Smuzhiyun * the type of message we are responding to. 218*4882a593Smuzhiyun */ 219*4882a593Smuzhiyun u32 message_size; 220*4882a593Smuzhiyun u32 segment_index; 221*4882a593Smuzhiyun u32 completion_status; 222*4882a593Smuzhiyun struct { 223*4882a593Smuzhiyun u32 failed:1; 224*4882a593Smuzhiyun u32 response_expected:1; 225*4882a593Smuzhiyun u32 server:1; 226*4882a593Smuzhiyun u32 test_message:1; 227*4882a593Smuzhiyun u32 partial_completion:1; 228*4882a593Smuzhiyun u32 preserve:1; 229*4882a593Smuzhiyun u32 writer_in_diag:1; 230*4882a593Smuzhiyun u32 reserve:25; 231*4882a593Smuzhiyun } __packed flags; 232*4882a593Smuzhiyun u32 reserved; 233*4882a593Smuzhiyun u64 message_handle; 234*4882a593Smuzhiyun u64 payload_vm_offset; 235*4882a593Smuzhiyun u32 payload_max_bytes; 236*4882a593Smuzhiyun u32 payload_bytes; 237*4882a593Smuzhiyun } __packed; 238*4882a593Smuzhiyun 239*4882a593Smuzhiyun /* 240*4882a593Smuzhiyun * struct controlvm_packet_device_create - For CONTROLVM_DEVICE_CREATE 241*4882a593Smuzhiyun * @bus_no: Bus # (0..n-1) from the msg receiver's end. 242*4882a593Smuzhiyun * @dev_no: Bus-relative (0..n-1) device number. 243*4882a593Smuzhiyun * @channel_addr: Guest physical address of the channel, which can be 244*4882a593Smuzhiyun * dereferenced by the receiver of this ControlVm command. 245*4882a593Smuzhiyun * @channel_bytes: Specifies size of the channel in bytes. 246*4882a593Smuzhiyun * @data_type_uuid: Specifies format of data in channel. 247*4882a593Smuzhiyun * @dev_inst_uuid: Instance guid for the device. 248*4882a593Smuzhiyun * @irq_info intr: Specifies interrupt information. 249*4882a593Smuzhiyun */ 250*4882a593Smuzhiyun struct controlvm_packet_device_create { 251*4882a593Smuzhiyun u32 bus_no; 252*4882a593Smuzhiyun u32 dev_no; 253*4882a593Smuzhiyun u64 channel_addr; 254*4882a593Smuzhiyun u64 channel_bytes; 255*4882a593Smuzhiyun guid_t data_type_guid; 256*4882a593Smuzhiyun guid_t dev_inst_guid; 257*4882a593Smuzhiyun struct irq_info intr; 258*4882a593Smuzhiyun } __packed; 259*4882a593Smuzhiyun 260*4882a593Smuzhiyun /* 261*4882a593Smuzhiyun * struct controlvm_packet_device_configure - For CONTROLVM_DEVICE_CONFIGURE 262*4882a593Smuzhiyun * @bus_no: Bus number (0..n-1) from the msg receiver's perspective. 263*4882a593Smuzhiyun * @dev_no: Bus-relative (0..n-1) device number. 264*4882a593Smuzhiyun */ 265*4882a593Smuzhiyun struct controlvm_packet_device_configure { 266*4882a593Smuzhiyun u32 bus_no; 267*4882a593Smuzhiyun u32 dev_no; 268*4882a593Smuzhiyun } __packed; 269*4882a593Smuzhiyun 270*4882a593Smuzhiyun /* Total 128 bytes */ 271*4882a593Smuzhiyun struct controlvm_message_device_create { 272*4882a593Smuzhiyun struct controlvm_message_header header; 273*4882a593Smuzhiyun struct controlvm_packet_device_create packet; 274*4882a593Smuzhiyun } __packed; 275*4882a593Smuzhiyun 276*4882a593Smuzhiyun /* Total 56 bytes */ 277*4882a593Smuzhiyun struct controlvm_message_device_configure { 278*4882a593Smuzhiyun struct controlvm_message_header header; 279*4882a593Smuzhiyun struct controlvm_packet_device_configure packet; 280*4882a593Smuzhiyun } __packed; 281*4882a593Smuzhiyun 282*4882a593Smuzhiyun /* 283*4882a593Smuzhiyun * struct controlvm_message_packet - This is the format for a message in any 284*4882a593Smuzhiyun * ControlVm queue. 285*4882a593Smuzhiyun * @struct create_bus: For CONTROLVM_BUS_CREATE. 286*4882a593Smuzhiyun * @bus_no: Bus # (0..n-1) from the msg receiver's perspective. 287*4882a593Smuzhiyun * @dev_count: Indicates the max number of devices on this bus. 288*4882a593Smuzhiyun * @channel_addr: Guest physical address of the channel, which can be 289*4882a593Smuzhiyun * dereferenced by the receiver of this ControlVM 290*4882a593Smuzhiyun * command. 291*4882a593Smuzhiyun * @channel_bytes: Size of the channel. 292*4882a593Smuzhiyun * @bus_data_type_uuid: Indicates format of data in bus channel. 293*4882a593Smuzhiyun * @bus_inst_uuid: Instance uuid for the bus. 294*4882a593Smuzhiyun * 295*4882a593Smuzhiyun * @struct destroy_bus: For CONTROLVM_BUS_DESTROY. 296*4882a593Smuzhiyun * @bus_no: Bus # (0..n-1) from the msg receiver's perspective. 297*4882a593Smuzhiyun * @reserved: Natural alignment purposes. 298*4882a593Smuzhiyun * 299*4882a593Smuzhiyun * @struct configure_bus: For CONTROLVM_BUS_CONFIGURE. 300*4882a593Smuzhiyun * @bus_no: Bus # (0..n-1) from the receiver's perspective. 301*4882a593Smuzhiyun * @reserved1: For alignment purposes. 302*4882a593Smuzhiyun * @guest_handle: This is used to convert guest physical address to 303*4882a593Smuzhiyun * physical address. 304*4882a593Smuzhiyun * @recv_bus_irq_handle: Specifies interrupt info. It is used by SP to 305*4882a593Smuzhiyun * register to receive interrupts from the CP. This 306*4882a593Smuzhiyun * interrupt is used for bus level notifications. 307*4882a593Smuzhiyun * The corresponding sendBusInterruptHandle is kept 308*4882a593Smuzhiyun * in CP. 309*4882a593Smuzhiyun * 310*4882a593Smuzhiyun * @struct create_device: For CONTROLVM_DEVICE_CREATE. 311*4882a593Smuzhiyun * 312*4882a593Smuzhiyun * @struct destroy_device: For CONTROLVM_DEVICE_DESTROY. 313*4882a593Smuzhiyun * @bus_no: Bus # (0..n-1) from the msg receiver's perspective. 314*4882a593Smuzhiyun * @dev_no: Bus-relative (0..n-1) device number. 315*4882a593Smuzhiyun * 316*4882a593Smuzhiyun * @struct configure_device: For CONTROLVM_DEVICE_CONFIGURE. 317*4882a593Smuzhiyun * 318*4882a593Smuzhiyun * @struct reconfigure_device: For CONTROLVM_DEVICE_RECONFIGURE. 319*4882a593Smuzhiyun * @bus_no: Bus # (0..n-1) from the msg receiver's perspective. 320*4882a593Smuzhiyun * @dev_no: Bus-relative (0..n-1) device number. 321*4882a593Smuzhiyun * 322*4882a593Smuzhiyun * @struct bus_change_state: For CONTROLVM_BUS_CHANGESTATE. 323*4882a593Smuzhiyun * @bus_no: 324*4882a593Smuzhiyun * @struct state: 325*4882a593Smuzhiyun * @reserved: Natural alignment purposes. 326*4882a593Smuzhiyun * 327*4882a593Smuzhiyun * @struct device_change_state: For CONTROLVM_DEVICE_CHANGESTATE. 328*4882a593Smuzhiyun * @bus_no: 329*4882a593Smuzhiyun * @dev_no: 330*4882a593Smuzhiyun * @struct state: 331*4882a593Smuzhiyun * @struct flags: 332*4882a593Smuzhiyun * @phys_device: =1 if message is for a physical device. 333*4882a593Smuzhiyun * @reserved: Natural alignment. 334*4882a593Smuzhiyun * @reserved1: Natural alignment. 335*4882a593Smuzhiyun * @reserved: Natural alignment purposes. 336*4882a593Smuzhiyun * 337*4882a593Smuzhiyun * @struct device_change_state_event: For CONTROLVM_DEVICE_CHANGESTATE_EVENT. 338*4882a593Smuzhiyun * @bus_no: 339*4882a593Smuzhiyun * @dev_no: 340*4882a593Smuzhiyun * @struct state: 341*4882a593Smuzhiyun * @reserved: Natural alignment purposes. 342*4882a593Smuzhiyun * 343*4882a593Smuzhiyun * @struct init_chipset: For CONTROLVM_CHIPSET_INIT. 344*4882a593Smuzhiyun * @bus_count: Indicates the max number of busses. 345*4882a593Smuzhiyun * @switch_count: Indicates the max number of switches. 346*4882a593Smuzhiyun * @enum features: 347*4882a593Smuzhiyun * @platform_number: 348*4882a593Smuzhiyun * 349*4882a593Smuzhiyun * @struct chipset_selftest: For CONTROLVM_CHIPSET_SELFTEST. 350*4882a593Smuzhiyun * @options: Reserved. 351*4882a593Smuzhiyun * @test: Bit 0 set to run embedded selftest. 352*4882a593Smuzhiyun * 353*4882a593Smuzhiyun * @addr: A physical address of something, that can be dereferenced by the 354*4882a593Smuzhiyun * receiver of this ControlVm command. 355*4882a593Smuzhiyun * 356*4882a593Smuzhiyun * @handle: A handle of something (depends on command id). 357*4882a593Smuzhiyun */ 358*4882a593Smuzhiyun struct controlvm_message_packet { 359*4882a593Smuzhiyun union { 360*4882a593Smuzhiyun struct { 361*4882a593Smuzhiyun u32 bus_no; 362*4882a593Smuzhiyun u32 dev_count; 363*4882a593Smuzhiyun u64 channel_addr; 364*4882a593Smuzhiyun u64 channel_bytes; 365*4882a593Smuzhiyun guid_t bus_data_type_guid; 366*4882a593Smuzhiyun guid_t bus_inst_guid; 367*4882a593Smuzhiyun } __packed create_bus; 368*4882a593Smuzhiyun struct { 369*4882a593Smuzhiyun u32 bus_no; 370*4882a593Smuzhiyun u32 reserved; 371*4882a593Smuzhiyun } __packed destroy_bus; 372*4882a593Smuzhiyun struct { 373*4882a593Smuzhiyun u32 bus_no; 374*4882a593Smuzhiyun u32 reserved1; 375*4882a593Smuzhiyun u64 guest_handle; 376*4882a593Smuzhiyun u64 recv_bus_irq_handle; 377*4882a593Smuzhiyun } __packed configure_bus; 378*4882a593Smuzhiyun struct controlvm_packet_device_create create_device; 379*4882a593Smuzhiyun struct { 380*4882a593Smuzhiyun u32 bus_no; 381*4882a593Smuzhiyun u32 dev_no; 382*4882a593Smuzhiyun } __packed destroy_device; 383*4882a593Smuzhiyun struct controlvm_packet_device_configure configure_device; 384*4882a593Smuzhiyun struct { 385*4882a593Smuzhiyun u32 bus_no; 386*4882a593Smuzhiyun u32 dev_no; 387*4882a593Smuzhiyun } __packed reconfigure_device; 388*4882a593Smuzhiyun struct { 389*4882a593Smuzhiyun u32 bus_no; 390*4882a593Smuzhiyun struct visor_segment_state state; 391*4882a593Smuzhiyun u8 reserved[2]; 392*4882a593Smuzhiyun } __packed bus_change_state; 393*4882a593Smuzhiyun struct { 394*4882a593Smuzhiyun u32 bus_no; 395*4882a593Smuzhiyun u32 dev_no; 396*4882a593Smuzhiyun struct visor_segment_state state; 397*4882a593Smuzhiyun struct { 398*4882a593Smuzhiyun u32 phys_device:1; 399*4882a593Smuzhiyun u32 reserved:31; 400*4882a593Smuzhiyun u32 reserved1; 401*4882a593Smuzhiyun } __packed flags; 402*4882a593Smuzhiyun u8 reserved[2]; 403*4882a593Smuzhiyun } __packed device_change_state; 404*4882a593Smuzhiyun struct { 405*4882a593Smuzhiyun u32 bus_no; 406*4882a593Smuzhiyun u32 dev_no; 407*4882a593Smuzhiyun struct visor_segment_state state; 408*4882a593Smuzhiyun u8 reserved[6]; 409*4882a593Smuzhiyun } __packed device_change_state_event; 410*4882a593Smuzhiyun struct { 411*4882a593Smuzhiyun u32 bus_count; 412*4882a593Smuzhiyun u32 switch_count; 413*4882a593Smuzhiyun enum visor_chipset_feature features; 414*4882a593Smuzhiyun u32 platform_number; 415*4882a593Smuzhiyun } __packed init_chipset; 416*4882a593Smuzhiyun struct { 417*4882a593Smuzhiyun u32 options; 418*4882a593Smuzhiyun u32 test; 419*4882a593Smuzhiyun } __packed chipset_selftest; 420*4882a593Smuzhiyun u64 addr; 421*4882a593Smuzhiyun u64 handle; 422*4882a593Smuzhiyun }; 423*4882a593Smuzhiyun } __packed; 424*4882a593Smuzhiyun 425*4882a593Smuzhiyun /* All messages in any ControlVm queue have this layout. */ 426*4882a593Smuzhiyun struct controlvm_message { 427*4882a593Smuzhiyun struct controlvm_message_header hdr; 428*4882a593Smuzhiyun struct controlvm_message_packet cmd; 429*4882a593Smuzhiyun } __packed; 430*4882a593Smuzhiyun 431*4882a593Smuzhiyun /* 432*4882a593Smuzhiyun * struct visor_controlvm_channel 433*4882a593Smuzhiyun * @struct header: 434*4882a593Smuzhiyun * @gp_controlvm: Guest phys addr of this channel. 435*4882a593Smuzhiyun * @gp_partition_tables: Guest phys addr of partition tables. 436*4882a593Smuzhiyun * @gp_diag_guest: Guest phys addr of diagnostic channel. 437*4882a593Smuzhiyun * @gp_boot_romdisk: Guest phys addr of (read* only) Boot 438*4882a593Smuzhiyun * ROM disk. 439*4882a593Smuzhiyun * @gp_boot_ramdisk: Guest phys addr of writable Boot RAM 440*4882a593Smuzhiyun * disk. 441*4882a593Smuzhiyun * @gp_acpi_table: Guest phys addr of acpi table. 442*4882a593Smuzhiyun * @gp_control_channel: Guest phys addr of control channel. 443*4882a593Smuzhiyun * @gp_diag_romdisk: Guest phys addr of diagnostic ROM disk. 444*4882a593Smuzhiyun * @gp_nvram: Guest phys addr of NVRAM channel. 445*4882a593Smuzhiyun * @request_payload_offset: Offset to request payload area. 446*4882a593Smuzhiyun * @event_payload_offset: Offset to event payload area. 447*4882a593Smuzhiyun * @request_payload_bytes: Bytes available in request payload area. 448*4882a593Smuzhiyun * @event_payload_bytes: Bytes available in event payload area. 449*4882a593Smuzhiyun * @control_channel_bytes: 450*4882a593Smuzhiyun * @nvram_channel_bytes: Bytes in PartitionNvram segment. 451*4882a593Smuzhiyun * @message_bytes: sizeof(CONTROLVM_MESSAGE). 452*4882a593Smuzhiyun * @message_count: CONTROLVM_MESSAGE_MAX. 453*4882a593Smuzhiyun * @gp_smbios_table: Guest phys addr of SMBIOS tables. 454*4882a593Smuzhiyun * @gp_physical_smbios_table: Guest phys addr of SMBIOS table. 455*4882a593Smuzhiyun * @gp_reserved: VISOR_MAX_GUESTS_PER_SERVICE. 456*4882a593Smuzhiyun * @virtual_guest_firmware_image_base: Guest physical address of EFI firmware 457*4882a593Smuzhiyun * image base. 458*4882a593Smuzhiyun * @virtual_guest_firmware_entry_point: Guest physical address of EFI firmware 459*4882a593Smuzhiyun * entry point. 460*4882a593Smuzhiyun * @virtual_guest_firmware_image_size: Guest EFI firmware image size. 461*4882a593Smuzhiyun * @virtual_guest_firmware_boot_base: GPA = 1MB where EFI firmware image is 462*4882a593Smuzhiyun * copied to. 463*4882a593Smuzhiyun * @virtual_guest_image_base: 464*4882a593Smuzhiyun * @virtual_guest_image_size: 465*4882a593Smuzhiyun * @prototype_control_channel_offset: 466*4882a593Smuzhiyun * @virtual_guest_partition_handle: 467*4882a593Smuzhiyun * @restore_action: Restore Action field to restore the 468*4882a593Smuzhiyun * guest partition. 469*4882a593Smuzhiyun * @dump_action: For Windows guests it shows if the 470*4882a593Smuzhiyun * visordisk is in dump mode. 471*4882a593Smuzhiyun * @nvram_fail_count: 472*4882a593Smuzhiyun * @saved_crash_message_count: = CONTROLVM_CRASHMSG_MAX. 473*4882a593Smuzhiyun * @saved_crash_message_offset: Offset to request payload area needed 474*4882a593Smuzhiyun * for crash dump. 475*4882a593Smuzhiyun * @installation_error: Type of error encountered during 476*4882a593Smuzhiyun * installation. 477*4882a593Smuzhiyun * @installation_text_id: Id of string to display. 478*4882a593Smuzhiyun * @installation_remaining_steps: Number of remaining installation steps 479*4882a593Smuzhiyun * (for progress bars). 480*4882a593Smuzhiyun * @tool_action: VISOR_TOOL_ACTIONS Installation Action 481*4882a593Smuzhiyun * field. 482*4882a593Smuzhiyun * @reserved: Alignment. 483*4882a593Smuzhiyun * @struct efi_visor_ind: 484*4882a593Smuzhiyun * @sp_reserved: 485*4882a593Smuzhiyun * @reserved2: Force signals to begin on 128-byte 486*4882a593Smuzhiyun * cache line. 487*4882a593Smuzhiyun * @struct request_queue: Guest partition uses this queue to send 488*4882a593Smuzhiyun * requests to Control. 489*4882a593Smuzhiyun * @struct response_queue: Control uses this queue to respond to 490*4882a593Smuzhiyun * service or guest partition request. 491*4882a593Smuzhiyun * @struct event_queue: Control uses this queue to send events 492*4882a593Smuzhiyun * to guest partition. 493*4882a593Smuzhiyun * @struct event_ack_queue: Service or guest partition uses this 494*4882a593Smuzhiyun * queue to ack Control events. 495*4882a593Smuzhiyun * @struct request_msg: Request fixed-size message pool - 496*4882a593Smuzhiyun * does not include payload. 497*4882a593Smuzhiyun * @struct response_msg: Response fixed-size message pool - 498*4882a593Smuzhiyun * does not include payload. 499*4882a593Smuzhiyun * @struct event_msg: Event fixed-size message pool - 500*4882a593Smuzhiyun * does not include payload. 501*4882a593Smuzhiyun * @struct event_ack_msg: Ack fixed-size message pool - 502*4882a593Smuzhiyun * does not include payload. 503*4882a593Smuzhiyun * @struct saved_crash_msg: Message stored during IOVM creation to 504*4882a593Smuzhiyun * be reused after crash. 505*4882a593Smuzhiyun */ 506*4882a593Smuzhiyun struct visor_controlvm_channel { 507*4882a593Smuzhiyun struct channel_header header; 508*4882a593Smuzhiyun u64 gp_controlvm; 509*4882a593Smuzhiyun u64 gp_partition_tables; 510*4882a593Smuzhiyun u64 gp_diag_guest; 511*4882a593Smuzhiyun u64 gp_boot_romdisk; 512*4882a593Smuzhiyun u64 gp_boot_ramdisk; 513*4882a593Smuzhiyun u64 gp_acpi_table; 514*4882a593Smuzhiyun u64 gp_control_channel; 515*4882a593Smuzhiyun u64 gp_diag_romdisk; 516*4882a593Smuzhiyun u64 gp_nvram; 517*4882a593Smuzhiyun u64 request_payload_offset; 518*4882a593Smuzhiyun u64 event_payload_offset; 519*4882a593Smuzhiyun u32 request_payload_bytes; 520*4882a593Smuzhiyun u32 event_payload_bytes; 521*4882a593Smuzhiyun u32 control_channel_bytes; 522*4882a593Smuzhiyun u32 nvram_channel_bytes; 523*4882a593Smuzhiyun u32 message_bytes; 524*4882a593Smuzhiyun u32 message_count; 525*4882a593Smuzhiyun u64 gp_smbios_table; 526*4882a593Smuzhiyun u64 gp_physical_smbios_table; 527*4882a593Smuzhiyun char gp_reserved[2688]; 528*4882a593Smuzhiyun u64 virtual_guest_firmware_image_base; 529*4882a593Smuzhiyun u64 virtual_guest_firmware_entry_point; 530*4882a593Smuzhiyun u64 virtual_guest_firmware_image_size; 531*4882a593Smuzhiyun u64 virtual_guest_firmware_boot_base; 532*4882a593Smuzhiyun u64 virtual_guest_image_base; 533*4882a593Smuzhiyun u64 virtual_guest_image_size; 534*4882a593Smuzhiyun u64 prototype_control_channel_offset; 535*4882a593Smuzhiyun u64 virtual_guest_partition_handle; 536*4882a593Smuzhiyun u16 restore_action; 537*4882a593Smuzhiyun u16 dump_action; 538*4882a593Smuzhiyun u16 nvram_fail_count; 539*4882a593Smuzhiyun u16 saved_crash_message_count; 540*4882a593Smuzhiyun u32 saved_crash_message_offset; 541*4882a593Smuzhiyun u32 installation_error; 542*4882a593Smuzhiyun u32 installation_text_id; 543*4882a593Smuzhiyun u16 installation_remaining_steps; 544*4882a593Smuzhiyun u8 tool_action; 545*4882a593Smuzhiyun u8 reserved; 546*4882a593Smuzhiyun struct efi_visor_indication efi_visor_ind; 547*4882a593Smuzhiyun u32 sp_reserved; 548*4882a593Smuzhiyun u8 reserved2[28]; 549*4882a593Smuzhiyun struct signal_queue_header request_queue; 550*4882a593Smuzhiyun struct signal_queue_header response_queue; 551*4882a593Smuzhiyun struct signal_queue_header event_queue; 552*4882a593Smuzhiyun struct signal_queue_header event_ack_queue; 553*4882a593Smuzhiyun struct controlvm_message request_msg[CONTROLVM_MESSAGE_MAX]; 554*4882a593Smuzhiyun struct controlvm_message response_msg[CONTROLVM_MESSAGE_MAX]; 555*4882a593Smuzhiyun struct controlvm_message event_msg[CONTROLVM_MESSAGE_MAX]; 556*4882a593Smuzhiyun struct controlvm_message event_ack_msg[CONTROLVM_MESSAGE_MAX]; 557*4882a593Smuzhiyun struct controlvm_message saved_crash_msg[CONTROLVM_CRASHMSG_MAX]; 558*4882a593Smuzhiyun } __packed; 559*4882a593Smuzhiyun 560*4882a593Smuzhiyun /* 561*4882a593Smuzhiyun * struct visor_controlvm_parameters_header 562*4882a593Smuzhiyun * 563*4882a593Smuzhiyun * The following header will be located at the beginning of PayloadVmOffset for 564*4882a593Smuzhiyun * various ControlVm commands. The receiver of a ControlVm command with a 565*4882a593Smuzhiyun * PayloadVmOffset will dereference this address and then use connection_offset, 566*4882a593Smuzhiyun * initiator_offset, and target_offset to get the location of UTF-8 formatted 567*4882a593Smuzhiyun * strings that can be parsed to obtain command-specific information. The value 568*4882a593Smuzhiyun * of total_length should equal PayloadBytes. The format of the strings at 569*4882a593Smuzhiyun * PayloadVmOffset will take different forms depending on the message. 570*4882a593Smuzhiyun */ 571*4882a593Smuzhiyun struct visor_controlvm_parameters_header { 572*4882a593Smuzhiyun u32 total_length; 573*4882a593Smuzhiyun u32 header_length; 574*4882a593Smuzhiyun u32 connection_offset; 575*4882a593Smuzhiyun u32 connection_length; 576*4882a593Smuzhiyun u32 initiator_offset; 577*4882a593Smuzhiyun u32 initiator_length; 578*4882a593Smuzhiyun u32 target_offset; 579*4882a593Smuzhiyun u32 target_length; 580*4882a593Smuzhiyun u32 client_offset; 581*4882a593Smuzhiyun u32 client_length; 582*4882a593Smuzhiyun u32 name_offset; 583*4882a593Smuzhiyun u32 name_length; 584*4882a593Smuzhiyun guid_t id; 585*4882a593Smuzhiyun u32 revision; 586*4882a593Smuzhiyun /* Natural alignment */ 587*4882a593Smuzhiyun u32 reserved; 588*4882a593Smuzhiyun } __packed; 589*4882a593Smuzhiyun 590*4882a593Smuzhiyun /* General Errors------------------------------------------------------[0-99] */ 591*4882a593Smuzhiyun #define CONTROLVM_RESP_SUCCESS 0 592*4882a593Smuzhiyun #define CONTROLVM_RESP_ALREADY_DONE 1 593*4882a593Smuzhiyun #define CONTROLVM_RESP_IOREMAP_FAILED 2 594*4882a593Smuzhiyun #define CONTROLVM_RESP_KMALLOC_FAILED 3 595*4882a593Smuzhiyun #define CONTROLVM_RESP_ID_UNKNOWN 4 596*4882a593Smuzhiyun #define CONTROLVM_RESP_ID_INVALID_FOR_CLIENT 5 597*4882a593Smuzhiyun /* CONTROLVM_INIT_CHIPSET-------------------------------------------[100-199] */ 598*4882a593Smuzhiyun #define CONTROLVM_RESP_CLIENT_SWITCHCOUNT_NONZERO 100 599*4882a593Smuzhiyun #define CONTROLVM_RESP_EXPECTED_CHIPSET_INIT 101 600*4882a593Smuzhiyun /* Maximum Limit----------------------------------------------------[200-299] */ 601*4882a593Smuzhiyun /* BUS_CREATE */ 602*4882a593Smuzhiyun #define CONTROLVM_RESP_ERROR_MAX_BUSES 201 603*4882a593Smuzhiyun /* DEVICE_CREATE */ 604*4882a593Smuzhiyun #define CONTROLVM_RESP_ERROR_MAX_DEVICES 202 605*4882a593Smuzhiyun /* Payload and Parameter Related------------------------------------[400-499] */ 606*4882a593Smuzhiyun /* SWITCH_ATTACHEXTPORT, DEVICE_CONFIGURE */ 607*4882a593Smuzhiyun #define CONTROLVM_RESP_PAYLOAD_INVALID 400 608*4882a593Smuzhiyun /* Multiple */ 609*4882a593Smuzhiyun #define CONTROLVM_RESP_INITIATOR_PARAMETER_INVALID 401 610*4882a593Smuzhiyun /* DEVICE_CONFIGURE */ 611*4882a593Smuzhiyun #define CONTROLVM_RESP_TARGET_PARAMETER_INVALID 402 612*4882a593Smuzhiyun /* DEVICE_CONFIGURE */ 613*4882a593Smuzhiyun #define CONTROLVM_RESP_CLIENT_PARAMETER_INVALID 403 614*4882a593Smuzhiyun /* Specified[Packet Structure] Value--------------------------------[500-599] */ 615*4882a593Smuzhiyun /* SWITCH_ATTACHINTPORT */ 616*4882a593Smuzhiyun /* BUS_CONFIGURE, DEVICE_CREATE, DEVICE_CONFIG, DEVICE_DESTROY */ 617*4882a593Smuzhiyun #define CONTROLVM_RESP_BUS_INVALID 500 618*4882a593Smuzhiyun /* SWITCH_ATTACHINTPORT*/ 619*4882a593Smuzhiyun /* DEVICE_CREATE, DEVICE_CONFIGURE, DEVICE_DESTROY */ 620*4882a593Smuzhiyun #define CONTROLVM_RESP_DEVICE_INVALID 501 621*4882a593Smuzhiyun /* DEVICE_CREATE, DEVICE_CONFIGURE */ 622*4882a593Smuzhiyun #define CONTROLVM_RESP_CHANNEL_INVALID 502 623*4882a593Smuzhiyun /* Partition Driver Callback Interface------------------------------[600-699] */ 624*4882a593Smuzhiyun /* BUS_CREATE, BUS_DESTROY, DEVICE_CREATE, DEVICE_DESTROY */ 625*4882a593Smuzhiyun #define CONTROLVM_RESP_VIRTPCI_DRIVER_FAILURE 604 626*4882a593Smuzhiyun /* Unable to invoke VIRTPCI callback. VIRTPCI Callback returned error. */ 627*4882a593Smuzhiyun /* BUS_CREATE, BUS_DESTROY, DEVICE_CREATE, DEVICE_DESTROY */ 628*4882a593Smuzhiyun #define CONTROLVM_RESP_VIRTPCI_DRIVER_CALLBACK_ERROR 605 629*4882a593Smuzhiyun /* Generic device callback returned error. */ 630*4882a593Smuzhiyun /* SWITCH_ATTACHEXTPORT, SWITCH_DETACHEXTPORT, DEVICE_CONFIGURE */ 631*4882a593Smuzhiyun #define CONTROLVM_RESP_GENERIC_DRIVER_CALLBACK_ERROR 606 632*4882a593Smuzhiyun /* Bus Related------------------------------------------------------[700-799] */ 633*4882a593Smuzhiyun /* BUS_DESTROY */ 634*4882a593Smuzhiyun #define CONTROLVM_RESP_ERROR_BUS_DEVICE_ATTACHED 700 635*4882a593Smuzhiyun /* Channel Related--------------------------------------------------[800-899] */ 636*4882a593Smuzhiyun /* GET_CHANNELINFO, DEVICE_DESTROY */ 637*4882a593Smuzhiyun #define CONTROLVM_RESP_CHANNEL_TYPE_UNKNOWN 800 638*4882a593Smuzhiyun /* DEVICE_CREATE */ 639*4882a593Smuzhiyun #define CONTROLVM_RESP_CHANNEL_SIZE_TOO_SMALL 801 640*4882a593Smuzhiyun /* Chipset Shutdown Related---------------------------------------[1000-1099] */ 641*4882a593Smuzhiyun #define CONTROLVM_RESP_CHIPSET_SHUTDOWN_FAILED 1000 642*4882a593Smuzhiyun #define CONTROLVM_RESP_CHIPSET_SHUTDOWN_ALREADY_ACTIVE 1001 643*4882a593Smuzhiyun /* Chipset Stop Related-------------------------------------------[1100-1199] */ 644*4882a593Smuzhiyun #define CONTROLVM_RESP_CHIPSET_STOP_FAILED_BUS 1100 645*4882a593Smuzhiyun #define CONTROLVM_RESP_CHIPSET_STOP_FAILED_SWITCH 1101 646*4882a593Smuzhiyun /* Device Related-------------------------------------------------[1400-1499] */ 647*4882a593Smuzhiyun #define CONTROLVM_RESP_DEVICE_UDEV_TIMEOUT 1400 648*4882a593Smuzhiyun 649*4882a593Smuzhiyun /* __CONTROLVMCHANNEL_H__ */ 650*4882a593Smuzhiyun #endif 651