acrn-hypervisor/hypervisor/include/public/acrn_common.h
Victor Sun 6071234337 HV: use term of UUID
The code mixed the usage on term of UUID and GUID, now use UUID to make
code more consistent, also will use lowercase (i.e. uuid) in variable name
definition.

Tracked-On: #2291

Signed-off-by: Victor Sun <victor.sun@intel.com>
Acked-by: Eddie Dong <eddie.dong@intel.com>
2019-04-12 13:45:32 +08:00

664 lines
17 KiB
C

/*
* common definition
*
* Copyright (C) 2017 Intel Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
/**
* @file acrn_common.h
*
* @brief acrn common data structure for hypercall or ioctl
*/
#ifndef ACRN_COMMON_H
#define ACRN_COMMON_H
#include <types.h>
/*
* Common structures for ACRN/VHM/DM
*/
/*
* IO request
*/
#define VHM_REQUEST_MAX 16U
#define REQ_STATE_FREE 3U
#define REQ_STATE_PENDING 0U
#define REQ_STATE_COMPLETE 1U
#define REQ_STATE_PROCESSING 2U
#define REQ_PORTIO 0U
#define REQ_MMIO 1U
#define REQ_PCICFG 2U
#define REQ_WP 3U
#define REQUEST_READ 0U
#define REQUEST_WRITE 1U
/* IOAPIC device model info */
#define VIOAPIC_RTE_NUM 48U /* vioapic pins */
#if VIOAPIC_RTE_NUM < 24U
#error "VIOAPIC_RTE_NUM must be larger than 23"
#endif
/* Generic VM flags from guest OS */
#define GUEST_FLAG_SECURE_WORLD_ENABLED (1UL << 0U) /* Whether secure world is enabled */
#define GUEST_FLAG_LAPIC_PASSTHROUGH (1UL << 1U) /* Whether LAPIC is passed through */
#define GUEST_FLAG_IO_COMPLETION_POLLING (1UL << 2U) /* Whether need hypervisor poll IO completion */
#define GUEST_FLAG_CLOS_REQUIRED (1UL << 3U) /* Whether CLOS is required */
#define GUEST_FLAG_HIDE_MTRR (1UL << 4U) /* Whether hide MTRR from VM */
#define GUEST_FLAG_RT (1UL << 5U) /* Whether the vm is RT-VM */
/* TODO: We may need to get this addr from guest ACPI instead of hardcode here */
#define VIRTUAL_PM1A_CNT_ADDR 0x404U
#define VIRTUAL_PM1A_SCI_EN 0x0001
#define VIRTUAL_PM1A_SLP_TYP 0x1c00U
#define VIRTUAL_PM1A_SLP_EN 0x2000U
#define VIRTUAL_PM1A_ALWAYS_ZERO 0xc003
/**
* @brief Hypercall
*
* @addtogroup acrn_hypercall ACRN Hypercall
* @{
*/
/**
* @brief Representation of a MMIO request
*/
struct mmio_request {
/**
* @brief Direction of the access
*
* Either \p REQUEST_READ or \p REQUEST_WRITE.
*/
uint32_t direction;
/**
* @brief reserved
*/
uint32_t reserved;
/**
* @brief Address of the I/O access
*/
uint64_t address;
/**
* @brief Width of the I/O access in byte
*/
uint64_t size;
/**
* @brief The value read for I/O reads or to be written for I/O writes
*/
uint64_t value;
} __aligned(8);
/**
* @brief Representation of a port I/O request
*/
struct pio_request {
/**
* @brief Direction of the access
*
* Either \p REQUEST_READ or \p REQUEST_WRITE.
*/
uint32_t direction;
/**
* @brief reserved
*/
uint32_t reserved;
/**
* @brief Port address of the I/O access
*/
uint64_t address;
/**
* @brief Width of the I/O access in byte
*/
uint64_t size;
/**
* @brief The value read for I/O reads or to be written for I/O writes
*/
uint32_t value;
} __aligned(8);
/**
* @brief Representation of a PCI configuration space access
*/
struct pci_request {
/**
* @brief Direction of the access
*
* Either \p REQUEST_READ or \p REQUEST_WRITE.
*/
uint32_t direction;
/**
* @brief Reserved
*/
uint32_t reserved[3];/* need keep same header fields with pio_request */
/**
* @brief Width of the I/O access in byte
*/
int64_t size;
/**
* @brief The value read for I/O reads or to be written for I/O writes
*/
int32_t value;
/**
* @brief The \p bus part of the BDF of the device
*/
int32_t bus;
/**
* @brief The \p device part of the BDF of the device
*/
int32_t dev;
/**
* @brief The \p function part of the BDF of the device
*/
int32_t func;
/**
* @brief The register to be accessed in the configuration space
*/
int32_t reg;
} __aligned(8);
union vhm_io_request {
struct pio_request pio;
struct pci_request pci;
struct mmio_request mmio;
int64_t reserved1[8];
};
/**
* @brief 256-byte VHM requests
*
* The state transitions of a VHM request are:
*
* FREE -> PENDING -> PROCESSING -> COMPLETE -> FREE -> ...
*
* When a request is in COMPLETE or FREE state, the request is owned by the
* hypervisor. SOS (VHM or DM) shall not read or write the internals of the
* request except the state.
*
* When a request is in PENDING or PROCESSING state, the request is owned by
* SOS. The hypervisor shall not read or write the request other than the state.
*
* Based on the rules above, a typical VHM request lifecycle should looks like
* the following.
*
* @verbatim embed:rst:leading-asterisk
*
* +-----------------------+-------------------------+----------------------+
* | SOS vCPU 0 | SOS vCPU x | UOS vCPU y |
* +=======================+=========================+======================+
* | | | Hypervisor: |
* | | | |
* | | | - Fill in type, |
* | | | addr, etc. |
* | | | - Pause UOS vCPU y |
* | | | - Set state to |
* | | | PENDING (a) |
* | | | - Fire upcall to |
* | | | SOS vCPU 0 |
* | | | |
* +-----------------------+-------------------------+----------------------+
* | VHM: | | |
* | | | |
* | - Scan for pending | | |
* | requests | | |
* | - Set state to | | |
* | PROCESSING (b) | | |
* | - Assign requests to | | |
* | clients (c) | | |
* | | | |
* +-----------------------+-------------------------+----------------------+
* | | Client: | |
* | | | |
* | | - Scan for assigned | |
* | | requests | |
* | | - Handle the | |
* | | requests (d) | |
* | | - Set state to COMPLETE | |
* | | - Notify the hypervisor | |
* | | | |
* +-----------------------+-------------------------+----------------------+
* | | Hypervisor: | |
* | | | |
* | | - resume UOS vCPU y | |
* | | (e) | |
* | | | |
* +-----------------------+-------------------------+----------------------+
* | | | Hypervisor: |
* | | | |
* | | | - Post-work (f) |
* | | | - set state to FREE |
* | | | |
* +-----------------------+-------------------------+----------------------+
*
* @endverbatim
*
* Note that the following shall hold.
*
* 1. (a) happens before (b)
* 2. (c) happens before (d)
* 3. (e) happens before (f)
* 4. One vCPU cannot trigger another I/O request before the previous one has
* completed (i.e. the state switched to FREE)
*
* Accesses to the state of a vhm_request shall be atomic and proper barriers
* are needed to ensure that:
*
* 1. Setting state to PENDING is the last operation when issuing a request in
* the hypervisor, as the hypervisor shall not access the request any more.
*
* 2. Due to similar reasons, setting state to COMPLETE is the last operation
* of request handling in VHM or clients in SOS.
*/
struct vhm_request {
/**
* @brief Type of this request.
*
* Byte offset: 0.
*/
uint32_t type;
/**
* @brief Hypervisor will poll completion if set.
*
* Byte offset: 4.
*/
uint32_t completion_polling;
/**
* @brief Reserved.
*
* Byte offset: 8.
*/
uint32_t reserved0[14];
/**
* @brief Details about this request.
*
* For REQ_PORTIO, this has type
* pio_request. For REQ_MMIO and REQ_WP, this has type mmio_request. For
* REQ_PCICFG, this has type pci_request.
*
* Byte offset: 64.
*/
union vhm_io_request reqs;
/**
* @brief Reserved.
*
* Byte offset: 128.
*/
uint32_t reserved1;
/**
* @brief The client which is distributed to handle this request.
*
* Accessed by VHM only.
*
* Byte offset: 132.
*/
int32_t client;
/**
* @brief The status of this request.
*
* Taking REQ_STATE_xxx as values.
*
* Byte offset: 136.
*/
uint32_t processed;
} __aligned(256);
union vhm_request_buffer {
struct vhm_request req_queue[VHM_REQUEST_MAX];
int8_t reserved[4096];
} __aligned(4096);
/**
* @brief Info to create a VM, the parameter for HC_CREATE_VM hypercall
*/
struct acrn_create_vm {
/** created vmid return to VHM. Keep it first field */
uint16_t vmid;
/** Reserved */
uint16_t reserved0;
/** VCPU numbers this VM want to create */
uint16_t vcpu_num;
/** Reserved */
uint16_t reserved1;
/** the UUID of this VM */
uint8_t uuid[16];
/* VM flag bits from Guest OS, now used
* GUEST_FLAG_SECURE_WORLD_ENABLED (1UL<<0)
*/
uint64_t vm_flag;
uint64_t req_buf;
/** Reserved for future use*/
uint8_t reserved2[16];
} __aligned(8);
#define MAX_VM_OS_NAME_LEN 32U
/**
* @brief Info to create a VCPU
*
* the parameter for HC_CREATE_VCPU hypercall
*/
struct acrn_create_vcpu {
/** the virtual CPU ID for the VCPU created */
uint16_t vcpu_id;
/** the physical CPU ID for the VCPU created */
uint16_t pcpu_id;
} __aligned(8);
/* General-purpose register layout aligned with the general-purpose register idx
* when vmexit, such as vmexit due to CR access, refer to SMD Vol.3C 27-6.
*/
struct acrn_gp_regs {
uint64_t rax;
uint64_t rcx;
uint64_t rdx;
uint64_t rbx;
uint64_t rsp;
uint64_t rbp;
uint64_t rsi;
uint64_t rdi;
uint64_t r8;
uint64_t r9;
uint64_t r10;
uint64_t r11;
uint64_t r12;
uint64_t r13;
uint64_t r14;
uint64_t r15;
};
/* struct to define how the descriptor stored in memory.
* Refer SDM Vol3 3.5.1 "Segment Descriptor Tables"
* Figure 3-11
*/
struct acrn_descriptor_ptr {
uint16_t limit;
uint64_t base;
uint16_t reserved[3]; /* align struct size to 64bit */
} __packed;
/**
* @brief registers info for vcpu.
*/
struct acrn_vcpu_regs {
struct acrn_gp_regs gprs;
struct acrn_descriptor_ptr gdt;
struct acrn_descriptor_ptr idt;
uint64_t rip;
uint64_t cs_base;
uint64_t cr0;
uint64_t cr4;
uint64_t cr3;
uint64_t ia32_efer;
uint64_t rflags;
uint64_t reserved_64[4];
uint32_t cs_ar;
uint32_t cs_limit;
uint32_t reserved_32[3];
/* don't change the order of following sel */
uint16_t cs_sel;
uint16_t ss_sel;
uint16_t ds_sel;
uint16_t es_sel;
uint16_t fs_sel;
uint16_t gs_sel;
uint16_t ldt_sel;
uint16_t tr_sel;
uint16_t reserved_16[4];
};
/**
* @brief Info to set vcpu state
*
* the pamameter for HC_SET_VCPU_STATE
*/
struct acrn_set_vcpu_regs {
/** the virtual CPU ID for the VCPU to set state */
uint16_t vcpu_id;
/** reserved space to make cpu_state aligned to 8 bytes */
uint16_t reserved0[3];
/** the structure to hold vcpu state */
struct acrn_vcpu_regs vcpu_regs;
} __aligned(8);
/**
* @brief Info to set ioreq buffer for a created VM
*
* the parameter for HC_SET_IOREQ_BUFFER hypercall
*/
struct acrn_set_ioreq_buffer {
/** guest physical address of VM request_buffer */
uint64_t req_buf;
} __aligned(8);
/** Operation types for setting IRQ line */
#define GSI_SET_HIGH 0U
#define GSI_SET_LOW 1U
#define GSI_RAISING_PULSE 2U
#define GSI_FALLING_PULSE 3U
/**
* @brief Info to Set/Clear/Pulse a virtual IRQ line for a VM
*
* the parameter for HC_SET_IRQLINE hypercall
*/
struct acrn_irqline_ops {
uint32_t gsi;
uint32_t op;
} __aligned(8);
/**
* @brief Info to inject a MSI interrupt to VM
*
* the parameter for HC_INJECT_MSI hypercall
*/
struct acrn_msi_entry {
/** MSI addr[19:12] with dest VCPU ID */
uint64_t msi_addr;
/** MSI data[7:0] with vector */
uint64_t msi_data;
} __aligned(8);
/**
* @brief Info to inject a NMI interrupt for a VM
*/
struct acrn_nmi_entry {
/** virtual CPU ID to inject */
uint16_t vcpu_id;
/** Reserved */
uint16_t reserved0;
/** Reserved */
uint32_t reserved1;
} __aligned(8);
/**
* @brief Info to remap pass-through PCI MSI for a VM
*
* the parameter for HC_VM_PCI_MSIX_REMAP hypercall
*/
struct acrn_vm_pci_msix_remap {
/** pass-through PCI device virtual BDF# */
uint16_t virt_bdf;
/** pass-through PCI device physical BDF# */
uint16_t phys_bdf;
/** pass-through PCI device MSI/MSI-X cap control data */
uint16_t msi_ctl;
/** reserved for alignment padding */
uint16_t reserved;
/** pass-through PCI device MSI address to remap, which will
* return the caller after remapping
*/
uint64_t msi_addr; /* IN/OUT: msi address to fix */
/** pass-through PCI device MSI data to remap, which will
* return the caller after remapping
*/
uint32_t msi_data;
/** pass-through PCI device is MSI or MSI-X
* 0 - MSI, 1 - MSI-X
*/
int32_t msix;
/** if the pass-through PCI device is MSI-X, this field contains
* the MSI-X entry table index
*/
uint32_t msix_entry_index;
/** if the pass-through PCI device is MSI-X, this field contains
* Vector Control for MSI-X Entry, field defined in MSI-X spec
*/
uint32_t vector_ctl;
} __aligned(8);
/**
* @brief Info The power state data of a VCPU.
*
*/
#define SPACE_SYSTEM_MEMORY 0U
#define SPACE_SYSTEM_IO 1U
#define SPACE_PCI_CONFIG 2U
#define SPACE_Embedded_Control 3U
#define SPACE_SMBUS 4U
#define SPACE_PLATFORM_COMM 10U
#define SPACE_FFixedHW 0x7FU
struct acpi_generic_address {
uint8_t space_id;
uint8_t bit_width;
uint8_t bit_offset;
uint8_t access_size;
uint64_t address;
} __aligned(8);
struct cpu_cx_data {
struct acpi_generic_address cx_reg;
uint8_t type;
uint32_t latency;
uint64_t power;
} __aligned(8);
struct cpu_px_data {
uint64_t core_frequency; /* megahertz */
uint64_t power; /* milliWatts */
uint64_t transition_latency; /* microseconds */
uint64_t bus_master_latency; /* microseconds */
uint64_t control; /* control value */
uint64_t status; /* success indicator */
} __aligned(8);
struct acpi_sx_pkg {
uint8_t val_pm1a;
uint8_t val_pm1b;
uint16_t reserved;
} __aligned(8);
struct pm_s_state_data {
struct acpi_generic_address pm1a_evt;
struct acpi_generic_address pm1b_evt;
struct acpi_generic_address pm1a_cnt;
struct acpi_generic_address pm1b_cnt;
struct acpi_sx_pkg s3_pkg;
struct acpi_sx_pkg s5_pkg;
uint32_t *wake_vector_32;
uint64_t *wake_vector_64;
} __aligned(8);
/**
* @brief Info PM command from DM/VHM.
*
* The command would specify request type(e.g. get px count or data) for
* specific VM and specific VCPU with specific state number.
* For Px, PMCMD_STATE_NUM means Px number from 0 to (MAX_PSTATE - 1),
* For Cx, PMCMD_STATE_NUM means Cx entry index from 1 to MAX_CX_ENTRY.
*/
#define PMCMD_VMID_MASK 0xff000000U
#define PMCMD_VCPUID_MASK 0x00ff0000U
#define PMCMD_STATE_NUM_MASK 0x0000ff00U
#define PMCMD_TYPE_MASK 0x000000ffU
#define PMCMD_VMID_SHIFT 24U
#define PMCMD_VCPUID_SHIFT 16U
#define PMCMD_STATE_NUM_SHIFT 8U
enum pm_cmd_type {
PMCMD_GET_PX_CNT,
PMCMD_GET_PX_DATA,
PMCMD_GET_CX_CNT,
PMCMD_GET_CX_DATA,
};
/**
* @brief Info to get a VM interrupt count data
*
* the parameter for HC_VM_INTR_MONITOR hypercall
*/
#define MAX_PTDEV_NUM 24U
struct acrn_intr_monitor {
/** sub command for intr monitor */
uint32_t cmd;
/** the count of this buffer to save */
uint32_t buf_cnt;
/** the buffer which save each interrupt count */
uint64_t buffer[MAX_PTDEV_NUM * 2];
} __aligned(8);
/** cmd for intr monitor **/
#define INTR_CMD_GET_DATA 0U
#define INTR_CMD_DELAY_INT 1U
/**
* @}
*/
#endif /* ACRN_COMMON_H */