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@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) {