diff --git a/hypervisor/Makefile b/hypervisor/Makefile index 1f288e70c..c2ff41004 100644 --- a/hypervisor/Makefile +++ b/hypervisor/Makefile @@ -212,6 +212,7 @@ ifeq ($(CONFIG_MULTIBOOT2),y) BOOT_C_SRCS += boot/multiboot2.c endif BOOT_C_SRCS += boot/reloc.c +BOOT_C_SRCS += arch/x86/ptcm.c # hardware management component HW_S_SRCS += arch/x86/idt.S diff --git a/hypervisor/arch/x86/cpu.c b/hypervisor/arch/x86/cpu.c index 5fe3d839c..55b6b3b24 100644 --- a/hypervisor/arch/x86/cpu.c +++ b/hypervisor/arch/x86/cpu.c @@ -28,6 +28,7 @@ #include #include #include +#include #define CPU_UP_TIMEOUT 100U /* millisecond */ #define CPU_DOWN_TIMEOUT 100U /* millisecond */ @@ -266,11 +267,15 @@ void init_pcpu_post(uint16_t pcpu_id) } ASSERT(get_pcpu_id() == BSP_CPU_ID, ""); + + init_psram(true); } else { pr_dbg("Core %hu is up", pcpu_id); pr_warn("Skipping VM configuration check which should be done before building HV binary."); + init_psram(false); + /* Initialize secondary processor interrupts. */ init_interrupt(pcpu_id); diff --git a/hypervisor/arch/x86/ptcm.c b/hypervisor/arch/x86/ptcm.c new file mode 100644 index 000000000..180436c8c --- /dev/null +++ b/hypervisor/arch/x86/ptcm.c @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2020 Intel Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#include +#include +#include +#include +#include +#include + + +/* is_psram_initialized is used to tell whether psram is successfully initialized for all cores */ +volatile bool is_psram_initialized = false; + +#ifdef CONFIG_PSRAM_ENABLED + +static struct ptct_entry_data_ptcm_binary *ptcm_binary = NULL; + +static struct acpi_table_header *acpi_ptct_tbl = NULL; + +static inline void *get_ptct_address() +{ + return (void *)acpi_ptct_tbl + sizeof(*acpi_ptct_tbl); +} + +static void parse_ptct(void) +{ + /* TODO: Will add in the next patch */ +} + +/* + * Function to initialize pSRAM. Both BSP and APs shall call this function to + * make sure pSRAM is initialized, which is required by PTCM. + * BSP: + * To parse PTCT and find the entry of PTCM command function + * AP: + * Wait until BSP has done the parsing work, then call the PTCM ABI. + * + * Synchronization of AP and BSP is ensured, both inside and outside PTCM. + * BSP shall be the last to finish the call. + */ +void init_psram(bool is_bsp) +{ + int32_t ptcm_ret_code; + struct ptcm_header *header; + ptcm_abi_func ptcm_command_func = NULL; + static uint64_t init_psram_cpus_mask = (1UL << BSP_CPU_ID); + + /* + * When we shut down an RTVM, its pCPUs will be re-initialized + * we must ensure init_psram() will only be executed at the first time when a pcpu is booted + * That's why we add "!is_psram_initialized" as an condition. + */ + if (!is_psram_initialized && (acpi_ptct_tbl != NULL)) { + if (is_bsp) { + parse_ptct(); + bitmap_clear_lock(get_pcpu_id(), &init_psram_cpus_mask); + } + + wait_sync_change(&init_psram_cpus_mask, 0UL); + pr_info("PTCT is parsed by BSP"); + header = hpa2hva(ptcm_binary->address); + pr_info("ptcm_bin_address:%llx, ptcm magic:%x, ptcm version:%x", + ptcm_binary->address, header->magic, header->version); + ASSERT(header->magic == PTCM_MAGIC, "Incorrect PTCM magic!"); + + ptcm_command_func = (ptcm_abi_func)(hpa2hva(ptcm_binary->address) + header->command_offset); + pr_info("ptcm command function is found at %llx",ptcm_command_func); + ptcm_ret_code = ptcm_command_func(PTCM_CMD_INIT_PSRAM, get_ptct_address()); + pr_info("ptcm initialization return %d", ptcm_ret_code); + /* return 0 for success, -1 for failure */ + ASSERT(ptcm_ret_code == 0); + + bitmap_set_lock(get_pcpu_id(), &init_psram_cpus_mask); + wait_sync_change(&init_psram_cpus_mask, ALL_CPUS_MASK); + + if (is_bsp) { + is_psram_initialized = true; + pr_info("BSP pSRAM has been initialized\n"); + } + } +} +#else +void init_psram(__unused bool is_bsp) +{ +} +#endif diff --git a/hypervisor/include/arch/x86/ptcm.h b/hypervisor/include/arch/x86/ptcm.h new file mode 100644 index 000000000..194ba9808 --- /dev/null +++ b/hypervisor/include/arch/x86/ptcm.h @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2020 Intel Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef PTCM_H +#define PTCM_H + +#include + +#define MSABI __attribute__((ms_abi)) + +typedef int32_t MSABI (*ptcm_abi_func)(uint32_t command, void *command_struct); + +#define PTCM_CMD_INIT_PSRAM (int32_t)1U +#define PTCM_CMD_CPUID (int32_t)2U +#define PTCM_CMD_RDMSR (int32_t)3U +#define PTCM_CMD_WRMSR (int32_t)4U + +#define PTCM_MAGIC 0x5054434dU + +struct ptcm_header { + uint32_t magic; + uint32_t version; + uint64_t command_offset; +} __packed; + +extern volatile bool is_psram_initialized; +void init_psram(bool is_bsp); +#endif /* PTCM_H */ diff --git a/hypervisor/include/arch/x86/ptct.h b/hypervisor/include/arch/x86/ptct.h new file mode 100644 index 000000000..54c0ec60d --- /dev/null +++ b/hypervisor/include/arch/x86/ptct.h @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2020 Intel Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef PTCT_H +#define PTCT_H + +#include + + +struct ptct_entry_data_ptcm_binary +{ + uint64_t address; + uint32_t size; +} __packed; + + +#endif /* PTCT_H */