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%) -- 2.4.3
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 -- 2.4.3
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 -- 2.4.3
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. -- 2.4.3
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; } -- 2.4.3
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; -- 2.4.3
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); -- 2.4.3
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; } -- 2.4.3
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 -- 2.4.3
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; -- 2.4.3
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. -- 2.4.3
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
participants (1)
-
Kevin O'Connor