This series is a fallout of work I was doing to test PAE. I think the cleanups in this series make sense even without PAE.
-Kevin
Kevin O'Connor (10): e820: Introduce e820_remove() and avoid exporting E820_HOLE e820: Rename memmap.c to e820map.c and use consistent "e820_" prefix e820: Update debugging messages to report 64bit values virtio: Simplify vring alignment code virtio: Move standard definitions from virtio-ring.h to standard headers malloc: Use consistent naming for internal low-level "alloc" functions malloc: Introduce common helper alloc_new_detail() malloc: Add warning if free() called on invalid memory malloc: Don't mix virtual and physical addresses memmap: Introduce SYMBOL() macro to access linker script symbols
Makefile | 2 +- src/biosvar.h | 6 +- src/{memmap.c => e820map.c} | 18 ++- src/{memmap.h => e820map.h} | 9 +- src/fw/biostables.c | 10 +- src/fw/coreboot.c | 8 +- src/fw/csm.c | 18 +-- src/fw/paravirt.c | 14 +-- src/fw/pciinit.c | 6 +- src/fw/shadow.c | 10 +- src/fw/xen.c | 9 +- src/hw/pvscsi.c | 2 +- src/hw/ramdisk.c | 5 +- src/hw/virtio-ring.h | 36 ++---- src/list.h | 10 ++ src/malloc.c | 294 +++++++++++++++++++++++--------------------- src/malloc.h | 11 +- src/memmap.h | 38 +++--- src/pmm.c | 16 +-- src/post.c | 41 +++--- src/system.c | 2 +- src/x86.h | 8 ++ 22 files changed, 293 insertions(+), 280 deletions(-) rename src/{memmap.c => e820map.c} (90%) copy src/{memmap.h => e820map.h} (66%)
The E820_HOLE definition is used internally in the e820 manipulation code to remove entries from the e820 map. Introduce the e820_remove() function so that the E820_HOLE definition does not need to be exported from the memmap.c code.
Signed-off-by: Kevin O'Connor kevin@koconnor.net --- src/malloc.c | 2 +- src/memmap.c | 10 +++++++++- src/memmap.h | 2 +- 3 files changed, 11 insertions(+), 3 deletions(-)
diff --git a/src/malloc.c b/src/malloc.c index c4cb171..5c05a8a 100644 --- a/src/malloc.c +++ b/src/malloc.c @@ -396,7 +396,7 @@ malloc_preinit(void) dprintf(3, "malloc preinit\n");
// Don't declare any memory between 0xa0000 and 0x100000 - add_e820(BUILD_LOWRAM_END, BUILD_BIOS_ADDR-BUILD_LOWRAM_END, E820_HOLE); + e820_remove(BUILD_LOWRAM_END, BUILD_BIOS_ADDR-BUILD_LOWRAM_END);
// Mark known areas as reserved. add_e820(BUILD_BIOS_ADDR, BUILD_BIOS_SIZE, E820_RESERVED); diff --git a/src/memmap.c b/src/memmap.c index e03f8d0..8c0c38d 100644 --- a/src/memmap.c +++ b/src/memmap.c @@ -54,7 +54,6 @@ e820_type_name(u32 type) case E820_ACPI: return "ACPI"; case E820_NVS: return "NVS"; case E820_UNUSABLE: return "UNUSABLE"; - case E820_HOLE: return "HOLE"; default: return "UNKNOWN"; } } @@ -73,6 +72,8 @@ dump_map(void) } }
+#define E820_HOLE ((u32)-1) // Used internally to remove entries + // Add a new entry to the list. This scans for overlaps and keeps the // list sorted. void @@ -136,6 +137,13 @@ add_e820(u64 start, u64 size, u32 type) //dump_map(); }
+// Remove any definitions in a memory range (make a memory hole). +void +e820_remove(u64 start, u64 size) +{ + add_e820(start, size, E820_HOLE); +} + // Report on final memory locations. void memmap_prepboot(void) diff --git a/src/memmap.h b/src/memmap.h index 7bda56e..e7d94ee 100644 --- a/src/memmap.h +++ b/src/memmap.h @@ -8,7 +8,6 @@ #define E820_ACPI 3 #define E820_NVS 4 #define E820_UNUSABLE 5 -#define E820_HOLE ((u32)-1) // Useful for removing entries
struct e820entry { u64 start; @@ -17,6 +16,7 @@ struct e820entry { };
void add_e820(u64 start, u64 size, u32 type); +void e820_remove(u64 start, u64 size); void memmap_prepboot(void);
// A typical OS page size
Rename memmap.c to e820map.c as the code in that file only deals with maintaining the e820 map. Move all the e820 definitions to new file e820map.h and use a consistent "e820_" prefix on all exported functions.
Signed-off-by: Kevin O'Connor kevin@koconnor.net --- Makefile | 2 +- src/{memmap.c => e820map.c} | 8 ++++---- src/{memmap.h => e820map.h} | 7 ++----- src/fw/coreboot.c | 8 ++++---- src/fw/csm.c | 14 +++++++------- src/fw/paravirt.c | 14 +++++++------- src/fw/pciinit.c | 6 +++--- src/fw/xen.c | 9 +++++---- src/hw/ramdisk.c | 5 +++-- src/malloc.c | 11 ++++++----- src/memmap.h | 28 +++------------------------- src/post.c | 6 +++--- src/system.c | 2 +- 13 files changed, 49 insertions(+), 71 deletions(-) rename src/{memmap.c => e820map.c} (96%) copy src/{memmap.h => e820map.h} (77%)
diff --git a/Makefile b/Makefile index 3a0d2e8..e5f28d4 100644 --- a/Makefile +++ b/Makefile @@ -36,7 +36,7 @@ SRCBOTH=misc.c stacks.c output.c string.c block.c cdrom.c disk.c mouse.c kbd.c \ hw/blockcmd.c hw/floppy.c hw/ata.c hw/ramdisk.c \ hw/lsi-scsi.c hw/esp-scsi.c hw/megasas.c SRC16=$(SRCBOTH) -SRC32FLAT=$(SRCBOTH) post.c memmap.c malloc.c romfile.c x86.c optionroms.c \ +SRC32FLAT=$(SRCBOTH) post.c e820map.c malloc.c romfile.c x86.c optionroms.c \ pmm.c font.c boot.c bootsplash.c jpeg.c bmp.c tcgbios.c sha1.c \ hw/ahci.c hw/pvscsi.c hw/usb-xhci.c hw/usb-hub.c hw/sdcard.c \ fw/coreboot.c fw/lzmadecode.c fw/multiboot.c fw/csm.c fw/biostables.c \ diff --git a/src/memmap.c b/src/e820map.c similarity index 96% rename from src/memmap.c rename to src/e820map.c index 8c0c38d..901ccdf 100644 --- a/src/memmap.c +++ b/src/e820map.c @@ -5,7 +5,7 @@ // This file may be distributed under the terms of the GNU LGPLv3 license.
#include "config.h" // BUILD_MAX_E820 -#include "memmap.h" // struct e820entry +#include "e820map.h" // struct e820entry #include "output.h" // dprintf #include "string.h" // memmove
@@ -77,7 +77,7 @@ dump_map(void) // Add a new entry to the list. This scans for overlaps and keeps the // list sorted. void -add_e820(u64 start, u64 size, u32 type) +e820_add(u64 start, u64 size, u32 type) { dprintf(8, "Add to e820 map: %08x %08x %d\n", (u32)start, (u32)size, type);
@@ -141,12 +141,12 @@ add_e820(u64 start, u64 size, u32 type) void e820_remove(u64 start, u64 size) { - add_e820(start, size, E820_HOLE); + e820_add(start, size, E820_HOLE); }
// Report on final memory locations. void -memmap_prepboot(void) +e820_prepboot(void) { dump_map(); } diff --git a/src/memmap.h b/src/e820map.h similarity index 77% copy from src/memmap.h copy to src/e820map.h index e7d94ee..de8b523 100644 --- a/src/memmap.h +++ b/src/e820map.h @@ -15,12 +15,9 @@ struct e820entry { u32 type; };
-void add_e820(u64 start, u64 size, u32 type); +void e820_add(u64 start, u64 size, u32 type); void e820_remove(u64 start, u64 size); -void memmap_prepboot(void); - -// A typical OS page size -#define PAGE_SIZE 4096 +void e820_prepboot(void);
// e820 map storage extern struct e820entry e820_list[]; diff --git a/src/fw/coreboot.c b/src/fw/coreboot.c index b077fe1..a47f524 100644 --- a/src/fw/coreboot.c +++ b/src/fw/coreboot.c @@ -7,10 +7,10 @@ #include "block.h" // MAXDESCSIZE #include "byteorder.h" // be32_to_cpu #include "config.h" // CONFIG_* +#include "e820map.h" // e820_add #include "hw/pci.h" // pci_probe_devices #include "lzmadecode.h" // LzmaDecode #include "malloc.h" // free -#include "memmap.h" // add_e820 #include "output.h" // dprintf #include "paravirt.h" // PlatformRunningOn #include "romfile.h" // romfile_findprefix @@ -184,12 +184,12 @@ coreboot_preinit(void) u32 type = m->type; if (type == CB_MEM_TABLE) type = E820_RESERVED; - add_e820(m->start, m->size, type); + e820_add(m->start, m->size, type); }
// Ughh - coreboot likes to set a map at 0x0000-0x1000, but this // confuses grub. So, override it. - add_e820(0, 16*1024, E820_RAM); + e820_add(0, 16*1024, E820_RAM);
struct cb_cbmem_ref *cbref = find_cb_subtable(cbh, CB_TAG_CBMEM_CONSOLE); if (cbref) { @@ -210,7 +210,7 @@ coreboot_preinit(void) fail: // No table found.. Use 16Megs as a dummy value. dprintf(1, "Unable to find coreboot table!\n"); - add_e820(0, 16*1024*1024, E820_RAM); + e820_add(0, 16*1024*1024, E820_RAM); return; }
diff --git a/src/fw/csm.c b/src/fw/csm.c index aee2f90..0467560 100644 --- a/src/fw/csm.c +++ b/src/fw/csm.c @@ -4,20 +4,20 @@ // // This file may be distributed under the terms of the GNU LGPLv3 license.
-#include "bregs.h" +#include "bregs.h" // struct bregs #include "config.h" // CONFIG_* +#include "e820map.h" // e820_add #include "farptr.h" // MAKE_FLATPTR -#include "hw/pci.h" -#include "hw/pic.h" +#include "hw/pci.h" // pci_probe_devices +#include "hw/pic.h" // pic_irqmask_read #include "malloc.h" // csm_malloc_preinit -#include "memmap.h" #include "output.h" // dprintf +#include "paravirt.h" // qemu_preinit #include "stacks.h" // wait_threads #include "std/acpi.h" // RSDP_SIGNATURE #include "std/bda.h" // struct bios_data_area_s #include "std/optionrom.h" // struct rom_header #include "util.h" // copy_smbios -#include "paravirt.h" // qemu_preinit
#define UINT8 u8 #define UINT16 u16 @@ -147,11 +147,11 @@ handle_csm_0002(struct bregs *regs) struct e820entry *p = (void *)csm_compat_table.E820Pointer; int i; for (i=0; i < csm_compat_table.E820Length / sizeof(struct e820entry); i++) - add_e820(p[i].start, p[i].size, p[i].type); + e820_add(p[i].start, p[i].size, p[i].type);
if (csm_init_table->HiPmmMemorySizeInBytes > BUILD_MAX_HIGHTABLE) { u32 hi_pmm_end = csm_init_table->HiPmmMemory + csm_init_table->HiPmmMemorySizeInBytes; - add_e820(hi_pmm_end - BUILD_MAX_HIGHTABLE, BUILD_MAX_HIGHTABLE, E820_RESERVED); + e820_add(hi_pmm_end - BUILD_MAX_HIGHTABLE, BUILD_MAX_HIGHTABLE, E820_RESERVED); }
// For PCIBIOS 1ab10e diff --git a/src/fw/paravirt.c b/src/fw/paravirt.c index db22ae8..acb44b9 100644 --- a/src/fw/paravirt.c +++ b/src/fw/paravirt.c @@ -10,11 +10,11 @@
#include "byteorder.h" // be32_to_cpu #include "config.h" // CONFIG_QEMU +#include "e820map.h" // e820_add #include "hw/pci.h" // create_pirtable #include "hw/pci_regs.h" // PCI_DEVICE_ID #include "hw/rtc.h" // CMOS_* #include "malloc.h" // malloc_tmp -#include "memmap.h" // add_e820 #include "output.h" // dprintf #include "paravirt.h" // qemu_cfg_preinit #include "romfile.h" // romfile_loadint @@ -114,10 +114,10 @@ qemu_preinit(void) | (rtc_read(CMOS_MEM_EXTMEM_HIGH) << 18)) + 1 * 1024 * 1024); RamSize = rs; - add_e820(0, rs, E820_RAM); + e820_add(0, rs, E820_RAM);
/* reserve 256KB BIOS area at the end of 4 GB */ - add_e820(0xfffc0000, 256*1024, E820_RESERVED); + e820_add(0xfffc0000, 256*1024, E820_RESERVED);
dprintf(1, "RamSize: 0x%08x [cmos]\n", RamSize); } @@ -302,7 +302,7 @@ qemu_cfg_e820(void) } /* fall through */ case E820_RESERVED: - add_e820(table[i].address, table[i].length, table[i].type); + e820_add(table[i].address, table[i].length, table[i].type); break; default: /* @@ -324,13 +324,13 @@ qemu_cfg_e820(void) int i; for (i = 0; i < count32; i++) { qemu_cfg_read(&entry, sizeof(entry)); - add_e820(entry.address, entry.length, entry.type); + e820_add(entry.address, entry.length, entry.type); } } else if (runningOnKVM()) { // Backwards compatibility - provide hard coded range. // 4 pages before the bios, 3 pages for vmx tss pages, the // other page for EPT real mode pagetable - add_e820(0xfffbc000, 4*4096, E820_RESERVED); + e820_add(0xfffbc000, 4*4096, E820_RESERVED); }
// Check for memory over 4Gig in cmos @@ -338,7 +338,7 @@ qemu_cfg_e820(void) | ((u32)rtc_read(CMOS_MEM_HIGHMEM_MID) << 24) | ((u64)rtc_read(CMOS_MEM_HIGHMEM_HIGH) << 32)); RamSizeOver4G = high; - add_e820(0x100000000ull, high, E820_RAM); + e820_add(0x100000000ull, high, E820_RAM); dprintf(1, "RamSizeOver4G: 0x%016llx [cmos]\n", RamSizeOver4G); }
diff --git a/src/fw/pciinit.c b/src/fw/pciinit.c index 3ad84ba..7b8aab7 100644 --- a/src/fw/pciinit.c +++ b/src/fw/pciinit.c @@ -9,13 +9,13 @@ #include "config.h" // CONFIG_* #include "dev-q35.h" // Q35_HOST_BRIDGE_PCIEXBAR_ADDR #include "dev-piix.h" // PIIX_* +#include "e820map.h" // e820_add #include "hw/ata.h" // PORT_ATA1_CMD_BASE #include "hw/pci.h" // pci_config_readl #include "hw/pci_ids.h" // PCI_VENDOR_ID_INTEL #include "hw/pci_regs.h" // PCI_COMMAND #include "list.h" // struct hlist_node #include "malloc.h" // free -#include "memmap.h" // add_e820 #include "output.h" // dprintf #include "paravirt.h" // RamSize #include "romfile.h" // romfile_loadint @@ -186,7 +186,7 @@ static void mch_isa_bridge_setup(struct pci_device *dev, void *arg) /* set root complex register block BAR */ pci_config_writel(bdf, ICH9_LPC_RCBA, ICH9_LPC_RCBA_ADDR | ICH9_LPC_RCBA_EN); - add_e820(ICH9_LPC_RCBA_ADDR, 16*1024, E820_RESERVED); + e820_add(ICH9_LPC_RCBA_ADDR, 16*1024, E820_RESERVED);
acpi_pm1a_cnt = acpi_pm_base + 0x04; pmtimer_setup(acpi_pm_base + 0x08); @@ -400,7 +400,7 @@ static void mch_mem_addr_setup(struct pci_device *dev, void *arg) pci_config_writel(bdf, Q35_HOST_BRIDGE_PCIEXBAR, 0); pci_config_writel(bdf, Q35_HOST_BRIDGE_PCIEXBAR + 4, upper); pci_config_writel(bdf, Q35_HOST_BRIDGE_PCIEXBAR, lower); - add_e820(addr, size, E820_RESERVED); + e820_add(addr, size, E820_RESERVED);
/* setup pci i/o window (above mmconfig) */ pcimem_start = addr + size; diff --git a/src/fw/xen.c b/src/fw/xen.c index dd8e8af..3f19ef2 100644 --- a/src/fw/xen.c +++ b/src/fw/xen.c @@ -4,16 +4,17 @@ // // This file may be distributed under the terms of the GNU LGPLv3 license.
-#include "config.h" +#include "config.h" // CONFIG_XEN +#include "e820map.h" // e820_add #include "hw/serialio.h" // DebugOutputPort #include "malloc.h" // memalign_high -#include "memmap.h" // add_e820 +#include "memmap.h" // PAGE_SIZE #include "output.h" // dprintf #include "paravirt.h" // PlatformRunningOn #include "string.h" // memcpy #include "util.h" // copy_acpi_rsdp #include "x86.h" // cpuid -#include "xen.h" +#include "xen.h" // xen_extraversion_t
#define INFO_PHYSICAL_ADDRESS 0x00001000
@@ -142,6 +143,6 @@ void xen_ramsize_preinit(void)
for (i = 0; i < info->e820_nr; i++) { struct e820entry *e = &e820[i]; - add_e820(e->start, e->size, e->type); + e820_add(e->start, e->size, e->type); } } diff --git a/src/hw/ramdisk.c b/src/hw/ramdisk.c index 4cdf95f..adec1d1 100644 --- a/src/hw/ramdisk.c +++ b/src/hw/ramdisk.c @@ -7,8 +7,9 @@ #include "biosvar.h" // GET_GLOBALFLAT #include "block.h" // struct drive_s #include "bregs.h" // struct bregs +#include "e820map.h" // e820_add #include "malloc.h" // memalign_tmphigh -#include "memmap.h" // add_e820 +#include "memmap.h" // PAGE_SIZE #include "output.h" // dprintf #include "romfile.h" // romfile_findprefix #include "stacks.h" // call16_int @@ -41,7 +42,7 @@ ramdisk_setup(void) warn_noalloc(); return; } - add_e820((u32)pos, size, E820_RESERVED); + e820_add((u32)pos, size, E820_RESERVED);
// Copy image into ram. int ret = file->copy(file, pos, size); diff --git a/src/malloc.c b/src/malloc.c index 5c05a8a..efd09b3 100644 --- a/src/malloc.c +++ b/src/malloc.c @@ -6,9 +6,10 @@
#include "biosvar.h" // GET_BDA #include "config.h" // BUILD_BIOS_ADDR +#include "e820map.h" // struct e820entry #include "list.h" // hlist_node #include "malloc.h" // _malloc -#include "memmap.h" // struct e820entry +#include "memmap.h" // PAGE_SIZE #include "output.h" // dprintf #include "stacks.h" // wait_preempt #include "std/optionrom.h" // OPTION_ROM_ALIGN @@ -399,7 +400,7 @@ malloc_preinit(void) e820_remove(BUILD_LOWRAM_END, BUILD_BIOS_ADDR-BUILD_LOWRAM_END);
// Mark known areas as reserved. - add_e820(BUILD_BIOS_ADDR, BUILD_BIOS_SIZE, E820_RESERVED); + e820_add(BUILD_BIOS_ADDR, BUILD_BIOS_SIZE, E820_RESERVED);
// Populate temp high ram u32 highram = 0; @@ -427,7 +428,7 @@ malloc_preinit(void) if (highram) { addSpace(&ZoneHigh, (void*)highram , (void*)highram + BUILD_MAX_HIGHTABLE); - add_e820(highram, BUILD_MAX_HIGHTABLE, E820_RESERVED); + e820_add(highram, BUILD_MAX_HIGHTABLE, E820_RESERVED); } }
@@ -521,7 +522,7 @@ malloc_prepboot(void)
// Reserve more low-mem if needed. u32 endlow = GET_BDA(mem_size_kb)*1024; - add_e820(endlow, BUILD_LOWRAM_END-endlow, E820_RESERVED); + e820_add(endlow, BUILD_LOWRAM_END-endlow, E820_RESERVED);
// Clear unused f-seg ram. struct allocinfo_s *info = findLast(&ZoneFSeg); @@ -533,7 +534,7 @@ malloc_prepboot(void) info = findLast(&ZoneHigh); if (info) { u32 giveback = ALIGN_DOWN(info->allocend - info->dataend, PAGE_SIZE); - add_e820((u32)info->dataend, giveback, E820_RAM); + e820_add((u32)info->dataend, giveback, E820_RAM); dprintf(1, "Returned %d bytes of ZoneHigh\n", giveback); }
diff --git a/src/memmap.h b/src/memmap.h index e7d94ee..c439982 100644 --- a/src/memmap.h +++ b/src/memmap.h @@ -1,29 +1,7 @@ -#ifndef __E820MAP_H -#define __E820MAP_H - -#include "types.h" // u64 - -#define E820_RAM 1 -#define E820_RESERVED 2 -#define E820_ACPI 3 -#define E820_NVS 4 -#define E820_UNUSABLE 5 - -struct e820entry { - u64 start; - u64 size; - u32 type; -}; - -void add_e820(u64 start, u64 size, u32 type); -void e820_remove(u64 start, u64 size); -void memmap_prepboot(void); +#ifndef __MEMMAP_H +#define __MEMMAP_H
// A typical OS page size #define PAGE_SIZE 4096
-// e820 map storage -extern struct e820entry e820_list[]; -extern int e820_count; - -#endif // e820map.h +#endif // memmap.h diff --git a/src/post.c b/src/post.c index e19b06c..89e6eff 100644 --- a/src/post.c +++ b/src/post.c @@ -8,6 +8,7 @@ #include "biosvar.h" // SET_BDA #include "bregs.h" // struct bregs #include "config.h" // CONFIG_* +#include "e820map.h" // e820_add #include "fw/paravirt.h" // qemu_cfg_preinit #include "fw/xen.h" // xen_preinit #include "hw/ahci.h" // ahci_setup @@ -24,7 +25,6 @@ #include "hw/virtio-blk.h" // virtio_blk_setup #include "hw/virtio-scsi.h" // virtio_scsi_setup #include "malloc.h" // malloc_init -#include "memmap.h" // add_e820 #include "output.h" // dprintf #include "string.h" // memset #include "util.h" // kbd_init @@ -102,7 +102,7 @@ bda_init(void) memset(ebda, 0, sizeof(*ebda)); ebda->size = esize;
- add_e820((u32)ebda, BUILD_LOWRAM_END-(u32)ebda, E820_RESERVED); + e820_add((u32)ebda, BUILD_LOWRAM_END-(u32)ebda, E820_RESERVED);
// Init extra stack StackPos = (void*)(&ExtraStack[BUILD_EXTRA_STACK_SIZE] - zonelow_base); @@ -191,7 +191,7 @@ prepareboot(void) cdrom_prepboot(); pmm_prepboot(); malloc_prepboot(); - memmap_prepboot(); + e820_prepboot();
HaveRunPost = 2;
diff --git a/src/system.c b/src/system.c index 60a6fce..438e60e 100644 --- a/src/system.c +++ b/src/system.c @@ -7,9 +7,9 @@
#include "biosvar.h" // GET_GLOBAL #include "bregs.h" // struct bregs +#include "e820map.h" // E820_RAM #include "hw/pic.h" // pic_reset #include "malloc.h" // LegacyRamSize -#include "memmap.h" // E820_RAM #include "output.h" // debug_enter #include "string.h" // memcpy_far #include "util.h" // handle_1553
Signed-off-by: Kevin O'Connor kevin@koconnor.net --- src/e820map.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/e820map.c b/src/e820map.c index 901ccdf..39445cf 100644 --- a/src/e820map.c +++ b/src/e820map.c @@ -79,7 +79,7 @@ dump_map(void) void e820_add(u64 start, u64 size, u32 type) { - dprintf(8, "Add to e820 map: %08x %08x %d\n", (u32)start, (u32)size, type); + dprintf(8, "Add to e820 map: %08llx %08llx %d\n", start, size, type);
if (! size) // Huh? Nothing to do.
Don't do phys_to_virt(virt_to_phys(vaddr)) for page alignment - page alignment can be determined directly from the virtual address.
Use the ALIGN() macro to make the code more readable.
Signed-off-by: Kevin O'Connor kevin@koconnor.net --- src/hw/virtio-ring.h | 29 +++++++++-------------------- 1 file changed, 9 insertions(+), 20 deletions(-)
diff --git a/src/hw/virtio-ring.h b/src/hw/virtio-ring.h index 7df9004..e8f3b82 100644 --- a/src/hw/virtio-ring.h +++ b/src/hw/virtio-ring.h @@ -5,10 +5,8 @@ #include "memmap.h" // PAGE_SIZE
#define PAGE_SHIFT 12 -#define PAGE_MASK (PAGE_SIZE-1)
#define virt_to_phys(v) (unsigned long)(v) -#define phys_to_virt(p) (void*)(p) /* Compiler barrier is enough as an x86 CPU does not reorder reads or writes */ #define smp_rmb() barrier() #define smp_wmb() barrier() @@ -73,10 +71,9 @@ struct vring { };
#define vring_size(num) \ - (((((sizeof(struct vring_desc) * num) + \ - (sizeof(struct vring_avail) + sizeof(u16) * num)) \ - + PAGE_MASK) & ~PAGE_MASK) + \ - (sizeof(struct vring_used) + sizeof(struct vring_used_elem) * num)) + (ALIGN(sizeof(struct vring_desc) * num + sizeof(struct vring_avail) \ + + sizeof(u16) * num, PAGE_SIZE) \ + + sizeof(struct vring_used) + sizeof(struct vring_used_elem) * num)
typedef unsigned char virtio_queue_t[vring_size(MAX_QUEUE_NUM)];
@@ -96,33 +93,25 @@ struct vring_list { unsigned int length; };
-static inline void vring_init(struct vring *vr, - unsigned int num, unsigned char *queue) +static inline void +vring_init(struct vring *vr, unsigned int num, unsigned char *queue) { - unsigned int i; - unsigned long pa; - ASSERT32FLAT(); vr->num = num;
/* physical address of desc must be page aligned */ - - pa = virt_to_phys(queue); - pa = (pa + PAGE_MASK) & ~PAGE_MASK; - vr->desc = phys_to_virt(pa); + vr->desc = (void*)ALIGN((u32)queue, PAGE_SIZE);
vr->avail = (struct vring_avail *)&vr->desc[num]; /* disable interrupts */ vr->avail->flags |= VRING_AVAIL_F_NO_INTERRUPT;
/* physical address of used must be page aligned */ + vr->used = (void*)ALIGN((u32)&vr->avail->ring[num], PAGE_SIZE);
- pa = virt_to_phys(&vr->avail->ring[num]); - pa = (pa + PAGE_MASK) & ~PAGE_MASK; - vr->used = phys_to_virt(pa); - + int i; for (i = 0; i < num - 1; i++) - vr->desc[i].next = i + 1; + vr->desc[i].next = i + 1; vr->desc[i].next = 0; }
Move PAGE_SHIFT / virt_to_phys() to memmap.h and smp_[rw]mb() to x86.h.
Signed-off-by: Kevin O'Connor kevin@koconnor.net --- src/hw/pvscsi.c | 2 +- src/hw/virtio-ring.h | 7 ------- src/memmap.h | 7 +++++++ src/x86.h | 8 ++++++++ 4 files changed, 16 insertions(+), 8 deletions(-)
diff --git a/src/hw/pvscsi.c b/src/hw/pvscsi.c index a462522..fa20efe 100644 --- a/src/hw/pvscsi.c +++ b/src/hw/pvscsi.c @@ -11,6 +11,7 @@ #include "blockcmd.h" // scsi_drive_setup #include "config.h" // CONFIG_* #include "malloc.h" // free +#include "memmap.h" // PAGE_SHIFT, virt_to_phys #include "output.h" // dprintf #include "pci.h" // foreachpci #include "pci_ids.h" // PCI_DEVICE_ID_VMWARE_PVSCSI @@ -19,7 +20,6 @@ #include "std/disk.h" // DISK_RET_SUCCESS #include "string.h" // memset #include "util.h" // usleep -#include "virtio-ring.h" // PAGE_SHIFT, virt_to_phys #include "x86.h" // writel
#define MASK(n) ((1 << (n)) - 1) diff --git a/src/hw/virtio-ring.h b/src/hw/virtio-ring.h index e8f3b82..7665fd5 100644 --- a/src/hw/virtio-ring.h +++ b/src/hw/virtio-ring.h @@ -4,13 +4,6 @@ #include "types.h" // u64 #include "memmap.h" // PAGE_SIZE
-#define PAGE_SHIFT 12 - -#define virt_to_phys(v) (unsigned long)(v) -/* Compiler barrier is enough as an x86 CPU does not reorder reads or writes */ -#define smp_rmb() barrier() -#define smp_wmb() barrier() - /* Status byte for guest to report progress, and synchronize features. */ /* We have seen device and processed generic fields (VIRTIO_CONFIG_F_VIRTIO) */ #define VIRTIO_CONFIG_S_ACKNOWLEDGE 1 diff --git a/src/memmap.h b/src/memmap.h index c439982..9a59024 100644 --- a/src/memmap.h +++ b/src/memmap.h @@ -1,7 +1,14 @@ #ifndef __MEMMAP_H #define __MEMMAP_H
+#include "types.h" // u32 + // A typical OS page size #define PAGE_SIZE 4096 +#define PAGE_SHIFT 12 + +static inline u32 virt_to_phys(void *v) { + return (u32)v; +}
#endif // memmap.h diff --git a/src/x86.h b/src/x86.h index 19d404f..53378e9 100644 --- a/src/x86.h +++ b/src/x86.h @@ -190,6 +190,14 @@ static inline void outsl(u16 port, u32 *data, u32 count) { : "+c"(count), "+S"(data) : "d"(port) : "memory"); }
+/* Compiler barrier is enough as an x86 CPU does not reorder reads or writes */ +static inline void smp_rmb(void) { + barrier(); +} +static inline void smp_wmb(void) { + barrier(); +} + static inline void writel(void *addr, u32 val) { barrier(); *(volatile u32 *)addr = val;
Use the "alloc_" prefix for all the low-level allocation functions and avoid camelCase naming.
Signed-off-by: Kevin O'Connor kevin@koconnor.net --- src/malloc.c | 102 +++++++++++++++++++++++++++++------------------------------ 1 file changed, 51 insertions(+), 51 deletions(-)
diff --git a/src/malloc.c b/src/malloc.c index efd09b3..db451ce 100644 --- a/src/malloc.c +++ b/src/malloc.c @@ -48,7 +48,7 @@ static struct zone_s *Zones[] VARVERIFY32INIT = {
// Find and reserve space from a given zone static void * -allocSpace(struct zone_s *zone, u32 size, u32 align, struct allocinfo_s *fill) +alloc_new(struct zone_s *zone, u32 size, u32 align, struct allocinfo_s *fill) { struct allocinfo_s *info; hlist_for_each_entry(info, &zone->head, node) { @@ -71,20 +71,9 @@ allocSpace(struct zone_s *zone, u32 size, u32 align, struct allocinfo_s *fill) return NULL; }
-// Release space allocated with allocSpace() -static void -freeSpace(struct allocinfo_s *info) -{ - struct allocinfo_s *next = container_of_or_null( - info->node.next, struct allocinfo_s, node); - if (next && next->allocend == info->data) - next->allocend = info->allocend; - hlist_del(&info->node); -} - // Add new memory to a zone static void -addSpace(struct zone_s *zone, void *start, void *end) +alloc_add(struct zone_s *zone, void *start, void *end) { // Find position to add space struct allocinfo_s *info; @@ -101,11 +90,11 @@ addSpace(struct zone_s *zone, void *start, void *end) hlist_add(&tempdetail.datainfo.node, pprev);
// Allocate final allocation info. - struct allocdetail_s *detail = allocSpace( + struct allocdetail_s *detail = alloc_new( &ZoneTmpHigh, sizeof(*detail), MALLOC_MIN_ALIGN, NULL); if (!detail) { - detail = allocSpace(&ZoneTmpLow, sizeof(*detail) - , MALLOC_MIN_ALIGN, NULL); + detail = alloc_new(&ZoneTmpLow, sizeof(*detail) + , MALLOC_MIN_ALIGN, NULL); if (!detail) { hlist_del(&tempdetail.datainfo.node); warn_noalloc(); @@ -121,9 +110,20 @@ addSpace(struct zone_s *zone, void *start, void *end) hlist_add(&detail->datainfo.node, pprev); }
-// Search all zones for an allocation obtained from allocSpace() +// Release space allocated with alloc_new() +static void +alloc_free(struct allocinfo_s *info) +{ + struct allocinfo_s *next = container_of_or_null( + info->node.next, struct allocinfo_s, node); + if (next && next->allocend == info->data) + next->allocend = info->allocend; + hlist_del(&info->node); +} + +// Search all zones for an allocation obtained from alloc_new() static struct allocinfo_s * -findAlloc(void *data) +alloc_find(void *data) { int i; for (i=0; i<ARRAY_SIZE(Zones); i++) { @@ -136,9 +136,9 @@ findAlloc(void *data) return NULL; }
-// Return the last sentinal node of a zone +// Find the lowest memory range added by alloc_add() static struct allocinfo_s * -findLast(struct zone_s *zone) +alloc_find_lowest(struct zone_s *zone) { struct allocinfo_s *info, *last = NULL; hlist_for_each_entry(info, &zone->head, node) { @@ -177,12 +177,12 @@ zonelow_expand(u32 size, u32 align, struct allocinfo_s *fill) { // Make sure to not move ebda while an optionrom is running. if (unlikely(wait_preempt())) { - void *data = allocSpace(&ZoneLow, size, align, fill); + void *data = alloc_new(&ZoneLow, size, align, fill); if (data) return data; }
- struct allocinfo_s *info = findLast(&ZoneLow); + struct allocinfo_s *info = alloc_find_lowest(&ZoneLow); if (!info) return NULL; u32 oldpos = (u32)info->allocend; @@ -190,7 +190,7 @@ zonelow_expand(u32 size, u32 align, struct allocinfo_s *fill) u32 bottom = (u32)info->dataend; if (newpos >= bottom && newpos <= oldpos) // Space already present. - return allocSpace(&ZoneLow, size, align, fill); + return alloc_new(&ZoneLow, size, align, fill); u16 ebda_seg = get_ebda_seg(); u32 ebda_pos = (u32)MAKE_FLATPTR(ebda_seg, 0); u8 ebda_size = GET_EBDA(ebda_seg, size); @@ -214,9 +214,9 @@ zonelow_expand(u32 size, u32 align, struct allocinfo_s *fill) info->data = (void*)newbottom; info->dataend = (void*)newbottom; } else - addSpace(&ZoneLow, (void*)newbottom, (void*)ebda_end); + alloc_add(&ZoneLow, (void*)newbottom, (void*)ebda_end);
- return allocSpace(&ZoneLow, size, align, fill); + return alloc_new(&ZoneLow, size, align, fill); }
@@ -233,22 +233,22 @@ _malloc(struct zone_s *zone, u32 size, u32 align) return NULL;
// Find and reserve space for bookkeeping. - struct allocdetail_s *detail = allocSpace( + struct allocdetail_s *detail = alloc_new( &ZoneTmpHigh, sizeof(*detail), MALLOC_MIN_ALIGN, NULL); if (!detail) { - detail = allocSpace(&ZoneTmpLow, sizeof(*detail) - , MALLOC_MIN_ALIGN, NULL); + detail = alloc_new(&ZoneTmpLow, sizeof(*detail) + , MALLOC_MIN_ALIGN, NULL); if (!detail) return NULL; } detail->handle = MALLOC_DEFAULT_HANDLE;
// Find and reserve space for main allocation - void *data = allocSpace(zone, size, align, &detail->datainfo); + void *data = alloc_new(zone, size, align, &detail->datainfo); if (!CONFIG_MALLOC_UPPERMEMORY && !data && zone == &ZoneLow) data = zonelow_expand(size, align, &detail->datainfo); if (!data) { - freeSpace(&detail->detailinfo); + alloc_free(&detail->detailinfo); return NULL; }
@@ -263,14 +263,14 @@ int _free(void *data) { ASSERT32FLAT(); - struct allocinfo_s *info = findAlloc(data); + struct allocinfo_s *info = alloc_find(data); if (!info || data == (void*)info || data == info->dataend) return -1; struct allocdetail_s *detail = container_of( info, struct allocdetail_s, datainfo); dprintf(8, "_free %p (detail=%p)\n", data, detail); - freeSpace(info); - freeSpace(&detail->detailinfo); + alloc_free(info); + alloc_free(&detail->detailinfo); return 0; }
@@ -302,7 +302,7 @@ void malloc_sethandle(void *data, u32 handle) { ASSERT32FLAT(); - struct allocinfo_s *info = findAlloc(data); + struct allocinfo_s *info = alloc_find(data); if (!info || data == (void*)info || data == info->dataend) return; struct allocdetail_s *detail = container_of( @@ -420,14 +420,14 @@ malloc_preinit(void) e = newe; } } - addSpace(&ZoneTmpHigh, (void*)s, (void*)e); + alloc_add(&ZoneTmpHigh, (void*)s, (void*)e); }
// Populate regions - addSpace(&ZoneTmpLow, (void*)BUILD_STACK_ADDR, (void*)BUILD_EBDA_MINIMUM); + alloc_add(&ZoneTmpLow, (void*)BUILD_STACK_ADDR, (void*)BUILD_EBDA_MINIMUM); if (highram) { - addSpace(&ZoneHigh, (void*)highram - , (void*)highram + BUILD_MAX_HIGHTABLE); + alloc_add(&ZoneHigh, (void*)highram + , (void*)highram + BUILD_MAX_HIGHTABLE); e820_add(highram, BUILD_MAX_HIGHTABLE, E820_RESERVED); } } @@ -438,13 +438,13 @@ csm_malloc_preinit(u32 low_pmm, u32 low_pmm_size, u32 hi_pmm, u32 hi_pmm_size) ASSERT32FLAT();
if (hi_pmm_size > BUILD_MAX_HIGHTABLE) { - void *hi_pmm_end = (void *)hi_pmm + hi_pmm_size; - addSpace(&ZoneTmpHigh, (void *)hi_pmm, hi_pmm_end - BUILD_MAX_HIGHTABLE); - addSpace(&ZoneHigh, hi_pmm_end - BUILD_MAX_HIGHTABLE, hi_pmm_end); + void *hi_pmm_end = (void*)hi_pmm + hi_pmm_size; + alloc_add(&ZoneTmpHigh, (void*)hi_pmm, hi_pmm_end - BUILD_MAX_HIGHTABLE); + alloc_add(&ZoneHigh, hi_pmm_end - BUILD_MAX_HIGHTABLE, hi_pmm_end); } else { - addSpace(&ZoneTmpHigh, (void *)hi_pmm, (void *)hi_pmm + hi_pmm_size); + alloc_add(&ZoneTmpHigh, (void*)hi_pmm, (void*)hi_pmm + hi_pmm_size); } - addSpace(&ZoneTmpLow, (void *)low_pmm, (void *)low_pmm + low_pmm_size); + alloc_add(&ZoneTmpLow, (void*)low_pmm, (void*)low_pmm + low_pmm_size); }
u32 LegacyRamSize VARFSEG; @@ -488,18 +488,18 @@ malloc_init(void) extern u8 varlow_start[], varlow_end[], final_varlow_start[]; memmove(final_varlow_start, varlow_start, varlow_end - varlow_start); if (CONFIG_MALLOC_UPPERMEMORY) { - addSpace(&ZoneLow, zonelow_base + OPROM_HEADER_RESERVE - , final_varlow_start); - RomBase = findLast(&ZoneLow); + alloc_add(&ZoneLow, zonelow_base + OPROM_HEADER_RESERVE + , final_varlow_start); + RomBase = alloc_find_lowest(&ZoneLow); } else { - addSpace(&ZoneLow, (void*)ALIGN_DOWN((u32)final_varlow_start, 1024) - , final_varlow_start); + alloc_add(&ZoneLow, (void*)ALIGN_DOWN((u32)final_varlow_start, 1024) + , final_varlow_start); }
// Add space available in f-segment to ZoneFSeg extern u8 zonefseg_start[], zonefseg_end[]; memset(zonefseg_start, 0, zonefseg_end - zonefseg_start); - addSpace(&ZoneFSeg, zonefseg_start, zonefseg_end); + alloc_add(&ZoneFSeg, zonefseg_start, zonefseg_end);
calcRamSize(); } @@ -525,13 +525,13 @@ malloc_prepboot(void) e820_add(endlow, BUILD_LOWRAM_END-endlow, E820_RESERVED);
// Clear unused f-seg ram. - struct allocinfo_s *info = findLast(&ZoneFSeg); + struct allocinfo_s *info = alloc_find_lowest(&ZoneFSeg); memset(info->dataend, 0, info->allocend - info->dataend); dprintf(1, "Space available for UMB: %x-%x, %x-%x\n" , RomEnd, base, (u32)info->dataend, (u32)info->allocend);
// Give back unused high ram. - info = findLast(&ZoneHigh); + info = alloc_find_lowest(&ZoneHigh); if (info) { u32 giveback = ALIGN_DOWN(info->allocend - info->dataend, PAGE_SIZE); e820_add((u32)info->dataend, giveback, E820_RAM);
Introduce helper for finding temp space to hold an "allocation detail struct" and use it in both alloc_add() and _malloc().
Signed-off-by: Kevin O'Connor kevin@koconnor.net --- src/list.h | 10 +++++++++ src/malloc.c | 72 +++++++++++++++++++++++++++++++----------------------------- 2 files changed, 47 insertions(+), 35 deletions(-)
diff --git a/src/list.h b/src/list.h index de656b9..94512e3 100644 --- a/src/list.h +++ b/src/list.h @@ -61,6 +61,16 @@ hlist_add_after(struct hlist_node *n, struct hlist_node *prev) hlist_add(n, &prev->next); }
+static inline void +hlist_replace(struct hlist_node *old, struct hlist_node *new) +{ + new->next = old->next; + if (new->next) + new->next->pprev = &new->next; + new->pprev = old->pprev; + *new->pprev = new; +} + #define hlist_for_each_entry(pos, head, member) \ for (pos = container_of((head)->first, typeof(*pos), member) \ ; pos != container_of(NULL, typeof(*pos), member) \ diff --git a/src/malloc.c b/src/malloc.c index db451ce..c41a0cb 100644 --- a/src/malloc.c +++ b/src/malloc.c @@ -57,8 +57,6 @@ alloc_new(struct zone_s *zone, u32 size, u32 align, struct allocinfo_s *fill) void *newallocend = (void*)ALIGN_DOWN((u32)allocend - size, align); if (newallocend >= dataend && newallocend <= allocend) { // Found space - now reserve it. - if (!fill) - fill = newallocend; fill->data = newallocend; fill->dataend = newallocend + size; fill->allocend = allocend; @@ -71,6 +69,28 @@ alloc_new(struct zone_s *zone, u32 size, u32 align, struct allocinfo_s *fill) return NULL; }
+// Reserve space for a 'struct allocdetail_s' and fill +static struct allocdetail_s * +alloc_new_detail(struct allocdetail_s *temp) +{ + struct allocdetail_s *detail = alloc_new( + &ZoneTmpHigh, sizeof(*detail), MALLOC_MIN_ALIGN, &temp->detailinfo); + if (!detail) { + detail = alloc_new(&ZoneTmpLow, sizeof(*detail) + , MALLOC_MIN_ALIGN, &temp->detailinfo); + if (!detail) { + warn_noalloc(); + return NULL; + } + } + + // Fill final 'detail' allocation from data in 'temp' + memcpy(detail, temp, sizeof(*detail)); + hlist_replace(&temp->detailinfo.node, &detail->detailinfo.node); + hlist_replace(&temp->datainfo.node, &detail->datainfo.node); + return detail; +} + // Add new memory to a zone static void alloc_add(struct zone_s *zone, void *start, void *end) @@ -85,29 +105,15 @@ alloc_add(struct zone_s *zone, void *start, void *end)
// Add space using temporary allocation info. struct allocdetail_s tempdetail; + tempdetail.handle = MALLOC_DEFAULT_HANDLE; tempdetail.datainfo.data = tempdetail.datainfo.dataend = start; tempdetail.datainfo.allocend = end; hlist_add(&tempdetail.datainfo.node, pprev);
// Allocate final allocation info. - struct allocdetail_s *detail = alloc_new( - &ZoneTmpHigh, sizeof(*detail), MALLOC_MIN_ALIGN, NULL); - if (!detail) { - detail = alloc_new(&ZoneTmpLow, sizeof(*detail) - , MALLOC_MIN_ALIGN, NULL); - if (!detail) { - hlist_del(&tempdetail.datainfo.node); - warn_noalloc(); - return; - } - } - - // Replace temp alloc space with final alloc space - pprev = tempdetail.datainfo.node.pprev; - hlist_del(&tempdetail.datainfo.node); - memcpy(&detail->datainfo, &tempdetail.datainfo, sizeof(detail->datainfo)); - detail->handle = MALLOC_DEFAULT_HANDLE; - hlist_add(&detail->datainfo.node, pprev); + struct allocdetail_s *detail = alloc_new_detail(&tempdetail); + if (!detail) + hlist_del(&tempdetail.datainfo.node); }
// Release space allocated with alloc_new() @@ -232,23 +238,19 @@ _malloc(struct zone_s *zone, u32 size, u32 align) if (!size) return NULL;
- // Find and reserve space for bookkeeping. - struct allocdetail_s *detail = alloc_new( - &ZoneTmpHigh, sizeof(*detail), MALLOC_MIN_ALIGN, NULL); - if (!detail) { - detail = alloc_new(&ZoneTmpLow, sizeof(*detail) - , MALLOC_MIN_ALIGN, NULL); - if (!detail) - return NULL; - } - detail->handle = MALLOC_DEFAULT_HANDLE; - // Find and reserve space for main allocation - void *data = alloc_new(zone, size, align, &detail->datainfo); + struct allocdetail_s tempdetail; + tempdetail.handle = MALLOC_DEFAULT_HANDLE; + void *data = alloc_new(zone, size, align, &tempdetail.datainfo); if (!CONFIG_MALLOC_UPPERMEMORY && !data && zone == &ZoneLow) - data = zonelow_expand(size, align, &detail->datainfo); - if (!data) { - alloc_free(&detail->detailinfo); + data = zonelow_expand(size, align, &tempdetail.datainfo); + if (!data) + return NULL; + + // Find and reserve space for bookkeeping. + struct allocdetail_s *detail = alloc_new_detail(&tempdetail); + if (!detail) { + alloc_free(&tempdetail.datainfo); return NULL; }
Signed-off-by: Kevin O'Connor kevin@koconnor.net --- src/malloc.c | 10 ++++++++++ src/malloc.h | 4 +--- 2 files changed, 11 insertions(+), 3 deletions(-)
diff --git a/src/malloc.c b/src/malloc.c index c41a0cb..f5c2ed4 100644 --- a/src/malloc.c +++ b/src/malloc.c @@ -276,6 +276,16 @@ _free(void *data) return 0; }
+void +free(void *data) +{ + if (!data) + return; + int ret = _free(data); + if (ret) + warn_internalerror(); +} + // Find the amount of free space in a given zone. u32 malloc_getspace(struct zone_s *zone) diff --git a/src/malloc.h b/src/malloc.h index 2bcb5bf..b765bc4 100644 --- a/src/malloc.h +++ b/src/malloc.h @@ -17,6 +17,7 @@ void malloc_init(void); void malloc_prepboot(void); void *_malloc(struct zone_s *zone, u32 size, u32 align); int _free(void *data); +void free(void *data); u32 malloc_getspace(struct zone_s *zone); void malloc_sethandle(void *data, u32 handle); void *malloc_findhandle(u32 handle); @@ -64,8 +65,5 @@ static inline void *memalign_tmp(u32 align, u32 size) { return ret; return memalign_tmplow(align, size); } -static inline void free(void *data) { - _free(data); -}
#endif // malloc.h
Consistently use 'u32' for physical addresses and pointers for virtual addresses in the malloc code. Introduce and use memremap() where a physical address needs to be converted to a virtual address. Use virt_to_phys() for the inverse.
Signed-off-by: Kevin O'Connor kevin@koconnor.net --- src/malloc.c | 164 +++++++++++++++++++++++++++++++---------------------------- src/malloc.h | 7 +-- src/memmap.h | 3 ++ src/pmm.c | 16 +++--- 4 files changed, 101 insertions(+), 89 deletions(-)
diff --git a/src/malloc.c b/src/malloc.c index f5c2ed4..106c7ea 100644 --- a/src/malloc.c +++ b/src/malloc.c @@ -18,7 +18,7 @@ // Information on a reserved area. struct allocinfo_s { struct hlist_node node; - void *data, *dataend, *allocend; + u32 range_start, range_end, alloc_size; };
// Information on a tracked memory allocation. @@ -47,42 +47,43 @@ static struct zone_s *Zones[] VARVERIFY32INIT = { ****************************************************************/
// Find and reserve space from a given zone -static void * +static u32 alloc_new(struct zone_s *zone, u32 size, u32 align, struct allocinfo_s *fill) { struct allocinfo_s *info; hlist_for_each_entry(info, &zone->head, node) { - void *dataend = info->dataend; - void *allocend = info->allocend; - void *newallocend = (void*)ALIGN_DOWN((u32)allocend - size, align); - if (newallocend >= dataend && newallocend <= allocend) { + u32 alloc_end = info->range_start + info->alloc_size; + u32 range_end = info->range_end; + u32 new_range_end = ALIGN_DOWN(range_end - size, align); + if (new_range_end >= alloc_end && new_range_end <= range_end) { // Found space - now reserve it. - fill->data = newallocend; - fill->dataend = newallocend + size; - fill->allocend = allocend; + fill->range_start = new_range_end; + fill->range_end = range_end; + fill->alloc_size = size;
- info->allocend = newallocend; + info->range_end = new_range_end; hlist_add_before(&fill->node, &info->node); - return newallocend; + return new_range_end; } } - return NULL; + return 0; }
// Reserve space for a 'struct allocdetail_s' and fill static struct allocdetail_s * alloc_new_detail(struct allocdetail_s *temp) { - struct allocdetail_s *detail = alloc_new( - &ZoneTmpHigh, sizeof(*detail), MALLOC_MIN_ALIGN, &temp->detailinfo); - if (!detail) { - detail = alloc_new(&ZoneTmpLow, sizeof(*detail) - , MALLOC_MIN_ALIGN, &temp->detailinfo); - if (!detail) { + u32 detail_addr = alloc_new(&ZoneTmpHigh, sizeof(struct allocdetail_s) + , MALLOC_MIN_ALIGN, &temp->detailinfo); + if (!detail_addr) { + detail_addr = alloc_new(&ZoneTmpLow, sizeof(struct allocdetail_s) + , MALLOC_MIN_ALIGN, &temp->detailinfo); + if (!detail_addr) { warn_noalloc(); return NULL; } } + struct allocdetail_s *detail = memremap(detail_addr, sizeof(*detail));
// Fill final 'detail' allocation from data in 'temp' memcpy(detail, temp, sizeof(*detail)); @@ -93,21 +94,22 @@ alloc_new_detail(struct allocdetail_s *temp)
// Add new memory to a zone static void -alloc_add(struct zone_s *zone, void *start, void *end) +alloc_add(struct zone_s *zone, u32 start, u32 end) { // Find position to add space struct allocinfo_s *info; struct hlist_node **pprev; hlist_for_each_entry_pprev(info, pprev, &zone->head, node) { - if (info->data < start) + if (info->range_start < start) break; }
// Add space using temporary allocation info. struct allocdetail_s tempdetail; tempdetail.handle = MALLOC_DEFAULT_HANDLE; - tempdetail.datainfo.data = tempdetail.datainfo.dataend = start; - tempdetail.datainfo.allocend = end; + tempdetail.datainfo.range_start = start; + tempdetail.datainfo.range_end = end; + tempdetail.datainfo.alloc_size = 0; hlist_add(&tempdetail.datainfo.node, pprev);
// Allocate final allocation info. @@ -122,20 +124,20 @@ alloc_free(struct allocinfo_s *info) { struct allocinfo_s *next = container_of_or_null( info->node.next, struct allocinfo_s, node); - if (next && next->allocend == info->data) - next->allocend = info->allocend; + if (next && next->range_end == info->range_start) + next->range_end = info->range_end; hlist_del(&info->node); }
// Search all zones for an allocation obtained from alloc_new() static struct allocinfo_s * -alloc_find(void *data) +alloc_find(u32 data) { int i; for (i=0; i<ARRAY_SIZE(Zones); i++) { struct allocinfo_s *info; hlist_for_each_entry(info, &Zones[i]->head, node) { - if (info->data == data) + if (info->range_start == data) return info; } } @@ -178,22 +180,22 @@ relocate_ebda(u32 newebda, u32 oldebda, u8 ebda_size) }
// Support expanding the ZoneLow dynamically. -static void * +static u32 zonelow_expand(u32 size, u32 align, struct allocinfo_s *fill) { // Make sure to not move ebda while an optionrom is running. if (unlikely(wait_preempt())) { - void *data = alloc_new(&ZoneLow, size, align, fill); + u32 data = alloc_new(&ZoneLow, size, align, fill); if (data) return data; }
struct allocinfo_s *info = alloc_find_lowest(&ZoneLow); if (!info) - return NULL; - u32 oldpos = (u32)info->allocend; + return 0; + u32 oldpos = info->range_end; u32 newpos = ALIGN_DOWN(oldpos - size, align); - u32 bottom = (u32)info->dataend; + u32 bottom = info->range_start + info->alloc_size; if (newpos >= bottom && newpos <= oldpos) // Space already present. return alloc_new(&ZoneLow, size, align, fill); @@ -208,19 +210,18 @@ zonelow_expand(u32 size, u32 align, struct allocinfo_s *fill) u32 newebda = ALIGN_DOWN(newbottom - ebda_size * 1024, 1024); if (newebda < BUILD_EBDA_MINIMUM) // Not enough space. - return NULL; + return 0;
// Move ebda int ret = relocate_ebda(newebda, ebda_pos, ebda_size); if (ret) - return NULL; + return 0;
// Update zone - if (ebda_end == bottom) { - info->data = (void*)newbottom; - info->dataend = (void*)newbottom; - } else - alloc_add(&ZoneLow, (void*)newbottom, (void*)ebda_end); + if (ebda_end == bottom) + info->range_start = newbottom; + else + alloc_add(&ZoneLow, newbottom, ebda_end);
return alloc_new(&ZoneLow, size, align, fill); } @@ -230,47 +231,54 @@ zonelow_expand(u32 size, u32 align, struct allocinfo_s *fill) * tracked memory allocations ****************************************************************/
-// Allocate memory from the given zone and track it as a PMM allocation -void * __malloc -_malloc(struct zone_s *zone, u32 size, u32 align) +// Allocate physical memory from the given zone and track it as a PMM allocation +u32 +malloc_palloc(struct zone_s *zone, u32 size, u32 align) { ASSERT32FLAT(); if (!size) - return NULL; + return 0;
// Find and reserve space for main allocation struct allocdetail_s tempdetail; tempdetail.handle = MALLOC_DEFAULT_HANDLE; - void *data = alloc_new(zone, size, align, &tempdetail.datainfo); + u32 data = alloc_new(zone, size, align, &tempdetail.datainfo); if (!CONFIG_MALLOC_UPPERMEMORY && !data && zone == &ZoneLow) data = zonelow_expand(size, align, &tempdetail.datainfo); if (!data) - return NULL; + return 0;
// Find and reserve space for bookkeeping. struct allocdetail_s *detail = alloc_new_detail(&tempdetail); if (!detail) { alloc_free(&tempdetail.datainfo); - return NULL; + return 0; }
- dprintf(8, "_malloc zone=%p size=%d align=%x ret=%p (detail=%p)\n" + dprintf(8, "phys_alloc zone=%p size=%d align=%x ret=%x (detail=%p)\n" , zone, size, align, data, detail);
return data; }
-// Free a data block allocated with _malloc +// Allocate virtual memory from the given zone +void * __malloc +_malloc(struct zone_s *zone, u32 size, u32 align) +{ + return memremap(malloc_palloc(zone, size, align), size); +} + +// Free a data block allocated with phys_alloc int -_free(void *data) +malloc_pfree(u32 data) { ASSERT32FLAT(); struct allocinfo_s *info = alloc_find(data); - if (!info || data == (void*)info || data == info->dataend) + if (!info || data == virt_to_phys(info) || !info->alloc_size) return -1; struct allocdetail_s *detail = container_of( info, struct allocdetail_s, datainfo); - dprintf(8, "_free %p (detail=%p)\n", data, detail); + dprintf(8, "phys_free %x (detail=%p)\n", data, detail); alloc_free(info); alloc_free(&detail->detailinfo); return 0; @@ -281,7 +289,7 @@ free(void *data) { if (!data) return; - int ret = _free(data); + int ret = malloc_pfree(virt_to_phys(data)); if (ret) warn_internalerror(); } @@ -295,7 +303,7 @@ malloc_getspace(struct zone_s *zone) u32 maxspace = 0; struct allocinfo_s *info; hlist_for_each_entry(info, &zone->head, node) { - u32 space = info->allocend - info->dataend; + u32 space = info->range_end - info->range_start - info->alloc_size; if (space > maxspace) maxspace = space; } @@ -311,34 +319,34 @@ malloc_getspace(struct zone_s *zone)
// Set a handle associated with an allocation. void -malloc_sethandle(void *data, u32 handle) +malloc_sethandle(u32 data, u32 handle) { ASSERT32FLAT(); struct allocinfo_s *info = alloc_find(data); - if (!info || data == (void*)info || data == info->dataend) + if (!info || data == virt_to_phys(info) || !info->alloc_size) return; struct allocdetail_s *detail = container_of( info, struct allocdetail_s, datainfo); detail->handle = handle; }
-// Find the data block allocated with _malloc with a given handle. -void * +// Find the data block allocated with phys_alloc with a given handle. +u32 malloc_findhandle(u32 handle) { int i; for (i=0; i<ARRAY_SIZE(Zones); i++) { struct allocinfo_s *info; hlist_for_each_entry(info, &Zones[i]->head, node) { - if (info->data != (void*)info) + if (info->range_start != virt_to_phys(info)) continue; struct allocdetail_s *detail = container_of( info, struct allocdetail_s, detailinfo); if (detail->handle == handle) - return detail->datainfo.data; + return detail->datainfo.range_start; } } - return NULL; + return 0; }
@@ -356,7 +364,7 @@ u32 rom_get_max(void) { if (CONFIG_MALLOC_UPPERMEMORY) - return ALIGN_DOWN((u32)RomBase->allocend - OPROM_HEADER_RESERVE + return ALIGN_DOWN(RomBase->range_end - OPROM_HEADER_RESERVE , OPTION_ROM_ALIGN); extern u8 final_readonly_start[]; return (u32)final_readonly_start; @@ -379,7 +387,7 @@ rom_reserve(u32 size) if (CONFIG_MALLOC_UPPERMEMORY) { if (newend < (u32)zonelow_base) newend = (u32)zonelow_base; - RomBase->data = RomBase->dataend = (void*)newend + OPROM_HEADER_RESERVE; + RomBase->range_start = newend + OPROM_HEADER_RESERVE; } return (void*)RomEnd; } @@ -432,14 +440,13 @@ malloc_preinit(void) e = newe; } } - alloc_add(&ZoneTmpHigh, (void*)s, (void*)e); + alloc_add(&ZoneTmpHigh, s, e); }
// Populate regions - alloc_add(&ZoneTmpLow, (void*)BUILD_STACK_ADDR, (void*)BUILD_EBDA_MINIMUM); + alloc_add(&ZoneTmpLow, BUILD_STACK_ADDR, BUILD_EBDA_MINIMUM); if (highram) { - alloc_add(&ZoneHigh, (void*)highram - , (void*)highram + BUILD_MAX_HIGHTABLE); + alloc_add(&ZoneHigh, highram, highram + BUILD_MAX_HIGHTABLE); e820_add(highram, BUILD_MAX_HIGHTABLE, E820_RESERVED); } } @@ -450,13 +457,13 @@ csm_malloc_preinit(u32 low_pmm, u32 low_pmm_size, u32 hi_pmm, u32 hi_pmm_size) ASSERT32FLAT();
if (hi_pmm_size > BUILD_MAX_HIGHTABLE) { - void *hi_pmm_end = (void*)hi_pmm + hi_pmm_size; - alloc_add(&ZoneTmpHigh, (void*)hi_pmm, hi_pmm_end - BUILD_MAX_HIGHTABLE); + u32 hi_pmm_end = hi_pmm + hi_pmm_size; + alloc_add(&ZoneTmpHigh, hi_pmm, hi_pmm_end - BUILD_MAX_HIGHTABLE); alloc_add(&ZoneHigh, hi_pmm_end - BUILD_MAX_HIGHTABLE, hi_pmm_end); } else { - alloc_add(&ZoneTmpHigh, (void*)hi_pmm, (void*)hi_pmm + hi_pmm_size); + alloc_add(&ZoneTmpHigh, hi_pmm, hi_pmm + hi_pmm_size); } - alloc_add(&ZoneTmpLow, (void*)low_pmm, (void*)low_pmm + low_pmm_size); + alloc_add(&ZoneTmpLow, low_pmm, low_pmm + low_pmm_size); }
u32 LegacyRamSize VARFSEG; @@ -500,18 +507,18 @@ malloc_init(void) extern u8 varlow_start[], varlow_end[], final_varlow_start[]; memmove(final_varlow_start, varlow_start, varlow_end - varlow_start); if (CONFIG_MALLOC_UPPERMEMORY) { - alloc_add(&ZoneLow, zonelow_base + OPROM_HEADER_RESERVE - , final_varlow_start); + alloc_add(&ZoneLow, (u32)zonelow_base + OPROM_HEADER_RESERVE + , (u32)final_varlow_start); RomBase = alloc_find_lowest(&ZoneLow); } else { - alloc_add(&ZoneLow, (void*)ALIGN_DOWN((u32)final_varlow_start, 1024) - , final_varlow_start); + alloc_add(&ZoneLow, ALIGN_DOWN((u32)final_varlow_start, 1024) + , (u32)final_varlow_start); }
// Add space available in f-segment to ZoneFSeg extern u8 zonefseg_start[], zonefseg_end[]; memset(zonefseg_start, 0, zonefseg_end - zonefseg_start); - alloc_add(&ZoneFSeg, zonefseg_start, zonefseg_end); + alloc_add(&ZoneFSeg, (u32)zonefseg_start, (u32)zonefseg_end);
calcRamSize(); } @@ -538,15 +545,16 @@ malloc_prepboot(void)
// Clear unused f-seg ram. struct allocinfo_s *info = alloc_find_lowest(&ZoneFSeg); - memset(info->dataend, 0, info->allocend - info->dataend); + u32 size = info->range_end - info->range_start; + memset(memremap(info->range_start, size), 0, size); dprintf(1, "Space available for UMB: %x-%x, %x-%x\n" - , RomEnd, base, (u32)info->dataend, (u32)info->allocend); + , RomEnd, base, info->range_start, info->range_end);
// Give back unused high ram. info = alloc_find_lowest(&ZoneHigh); if (info) { - u32 giveback = ALIGN_DOWN(info->allocend - info->dataend, PAGE_SIZE); - e820_add((u32)info->dataend, giveback, E820_RAM); + u32 giveback = ALIGN_DOWN(info->range_end-info->range_start, PAGE_SIZE); + e820_add(info->range_start, giveback, E820_RAM); dprintf(1, "Returned %d bytes of ZoneHigh\n", giveback); }
diff --git a/src/malloc.h b/src/malloc.h index b765bc4..f148bfe 100644 --- a/src/malloc.h +++ b/src/malloc.h @@ -15,12 +15,13 @@ void malloc_preinit(void); extern u32 LegacyRamSize; void malloc_init(void); void malloc_prepboot(void); +u32 malloc_palloc(struct zone_s *zone, u32 size, u32 align); void *_malloc(struct zone_s *zone, u32 size, u32 align); -int _free(void *data); +int malloc_pfree(u32 data); void free(void *data); u32 malloc_getspace(struct zone_s *zone); -void malloc_sethandle(void *data, u32 handle); -void *malloc_findhandle(u32 handle); +void malloc_sethandle(u32 data, u32 handle); +u32 malloc_findhandle(u32 handle);
#define MALLOC_DEFAULT_HANDLE 0xFFFFFFFF // Minimum alignment of malloc'd memory diff --git a/src/memmap.h b/src/memmap.h index 9a59024..092e2ad 100644 --- a/src/memmap.h +++ b/src/memmap.h @@ -10,5 +10,8 @@ static inline u32 virt_to_phys(void *v) { return (u32)v; } +static inline void *memremap(u32 addr, u32 len) { + return (void*)addr; +}
#endif // memmap.h diff --git a/src/pmm.c b/src/pmm.c index 304faab..6403414 100644 --- a/src/pmm.c +++ b/src/pmm.c @@ -65,26 +65,26 @@ handle_pmm00(u16 *args) if (align < MALLOC_MIN_ALIGN) align = MALLOC_MIN_ALIGN; } - void *data; + u32 data; switch (flags & 3) { default: case 0: return 0; case 1: - data = _malloc(lowzone, size, align); + data = malloc_palloc(lowzone, size, align); break; case 2: - data = _malloc(highzone, size, align); + data = malloc_palloc(highzone, size, align); break; case 3: { - data = _malloc(lowzone, size, align); + data = malloc_palloc(lowzone, size, align); if (!data) - data = _malloc(highzone, size, align); + data = malloc_palloc(highzone, size, align); } } if (data && handle != MALLOC_DEFAULT_HANDLE) malloc_sethandle(data, handle); - return (u32)data; + return data; }
// PMM - find @@ -95,7 +95,7 @@ handle_pmm01(u16 *args) dprintf(3, "pmm01: handle=%x\n", handle); if (handle == MALLOC_DEFAULT_HANDLE) return 0; - return (u32)malloc_findhandle(handle); + return malloc_findhandle(handle); }
// PMM - deallocate @@ -104,7 +104,7 @@ handle_pmm02(u16 *args) { u32 buffer = *(u32*)&args[1]; dprintf(3, "pmm02: buffer=%x\n", buffer); - int ret = _free((void*)buffer); + int ret = malloc_pfree(buffer); if (ret) // Error return 1;
Use a macro to define and obtain the value of a symbol introduced by the linker scripts (scripts/layoutrom.py).
Signed-off-by: Kevin O'Connor kevin@koconnor.net --- src/biosvar.h | 6 +++--- src/fw/biostables.c | 10 +++++----- src/fw/csm.c | 4 ++-- src/fw/shadow.c | 10 ++++------ src/malloc.c | 25 ++++++++++++------------- src/memmap.h | 4 ++++ src/post.c | 35 ++++++++++++++++------------------- 7 files changed, 46 insertions(+), 48 deletions(-)
diff --git a/src/biosvar.h b/src/biosvar.h index 3b40957..f61fb6a 100644 --- a/src/biosvar.h +++ b/src/biosvar.h @@ -8,6 +8,7 @@
#include "config.h" // SEG_BDA #include "farptr.h" // GET_FARVAR +#include "memmap.h" // SYMBOL #include "std/bda.h" // struct bios_data_area_s
@@ -112,13 +113,12 @@ static inline u16 get_global_seg(void) { * "Low" memory variables ****************************************************************/
-extern u8 _zonelow_seg, zonelow_base[]; -#define SEG_LOW ((u32)&_zonelow_seg) +#define SEG_LOW SYMBOL(_zonelow_seg)
#if MODESEGMENT #define GET_LOW(var) GET_FARVAR(SEG_LOW, (var)) #define SET_LOW(var, val) SET_FARVAR(SEG_LOW, (var), (val)) -#define LOWFLAT2LOW(var) ((typeof(var))((void*)(var) - (u32)zonelow_base)) +#define LOWFLAT2LOW(var) ((typeof(var))((void*)(var) - SYMBOL(zonelow_base))) #else #define GET_LOW(var) (var) #define SET_LOW(var, val) do { (var) = (val); } while (0) diff --git a/src/fw/biostables.c b/src/fw/biostables.c index 71a1a0d..cc7a730 100644 --- a/src/fw/biostables.c +++ b/src/fw/biostables.c @@ -6,14 +6,15 @@
#include "byteorder.h" // le32_to_cpu #include "config.h" // CONFIG_* +#include "hw/pci.h" // pci_config_writeb #include "malloc.h" // malloc_fseg +#include "memmap.h" // SYMBOL #include "output.h" // dprintf -#include "hw/pci.h" // pci_config_writeb +#include "romfile.h" // romfile_find #include "std/acpi.h" // struct rsdp_descriptor #include "std/mptable.h" // MPTABLE_SIGNATURE #include "std/pirtable.h" // struct pir_header #include "std/smbios.h" // struct smbios_entry_point -#include "romfile.h" #include "string.h" // memcpy #include "util.h" // copy_table #include "x86.h" // outb @@ -122,9 +123,8 @@ copy_acpi_rsdp(void *pos)
void *find_acpi_rsdp(void) { - extern u8 zonefseg_start[], zonefseg_end[]; - unsigned long start = (unsigned long)zonefseg_start; - unsigned long end = (unsigned long)zonefseg_end; + unsigned long start = SYMBOL(zonefseg_start); + unsigned long end = SYMBOL(zonefseg_end); unsigned long pos;
for (pos = ALIGN(start, 0x10); pos <= ALIGN_DOWN(end, 0x10); pos += 0x10) diff --git a/src/fw/csm.c b/src/fw/csm.c index 0467560..c837d17 100644 --- a/src/fw/csm.c +++ b/src/fw/csm.c @@ -11,6 +11,7 @@ #include "hw/pci.h" // pci_probe_devices #include "hw/pic.h" // pic_irqmask_read #include "malloc.h" // csm_malloc_preinit +#include "memmap.h" // SYMBOL #include "output.h" // dprintf #include "paravirt.h" // qemu_preinit #include "stacks.h" // wait_threads @@ -47,12 +48,11 @@ static void csm_return(struct bregs *regs) { u32 rommax = rom_get_max(); - extern u8 final_readonly_start[];
dprintf(3, "handle_csm returning AX=%04x\n", regs->ax);
csm_compat_table.UmaAddress = rommax; - csm_compat_table.UmaSize = (u32)final_readonly_start - rommax; + csm_compat_table.UmaSize = SYMBOL(final_readonly_start) - rommax;
PICMask = pic_irqmask_read(); __csm_return(regs); diff --git a/src/fw/shadow.c b/src/fw/shadow.c index 936ae28..ee87d36 100644 --- a/src/fw/shadow.c +++ b/src/fw/shadow.c @@ -53,9 +53,8 @@ __make_bios_writable_intel(u16 bdf, u32 pam0) return;
// Copy bios. - extern u8 code32flat_start[], code32flat_end[]; - memcpy(code32flat_start, code32flat_start + BIOS_SRC_OFFSET - , code32flat_end - code32flat_start); + memcpy(VSYMBOL(code32flat_start), VSYMBOL(code32flat_start) + BIOS_SRC_OFFSET + , SYMBOL(code32flat_end) - SYMBOL(code32flat_start)); }
static void @@ -165,7 +164,6 @@ qemu_prep_reset(void) // QEMU doesn't map 0xc0000-0xfffff back to the original rom on a // reset, so do that manually before invoking a hard reset. make_bios_writable(); - extern u8 code32flat_start[], code32flat_end[]; - memcpy(code32flat_start, code32flat_start + BIOS_SRC_OFFSET - , code32flat_end - code32flat_start); + memcpy(VSYMBOL(code32flat_start), VSYMBOL(code32flat_start) + BIOS_SRC_OFFSET + , SYMBOL(code32flat_end) - SYMBOL(code32flat_start)); } diff --git a/src/malloc.c b/src/malloc.c index 106c7ea..5113bb6 100644 --- a/src/malloc.c +++ b/src/malloc.c @@ -366,8 +366,7 @@ rom_get_max(void) if (CONFIG_MALLOC_UPPERMEMORY) return ALIGN_DOWN(RomBase->range_end - OPROM_HEADER_RESERVE , OPTION_ROM_ALIGN); - extern u8 final_readonly_start[]; - return (u32)final_readonly_start; + return SYMBOL(final_readonly_start); }
// Return the end of the last deployed option rom. @@ -385,8 +384,8 @@ rom_reserve(u32 size) if (newend > rom_get_max()) return NULL; if (CONFIG_MALLOC_UPPERMEMORY) { - if (newend < (u32)zonelow_base) - newend = (u32)zonelow_base; + if (newend < SYMBOL(zonelow_base)) + newend = SYMBOL(zonelow_base); RomBase->range_start = newend + OPROM_HEADER_RESERVE; } return (void*)RomEnd; @@ -504,21 +503,21 @@ malloc_init(void) }
// Initialize low-memory region - extern u8 varlow_start[], varlow_end[], final_varlow_start[]; - memmove(final_varlow_start, varlow_start, varlow_end - varlow_start); + memmove(VSYMBOL(final_varlow_start), VSYMBOL(varlow_start) + , SYMBOL(varlow_end) - SYMBOL(varlow_start)); if (CONFIG_MALLOC_UPPERMEMORY) { - alloc_add(&ZoneLow, (u32)zonelow_base + OPROM_HEADER_RESERVE - , (u32)final_varlow_start); + alloc_add(&ZoneLow, SYMBOL(zonelow_base) + OPROM_HEADER_RESERVE + , SYMBOL(final_varlow_start)); RomBase = alloc_find_lowest(&ZoneLow); } else { - alloc_add(&ZoneLow, ALIGN_DOWN((u32)final_varlow_start, 1024) - , (u32)final_varlow_start); + alloc_add(&ZoneLow, ALIGN_DOWN(SYMBOL(final_varlow_start), 1024) + , SYMBOL(final_varlow_start)); }
// Add space available in f-segment to ZoneFSeg - extern u8 zonefseg_start[], zonefseg_end[]; - memset(zonefseg_start, 0, zonefseg_end - zonefseg_start); - alloc_add(&ZoneFSeg, (u32)zonefseg_start, (u32)zonefseg_end); + memset(VSYMBOL(zonefseg_start), 0 + , SYMBOL(zonefseg_end) - SYMBOL(zonefseg_start)); + alloc_add(&ZoneFSeg, SYMBOL(zonefseg_start), SYMBOL(zonefseg_end));
calcRamSize(); } diff --git a/src/memmap.h b/src/memmap.h index 092e2ad..22bd4bc 100644 --- a/src/memmap.h +++ b/src/memmap.h @@ -14,4 +14,8 @@ static inline void *memremap(u32 addr, u32 len) { return (void*)addr; }
+// Return the value of a linker script symbol (see scripts/layoutrom.py) +#define SYMBOL(SYM) ({ extern char SYM; (u32)&SYM; }) +#define VSYMBOL(SYM) ((void*)SYMBOL(SYM)) + #endif // memmap.h diff --git a/src/post.c b/src/post.c index 89e6eff..49c22b8 100644 --- a/src/post.c +++ b/src/post.c @@ -25,6 +25,7 @@ #include "hw/virtio-blk.h" // virtio_blk_setup #include "hw/virtio-scsi.h" // virtio_scsi_setup #include "malloc.h" // malloc_init +#include "memmap.h" // SYMBOL #include "output.h" // dprintf #include "string.h" // memset #include "util.h" // kbd_init @@ -89,9 +90,8 @@ bda_init(void)
int esize = EBDA_SIZE_START; u16 ebda_seg = EBDA_SEGMENT_START; - extern u8 final_varlow_start[]; if (!CONFIG_MALLOC_UPPERMEMORY) - ebda_seg = FLATPTR_TO_SEG(ALIGN_DOWN((u32)final_varlow_start, 1024) + ebda_seg = FLATPTR_TO_SEG(ALIGN_DOWN(SYMBOL(final_varlow_start), 1024) - EBDA_SIZE_START*1024); SET_BDA(ebda_seg, ebda_seg);
@@ -105,7 +105,7 @@ bda_init(void) e820_add((u32)ebda, BUILD_LOWRAM_END-(u32)ebda, E820_RESERVED);
// Init extra stack - StackPos = (void*)(&ExtraStack[BUILD_EXTRA_STACK_SIZE] - zonelow_base); + StackPos = &ExtraStack[BUILD_EXTRA_STACK_SIZE] - SYMBOL(zonelow_base); }
void @@ -276,30 +276,27 @@ reloc_preinit(void *f, void *arg) void (*func)(void *) __noreturn = f; if (!CONFIG_RELOCATE_INIT) func(arg); - // Symbols populated by the build. - extern u8 code32flat_start[]; - extern u8 _reloc_min_align; - extern u32 _reloc_abs_start[], _reloc_abs_end[]; - extern u32 _reloc_rel_start[], _reloc_rel_end[]; - extern u32 _reloc_init_start[], _reloc_init_end[]; - extern u8 code32init_start[], code32init_end[];
// Allocate space for init code. - u32 initsize = code32init_end - code32init_start; - u32 codealign = (u32)&_reloc_min_align; + u32 initsize = SYMBOL(code32init_end) - SYMBOL(code32init_start); + u32 codealign = SYMBOL(_reloc_min_align); void *codedest = memalign_tmp(codealign, initsize); + void *codesrc = VSYMBOL(code32init_start); if (!codedest) panic("No space for init relocation.\n");
// Copy code and update relocs (init absolute, init relative, and runtime) dprintf(1, "Relocating init from %p to %p (size %d)\n" - , code32init_start, codedest, initsize); - s32 delta = codedest - (void*)code32init_start; - memcpy(codedest, code32init_start, initsize); - updateRelocs(codedest, _reloc_abs_start, _reloc_abs_end, delta); - updateRelocs(codedest, _reloc_rel_start, _reloc_rel_end, -delta); - updateRelocs(code32flat_start, _reloc_init_start, _reloc_init_end, delta); - if (f >= (void*)code32init_start && f < (void*)code32init_end) + , codesrc, codedest, initsize); + s32 delta = codedest - codesrc; + memcpy(codedest, codesrc, initsize); + updateRelocs(codedest, VSYMBOL(_reloc_abs_start), VSYMBOL(_reloc_abs_end) + , delta); + updateRelocs(codedest, VSYMBOL(_reloc_rel_start), VSYMBOL(_reloc_rel_end) + , -delta); + updateRelocs(VSYMBOL(code32flat_start), VSYMBOL(_reloc_init_start) + , VSYMBOL(_reloc_init_end), delta); + if (f >= codesrc && f < VSYMBOL(code32init_end)) func = f + delta;
// Call function in relocated code.
On Fri, Oct 09, 2015 at 01:53:28PM -0400, Kevin O'Connor wrote:
This series is a fallout of work I was doing to test PAE. I think the cleanups in this series make sense even without PAE.
FYI, I committed this series.
-Kevin