diff --git a/devicemodel/hw/acpi/acpi_pm.c b/devicemodel/hw/acpi/acpi_pm.c index a4fc1273e..a9f73ef4a 100644 --- a/devicemodel/hw/acpi/acpi_pm.c +++ b/devicemodel/hw/acpi/acpi_pm.c @@ -59,6 +59,17 @@ static inline uint8_t get_vcpu_px_cnt(struct vmctx *ctx, int vcpu_id) return (uint8_t)px_cnt; } +uint8_t get_vcpu_cx_cnt(struct vmctx *ctx, int vcpu_id) +{ + uint64_t cx_cnt; + + if (get_vcpu_pm_info(ctx, vcpu_id, PMCMD_GET_CX_CNT, &cx_cnt)) { + return 0; + } + + return (uint8_t)cx_cnt; +} + static int get_vcpu_px_data(struct vmctx *ctx, int vcpu_id, int px_num, struct cpu_px_data *vcpu_px_data) { @@ -88,6 +99,35 @@ static int get_vcpu_px_data(struct vmctx *ctx, int vcpu_id, return 0; } +int get_vcpu_cx_data(struct vmctx *ctx, int vcpu_id, + int cx_num, struct cpu_cx_data *vcpu_cx_data) +{ + uint64_t *pm_ioctl_buf; + enum pm_cmd_type cmd_type = PMCMD_GET_CX_DATA; + + pm_ioctl_buf = malloc(sizeof(struct cpu_cx_data)); + if (!pm_ioctl_buf) { + return -1; + } + + *pm_ioctl_buf = ((ctx->vmid << PMCMD_VMID_SHIFT) & PMCMD_VMID_MASK) + | ((vcpu_id << PMCMD_VCPUID_SHIFT) & PMCMD_VCPUID_MASK) + | ((cx_num << PMCMD_STATE_NUM_SHIFT) & PMCMD_STATE_NUM_MASK) + | cmd_type; + + /* get and validate cx data */ + if (vm_get_cpu_state(ctx, pm_ioctl_buf)) { + free(pm_ioctl_buf); + return -1; + } + + memcpy(vcpu_cx_data, pm_ioctl_buf, + sizeof(struct cpu_cx_data)); + + free(pm_ioctl_buf); + return 0; +} + /* _PPC: Performance Present Capabilities * hard code _PPC to 0, all states are available. */ diff --git a/devicemodel/include/public/acrn_common.h b/devicemodel/include/public/acrn_common.h index 3b9e772e1..f9285ab54 100644 --- a/devicemodel/include/public/acrn_common.h +++ b/devicemodel/include/public/acrn_common.h @@ -311,6 +311,21 @@ struct acrn_vm_pci_msix_remap { * @brief Info The power state data of a VCPU. * */ +struct acrn_register { + uint8_t space_id; + uint8_t bit_width; + uint8_t bit_offset; + uint8_t access_size; + uint64_t address; +} __attribute__((aligned(8))); + +struct cpu_cx_data { + struct acrn_register cx_reg; + uint8_t type; + uint32_t latency; + uint64_t power; +} __attribute__((aligned(8))); + struct cpu_px_data { uint64_t core_frequency; /* megahertz */ uint64_t power; /* milliWatts */ @@ -323,8 +338,10 @@ struct cpu_px_data { /** * @brief Info PM command from DM/VHM. * - * The command would specify request type(i.e. get px count or data) for - * specific VM and specific VCPU with specific state number.like P(n). + * 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 0xff000000 #define PMCMD_VCPUID_MASK 0x00ff0000 @@ -338,6 +355,8 @@ struct cpu_px_data { enum pm_cmd_type { PMCMD_GET_PX_CNT, PMCMD_GET_PX_DATA, + PMCMD_GET_CX_CNT, + PMCMD_GET_CX_DATA, }; /**