hv:ptct: add funtion to parse ptct acpi table

Add function to parse PTCT ACPI Table. For now, we need to parse:
1. Where's the PTCM_Binary
2. The range of pSRAM

Tracked-On: #5330

Signed-off-by: Qian Wang <qian1.wang@intel.com>
Signed-off-by: Li Fei1 <fei1.li@intel.com>
Reviewed-by: Wang, Yu1 <yu1.wang@intel.com>
This commit is contained in:
Li Fei1 2020-09-14 21:48:00 +08:00 committed by wenlingz
parent 60456577bd
commit 8bc963a27c
4 changed files with 208 additions and 0 deletions

View File

@ -213,6 +213,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

102
hypervisor/arch/x86/ptcm.c Normal file
View File

@ -0,0 +1,102 @@
/*
* Copyright (C) 2020 Intel Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <types.h>
#include <logmsg.h>
#include <misc_cfg.h>
#include <ptct.h>
uint64_t psram_area_bottom = PSRAM_BASE_HPA;
uint64_t psram_area_top = PSRAM_BASE_HPA;
#ifdef CONFIG_PTCM_ENABLED
struct ptcm_mem_region ptcm_mem_regions[MAX_PCPU_NUM];
struct ptct_entry_data_ptcm_binary ptcm_binary;
uint32_t l2_psram_regions_count = 0U;
uint32_t l3_psram_regions_count = 0U;
struct ptct_entry_data_psram l2_psram_regions[MAX_L2_PSRAM_REGIONS];
struct ptct_entry_data_psram l3_psram_regions[MAX_L3_PSRAM_REGIONS];
static void parse_ptct(void)
{
struct ptct_entry *entry;
struct ptcm_mem_region *p_mem_region;
struct ptct_entry_data_psram *psram_entry;
struct ptct_entry_data_ptcm_binary* ptcm_binary_entry;
struct acpi_table_ptct* acpi_ptct = ((struct acpi_table_ptct *)get_acpi_tbl(ACPI_SIG_PTCT));
pr_fatal("find PTCT subtable in HPA %llx, length: %d", acpi_ptct, acpi_ptct->header.length);
entry = &acpi_ptct->ptct_first_entry; //&acpi_ptct->ptct_entries[0];
pr_fatal("find PTCT base entry, in HPA %llx", entry);
while (((uint64_t)entry - (uint64_t)acpi_ptct) < acpi_ptct->header.length) {
switch (entry->type) {
case PTCT_ENTRY_TYPE_PTCM_BINARY:
pr_fatal("PTCT_ENTRY_TYPE_PTCM_BINARY");
ptcm_binary_entry = (struct ptct_entry_data_ptcm_binary *)entry->data;
ptcm_binary.address = ptcm_binary_entry->address;
ptcm_binary.size = ptcm_binary_entry->size;
if (psram_area_top < ptcm_binary.address + ptcm_binary.size) {
psram_area_top = ptcm_binary.address + ptcm_binary.size;
}
pr_fatal("find PTCM bin, in HPA %llx, size %llx", ptcm_binary.address, ptcm_binary.size);
break;
case PTCT_ENTRY_TYPE_PSRAM:
pr_fatal("PTCT_ENTRY_TYPE_PSRAM");
psram_entry = (struct ptct_entry_data_psram *)entry->data;
if (psram_entry->apic_id_0 >= MAX_PCPU_NUM) {
break;
}
p_mem_region = &ptcm_mem_regions[psram_entry->apic_id_0];
if (psram_entry->cache_level == 3) {
if (l3_psram_regions_count >= MAX_L3_PSRAM_REGIONS){
pr_fatal("Too many L3 regions!");
break;
}
p_mem_region->l3_valid = true;
p_mem_region->l3_base = psram_entry->base;
p_mem_region->l3_size = psram_entry->size;
p_mem_region->l3_ways = psram_entry->ways;
p_mem_region->l3_clos[PTCM_CLOS_INDEX_SETUP] = p_mem_region->l3_ways;
p_mem_region->l3_clos[PTCM_CLOS_INDEX_LOCK] ^= p_mem_region->l3_ways;
if (psram_area_top < p_mem_region->l3_base + p_mem_region->l3_size) {
psram_area_top = p_mem_region->l3_base + p_mem_region->l3_size;
}
l3_psram_regions_count++;
pr_fatal("found L3 psram, in HPA %llx, size %llx", p_mem_region->l3_base, p_mem_region->l3_size);
} else if (psram_entry->cache_level == 2) {
if (l2_psram_regions_count >= MAX_L2_PSRAM_REGIONS){
pr_fatal("Too many L2 regions!");
break;
}
p_mem_region->l2_valid = true;
p_mem_region->l2_base = psram_entry->base;
p_mem_region->l2_size = psram_entry->size;
p_mem_region->l2_ways = psram_entry->ways;
p_mem_region->l2_clos[PTCM_CLOS_INDEX_SETUP] = p_mem_region->l2_ways;
p_mem_region->l2_clos[PTCM_CLOS_INDEX_LOCK] ^= p_mem_region->l2_ways;
if (psram_area_top < p_mem_region->l2_base + p_mem_region->l2_size) {
psram_area_top = p_mem_region->l2_base + p_mem_region->l2_size;
}
l2_psram_regions_count++;
pr_fatal("found L2 psram, in HPA %llx, size %llx", psram_entry->base, psram_entry->size);
}
break;
/* In current phase, we ignore other entries like gt_clos and wrc_close*/
default:
break;
}
/* point to next ptct entry */
pr_fatal("%s entry: 0x%lx, size: %d\n", __func__, entry, entry->size);
entry = (struct ptct_entry *)((uint64_t)entry + entry->size);
}
}
#endif

View File

@ -57,6 +57,7 @@
#define ACPI_SIG_MCFG "MCFG" /* Memory Mapped Configuration table */
#define ACPI_SIG_DSDT "DSDT" /* Differentiated System Description Table */
#define ACPI_SIG_TPM2 "TPM2" /* Trusted Platform Module hardware interface table */
#define ACPI_SIG_PTCT "PTCT"
struct packed_gas {
uint8_t space_id;

View File

@ -0,0 +1,104 @@
/*
* Copyright (C) 2020 Intel Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef PTCT_H
#define PTCT_H
#include <acpi.h>
#define MAX_L2_PSRAM_REGIONS 4U
#define MAX_L3_PSRAM_REGIONS 1U
#define PTCT_ENTRY_TYPE_PTCD_LIMIT 1U
#define PTCT_ENTRY_TYPE_PTCM_BINARY 2U
#define PTCT_ENTRY_TYPE_WRC_L3_MASKS 3U
#define PTCT_ENTRY_TYPE_GT_L3_MASKS 4U
#define PTCT_ENTRY_TYPE_PSRAM 5U
#define PTCT_ENTRY_TYPE_STREAM_DATAPATH 6U
#define PTCT_ENTRY_TYPE_TIMEAWARE_SUBSYS 7U
#define PTCT_ENTRY_TYPE_RT_IOMMU 8U
#define PTCT_ENTRY_TYPE_MEM_HIERARCHY_LATENCY 9U
#define PSRAM_BASE_HPA 0x40080000U
#define PSRAM_BASE_GPA 0x40080000U
#define PSRAM_MAX_SIZE 0x00800000U
struct ptct_entry{
uint16_t size;
uint16_t format;
uint32_t type;
uint32_t data[64];
};
struct acpi_table_ptct {
struct acpi_table_header header;
struct ptct_entry ptct_first_entry;
};
struct ptct_entry_data_ptcd_limit
{
uint32_t max_ia_l2_clos;
uint32_t max_ia_l3_clos;
uint32_t max_l2_instances;
uint32_t max_gt_clos;
uint32_t max_wrc_clos;
uint32_t max_tcc_buffers;
uint32_t max_tcc_buffers_apic_id;
uint32_t max_tcc_streams;
uint32_t max_tcc_registers;
uint32_t ptcd_limit_reserves_1;
uint32_t ptcd_limit_reserves_2;
};
struct ptct_entry_data_ptcm_binary
{
uint64_t address;
uint32_t size;
};
struct ptct_entry_data_psram
{
uint32_t cache_level;
uint64_t base;
uint32_t ways;
uint32_t size;
uint32_t apic_id_0; /*only 1 core is responsible for initialization of this mem region*/
};
enum ptcm_cache_level
{
PTCM_CACHE_LEVEL_EMPTY = 0,
PTCM_CACHE_LEVEL_2 = 2,
PTCM_CACHE_LEVEL_3 = 3
};
enum ptcm_clos_index
{
PTCM_CLOS_INDEX_NOLOCK = 0,
PTCM_CLOS_INDEX_LOCK,
PTCM_CLOS_INDEX_SETUP,
PTCM_CLOS_NUM_OF
};
struct ptcm_mem_region
{
bool l2_valid;
bool l3_valid;
uint64_t l2_base;
uint64_t l2_size;
uint32_t l2_ways;
uint32_t l2_clos[PTCM_CLOS_NUM_OF];
uint64_t l3_base;
uint32_t l3_size;
uint32_t l3_ways;
uint32_t l3_clos[PTCM_CLOS_NUM_OF];
};
extern uint64_t psram_area_bottom;
extern uint64_t psram_area_top;
#endif /* PTCT_H */