[SeaBIOS] [PATCH] ata: Many CPUs cause seabios not to find boot disk

Huaitong Han huaitong.han at intel.com
Mon Aug 3 07:59:25 CEST 2015


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 at 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




More information about the SeaBIOS mailing list