aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKevin O'Connor <kevin@koconnor.net>2009-08-30 19:19:31 -0400
committerKevin O'Connor <kevin@koconnor.net>2009-08-30 19:19:31 -0400
commit415d4298dfad6122c5a41214bd977b3598317718 (patch)
tree2e60f94207aee637c6c22dbc8912630a443e9497
parent7b184d8470308095340622d8376878a20fff299e (diff)
downloadseabios-hppa-415d4298dfad6122c5a41214bd977b3598317718.zip
seabios-hppa-415d4298dfad6122c5a41214bd977b3598317718.tar.gz
seabios-hppa-415d4298dfad6122c5a41214bd977b3598317718.tar.bz2
Cleanups for malloc code.
Fix bug where zones over 2gig may fail to allocate. Add memalign_high() and use for acpi facs allocation. Misc code cleanups.
-rw-r--r--src/acpi.c13
-rw-r--r--src/memmap.h3
-rw-r--r--src/pmm.c23
-rw-r--r--src/types.h3
-rw-r--r--src/util.h17
5 files changed, 29 insertions, 30 deletions
diff --git a/src/acpi.c b/src/acpi.c
index 2198805..d0c9201 100644
--- a/src/acpi.c
+++ b/src/acpi.c
@@ -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);
diff --git a/src/memmap.h b/src/memmap.h
index 4494538..616ae35 100644
--- a/src/memmap.h
+++ b/src/memmap.h
@@ -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;
diff --git a/src/pmm.c b/src/pmm.c
index 3b4aa07..1732c69 100644
--- 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);
diff --git a/src/types.h b/src/types.h
index bbb38bb..215b666 100644
--- a/src/types.h
+++ b/src/types.h
@@ -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)))
diff --git a/src/util.h b/src/util.h
index b8d8233..a8f75a3 100644
--- a/src/util.h
+++ b/src/util.h
@@ -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);