[syslinux:firmware] firmware: Move memory operations into firmware

syslinux-bot for Matt Fleming matt.fleming at intel.com
Thu Nov 15 11:51:07 PST 2012


Commit-ID:  d87b69dccdf1a42942c277ca6b074a69b95d87c4
Gitweb:     http://www.syslinux.org/commit/d87b69dccdf1a42942c277ca6b074a69b95d87c4
Author:     Matt Fleming <matt.fleming at intel.com>
AuthorDate: Thu, 15 Nov 2012 11:54:16 +0000
Committer:  Matt Fleming <matt.fleming at intel.com>
CommitDate: Thu, 15 Nov 2012 13:06:45 +0000

firmware: Move memory operations into firmware

Instead of littering core/mem with #ifdef SYSLINUX_EFI move memory
operations into the 'firmware' structure so that they can be
implemented differently for BIOS and EFI.

Signed-off-by: Matt Fleming <matt.fleming at intel.com>

---
 com32/include/syslinux/firmware.h | 10 +++++++++-
 com32/lib/syslinux/memscan.c      |  2 +-
 core/bios.c                       | 13 ++++++++++++-
 core/mem/free.c                   | 22 ++++++++++++----------
 core/mem/malloc.c                 | 38 +++++++++++++++++++++-----------------
 efi/efi.h                         |  5 +++++
 efi/main.c                        |  9 ++++++++-
 efi/mem.c                         | 22 ++++++++++++++++++++++
 mk/efi.mk                         |  2 +-
 9 files changed, 91 insertions(+), 32 deletions(-)

diff --git a/com32/include/syslinux/firmware.h b/com32/include/syslinux/firmware.h
index cfe3b8d..c2b5a44 100644
--- a/com32/include/syslinux/firmware.h
+++ b/com32/include/syslinux/firmware.h
@@ -37,13 +37,20 @@ struct vesa_ops {
 	int (*font_query)(uint8_t **);
 };
 
+enum heap;
+struct mem_ops {
+	void *(*malloc)(size_t, enum heap, size_t);
+	void *(*realloc)(void *, size_t);
+	void (*free)(void *);
+	int (*scan_memory)(scan_memory_callback_t, void *);
+};
+
 struct disk_private;
 struct initramfs;
 struct setup_data;
 
 struct firmware {
 	void (*init)(void);
-	int (*scan_memory)(scan_memory_callback_t, void *);
 	void (*adjust_screen)(void);
 	void (*cleanup)(void);
 	struct disk *(*disk_init)(void *);
@@ -55,6 +62,7 @@ struct firmware {
 	int (*boot_linux)(void *, size_t, struct initramfs *,
 			  struct setup_data *, char *);
 	struct vesa_ops *vesa;
+	struct mem_ops *mem;
 };
 
 extern struct firmware *firmware;
diff --git a/com32/lib/syslinux/memscan.c b/com32/lib/syslinux/memscan.c
index ccd0e5c..0ff25d7 100644
--- a/com32/lib/syslinux/memscan.c
+++ b/com32/lib/syslinux/memscan.c
@@ -160,5 +160,5 @@ int bios_scan_memory(scan_memory_callback_t callback, void *data)
 
 int syslinux_scan_memory(scan_memory_callback_t callback, void *data)
 {
-	return firmware->scan_memory(callback, data);
+	return firmware->mem->scan_memory(callback, data);
 }
diff --git a/core/bios.c b/core/bios.c
index 5207a5d..5b4a8ce 100644
--- a/core/bios.c
+++ b/core/bios.c
@@ -539,9 +539,19 @@ void bios_init(void)
 	check_escapes();
 }
 
+extern void *bios_malloc(size_t, enum heap, size_t);
+extern void *bios_realloc(void *, size_t);
+extern void bios_free(void *);
+
+struct mem_ops bios_mem_ops = {
+	.malloc = bios_malloc,
+	.realloc = bios_realloc,
+	.free = bios_free,
+	.scan_memory = bios_scan_memory,
+};
+
 struct firmware bios_fw = {
 	.init = bios_init,
-	.scan_memory = bios_scan_memory,
 	.adjust_screen = bios_adjust_screen,
 	.cleanup = bios_cleanup_hardware,
 	.disk_init = bios_disk_init,
@@ -551,6 +561,7 @@ struct firmware bios_fw = {
 	.get_serial_console_info = bios_get_serial_console_info,
 	.adv_ops = &bios_adv_ops,
 	.vesa = &bios_vesa_ops,
+	.mem = &bios_mem_ops,
 };
 
 void syslinux_register_bios(void)
diff --git a/core/mem/free.c b/core/mem/free.c
index d22813d..b0eb714 100644
--- a/core/mem/free.c
+++ b/core/mem/free.c
@@ -4,6 +4,7 @@
  * Very simple linked-list based malloc()/free().
  */
 
+#include <syslinux/firmware.h>
 #include <stdlib.h>
 #include <dprintf.h>
 #include "malloc.h"
@@ -66,18 +67,10 @@ __free_block(struct free_arena_header *ah)
     return ah;
 }
 
-void free(void *ptr)
+void bios_free(void *ptr)
 {
     struct free_arena_header *ah;
 
-    dprintf("free(%p) @ %p\n", ptr, __builtin_return_address(0));
-
-    if ( !ptr )
-        return;
-
-#ifdef SYSLINUX_EFI
-    FreePool(ptr);
-#else
     ah = (struct free_arena_header *)
         ((struct arena_header *)ptr - 1);
 
@@ -86,7 +79,16 @@ void free(void *ptr)
 #endif
 
     __free_block(ah);
-#endif
+}
+
+void free(void *ptr)
+{
+    dprintf("free(%p) @ %p\n", ptr, __builtin_return_address(0));
+
+    if ( !ptr )
+        return;
+
+    firmware->mem->free(ptr);
 
   /* Here we could insert code to return memory to the system. */
 }
diff --git a/core/mem/malloc.c b/core/mem/malloc.c
index df05db0..fe8af5a 100644
--- a/core/mem/malloc.c
+++ b/core/mem/malloc.c
@@ -4,6 +4,7 @@
  * Very simple linked-list based malloc()/free().
  */
 
+#include <syslinux/firmware.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <errno.h>
@@ -60,18 +61,12 @@ static void *__malloc_from_block(struct free_arena_header *fp,
     return (void *)(&fp->a + 1);
 }
 
-static void *_malloc(size_t size, enum heap heap, malloc_tag_t tag)
+void *bios_malloc(size_t size, enum heap heap, malloc_tag_t tag)
 {
     struct free_arena_header *fp;
     struct free_arena_header *head = &__core_malloc_head[heap];
     void *p = NULL;
 
-    dprintf("_malloc(%zu, %u, %u) @ %p = ",
-	size, heap, tag, __builtin_return_address(0));
-
-#ifdef SYSLINUX_EFI
-    p = AllocatePool(size);
-#else
     if (size) {
 	/* Add the obligatory arena header, and round up */
 	size = (size + 2 * sizeof(struct arena_header) - 1) & ARENA_SIZE_MASK;
@@ -84,7 +79,18 @@ static void *_malloc(size_t size, enum heap heap, malloc_tag_t tag)
 	    }
         }
     }
-#endif
+
+    return p;
+}
+
+static void *_malloc(size_t size, enum heap heap, malloc_tag_t tag)
+{
+    void *p;
+
+    dprintf("_malloc(%zu, %u, %u) @ %p = ",
+	size, heap, tag, __builtin_return_address(0));
+
+    p = firmware->mem->malloc(size, heap, tag);
 
     dprintf("%p\n", p);
     return p;
@@ -110,20 +116,14 @@ void *pmapi_lmalloc(size_t size)
     return _malloc(size, HEAP_LOWMEM, MALLOC_MODULE);
 }
 
-void *realloc(void *ptr, size_t size)
+void *bios_realloc(void *ptr, size_t size)
 {
     struct free_arena_header *ah, *nah;
     struct free_arena_header *head;
-	
+
     void *newptr;
     size_t newsize, oldsize, xsize;
 
-#ifdef SYSLINUX_EFI
-    newptr = AllocatePool(size);
-    memcpy(newptr, ptr, size);
-    FreePool(ptr);
-    return newptr;
-#else
     if (!ptr)
 	return malloc(size);
 
@@ -215,7 +215,11 @@ void *realloc(void *ptr, size_t size)
 	    return newptr;
 	}
     }
-#endif
+}
+
+void *realloc(void *ptr, size_t size)
+{
+    return firmware->mem->realloc(ptr, size);
 }
 
 void *zalloc(size_t size)
diff --git a/efi/efi.h b/efi/efi.h
index 700c055..97b4644 100644
--- a/efi/efi.h
+++ b/efi/efi.h
@@ -15,4 +15,9 @@ extern void setup_screen(struct screen_info *);
 
 extern void efi_write_char(uint8_t, uint8_t);
 
+enum heap;
+extern void *efi_malloc(size_t, enum heap, size_t);
+extern void *efi_realloc(void *, size_t);
+extern void efi_free(void *);
+
 #endif /* _SYSLINUX_EFI_H */
diff --git a/efi/main.c b/efi/main.c
index 99dc208..3bd8491 100644
--- a/efi/main.c
+++ b/efi/main.c
@@ -1046,9 +1046,15 @@ extern void serialcfg(uint16_t *, uint16_t *, uint16_t *);
 
 extern struct vesa_ops efi_vesa_ops;
 
+struct mem_ops efi_mem_ops = {
+	.malloc = efi_malloc,
+	.realloc = efi_realloc,
+	.free = efi_free,
+	.scan_memory = efi_scan_memory,
+};
+
 struct firmware efi_fw = {
 	.init = efi_init,
-	.scan_memory = efi_scan_memory,
 	.disk_init = efi_disk_init,
 	.o_ops = &efi_ops,
 	.i_ops = &efi_iops,
@@ -1057,6 +1063,7 @@ struct firmware efi_fw = {
 	.adv_ops = &efi_adv_ops,
 	.boot_linux = efi_boot_linux,
 	.vesa = &efi_vesa_ops,
+	.mem = &efi_mem_ops,
 };
 
 static inline void syslinux_register_efi(void)
diff --git a/efi/mem.c b/efi/mem.c
new file mode 100644
index 0000000..6203ff2
--- /dev/null
+++ b/efi/mem.c
@@ -0,0 +1,22 @@
+#include <mem/malloc.h>
+#include "efi.h"
+
+void *efi_malloc(size_t size, enum heap heap, malloc_tag_t tag)
+{
+	return AllocatePool(size);
+}
+
+void *efi_realloc(void *ptr, size_t size)
+{
+	void *newptr;
+
+	newptr = AllocatePool(size);
+	memcpy(newptr, ptr, size);
+	FreePool(ptr);
+	return newptr;
+}
+
+void efi_free(void *ptr)
+{
+	FreePool(ptr);
+}
diff --git a/mk/efi.mk b/mk/efi.mk
index db70ec8..b13000c 100644
--- a/mk/efi.mk
+++ b/mk/efi.mk
@@ -32,7 +32,7 @@ FORMAT=efi-app-$(EFI_SUBARCH)
 CFLAGS = -I$(EFIINC) -I$(EFIINC)/$(EFI_SUBARCH) \
 		-DEFI_FUNCTION_WRAPPER -fPIC -fshort-wchar -ffreestanding \
 		-Wall -I$(com32)/include -I$(com32)/include/sys \
-		-I$(core)/include $(CARCHOPT) \
+		-I$(core)/include -I$(core)/ $(CARCHOPT) \
 		-I$(com32)/lib/ -I$(com32)/libutil/include -std=gnu99 -DELF_DEBUG -DSYSLINUX_EFI \
 		$(GCCWARN) -D__COM32__
 


More information about the Syslinux-commits mailing list