Calculate a LegacyRamSize directly from the e820 map for use by handle_1588() and handle_15e801() (the only two external interfaces that require "RamSize"). All other users of the existing RamSize (and RamSizeOver4G) variables are specific to QEMU, so move the declarations to paravirt.c.
Signed-off-by: Kevin O'Connor kevin@koconnor.net ---
It's not ideal to calculate the ram size in 16bit mode, so do the scan in 32bit mode and cache the results. In order to handle the various cases of CSM/not-csm, and pre/post optionrom, perform the calculation twice - once at the start of POST and again as the end of POST.
--- src/acpi.c | 1 + src/coreboot.c | 17 +---------------- src/misc.c | 5 ----- src/mtrr.c | 1 + src/paravirt.c | 6 ++++++ src/paravirt.h | 2 ++ src/pciinit.c | 1 + src/pmm.c | 26 ++++++++++++++++++++++++-- src/smbios.c | 1 + src/system.c | 4 ++-- src/util.h | 3 +-- src/xen.c | 13 ------------- 12 files changed, 40 insertions(+), 40 deletions(-)
diff --git a/src/acpi.c b/src/acpi.c index f7a2e55..7575fc6 100644 --- a/src/acpi.c +++ b/src/acpi.c @@ -13,6 +13,7 @@ #include "pci_regs.h" // PCI_INTERRUPT_LINE #include "ioport.h" // inl #include "config.h" // CONFIG_* +#include "paravirt.h" // RamSize #include "dev-q35.h"
/****************************************************/ diff --git a/src/coreboot.c b/src/coreboot.c index 0d44834..f0484e1 100644 --- a/src/coreboot.c +++ b/src/coreboot.c @@ -148,28 +148,15 @@ coreboot_preinit(void) if (!cbm) goto fail;
- u64 maxram = 0, maxram_over4G = 0; int i, count = MEM_RANGE_COUNT(cbm); for (i=0; i<count; i++) { struct cb_memory_range *m = &cbm->map[i]; u32 type = m->type; - if (type == CB_MEM_TABLE) { + if (type == CB_MEM_TABLE) type = E820_RESERVED; - } else if (type == E820_ACPI || type == E820_RAM) { - u64 end = m->start + m->size; - if (end > 0x100000000ull) { - end -= 0x100000000ull; - if (end > maxram_over4G) - maxram_over4G = end; - } else if (end > maxram) - maxram = end; - } add_e820(m->start, m->size, type); }
- RamSize = maxram; - RamSizeOver4G = maxram_over4G; - // Ughh - coreboot likes to set a map at 0x0000-0x1000, but this // confuses grub. So, override it. add_e820(0, 16*1024, E820_RAM); @@ -186,8 +173,6 @@ coreboot_preinit(void) fail: // No table found.. Use 16Megs as a dummy value. dprintf(1, "Unable to find coreboot table!\n"); - RamSize = 16*1024*1024; - RamSizeOver4G = 0; add_e820(0, 16*1024*1024, E820_RAM); return; } diff --git a/src/misc.c b/src/misc.c index fb7aad4..a34405c 100644 --- a/src/misc.c +++ b/src/misc.c @@ -10,11 +10,6 @@ #include "util.h" // debug_enter #include "pic.h" // enable_hwirq
-// Amount of continuous ram under 4Gig -u32 RamSize VARFSEG; -// Amount of continuous ram >4Gig -u64 RamSizeOver4G; -
/**************************************************************** * Misc 16bit ISRs diff --git a/src/mtrr.c b/src/mtrr.c index 56f85f9..0f94c2c 100644 --- a/src/mtrr.c +++ b/src/mtrr.c @@ -7,6 +7,7 @@ #include "util.h" // dprintf #include "config.h" // CONFIG_* #include "pci.h" // pcimem_start +#include "paravirt.h" // RamSize
#define MSR_MTRRcap 0x000000fe #define MSR_MTRRfix64K_00000 0x00000250 diff --git a/src/paravirt.c b/src/paravirt.c index 9ea3dd5..f061039 100644 --- a/src/paravirt.c +++ b/src/paravirt.c @@ -21,6 +21,10 @@ #include "pci.h" // create_pirtable #include "xen.h" // xen_biostable_setup
+// Amount of continuous ram under 4Gig +u32 RamSize; +// Amount of continuous ram >4Gig +u64 RamSizeOver4G; // Type of emulator platform. int PlatformRunningOn VARFSEG;
@@ -83,6 +87,8 @@ qemu_preinit(void)
/* reserve 256KB BIOS area at the end of 4 GB */ add_e820(0xfffc0000, 256*1024, E820_RESERVED); + + dprintf(1, "Ram Size=0x%08x (0x%016llx high)\n", RamSize, RamSizeOver4G); }
void diff --git a/src/paravirt.h b/src/paravirt.h index 7237731..fce5af9 100644 --- a/src/paravirt.h +++ b/src/paravirt.h @@ -9,6 +9,8 @@ #define PF_XEN (1<<1) #define PF_KVM (1<<2)
+extern u32 RamSize; +extern u64 RamSizeOver4G; extern int PlatformRunningOn;
static inline int runningOnQEMU(void) { diff --git a/src/pciinit.c b/src/pciinit.c index 306b125..77cac0a 100644 --- a/src/pciinit.c +++ b/src/pciinit.c @@ -12,6 +12,7 @@ #include "ioport.h" // PORT_ATA1_CMD_BASE #include "config.h" // CONFIG_* #include "memmap.h" // add_e820 +#include "paravirt.h" // RamSize #include "dev-q35.h"
/* PM Timer ticks per second (HZ) */ diff --git a/src/pmm.c b/src/pmm.c index c717884..42484cd 100644 --- a/src/pmm.c +++ b/src/pmm.c @@ -225,8 +225,6 @@ malloc_preinit(void) ASSERT32FLAT(); dprintf(3, "malloc preinit\n");
- dprintf(1, "Ram Size=0x%08x (0x%016llx high)\n", RamSize, RamSizeOver4G); - // Don't declare any memory between 0xa0000 and 0x100000 add_e820(BUILD_LOWRAM_END, BUILD_BIOS_ADDR-BUILD_LOWRAM_END, E820_HOLE);
@@ -278,6 +276,26 @@ csm_malloc_preinit(u32 low_pmm, u32 low_pmm_size, u32 hi_pmm, u32 hi_pmm_size) addSpace(&ZoneTmpLow, (void *)low_pmm, (void *)low_pmm + low_pmm_size); }
+u32 LegacyRamSize VARFSEG; + +// Calculate the maximum ramsize (less than 4gig) from e820 map. +static void +calcRamSize(void) +{ + u32 rs = 0; + int i; + for (i=e820_count-1; i>=0; i--) { + struct e820entry *en = &e820_list[i]; + u64 end = en->start + en->size; + u32 type = en->type; + if (end <= 0xffffffff && (type == E820_ACPI || type == E820_RAM)) { + rs = end; + break; + } + } + LegacyRamSize = rs >= 1024*1024 ? rs : 1024*1024; +} + // Update pointers after code relocation. void malloc_init(void) @@ -309,6 +327,8 @@ malloc_init(void) , (u32)final_code32flat_start - BUILD_BIOS_ADDR); addSpace(&ZoneFSeg, (void*)BUILD_BIOS_ADDR, final_code32flat_start); } + + calcRamSize(); }
void @@ -338,6 +358,8 @@ malloc_prepboot(void) add_e820((u32)info->dataend, giveback, E820_RAM); dprintf(1, "Returned %d bytes of ZoneHigh\n", giveback); } + + calcRamSize(); }
diff --git a/src/smbios.c b/src/smbios.c index a9d76f0..f0b83b3 100644 --- a/src/smbios.c +++ b/src/smbios.c @@ -7,6 +7,7 @@
#include "util.h" // dprintf #include "config.h" // CONFIG_* +#include "paravirt.h" // RamSize #include "smbios.h" // struct smbios_entry_point
struct smbios_entry_point *SMBiosAddr; diff --git a/src/system.c b/src/system.c index dc1dd7d..7b481a8 100644 --- a/src/system.c +++ b/src/system.c @@ -174,7 +174,7 @@ handle_1587(struct bregs *regs) static void handle_1588(struct bregs *regs) { - u32 rs = GET_GLOBAL(RamSize); + u32 rs = GET_GLOBAL(LegacyRamSize);
// According to Ralf Brown's interrupt the limit should be 15M, // but real machines mostly return max. 63M. @@ -270,7 +270,7 @@ handle_15e801(struct bregs *regs) // regs.u.r16.ax = 0; // regs.u.r16.bx = 0;
- u32 rs = GET_GLOBAL(RamSize); + u32 rs = GET_GLOBAL(LegacyRamSize);
// Get the amount of extended memory (above 1M) if (rs > 16*1024*1024) { diff --git a/src/util.h b/src/util.h index 9303b5a..306a8bf 100644 --- a/src/util.h +++ b/src/util.h @@ -371,6 +371,7 @@ int rom_confirm(u32 size); void csm_malloc_preinit(u32 low_pmm, u32 low_pmm_size, u32 hi_pmm, u32 hi_pmm_size); void malloc_preinit(void); +extern u32 LegacyRamSize; void malloc_init(void); void malloc_prepboot(void); void *pmm_malloc(struct zone_s *zone, u32 handle, u32 size, u32 align); @@ -450,8 +451,6 @@ void reset_vector(void) __noreturn;
// misc.c void mathcp_setup(void); -extern u32 RamSize; -extern u64 RamSizeOver4G; extern u8 BiosChecksum;
// version (auto generated file out/version.c) diff --git a/src/xen.c b/src/xen.c index 569fcc0..db542c3 100644 --- a/src/xen.c +++ b/src/xen.c @@ -130,7 +130,6 @@ void xen_biostable_setup(void)
void xen_ramsize_preinit(void) { - u64 maxram = 0, maxram_over4G = 0; int i; struct xen_seabios_info *info = (void *)INFO_PHYSICAL_ADDRESS; struct e820entry *e820 = (struct e820entry *)info->e820; @@ -140,18 +139,6 @@ void xen_ramsize_preinit(void)
for (i = 0; i < info->e820_nr; i++) { struct e820entry *e = &e820[i]; - if (e->type == E820_ACPI || e->type == E820_RAM) { - u64 end = e->start + e->size; - if (end > 0x100000000ull) { - end -= 0x100000000ull; - if (end > maxram_over4G) - maxram_over4G = end; - } else if (end > maxram) - maxram = end; - } add_e820(e->start, e->size, e->type); } - - RamSize = maxram; - RamSizeOver4G = maxram_over4G; }