diff --git a/Makefile b/Makefile index 4722fb410..ea4a6ae88 100644 --- a/Makefile +++ b/Makefile @@ -104,6 +104,7 @@ C_SRCS += arch/x86/vmexit.c C_SRCS += arch/x86/vmx.c C_SRCS += arch/x86/assign.c C_SRCS += arch/x86/trusty.c +C_SRCS += arch/x86/cpu_state_tbl.c C_SRCS += arch/x86/guest/vcpu.c C_SRCS += arch/x86/guest/vm.c C_SRCS += arch/x86/guest/instr_emul_wrapper.c diff --git a/arch/x86/cpu.c b/arch/x86/cpu.c index fe6a3f5a3..b5aad5e52 100644 --- a/arch/x86/cpu.c +++ b/arch/x86/cpu.c @@ -36,6 +36,7 @@ #include #include #include +#include #ifdef CONFIG_EFI_STUB extern uint32_t efi_physical_available_ap_bitmap; @@ -398,6 +399,8 @@ void bsp_boot_init(void) get_cpu_name(); + load_cpu_state_data(); + /* Initialize the hypervisor paging */ init_paging(); diff --git a/arch/x86/cpu_state_tbl.c b/arch/x86/cpu_state_tbl.c new file mode 100644 index 000000000..c49f13ef0 --- /dev/null +++ b/arch/x86/cpu_state_tbl.c @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2018 Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include + +/* The table includes cpu px info of Intel A3960 SoC */ +struct cpu_px_data px_a3960[] = { + {0x960, 0, 0xA, 0xA, 0x1800, 0x1800}, /* P0 */ + {0x8FC, 0, 0xA, 0xA, 0x1700, 0x1700}, /* P1 */ + {0x898, 0, 0xA, 0xA, 0x1600, 0x1600}, /* P2 */ + {0x834, 0, 0xA, 0xA, 0x1500, 0x1500}, /* P3 */ + {0x7D0, 0, 0xA, 0xA, 0x1400, 0x1400}, /* P4 */ + {0x76C, 0, 0xA, 0xA, 0x1300, 0x1300}, /* P5 */ + {0x708, 0, 0xA, 0xA, 0x1200, 0x1200}, /* P6 */ + {0x6A4, 0, 0xA, 0xA, 0x1100, 0x1100}, /* P7 */ + {0x640, 0, 0xA, 0xA, 0x1000, 0x1000}, /* P8 */ + {0x5DC, 0, 0xA, 0xA, 0x0F00, 0x0F00}, /* P9 */ + {0x578, 0, 0xA, 0xA, 0x0E00, 0x0E00}, /* P10 */ + {0x514, 0, 0xA, 0xA, 0x0D00, 0x0D00}, /* P11 */ + {0x4B0, 0, 0xA, 0xA, 0x0C00, 0x0C00}, /* P12 */ + {0x44C, 0, 0xA, 0xA, 0x0B00, 0x0B00}, /* P13 */ + {0x3E8, 0, 0xA, 0xA, 0x0A00, 0x0A00}, /* P14 */ + {0x384, 0, 0xA, 0xA, 0x0900, 0x0900}, /* P15 */ + {0x320, 0, 0xA, 0xA, 0x0800, 0x0800} /* P16 */ +}; + +struct cpu_state_table cpu_state_tbl[] = { + {"Intel(R) Atom(TM) Processor A3960 @ 1.90GHz", 17, px_a3960} +}; + +static int get_state_tbl_idx(char *cpuname) +{ + int i; + int count = ARRAY_SIZE(cpu_state_tbl); + + if (!cpuname) { + return -1; + } + + for (i = 0; i < count; i++) { + if (!strcmp((cpu_state_tbl[i].model_name), + cpuname)) { + return i; + } + } + + return -1; +} + +void load_cpu_state_data(void) +{ + int tbl_idx; + + boot_cpu_data.px_cnt = 0; + boot_cpu_data.px_data = NULL; + + tbl_idx = get_state_tbl_idx(boot_cpu_data.model_name); + if (tbl_idx < 0) { + /* The state table is not found. */ + return; + } + + if (!((cpu_state_tbl + tbl_idx)->px_cnt) + || !((cpu_state_tbl + tbl_idx)->px_data)) { + /* The state table must be wrong. */ + return; + } + + if ((cpu_state_tbl + tbl_idx)->px_cnt > MAX_PSTATE) { + boot_cpu_data.px_cnt = MAX_PSTATE; + } else { + boot_cpu_data.px_cnt = (cpu_state_tbl + tbl_idx)->px_cnt; + } + + boot_cpu_data.px_data = (cpu_state_tbl + tbl_idx)->px_data; + +} diff --git a/include/arch/x86/cpu.h b/include/arch/x86/cpu.h index c34b1cba6..43a882a61 100644 --- a/include/arch/x86/cpu.h +++ b/include/arch/x86/cpu.h @@ -237,10 +237,14 @@ struct cpuinfo_x86 { uint64_t physical_address_mask; uint32_t cpuid_leaves[FEATURE_WORDS]; char model_name[64]; + uint8_t px_cnt; + struct cpu_px_data *px_data; }; extern struct cpuinfo_x86 boot_cpu_data; +#define MAX_PSTATE 20 + /* Function prototypes */ void cpu_halt(uint32_t logical_id); uint64_t cpu_cycles_per_second(void); diff --git a/include/arch/x86/cpu_state_tbl.h b/include/arch/x86/cpu_state_tbl.h new file mode 100644 index 000000000..3cbf2bfc0 --- /dev/null +++ b/include/arch/x86/cpu_state_tbl.h @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2018 Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef CPU_STATE_TBL_H +#define CPU_STATE_TBL_H + +struct cpu_state_table { + char model_name[64]; + uint8_t px_cnt; + struct cpu_px_data *px_data; +}; + +void load_cpu_state_data(void); + +#endif /* CPU_STATE_TBL_H */ diff --git a/include/public/acrn_common.h b/include/public/acrn_common.h index 033660756..c179060e4 100644 --- a/include/public/acrn_common.h +++ b/include/public/acrn_common.h @@ -288,6 +288,19 @@ struct acrn_vm_pci_msix_remap { */ #define GUEST_CFG_OFFSET 0xd0000 +/** + * @brief Info The power state data of a VCPU. + * + */ +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 */ +} __attribute__((aligned(8))); + /** * @} */