mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-06-19 12:12:16 +00:00
hv: pSRAM: add pSRAM support for pre-launched RTVM
1.Modified the virtual e820 table for pre-launched VM. We added a segment for pSRAM, and thus lowmem RAM is split into two parts. Logics are added to deal with the split. 2.Added EPT mapping of pSRAM segment for pre-launched RTVM if it uses pSRAM. Tracked-On: #5330 Signed-off-by: Qian Wang <qian1.wang@intel.com> Acked-by: Eddie Dong <eddie.dong@intel.com>
This commit is contained in:
parent
7bd0f7507e
commit
99ee76781f
@ -10,9 +10,12 @@
|
|||||||
#include <reloc.h>
|
#include <reloc.h>
|
||||||
#include <vacpi.h>
|
#include <vacpi.h>
|
||||||
#include <logmsg.h>
|
#include <logmsg.h>
|
||||||
|
#include <ptcm.h>
|
||||||
|
|
||||||
#define ENTRY_HPA1 2U
|
#define ENTRY_HPA1_LOW_PART1 2U
|
||||||
#define ENTRY_HPA1_HI 6U
|
#define ENTRY_HPA1_LOW_PART2 4U
|
||||||
|
#define ENTRY_PSRAM 3U
|
||||||
|
#define ENTRY_HPA1_HI 8U
|
||||||
|
|
||||||
static struct e820_entry sos_vm_e820[E820_MAX_ENTRIES];
|
static struct e820_entry sos_vm_e820[E820_MAX_ENTRIES];
|
||||||
static struct e820_entry pre_vm_e820[PRE_VM_NUM][E820_MAX_ENTRIES];
|
static struct e820_entry pre_vm_e820[PRE_VM_NUM][E820_MAX_ENTRIES];
|
||||||
@ -130,9 +133,20 @@ static const struct e820_entry pre_ve820_template[E820_MAX_ENTRIES] = {
|
|||||||
.length = 0x10000UL, /* 64KB */
|
.length = 0x10000UL, /* 64KB */
|
||||||
.type = E820_TYPE_RESERVED
|
.type = E820_TYPE_RESERVED
|
||||||
},
|
},
|
||||||
{ /* hpa1 */
|
/* pSRAM segment splits the lowmem into two parts */
|
||||||
.baseaddr = 0x100000UL, /* 1MB */
|
{ /* part1 of lowmem of hpa1*/
|
||||||
.length = (MEM_2G - MEM_2M),
|
.baseaddr = MEM_1M, /* 1MB */
|
||||||
|
.length = PSRAM_BASE_GPA - MEM_1M,
|
||||||
|
.type = E820_TYPE_RAM
|
||||||
|
},
|
||||||
|
{ /* pSRAM */
|
||||||
|
.baseaddr = PSRAM_BASE_GPA,
|
||||||
|
.length = PSRAM_MAX_SIZE,
|
||||||
|
.type = E820_TYPE_RESERVED
|
||||||
|
},
|
||||||
|
{ /* part2 of lowmem of hpa1*/
|
||||||
|
.baseaddr = PSRAM_BASE_GPA + PSRAM_MAX_SIZE,
|
||||||
|
.length = MEM_2G - MEM_1M - (PSRAM_BASE_GPA + PSRAM_MAX_SIZE),
|
||||||
.type = E820_TYPE_RAM
|
.type = E820_TYPE_RAM
|
||||||
},
|
},
|
||||||
{ /* ACPI Reclaim */
|
{ /* ACPI Reclaim */
|
||||||
@ -170,23 +184,37 @@ static inline uint64_t add_ram_entry(struct e820_entry *entry, uint64_t gpa, uin
|
|||||||
*
|
*
|
||||||
* entry0: usable under 1MB
|
* entry0: usable under 1MB
|
||||||
* entry1: reserved for MP Table/ACPI RSDP from 0xf0000 to 0xfffff
|
* entry1: reserved for MP Table/ACPI RSDP from 0xf0000 to 0xfffff
|
||||||
* entry2: usable for hpa1 or hpa1_lo from 0x100000
|
* entry2: usable, the part1 of hpa1 in lowmem, from 0x100000, and up to the bottom of pSRAM area.
|
||||||
* entry3: ACPI Reclaim from 0x7ff00000 to 0x7ffeffff
|
* entry3: reserved, pSRAM segment, which will be identically mapped to physical pSRAM segment rather than hpa1.
|
||||||
* entry4: ACPI NVS from 0x7fff0000 to 0x7fffffff
|
* entry4: usable, the part2 of hpa1 in lowmem, from the ceil of pSRAM segment, and up to 2G-1M.
|
||||||
* entry5: reserved for 32bit PCI hole from 0x80000000 to 0xffffffff
|
* entry5: ACPI Reclaim from 0x7ff00000 to 0x7ffeffff
|
||||||
* (entry6): usable for
|
* entry6: ACPI NVS from 0x7fff0000 to 0x7fffffff
|
||||||
* a) hpa1_hi, if hpa1 > 2GB
|
* entry7: reserved for 32bit PCI hole from 0x80000000 to 0xffffffff
|
||||||
* b) hpa2, if (hpa1 + hpa2) < 2GB
|
* (entry8): usable for
|
||||||
* c) hpa2_lo, if hpa1 < 2GB and (hpa1 + hpa2) > 2GB
|
* a) hpa1_hi, if hpa1 > 2GB - PSRAM_MAX_SIZE
|
||||||
* (entry7): usable for
|
* b) hpa2, if (hpa1 + hpa2) < 2GB - PSRAM_MAX_SIZE
|
||||||
* a) hpa2, if hpa1 > 2GB
|
* c) hpa2_lo, if hpa1 < 2GB - PSRAM_MAX_SIZE and (hpa1 + hpa2) > 2GB - PSRAM_MAX_SIZE
|
||||||
* b) hpa2_hi, if hpa1 < 2GB and (hpa1 + hpa2) > 2GB
|
* (entry9): usable for
|
||||||
|
* a) hpa2, if hpa1 > 2GB - PSRAM_MAX_SIZE
|
||||||
|
* b) hpa2_hi, if hpa1 < 2GB - PSRAM_MAX_SIZE and (hpa1 + hpa2) > 2GB - PSRAM_MAX_SIZE
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
The actual memory mapping under 2G looks like below:
|
||||||
|
|<--1M-->|
|
||||||
|
|<-----hpa1_low_part1--->|
|
||||||
|
|<---pSRAM--->|
|
||||||
|
|<-----hpa1_low_part2--->|
|
||||||
|
|<---Non-mapped hole (if there is)-->|
|
||||||
|
|<---1M ACPI NVS/DATA--->|
|
||||||
*/
|
*/
|
||||||
void create_prelaunched_vm_e820(struct acrn_vm *vm)
|
void create_prelaunched_vm_e820(struct acrn_vm *vm)
|
||||||
{
|
{
|
||||||
struct acrn_vm_config *vm_config = get_vm_config(vm->vm_id);
|
struct acrn_vm_config *vm_config = get_vm_config(vm->vm_id);
|
||||||
uint64_t gpa_start = 0x100000000UL;
|
uint64_t gpa_start = 0x100000000UL;
|
||||||
uint64_t hpa1_hi_size, hpa2_lo_size;
|
uint64_t hpa1_hi_size, hpa2_lo_size;
|
||||||
|
uint64_t lowmem_max_length = MEM_2G - PSRAM_MAX_SIZE;
|
||||||
|
uint64_t hpa1_part1_max_length = PSRAM_BASE_GPA - MEM_1M;
|
||||||
uint64_t remaining_hpa2_size = vm_config->memory.size_hpa2;
|
uint64_t remaining_hpa2_size = vm_config->memory.size_hpa2;
|
||||||
uint32_t entry_idx = ENTRY_HPA1_HI;
|
uint32_t entry_idx = ENTRY_HPA1_HI;
|
||||||
|
|
||||||
@ -195,24 +223,36 @@ void create_prelaunched_vm_e820(struct acrn_vm *vm)
|
|||||||
(const void *)pre_ve820_template, E820_MAX_ENTRIES * sizeof(struct e820_entry));
|
(const void *)pre_ve820_template, E820_MAX_ENTRIES * sizeof(struct e820_entry));
|
||||||
|
|
||||||
/* sanitize entry for hpa1 */
|
/* sanitize entry for hpa1 */
|
||||||
if (vm_config->memory.size > MEM_2G) {
|
if (vm_config->memory.size > lowmem_max_length) {
|
||||||
/* need to split hpa1 and add an entry for hpa1_hi */
|
/* need to split hpa1 and add an entry for hpa1_hi */
|
||||||
hpa1_hi_size = vm_config->memory.size - MEM_2G;
|
hpa1_hi_size = vm_config->memory.size - lowmem_max_length;
|
||||||
gpa_start = add_ram_entry((vm->e820_entries + entry_idx), gpa_start, hpa1_hi_size);
|
gpa_start = add_ram_entry((vm->e820_entries + entry_idx), gpa_start, hpa1_hi_size);
|
||||||
entry_idx++;
|
entry_idx++;
|
||||||
|
} else if (vm_config->memory.size <= MEM_1M + hpa1_part1_max_length + MEM_1M) {
|
||||||
|
/* in this case, hpa1 is only enough for the first 1M + part1 + last 1M (ACPI NVS/DATA), so part2 will be empty */
|
||||||
|
vm->e820_entries[ENTRY_HPA1_LOW_PART1].length = vm_config->memory.size - MEM_2M; /* 2M includes the first and last 1M */
|
||||||
|
vm->e820_entries[ENTRY_HPA1_LOW_PART2].length = 0;
|
||||||
} else {
|
} else {
|
||||||
/* need to revise length of hpa1 entry to its actual size, excluding size of low 1MB and ACPI space */
|
/* Otherwise, part2 is not empty. */
|
||||||
vm->e820_entries[ENTRY_HPA1].length = vm_config->memory.size - MEM_2M;
|
vm->e820_entries[ENTRY_HPA1_LOW_PART2].length = vm_config->memory.size - PSRAM_BASE_GPA - MEM_1M;
|
||||||
/* need to set gpa_start for hpa2 */
|
/* need to set gpa_start for hpa2 */
|
||||||
gpa_start = vm->e820_entries[ENTRY_HPA1].baseaddr + vm->e820_entries[ENTRY_HPA1].length;
|
|
||||||
if ((vm_config->memory.size < MEM_2G)
|
|
||||||
&& (remaining_hpa2_size > (MEM_2G - vm_config->memory.size))) {
|
|
||||||
/* need to split hpa2 and add an entry for hpa2_lo */
|
|
||||||
hpa2_lo_size = remaining_hpa2_size - (MEM_2G - vm_config->memory.size);
|
|
||||||
gpa_start = add_ram_entry((vm->e820_entries + entry_idx), gpa_start, hpa2_lo_size);
|
|
||||||
remaining_hpa2_size -= hpa2_lo_size;
|
|
||||||
entry_idx++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hpa2_lo_size = (lowmem_max_length - vm_config->memory.size);
|
||||||
|
gpa_start = vm->e820_entries[ENTRY_HPA1_LOW_PART2].baseaddr + vm->e820_entries[ENTRY_HPA1_LOW_PART2].length;
|
||||||
|
|
||||||
|
if (hpa2_lo_size > 0 && remaining_hpa2_size > 0) {
|
||||||
|
/* In this case, hpa2 may have some parts to be mapped to lowmem, so we add an entry for hpa2_lo */
|
||||||
|
if (remaining_hpa2_size > hpa2_lo_size) {
|
||||||
|
remaining_hpa2_size -= hpa2_lo_size;
|
||||||
|
gpa_start = 0x100000000U;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
hpa2_lo_size = remaining_hpa2_size;
|
||||||
|
remaining_hpa2_size = 0;
|
||||||
|
}
|
||||||
|
(void)add_ram_entry((vm->e820_entries + entry_idx), gpa_start, hpa2_lo_size);
|
||||||
|
entry_idx++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check whether need an entry for remaining hpa2 */
|
/* check whether need an entry for remaining hpa2 */
|
||||||
|
@ -35,6 +35,7 @@
|
|||||||
#include <trampoline.h>
|
#include <trampoline.h>
|
||||||
#include <assign.h>
|
#include <assign.h>
|
||||||
#include <vgpio.h>
|
#include <vgpio.h>
|
||||||
|
#include <ptcm.h>
|
||||||
|
|
||||||
/* Local variables */
|
/* Local variables */
|
||||||
|
|
||||||
@ -228,7 +229,16 @@ static void prepare_prelaunched_vm_memmap(struct acrn_vm *vm, const struct acrn_
|
|||||||
const struct e820_entry *entry = &(vm->e820_entries[i]);
|
const struct e820_entry *entry = &(vm->e820_entries[i]);
|
||||||
|
|
||||||
if (entry->length == 0UL) {
|
if (entry->length == 0UL) {
|
||||||
break;
|
continue;
|
||||||
|
} else {
|
||||||
|
if (is_psram_initialized && (entry->baseaddr == PSRAM_BASE_GPA) &&
|
||||||
|
((vm_config->guest_flags & GUEST_FLAG_RT) != 0U)){
|
||||||
|
/* pass through pSRAM to pre-RTVM */
|
||||||
|
pr_fatal("%s, %d___", __func__, __LINE__);
|
||||||
|
ept_add_mr(vm, (uint64_t *)vm->arch_vm.nworld_eptp,
|
||||||
|
PSRAM_BASE_HPA, PSRAM_BASE_GPA, PSRAM_MAX_SIZE, EPT_RWX | EPT_WB);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (remaining_hpa_size >= entry->length) {
|
if (remaining_hpa_size >= entry->length) {
|
||||||
|
Loading…
Reference in New Issue
Block a user