From 00b3a28d5da1ed3f3e05063f3836ebdad063d4a2 Mon Sep 17 00:00:00 2001 From: Yonghua Huang Date: Mon, 17 May 2021 11:45:44 +0800 Subject: [PATCH] hv: update RTCT parser to support RTCT version 2 RTCT has been updated to version 2, this patch updates hypervisor RTCT parser to support both version 1 and version 2 of RTCT. Tracked-On: #6020 Signed-off-by: Yonghua Huang Reviewed-by: Jason CJ Chen --- hypervisor/arch/x86/rtcm.c | 77 ++++++++++++++++++-------- hypervisor/include/arch/x86/asm/rtct.h | 26 +++++++++ 2 files changed, 79 insertions(+), 24 deletions(-) diff --git a/hypervisor/arch/x86/rtcm.c b/hypervisor/arch/x86/rtcm.c index ec69b7877..5b5a0af13 100644 --- a/hypervisor/arch/x86/rtcm.c +++ b/hypervisor/arch/x86/rtcm.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -21,6 +22,15 @@ static volatile bool is_sw_sram_initialized = false; #ifdef CONFIG_SSRAM_ENABLED +#define foreach_rtct_entry(rtct, e) \ + for (e = (void *)rtct + sizeof(struct acpi_table_header); \ + ((uint64_t)e - (uint64_t)rtct) < rtct->length; \ + e = (struct rtct_entry *)((uint64_t)e + e->size)) + +#define RTCT_V1 1U +#define RTCT_V2 2U +static uint32_t rtct_version = RTCT_V1; + static struct rtct_entry_data_rtcm_binary *rtcm_binary = NULL; static struct acpi_table_header *acpi_rtct_tbl = NULL; @@ -36,6 +46,9 @@ void set_rtct_tbl(void *rtct_tbl_addr) } /* + *@desc This function parses native RTCT ACPI talbe to figure out the entry to CRL binary + * and SSRAM range. All SSRAM regions shall be continuous and L3 cache be inclusive. + * *@pre the SSRAM region is separate and never mixed with normal DRAM *@pre acpi_rtct_tbl != NULL */ @@ -44,33 +57,49 @@ static void parse_rtct(void) uint64_t bottom_hpa = ULONG_MAX; struct rtct_entry *entry; struct rtct_entry_data_ssram *ssram; + struct rtct_entry_data_ssram_v2 *ssram_v2; + struct rtct_entry_data_compatibility *compat; - entry = get_rtct_entry_base(); - while (((uint64_t)entry - (uint64_t)acpi_rtct_tbl) < acpi_rtct_tbl->length) { - switch (entry->type) { - case RTCT_ENTRY_TYPE_RTCM_BINARY: - rtcm_binary = (struct rtct_entry_data_rtcm_binary *)entry->data; - ASSERT((rtcm_binary->address != 0UL && rtcm_binary->size != 0U), "Invalid PTCM binary."); - pr_info("found RTCM bin, in HPA %llx, size %llx", rtcm_binary->address, rtcm_binary->size); - break; - - case RTCT_ENTRY_TYPE_SOFTWARE_SRAM: - ssram = (struct rtct_entry_data_ssram *)entry->data; - if (ssram_top_hpa < ssram->base + ssram->size) { - ssram_top_hpa = ssram->base + ssram->size; - } - if (bottom_hpa > ssram->base) { - bottom_hpa = ssram->base; - } - pr_info("found L%d Software SRAM, at HPA %llx, size %x", ssram->cache_level, - ssram->base, ssram->size); - break; - /* In current phase, we ignore other entries like gt_clos and wrc_close */ - default: + /* Check RTCT format */ + foreach_rtct_entry(acpi_rtct_tbl, entry) { + if (entry->type == RTCT_V2_COMPATIBILITY) { + compat = (struct rtct_entry_data_compatibility *)entry->data; + rtct_version = compat->rtct_ver_major; break; } - /* point to next rtct entry */ - entry = (struct rtct_entry *)((uint64_t)entry + entry->size); + } + pr_info("RTCT Version: V%d.\n", rtct_version); + + if (rtct_version == RTCT_V1) { + foreach_rtct_entry(acpi_rtct_tbl, entry) { + if (entry->type == RTCT_ENTRY_TYPE_SOFTWARE_SRAM) { + ssram = (struct rtct_entry_data_ssram *)entry->data; + + ssram_top_hpa = max(ssram_top_hpa, ssram->base + ssram->size); + bottom_hpa = min(bottom_hpa, ssram->base); + pr_info("found L%d Software SRAM, at HPA %llx, size %x", + ssram->cache_level, ssram->base, ssram->size); + } else if (entry->type == RTCT_ENTRY_TYPE_RTCM_BINARY) { + rtcm_binary = (struct rtct_entry_data_rtcm_binary *)entry->data; + ASSERT((rtcm_binary->address != 0UL && rtcm_binary->size != 0U), + "Invalid PTCM binary."); + } + } + } else if (rtct_version == RTCT_V2) { + foreach_rtct_entry(acpi_rtct_tbl, entry) { + if (entry->type == RTCT_V2_SSRAM) { + ssram_v2 = (struct rtct_entry_data_ssram_v2 *)entry->data; + + ssram_top_hpa = max(ssram_top_hpa, ssram_v2->base + ssram_v2->size); + bottom_hpa = min(bottom_hpa, ssram_v2->base); + pr_info("found L%d Software SRAM, at HPA %llx, size %x", + ssram_v2->cache_level, ssram_v2->base, ssram_v2->size); + } else if (entry->type == RTCT_V2_CRL_BINARY) { + rtcm_binary = (struct rtct_entry_data_rtcm_binary *)entry->data; + ASSERT((rtcm_binary->address != 0UL && rtcm_binary->size != 0U), + "Invalid PTCM binary."); + } + } } if (bottom_hpa != ULONG_MAX) { diff --git a/hypervisor/include/arch/x86/asm/rtct.h b/hypervisor/include/arch/x86/asm/rtct.h index e1431ff69..9092f87ba 100644 --- a/hypervisor/include/arch/x86/asm/rtct.h +++ b/hypervisor/include/arch/x86/asm/rtct.h @@ -21,6 +21,17 @@ #define RTCT_ENTRY_TYPE_RT_IOMMU 8U #define RTCT_ENTRY_TYPE_MEM_HIERARCHY_LATENCY 9U +#define RTCT_V2_COMPATIBILITY 0U +#define RTCT_V2_RTCD_LIMIT 1U +#define RTCT_V2_CRL_BINARY 2U +#define RTCT_V2_IA_WAYMASK 3U +#define RTCT_V2_WRC_WAYMASK 4U +#define RTCT_V2_GT_WAYMASK 5U +#define RTCT_V2_SSRAM_WAYMASK 6U +#define RTCT_V2_SSRAM 7U +#define RTCT_V2_MEMORY_HIERARCHY_LATENCY 8U +#define RTCT_V2_ERROR_LOG_ADDRESS 9U + #if !defined(PRE_RTVM_SW_SRAM_ENABLED) /* * PRE_RTVM_SW_SRAM_BASE_GPA is for Prelaunch VM only and @@ -42,6 +53,13 @@ struct rtct_entry { uint32_t data[64]; } __packed; +struct rtct_entry_data_compatibility { + uint32_t rtct_ver_major; + uint32_t rtct_ver_minor; + uint32_t rtcd_ver_major; + uint32_t rtcd_ver_minor; +} __packed; + struct rtct_entry_data_rtcm_binary { uint64_t address; @@ -57,6 +75,14 @@ struct rtct_entry_data_ssram uint32_t apic_id_0; /*only the first core is responsible for initialization of L3 mem region*/ } __packed; +struct rtct_entry_data_ssram_v2 { + uint32_t cache_level; + uint32_t cache_id; + uint64_t base; + uint32_t size; + uint32_t shared; +} __packed; + uint64_t get_software_sram_base(void); uint64_t get_software_sram_size(void); #endif /* RTCT_H */