dm: build E820 map for OVMF
OVMF requires a more descriptive mechanism than RTC CMOS to retrieve ACRN's memory layout, so we now pass the E820 map to it, starting at 0xEF000 (ROM area). ACRN currently uses [4GB, 5GB) as its 64-bit PCI host aperture. This is inconsistent with OVMF's assumption of its platform's memory layout, because it derives the size of high memory from RTC CMOS, which is incapable of describing the 64-bit PCI hole. By default, OVMF uses RTC CMOS 0x5b/0x5c/0x5d to determine the size of high memory. This value only tells OVMF how much memory is above 4GB, but not the platform's memory layout above 4GB. Using RTC CMOS works for QEMU, because QEMU places its 64-bit PCI host aperture above its highmem. Therefore, OVMF can always assume highmem is located at [4GB, 4GB + highmem), which is not where ACRN's highmem is located. For example, if we have 1GB of usable memory above 4GB, ACRN will place it at [5GB, 6GB). This change allows OVMF to correctly identify the guest's memory layout. It will consider any reserved region above 4GB as 64-bit PCI host aperture. MP table, SMBIOS and ACPI tables are all located above 0xF0000 so it is guaranteed that there is no overlap. There can only be a maximum of 128 E820 entries. v1 -> v2: - provide more explanation to this commit - add signature before E820 map for OVMF backward compatibility Tracked-On: #2792 Signed-off-by: Peter Fang <peter.fang@intel.com> Reviewed-by: Eddie Dong <eddie.dong@intel.com> Acked-by: Yin Fengwei <fengwei.yin@intel.com>
This commit is contained in:
parent
4dd1331072
commit
071ce15ed4
|
@ -53,7 +53,10 @@
|
|||
*/
|
||||
|
||||
/* ovmf real entry is reset vector, which is (OVMF_TOP - 16) */
|
||||
#define OVMF_TOP(ctx) (4*GB)
|
||||
#define OVMF_TOP(ctx) (4*GB)
|
||||
|
||||
/* located in the ROM area */
|
||||
#define OVMF_E820_BASE 0x000EF000UL
|
||||
|
||||
static char ovmf_path[STR_LEN];
|
||||
static size_t ovmf_size;
|
||||
|
@ -130,6 +133,11 @@ int
|
|||
acrn_sw_load_ovmf(struct vmctx *ctx)
|
||||
{
|
||||
int ret;
|
||||
struct {
|
||||
char signature[4];
|
||||
uint32_t nentries;
|
||||
struct e820_entry map[];
|
||||
} __attribute__((packed)) *e820;
|
||||
|
||||
init_cmos_vrpmb(ctx);
|
||||
|
||||
|
@ -138,6 +146,14 @@ acrn_sw_load_ovmf(struct vmctx *ctx)
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
e820 = paddr_guest2host(ctx, OVMF_E820_BASE,
|
||||
e820_default_entries[LOWRAM_E820_ENTRY].baseaddr -
|
||||
OVMF_E820_BASE);
|
||||
assert(e820 != NULL);
|
||||
|
||||
strncpy(e820->signature, "820", sizeof(e820->signature));
|
||||
e820->nentries = acrn_create_e820_table(ctx, e820->map);
|
||||
|
||||
printf("SW_LOAD: ovmf_entry 0x%lx\n", OVMF_TOP(ctx) - 16);
|
||||
|
||||
/* set guest bsp state. Will call hypercall set bsp state
|
||||
|
|
Loading…
Reference in New Issue