X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=src%2Fpmm.c;h=82a0b1d0dc4fb61ff58605fe5683d904cb5323d0;hb=refs%2Fheads%2Fcoreboot;hp=228bc3663769aef393df12c40856fe2bc2cb2079;hpb=42a1d4cdb09535d9c5880880af6a17d6741377a6;p=seabios.git diff --git a/src/pmm.c b/src/pmm.c index 228bc36..82a0b1d 100644 --- a/src/pmm.c +++ b/src/pmm.c @@ -10,22 +10,6 @@ #include "farptr.h" // GET_FARVAR #include "biosvar.h" // GET_BDA - -#if MODESEGMENT -// The 16bit pmm entry points runs in "big real" mode, and can -// therefore read/write to the 32bit malloc variables. -#define GET_PMMVAR(var) ({ \ - SET_SEG(ES, 0); \ - __GET_VAR("addr32 ", ES, (var)); }) -#define SET_PMMVAR(var, val) do { \ - SET_SEG(ES, 0); \ - __SET_VAR("addr32 ", ES, (var), (val)); \ - } while (0) -#else -#define GET_PMMVAR(var) (var) -#define SET_PMMVAR(var, val) do { (var) = (val); } while (0) -#endif - // Information on a reserved area. struct allocinfo_s { struct allocinfo_s *next, **pprev; @@ -44,13 +28,9 @@ struct zone_s { struct allocinfo_s *info; }; -struct zone_s ZoneLow VAR32FLATVISIBLE; -struct zone_s ZoneHigh VAR32FLATVISIBLE; -struct zone_s ZoneFSeg VAR32FLATVISIBLE; -struct zone_s ZoneTmpLow VAR32FLATVISIBLE; -struct zone_s ZoneTmpHigh VAR32FLATVISIBLE; +struct zone_s ZoneLow, ZoneHigh, ZoneFSeg, ZoneTmpLow, ZoneTmpHigh; -struct zone_s *Zones[] VAR32FLATVISIBLE = { +static struct zone_s *Zones[] = { &ZoneTmpLow, &ZoneLow, &ZoneFSeg, &ZoneTmpHigh, &ZoneHigh }; @@ -64,24 +44,24 @@ static void * allocSpace(struct zone_s *zone, u32 size, u32 align, struct allocinfo_s *fill) { struct allocinfo_s *info; - for (info = GET_PMMVAR(zone->info); info; info = GET_PMMVAR(info->next)) { - void *dataend = GET_PMMVAR(info->dataend); - void *allocend = GET_PMMVAR(info->allocend); + for (info = zone->info; info; info = info->next) { + void *dataend = info->dataend; + void *allocend = info->allocend; void *newallocend = (void*)ALIGN_DOWN((u32)allocend - size, align); if (newallocend >= dataend && newallocend <= allocend) { // Found space - now reserve it. - struct allocinfo_s **pprev = GET_PMMVAR(info->pprev); + struct allocinfo_s **pprev = info->pprev; if (!fill) fill = newallocend; - SET_PMMVAR(fill->next, info); - SET_PMMVAR(fill->pprev, pprev); - SET_PMMVAR(fill->data, newallocend); - SET_PMMVAR(fill->dataend, newallocend + size); - SET_PMMVAR(fill->allocend, allocend); - - SET_PMMVAR(info->allocend, newallocend); - SET_PMMVAR(info->pprev, &fill->next); - SET_PMMVAR(*pprev, fill); + fill->next = info; + fill->pprev = pprev; + fill->data = newallocend; + fill->dataend = newallocend + size; + fill->allocend = allocend; + + info->allocend = newallocend; + info->pprev = &fill->next; + *pprev = fill; return newallocend; } } @@ -92,13 +72,13 @@ allocSpace(struct zone_s *zone, u32 size, u32 align, struct allocinfo_s *fill) static void freeSpace(struct allocinfo_s *info) { - struct allocinfo_s *next = GET_PMMVAR(info->next); - struct allocinfo_s **pprev = GET_PMMVAR(info->pprev); - SET_PMMVAR(*pprev, next); + struct allocinfo_s *next = info->next; + struct allocinfo_s **pprev = info->pprev; + *pprev = next; if (next) { - if (GET_PMMVAR(next->allocend) == GET_PMMVAR(info->data)) - SET_PMMVAR(next->allocend, GET_PMMVAR(info->allocend)); - SET_PMMVAR(next->pprev, pprev); + if (next->allocend == info->data) + next->allocend = info->allocend; + next->pprev = pprev; } } @@ -109,8 +89,8 @@ addSpace(struct zone_s *zone, void *start, void *end) // Find position to add space struct allocinfo_s **pprev = &zone->info, *info; for (;;) { - info = GET_PMMVAR(*pprev); - if (!info || GET_PMMVAR(info->data) < start) + info = *pprev; + if (!info || info->data < start) break; pprev = &info->next; } @@ -121,11 +101,9 @@ addSpace(struct zone_s *zone, void *start, void *end) tempdetail.datainfo.pprev = pprev; tempdetail.datainfo.data = tempdetail.datainfo.dataend = start; tempdetail.datainfo.allocend = end; - tempdetail.handle = PMM_DEFAULT_HANDLE; - struct allocdetail_s *tempdetailp = MAKE_FLATPTR(GET_SEG(SS), &tempdetail); - SET_PMMVAR(*pprev, &tempdetailp->datainfo); + *pprev = &tempdetail.datainfo; if (info) - SET_PMMVAR(info->pprev, &tempdetailp->datainfo.next); + info->pprev = &tempdetail.datainfo.next; // Allocate final allocation info. struct allocdetail_s *detail = allocSpace( @@ -134,26 +112,21 @@ addSpace(struct zone_s *zone, void *start, void *end) detail = allocSpace(&ZoneTmpLow, sizeof(*detail) , MALLOC_MIN_ALIGN, NULL); if (!detail) { - SET_PMMVAR(*tempdetail.datainfo.pprev, tempdetail.datainfo.next); + *tempdetail.datainfo.pprev = tempdetail.datainfo.next; if (tempdetail.datainfo.next) - SET_PMMVAR(tempdetail.datainfo.next->pprev - , tempdetail.datainfo.pprev); + tempdetail.datainfo.next->pprev = tempdetail.datainfo.pprev; warn_noalloc(); return; } } // Replace temp alloc space with final alloc space - SET_PMMVAR(detail->datainfo.next, tempdetail.datainfo.next); - SET_PMMVAR(detail->datainfo.pprev, tempdetail.datainfo.pprev); - SET_PMMVAR(detail->datainfo.data, tempdetail.datainfo.data); - SET_PMMVAR(detail->datainfo.dataend, tempdetail.datainfo.dataend); - SET_PMMVAR(detail->datainfo.allocend, tempdetail.datainfo.allocend); - SET_PMMVAR(detail->handle, PMM_DEFAULT_HANDLE); - - SET_PMMVAR(*tempdetail.datainfo.pprev, &detail->datainfo); + memcpy(&detail->datainfo, &tempdetail.datainfo, sizeof(detail->datainfo)); + detail->handle = PMM_DEFAULT_HANDLE; + + *tempdetail.datainfo.pprev = &detail->datainfo; if (tempdetail.datainfo.next) - SET_PMMVAR(tempdetail.datainfo.next->pprev, &detail->datainfo.next); + tempdetail.datainfo.next->pprev = &detail->datainfo.next; } // Search all zones for an allocation obtained from allocSpace() @@ -162,10 +135,10 @@ findAlloc(void *data) { int i; for (i=0; iinfo); info; info = GET_PMMVAR(info->next)) - if (GET_PMMVAR(info->data) == data) + for (info = zone->info; info; info = info->next) + if (info->data == data) return info; } return NULL; @@ -175,11 +148,11 @@ findAlloc(void *data) static struct allocinfo_s * findLast(struct zone_s *zone) { - struct allocinfo_s *info = GET_PMMVAR(zone->info); + struct allocinfo_s *info = zone->info; if (!info) return NULL; for (;;) { - struct allocinfo_s *next = GET_PMMVAR(info->next); + struct allocinfo_s *next = info->next; if (!next) return info; info = next; @@ -197,17 +170,6 @@ malloc_setup(void) ASSERT32FLAT(); dprintf(3, "malloc setup\n"); - ZoneLow.info = ZoneHigh.info = ZoneFSeg.info = NULL; - ZoneTmpLow.info = ZoneTmpHigh.info = NULL; - - // Clear memory in 0xf0000 area. - extern u8 code32flat_start[]; - if ((u32)code32flat_start > BUILD_BIOS_ADDR) - // Clear unused parts of f-segment - memset((void*)BUILD_BIOS_ADDR, 0 - , (u32)code32flat_start - BUILD_BIOS_ADDR); - memset(BiosTableSpace, 0, CONFIG_MAX_BIOSTABLE); - // Populate temp high ram u32 highram = 0; int i; @@ -240,9 +202,33 @@ malloc_setup(void) } } +// Update pointers after code relocation. +void +malloc_fixupreloc(void) +{ + ASSERT32FLAT(); + if (!CONFIG_RELOCATE_INIT) + return; + dprintf(3, "malloc fixup reloc\n"); + + int i; + for (i=0; iinfo->pprev = &zone->info; + } + + // Add space free'd during relocation in f-segment to ZoneFSeg + extern u8 code32init_end[]; + if ((u32)code32init_end > BUILD_BIOS_ADDR) { + memset((void*)BUILD_BIOS_ADDR, 0, (u32)code32init_end - BUILD_BIOS_ADDR); + addSpace(&ZoneFSeg, (void*)BUILD_BIOS_ADDR, code32init_end); + } +} + void malloc_finalize(void) { + ASSERT32FLAT(); dprintf(3, "malloc finalize\n"); // Reserve more low-mem if needed. @@ -256,9 +242,6 @@ malloc_finalize(void) add_e820((u32)info->dataend, giveback, E820_RAM); dprintf(1, "Returned %d bytes of ZoneHigh\n", giveback); } - - // Clear low-memory allocations. - memset((void*)BUILD_STACK_ADDR, 0, BUILD_EBDA_MINIMUM - BUILD_STACK_ADDR); } @@ -276,14 +259,7 @@ relocate_ebda(u32 newebda, u32 oldebda, u8 ebda_size) return -1; // Do copy - if (MODESEGMENT) - memcpy_far(FLATPTR_TO_SEG(newebda) - , (void*)FLATPTR_TO_OFFSET(newebda) - , FLATPTR_TO_SEG(oldebda) - , (void*)FLATPTR_TO_OFFSET(oldebda) - , ebda_size * 1024); - else - memmove((void*)newebda, (void*)oldebda, ebda_size * 1024); + memmove((void*)newebda, (void*)oldebda, ebda_size * 1024); // Update indexes dprintf(1, "ebda moved from %x to %x\n", oldebda, newebda); @@ -299,9 +275,9 @@ zonelow_expand(u32 size, u32 align) struct allocinfo_s *info = findLast(&ZoneLow); if (!info) return; - u32 oldpos = (u32)GET_PMMVAR(info->allocend); + u32 oldpos = (u32)info->allocend; u32 newpos = ALIGN_DOWN(oldpos - size, align); - u32 bottom = (u32)GET_PMMVAR(info->dataend); + u32 bottom = (u32)info->dataend; if (newpos >= bottom && newpos <= oldpos) // Space already present. return; @@ -325,8 +301,8 @@ zonelow_expand(u32 size, u32 align) // Update zone if (ebda_end == bottom) { - SET_PMMVAR(info->data, (void*)newbottom); - SET_PMMVAR(info->dataend, (void*)newbottom); + info->data = (void*)newbottom; + info->dataend = (void*)newbottom; } else addSpace(&ZoneLow, (void*)newbottom, (void*)ebda_end); } @@ -360,6 +336,7 @@ allocExpandSpace(struct zone_s *zone, u32 size, u32 align void * __malloc pmm_malloc(struct zone_s *zone, u32 handle, u32 size, u32 align) { + ASSERT32FLAT(); if (!size) return NULL; @@ -384,7 +361,7 @@ pmm_malloc(struct zone_s *zone, u32 handle, u32 size, u32 align) " ret=%p (detail=%p)\n" , zone, handle, size, align , data, detail); - SET_PMMVAR(detail->handle, handle); + detail->handle = handle; return data; } @@ -393,8 +370,9 @@ pmm_malloc(struct zone_s *zone, u32 handle, u32 size, u32 align) int pmm_free(void *data) { + ASSERT32FLAT(); struct allocinfo_s *info = findAlloc(data); - if (!info || data == (void*)info || data == GET_PMMVAR(info->dataend)) + if (!info || data == (void*)info || data == info->dataend) return -1; struct allocdetail_s *detail = container_of( info, struct allocdetail_s, datainfo); @@ -412,8 +390,8 @@ pmm_getspace(struct zone_s *zone) // XXX - results not reliable when CONFIG_THREAD_OPTIONROMS u32 maxspace = 0; struct allocinfo_s *info; - for (info = GET_PMMVAR(zone->info); info; info = GET_PMMVAR(info->next)) { - u32 space = GET_PMMVAR(info->allocend) - GET_PMMVAR(info->dataend); + for (info = zone->info; info; info = info->next) { + u32 space = info->allocend - info->dataend; if (space > maxspace) maxspace = space; } @@ -433,16 +411,15 @@ pmm_find(u32 handle) { int i; for (i=0; iinfo); info - ; info = GET_PMMVAR(info->next)) { - if (GET_PMMVAR(info->data) != (void*)info) + for (info = zone->info; info; info = info->next) { + if (info->data != (void*)info) continue; struct allocdetail_s *detail = container_of( info, struct allocdetail_s, detailinfo); - if (GET_PMMVAR(detail->handle) == handle) - return GET_PMMVAR(detail->datainfo.data); + if (detail->handle == handle) + return detail->datainfo.data; } } return NULL; @@ -566,21 +543,35 @@ handle_pmmXX(u16 *args) return PMM_FUNCTION_NOT_SUPPORTED; } -u32 VISIBLE16 +u32 VISIBLE32INIT handle_pmm(u16 *args) { + ASSERT32FLAT(); if (! CONFIG_PMM) return PMM_FUNCTION_NOT_SUPPORTED; u16 arg1 = args[0]; dprintf(DEBUG_HDL_pmm, "pmm call arg1=%x\n", arg1); + int oldpreempt; + if (CONFIG_THREAD_OPTIONROMS) { + // Not a preemption event - don't wait in wait_preempt() + oldpreempt = CanPreempt; + CanPreempt = 0; + } + + u32 ret; switch (arg1) { - case 0x00: return handle_pmm00(args); - case 0x01: return handle_pmm01(args); - case 0x02: return handle_pmm02(args); - default: return handle_pmmXX(args); + case 0x00: ret = handle_pmm00(args); break; + case 0x01: ret = handle_pmm01(args); break; + case 0x02: ret = handle_pmm02(args); break; + default: ret = handle_pmmXX(args); break; } + + if (CONFIG_THREAD_OPTIONROMS) + CanPreempt = oldpreempt; + + return ret; } // romlayout.S