Cleanups for malloc code.
authorKevin O'Connor <kevin@koconnor.net>
Sun, 30 Aug 2009 23:19:31 +0000 (19:19 -0400)
committerKevin O'Connor <kevin@koconnor.net>
Sun, 30 Aug 2009 23:19:31 +0000 (19:19 -0400)
Fix bug where zones over 2gig may fail to allocate.
Add memalign_high() and use for acpi facs allocation.
Misc code cleanups.

src/acpi.c
src/memmap.h
src/pmm.c
src/types.h
src/util.h

index 2198805c69f0a1ee3349b1bf4c9682a5e65cd61d..d0c920189a2f451f6c8c5e4b8d524b3874812a91 100644 (file)
@@ -254,7 +254,7 @@ static void
 build_fadt(struct rsdt_descriptor_rev1 *rsdt, int bdf)
 {
     struct fadt_descriptor_rev1 *fadt = malloc_high(sizeof(*fadt));
-    struct facs_descriptor_rev1 *facs = malloc_high(sizeof(*facs) + 63);
+    struct facs_descriptor_rev1 *facs = memalign_high(64, sizeof(*facs));
     void *dsdt = malloc_high(sizeof(AmlCode));
 
     if (!fadt || !facs || !dsdt) {
@@ -263,7 +263,6 @@ build_fadt(struct rsdt_descriptor_rev1 *rsdt, int bdf)
     }
 
     /* FACS */
-    facs = (void*)ALIGN((u32)facs, 64);
     memset(facs, 0, sizeof(*facs));
     facs->signature = FACS_SIGNATURE;
     facs->length = cpu_to_le32(sizeof(*facs));
@@ -432,9 +431,10 @@ acpi_bios_init(void)
         return;
 
     // Create initial rsdt table
+    struct rsdp_descriptor *rsdp = malloc_fseg(sizeof(*rsdp));
     struct rsdt_descriptor_rev1 *rsdt = malloc_high(sizeof(*rsdt));
-    if (!rsdt) {
-        dprintf(1, "Not enough memory for acpi rsdt table!\n");
+    if (!rsdp || !rsdt) {
+        dprintf(1, "Not enough memory for acpi rsdp/rsdt table!\n");
         return;
     }
     memset(rsdt, 0, sizeof(*rsdt));
@@ -448,11 +448,6 @@ acpi_bios_init(void)
     build_header((void*)rsdt, RSDT_SIGNATURE, rsdt->length, 1, NULL);
 
     // Build rsdp pointer table
-    struct rsdp_descriptor *rsdp = malloc_fseg(sizeof(*rsdp));
-    if (!rsdp) {
-        dprintf(1, "Not enough memory for acpi rsdp!\n");
-        return;
-    }
     memset(rsdp, 0, sizeof(*rsdp));
     rsdp->signature = RSDP_SIGNATURE;
     memcpy(rsdp->oem_id, CONFIG_APPNAME6, 6);
index 4494538d9161c05a3685e667b2bdc4cee89ee92a..616ae3534e400d6cfd5d3a739527556dad260dd5 100644 (file)
@@ -21,6 +21,9 @@ void memmap_setup();
 void memmap_finalize();
 struct e820entry *find_high_area(u32 size);
 
+// A typical OS page size
+#define PAGE_SIZE 4096
+
 // e820 map storage (defined in system.c)
 extern struct e820entry e820_list[];
 extern int e820_count;
index 3b4aa07ccc06d865484f846f2c6cb0d429a02917..1732c69b28563236dda87e39a9ff3b031146f159 100644 (file)
--- a/src/pmm.c
+++ b/src/pmm.c
@@ -39,11 +39,12 @@ struct zone_s *Zones[] VAR32VISIBLE = {
 };
 
 // Obtain memory from a given zone.
-static void *
+void *
 zone_malloc(struct zone_s *zone, u32 size, u32 align)
 {
-    u32 newpos = (GET_PMMVAR(zone->cur) - size) / align * align;
-    if ((s32)(newpos - GET_PMMVAR(zone->bottom)) < 0)
+    u32 oldpos = GET_PMMVAR(zone->cur);
+    u32 newpos = ALIGN_DOWN(oldpos - size, align);
+    if (newpos < GET_PMMVAR(zone->bottom) || newpos > oldpos)
         // No space
         return NULL;
     SET_PMMVAR(zone->cur, newpos);
@@ -88,20 +89,6 @@ dumpZones()
     }
 }
 
-// Allocate memory at the top of 32bit ram.
-void *
-malloc_high(u32 size)
-{
-    return zone_malloc(&ZoneHigh, size, MALLOC_MIN_ALIGN);
-}
-
-// Allocate memory in the 0xf0000-0x100000 area of ram.
-void *
-malloc_fseg(u32 size)
-{
-    return zone_malloc(&ZoneFSeg, size, MALLOC_MIN_ALIGN);
-}
-
 void
 malloc_setup()
 {
@@ -148,7 +135,7 @@ malloc_finalize()
     dumpZones();
 
     // Give back unused high ram.
-    u32 giveback = (ZoneHigh.cur - ZoneHigh.bottom) / 4096 * 4096;
+    u32 giveback = ALIGN_DOWN(ZoneHigh.cur - ZoneHigh.bottom, PAGE_SIZE);
     add_e820(ZoneHigh.bottom, giveback, E820_RAM);
     dprintf(1, "Returned %d bytes of ZoneHigh\n", giveback);
 
index bbb38bbb2e0d12e3ee3139355ca487950bbae485..215b666a8a9149b3be02f70081d484f6a6792d2d 100644 (file)
@@ -72,11 +72,12 @@ union u64_u32_u {
 #define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d))
 #define ALIGN(x,a)              __ALIGN_MASK(x,(typeof(x))(a)-1)
 #define __ALIGN_MASK(x,mask)    (((x)+(mask))&~(mask))
+#define ALIGN_DOWN(x,a)         ((x) & ~((typeof(x))(a)-1))
 #define container_of(ptr, type, member) ({                      \
         const typeof( ((type *)0)->member ) *__mptr = (ptr);    \
         (type *)( (char *)__mptr - offsetof(type,member) );})
 
-#define NULL ((void *)0)
+#define NULL ((void*)0)
 
 #define __weak __attribute__((weak))
 #define __section(S) __attribute__((section(S)))
index b8d82332173d967dd2636c37ae0019f0f74350a0..a8f75a3caee18f063be507290d311b6b60f4d0cf 100644 (file)
@@ -252,14 +252,27 @@ u16 get_pnp_offset();
 void pnp_setup();
 
 // pmm.c
-void *malloc_high(u32 size);
-void *malloc_fseg(u32 size);
+extern struct zone_s ZoneLow, ZoneHigh, ZoneFSeg, ZoneTmpLow, ZoneTmpHigh;
+void *zone_malloc(struct zone_s *zone, u32 size, u32 align);
 void malloc_setup();
 void malloc_finalize();
 void pmm_setup();
 void pmm_finalize();
 // Minimum alignment of malloc'd memory
 #define MALLOC_MIN_ALIGN 16
+// Helper functions for memory allocation.
+static inline void *malloc_high(u32 size) {
+    return zone_malloc(&ZoneHigh, size, MALLOC_MIN_ALIGN);
+}
+static inline void *malloc_fseg(u32 size) {
+    return zone_malloc(&ZoneFSeg, size, MALLOC_MIN_ALIGN);
+}
+static inline void *memalign_tmphigh(u32 align, u32 size) {
+    return zone_malloc(&ZoneTmpHigh, size, align);
+}
+static inline void *memalign_high(u32 align, u32 size) {
+    return zone_malloc(&ZoneHigh, size, align);
+}
 
 // mtrr.c
 void mtrr_setup(void);