When CPUs are 76, mptable_setup will alloc much
fseg memory,and init_atadrive allocation fails.
when CPUs are 86, mptable_setup allocation is too
much to be met, and init_atadrive allocs success.
So when CPUs are 76~85, seabios cannot find boot
disk because init_atadrive allocation fails.
Set a reserved area from fsegzone for atadrive
allocation, and the fsegzone space also increases
by the reserved area space.
Signed-off-by: Huaitong Han <huaitong.han(a)intel.com>
diff --git a/scripts/layoutrom.py b/scripts/layoutrom.py
index b976fb0..a7bc5b1 100755
--- a/scripts/layoutrom.py
+++ b/scripts/layoutrom.py
@@ -62,7 +62,7 @@ BUILD_BIOS_SIZE = 0x10000
BUILD_ROM_START = 0xc0000
BUILD_LOWRAM_END = 0xa0000
# Space to reserve in f-segment for dynamic allocations
-BUILD_MIN_BIOSTABLE = 2048
+BUILD_MIN_BIOSTABLE = 2304
# Layout the 16bit code. This ensures sections with fixed offset
# requirements are placed in the correct location. It also places the
diff --git a/src/hw/ata.c b/src/hw/ata.c
index fbbbbc1..12bd01f 100644
--- a/src/hw/ata.c
+++ b/src/hw/ata.c
@@ -710,7 +710,7 @@ ata_extract_model(char *model, u32 size, u16 *buffer)
static struct atadrive_s *
init_atadrive(struct atadrive_s *dummy, u16 *buffer)
{
- struct atadrive_s *adrive = malloc_fseg(sizeof(*adrive));
+ struct atadrive_s *adrive = malloc_reserved_fseg(sizeof(*adrive));
if (!adrive) {
warn_noalloc();
return NULL;
@@ -920,7 +920,7 @@ init_controller(struct pci_device *pci, int chanid, int irq
, u32 port1, u32 port2, u32 master)
{
static int ataid = 0;
- struct ata_channel_s *chan_gf = malloc_fseg(sizeof(*chan_gf));
+ struct ata_channel_s *chan_gf = malloc_reserved_fseg(sizeof(*chan_gf));
if (!chan_gf) {
warn_noalloc();
return;
diff --git a/src/malloc.c b/src/malloc.c
index c4cb171..16114f5 100644
--- a/src/malloc.c
+++ b/src/malloc.c
@@ -296,6 +296,19 @@ malloc_getspace(struct zone_s *zone)
return maxspace - reserve;
}
+u32 malloc_get_zone_space(struct zone_s *zone)
+{
+ // XXX - results not reliable when CONFIG_THREAD_OPTIONROMS
+ u32 totalspace = 0;
+ struct allocinfo_s *info;
+ hlist_for_each_entry(info, &zone->head, node) {
+ u32 space = info->allocend - info->dataend;
+ totalspace += space;
+ }
+
+ return totalspace;
+}
+
// Set a handle associated with an allocation.
void
malloc_sethandle(void *data, u32 handle)
diff --git a/src/malloc.h b/src/malloc.h
index 2bcb5bf..c70a468 100644
--- a/src/malloc.h
+++ b/src/malloc.h
@@ -20,6 +20,10 @@ int _free(void *data);
u32 malloc_getspace(struct zone_s *zone);
void malloc_sethandle(void *data, u32 handle);
void *malloc_findhandle(u32 handle);
+u32 malloc_get_zone_space(struct zone_s *zone);
+
+//Set a reserved zone to prevent key memory allocation failure
+#define RESERVED_FSEG_ZONE 256
#define MALLOC_DEFAULT_HANDLE 0xFFFFFFFF
// Minimum alignment of malloc'd memory
@@ -32,6 +36,13 @@ static inline void *malloc_high(u32 size) {
return _malloc(&ZoneHigh, size, MALLOC_MIN_ALIGN);
}
static inline void *malloc_fseg(u32 size) {
+ u32 allspace = malloc_get_zone_space(&ZoneFSeg);
+ if (allspace < (size + RESERVED_FSEG_ZONE))
+ return NULL;
+
+ return _malloc(&ZoneFSeg, size, MALLOC_MIN_ALIGN);
+}
+static inline void *malloc_reserved_fseg(u32 size){
return _malloc(&ZoneFSeg, size, MALLOC_MIN_ALIGN);
}
static inline void *malloc_tmplow(u32 size) {
--
1.9.1