mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-06-21 13:08:42 +00:00
hv: add method to deal with ">4G MMIO" BIOS option
1. Fixed the bug that HV may crush when ">4G MMIO" BIOS option is disabled. 2. Fixed the bug that RTVM may encounter problems at reboot time when it makes use of pSRAM 3. HV will skip PTCM initialization when it cannot find PTCM. 4. Some codes are refined. Tracked-On: #5330 Signed-off-by: Qian Wang <qian1.wang@intel.com>
This commit is contained in:
parent
57a6d35188
commit
793b99e3f6
@ -28,7 +28,7 @@
|
|||||||
#include <sgx.h>
|
#include <sgx.h>
|
||||||
#include <uart16550.h>
|
#include <uart16550.h>
|
||||||
#include <ivshmem.h>
|
#include <ivshmem.h>
|
||||||
#include <ptct.h>
|
#include <ptcm.h>
|
||||||
|
|
||||||
#define CPU_UP_TIMEOUT 100U /* millisecond */
|
#define CPU_UP_TIMEOUT 100U /* millisecond */
|
||||||
#define CPU_DOWN_TIMEOUT 100U /* millisecond */
|
#define CPU_DOWN_TIMEOUT 100U /* millisecond */
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
#include <types.h>
|
#include <types.h>
|
||||||
#include <logmsg.h>
|
#include <logmsg.h>
|
||||||
#include <misc_cfg.h>
|
#include <misc_cfg.h>
|
||||||
|
#include <mmu.h>
|
||||||
#include <ptcm.h>
|
#include <ptcm.h>
|
||||||
|
|
||||||
uint64_t psram_area_bottom;
|
uint64_t psram_area_bottom;
|
||||||
@ -26,29 +27,26 @@ static void parse_ptct(void)
|
|||||||
struct ptcm_mem_region *p_mem_region;
|
struct ptcm_mem_region *p_mem_region;
|
||||||
struct ptct_entry_data_psram *psram_entry;
|
struct ptct_entry_data_psram *psram_entry;
|
||||||
struct ptct_entry_data_ptcm_binary* ptcm_binary_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));
|
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);
|
pr_info("found PTCT subtable in HPA %llx, length: %d", acpi_ptct, acpi_ptct->header.length);
|
||||||
|
|
||||||
entry = &acpi_ptct->ptct_first_entry; //&acpi_ptct->ptct_entries[0];
|
entry = &acpi_ptct->ptct_first_entry; //&acpi_ptct->ptct_entries[0];
|
||||||
pr_fatal("find PTCT base entry, in HPA %llx", entry);
|
|
||||||
|
|
||||||
psram_area_bottom = PSRAM_BASE_HPA;
|
psram_area_bottom = PSRAM_BASE_HPA;
|
||||||
|
|
||||||
while (((uint64_t)entry - (uint64_t)acpi_ptct) < acpi_ptct->header.length) {
|
while (((uint64_t)entry - (uint64_t)acpi_ptct) < acpi_ptct->header.length) {
|
||||||
switch (entry->type) {
|
switch (entry->type) {
|
||||||
case PTCT_ENTRY_TYPE_PTCM_BINARY:
|
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_entry = (struct ptct_entry_data_ptcm_binary *)entry->data;
|
||||||
ptcm_binary.address = ptcm_binary_entry->address;
|
ptcm_binary.address = ptcm_binary_entry->address;
|
||||||
ptcm_binary.size = ptcm_binary_entry->size;
|
ptcm_binary.size = ptcm_binary_entry->size;
|
||||||
if (psram_area_top < ptcm_binary.address + ptcm_binary.size) {
|
if (psram_area_top < ptcm_binary.address + ptcm_binary.size) {
|
||||||
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);
|
pr_info("found PTCM bin, in HPA %llx, size %llx", ptcm_binary.address, ptcm_binary.size);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PTCT_ENTRY_TYPE_PSRAM:
|
case PTCT_ENTRY_TYPE_PSRAM:
|
||||||
pr_fatal("PTCT_ENTRY_TYPE_PSRAM");
|
|
||||||
psram_entry = (struct ptct_entry_data_psram *)entry->data;
|
psram_entry = (struct ptct_entry_data_psram *)entry->data;
|
||||||
if (psram_entry->apic_id_0 >= MAX_PCPU_NUM) {
|
if (psram_entry->apic_id_0 >= MAX_PCPU_NUM) {
|
||||||
break;
|
break;
|
||||||
@ -57,7 +55,7 @@ static void parse_ptct(void)
|
|||||||
p_mem_region = &ptcm_mem_regions[psram_entry->apic_id_0];
|
p_mem_region = &ptcm_mem_regions[psram_entry->apic_id_0];
|
||||||
if (psram_entry->cache_level == 3) {
|
if (psram_entry->cache_level == 3) {
|
||||||
if (l3_psram_regions_count >= MAX_L3_PSRAM_REGIONS){
|
if (l3_psram_regions_count >= MAX_L3_PSRAM_REGIONS){
|
||||||
pr_fatal("Too many L3 regions!");
|
pr_err("Too many L3 regions!");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -71,10 +69,10 @@ static void parse_ptct(void)
|
|||||||
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++;
|
l3_psram_regions_count++;
|
||||||
pr_fatal("found L3 psram, in HPA %llx, size %llx", p_mem_region->l3_base, p_mem_region->l3_size);
|
pr_info("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) {
|
} else if (psram_entry->cache_level == 2) {
|
||||||
if (l2_psram_regions_count >= MAX_L2_PSRAM_REGIONS){
|
if (l2_psram_regions_count >= MAX_L2_PSRAM_REGIONS){
|
||||||
pr_fatal("Too many L2 regions!");
|
pr_err("Too many L2 regions!");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
p_mem_region->l2_valid = true;
|
p_mem_region->l2_valid = true;
|
||||||
@ -87,46 +85,57 @@ static void parse_ptct(void)
|
|||||||
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++;
|
l2_psram_regions_count++;
|
||||||
pr_fatal("found L2 psram, in HPA %llx, size %llx", psram_entry->base, psram_entry->size);
|
pr_info("found L2 psram, in HPA %llx, size %llx", psram_entry->base, psram_entry->size);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
/* In current phase, we ignore other entries like gt_clos and wrc_close */
|
||||||
/* In current phase, we ignore other entries like gt_clos and wrc_close*/
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* point to next ptct entry */
|
/* 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);
|
entry = (struct ptct_entry *)((uint64_t)entry + entry->size);
|
||||||
}
|
}
|
||||||
|
psram_area_top = round_page_up(psram_area_top);
|
||||||
|
psram_area_bottom = round_page_down(psram_area_bottom);
|
||||||
}
|
}
|
||||||
|
|
||||||
static volatile uint64_t ptcm_command_interface_offset;
|
static volatile uint64_t ptcm_command_interface_offset;
|
||||||
static volatile struct ptct_entry* ptct_base_entry;
|
static volatile struct ptct_entry* ptct_base_entry;
|
||||||
static volatile ptcm_command_abi ptcm_command_interface = NULL;
|
static volatile ptcm_command_abi ptcm_command_interface = NULL;
|
||||||
|
/* psram_is_initialized is used to tell whether psram is successfully initialized for all cores */
|
||||||
static volatile bool psram_is_initialized = false;
|
static volatile bool psram_is_initialized = false;
|
||||||
|
|
||||||
void init_psram(bool is_bsp)
|
int32_t init_psram(bool is_bsp)
|
||||||
{
|
{
|
||||||
uint32_t magic,version;
|
uint32_t magic,version;
|
||||||
int ret;
|
int32_t ptcm_ret_code;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
if (get_acpi_tbl(ACPI_SIG_PTCT) != NULL) {
|
/* 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 */
|
||||||
|
if (get_acpi_tbl(ACPI_SIG_PTCT) != NULL && psram_is_initialized == false) {
|
||||||
if (is_bsp) {
|
if (is_bsp) {
|
||||||
parse_ptct();
|
parse_ptct();
|
||||||
pr_fatal("PTCT is parsed by BSP");
|
pr_info("PTCT is parsed by BSP");
|
||||||
ptct_base_entry = (struct ptct_entry*)((uint64_t)get_acpi_tbl(ACPI_SIG_PTCT) + 0x24);
|
ptct_base_entry = (struct ptct_entry*)((uint64_t)get_acpi_tbl(ACPI_SIG_PTCT) + 0x24);
|
||||||
pr_fatal("ptct_base_entry is found by BSP at %llx", ptct_base_entry);
|
pr_info("ptct_base_entry is found by BSP at %llx", ptct_base_entry);
|
||||||
magic = ((uint32_t *)ptcm_binary.address)[0];
|
magic = ((uint32_t *)ptcm_binary.address)[0];
|
||||||
version = ((uint32_t *)ptcm_binary.address)[1];
|
version = ((uint32_t *)ptcm_binary.address)[1];
|
||||||
ptcm_command_interface_offset =*(uint64_t *)(ptcm_binary.address + 0x8);
|
ptcm_command_interface_offset = *(uint64_t *)(ptcm_binary.address + 0x8);
|
||||||
pr_fatal("ptcm_bin_address:%llx", ptcm_binary.address);
|
pr_info("ptcm_bin_address:%llx", ptcm_binary.address);
|
||||||
pr_fatal("ptcm_command_interface_offset is %llx", ptcm_command_interface_offset);
|
pr_info("ptcm magic:%x", magic);
|
||||||
pr_fatal("magic:%x", magic);
|
pr_info("ptcm version:%x", version);
|
||||||
pr_fatal("version:%x", version);
|
|
||||||
|
|
||||||
ptcm_command_interface = (ptcm_command_abi)(ptcm_binary.address + ptcm_command_interface_offset);
|
if (magic != PTCM_MAGIC ){
|
||||||
pr_fatal("ptcm_command_interface is found at %llx",ptcm_command_interface);
|
pr_err("Incorrect PTCM magic! Please turn off 'Above 4G MMIO Assignment' option in BIOS");
|
||||||
|
psram_area_bottom = psram_area_top = 0;
|
||||||
|
ptcm_command_interface = (ptcm_command_abi)(-1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ptcm_command_interface = (ptcm_command_abi)(ptcm_binary.address + ptcm_command_interface_offset);
|
||||||
|
pr_info("ptcm command interface is found at %llx",ptcm_command_interface);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
//all AP should wait until BSP finishes parsing PTCT and finding the command interface.
|
//all AP should wait until BSP finishes parsing PTCT and finding the command interface.
|
||||||
while (!ptcm_command_interface) {
|
while (!ptcm_command_interface) {
|
||||||
@ -134,24 +143,31 @@ void init_psram(bool is_bsp)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = ptcm_command_interface(PTCM_CMD_INIT_PSRAM, (void *)ptct_base_entry);
|
if ((int64_t)ptcm_command_interface != -1){ /* ptcm_command_interface is found */
|
||||||
pr_fatal("PTCM initialization for core %d with return code %d!!!!!!!!!!!!!", get_pcpu_id(), ret);
|
ptcm_ret_code = ptcm_command_interface(PTCM_CMD_INIT_PSRAM, (void *)ptct_base_entry);
|
||||||
/* TODO: to handle the return errno gracefully */
|
pr_info("ptcm initialization for core %d with return code %d", get_pcpu_id(), ptcm_ret_code);
|
||||||
ASSERT(ret == PTCM_STATUS_SUCCESS);
|
/* TODO: to handle the return errno gracefully */
|
||||||
|
ASSERT(ptcm_ret_code == PTCM_STATUS_SUCCESS);
|
||||||
/* wait until all cores finishes pSRAM initialization*/
|
/* wait until all cores finishes pSRAM initialization*/
|
||||||
if (is_bsp){
|
if (is_bsp){
|
||||||
psram_is_initialized = true;
|
psram_is_initialized = true;
|
||||||
pr_fatal("BSP pSRAM has been initialized\n");
|
pr_info("BSP pSRAM has been initialized\n");
|
||||||
} else{
|
}
|
||||||
while (psram_is_initialized) {
|
else{
|
||||||
continue;
|
while (!psram_is_initialized) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
ret = -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
void init_psram(__unused bool is_bsp)
|
int32_t init_psram(__unused bool is_bsp)
|
||||||
{
|
{
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -18,6 +18,8 @@ typedef int32_t MSABI (*ptcm_command_abi)(uint32_t command, void *command_struct
|
|||||||
#define PTCM_CMD_RDMSR (int32_t)3U
|
#define PTCM_CMD_RDMSR (int32_t)3U
|
||||||
#define PTCM_CMD_WRMSR (int32_t)4U
|
#define PTCM_CMD_WRMSR (int32_t)4U
|
||||||
|
|
||||||
|
#define PTCM_MAGIC 0x5054434dU
|
||||||
|
|
||||||
#define PCTM_L2_CLOS_MASK_MAX_NUM 8U
|
#define PCTM_L2_CLOS_MASK_MAX_NUM 8U
|
||||||
#define PCTM_L3_CLOS_MASK_MAX_NUM 4U
|
#define PCTM_L3_CLOS_MASK_MAX_NUM 4U
|
||||||
|
|
||||||
@ -37,4 +39,5 @@ struct ptcm_header
|
|||||||
uint64_t command_interface_offset;
|
uint64_t command_interface_offset;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
int32_t init_psram(bool is_bsp);
|
||||||
#endif /* PTCM_H */
|
#endif /* PTCM_H */
|
||||||
|
@ -101,5 +101,4 @@ struct ptcm_mem_region
|
|||||||
|
|
||||||
extern uint64_t psram_area_bottom;
|
extern uint64_t psram_area_bottom;
|
||||||
extern uint64_t psram_area_top;
|
extern uint64_t psram_area_top;
|
||||||
void init_psram(bool is_bsp);
|
|
||||||
#endif /* PTCT_H */
|
#endif /* PTCT_H */
|
||||||
|
Loading…
Reference in New Issue
Block a user