Annotation of qemu/roms/seabios/src/pmm.c, revision 1.1.1.5

1.1       root        1: // Post memory manager (PMM) calls
                      2: //
                      3: // Copyright (C) 2009  Kevin O'Connor <[email protected]>
                      4: //
                      5: // This file may be distributed under the terms of the GNU LGPLv3 license.
                      6: 
                      7: #include "util.h" // checksum
                      8: #include "config.h" // BUILD_BIOS_ADDR
1.1.1.3   root        9: #include "memmap.h" // struct e820entry
1.1       root       10: #include "farptr.h" // GET_FARVAR
                     11: #include "biosvar.h" // GET_BDA
                     12: 
1.1.1.3   root       13: // Information on a reserved area.
                     14: struct allocinfo_s {
                     15:     struct allocinfo_s *next, **pprev;
                     16:     void *data, *dataend, *allocend;
                     17: };
                     18: 
                     19: // Information on a tracked memory allocation.
                     20: struct allocdetail_s {
                     21:     struct allocinfo_s detailinfo;
                     22:     struct allocinfo_s datainfo;
                     23:     u32 handle;
                     24: };
                     25: 
                     26: // The various memory zones.
1.1       root       27: struct zone_s {
1.1.1.3   root       28:     struct allocinfo_s *info;
1.1       root       29: };
                     30: 
1.1.1.5 ! root       31: struct zone_s ZoneLow, ZoneHigh, ZoneFSeg, ZoneTmpLow, ZoneTmpHigh;
1.1       root       32: 
1.1.1.5 ! root       33: static struct zone_s *Zones[] = {
1.1       root       34:     &ZoneTmpLow, &ZoneLow, &ZoneFSeg, &ZoneTmpHigh, &ZoneHigh
                     35: };
                     36: 
                     37: 
                     38: /****************************************************************
1.1.1.3   root       39:  * low-level memory reservations
                     40:  ****************************************************************/
                     41: 
                     42: // Find and reserve space from a given zone
                     43: static void *
                     44: allocSpace(struct zone_s *zone, u32 size, u32 align, struct allocinfo_s *fill)
                     45: {
                     46:     struct allocinfo_s *info;
1.1.1.5 ! root       47:     for (info = zone->info; info; info = info->next) {
        !            48:         void *dataend = info->dataend;
        !            49:         void *allocend = info->allocend;
1.1.1.3   root       50:         void *newallocend = (void*)ALIGN_DOWN((u32)allocend - size, align);
                     51:         if (newallocend >= dataend && newallocend <= allocend) {
                     52:             // Found space - now reserve it.
1.1.1.5 ! root       53:             struct allocinfo_s **pprev = info->pprev;
1.1.1.3   root       54:             if (!fill)
                     55:                 fill = newallocend;
1.1.1.5 ! root       56:             fill->next = info;
        !            57:             fill->pprev = pprev;
        !            58:             fill->data = newallocend;
        !            59:             fill->dataend = newallocend + size;
        !            60:             fill->allocend = allocend;
        !            61: 
        !            62:             info->allocend = newallocend;
        !            63:             info->pprev = &fill->next;
        !            64:             *pprev = fill;
1.1.1.3   root       65:             return newallocend;
                     66:         }
                     67:     }
                     68:     return NULL;
                     69: }
                     70: 
                     71: // Release space allocated with allocSpace()
                     72: static void
                     73: freeSpace(struct allocinfo_s *info)
                     74: {
1.1.1.5 ! root       75:     struct allocinfo_s *next = info->next;
        !            76:     struct allocinfo_s **pprev = info->pprev;
        !            77:     *pprev = next;
1.1.1.3   root       78:     if (next) {
1.1.1.5 ! root       79:         if (next->allocend == info->data)
        !            80:             next->allocend = info->allocend;
        !            81:         next->pprev = pprev;
1.1.1.3   root       82:     }
                     83: }
                     84: 
                     85: // Add new memory to a zone
                     86: static void
                     87: addSpace(struct zone_s *zone, void *start, void *end)
                     88: {
                     89:     // Find position to add space
                     90:     struct allocinfo_s **pprev = &zone->info, *info;
                     91:     for (;;) {
1.1.1.5 ! root       92:         info = *pprev;
        !            93:         if (!info || info->data < start)
1.1.1.3   root       94:             break;
                     95:         pprev = &info->next;
                     96:     }
                     97: 
                     98:     // Add space using temporary allocation info.
                     99:     struct allocdetail_s tempdetail;
                    100:     tempdetail.datainfo.next = info;
                    101:     tempdetail.datainfo.pprev = pprev;
                    102:     tempdetail.datainfo.data = tempdetail.datainfo.dataend = start;
                    103:     tempdetail.datainfo.allocend = end;
1.1.1.5 ! root      104:     *pprev = &tempdetail.datainfo;
1.1.1.3   root      105:     if (info)
1.1.1.5 ! root      106:         info->pprev = &tempdetail.datainfo.next;
1.1.1.3   root      107: 
                    108:     // Allocate final allocation info.
                    109:     struct allocdetail_s *detail = allocSpace(
                    110:         &ZoneTmpHigh, sizeof(*detail), MALLOC_MIN_ALIGN, NULL);
                    111:     if (!detail) {
                    112:         detail = allocSpace(&ZoneTmpLow, sizeof(*detail)
                    113:                             , MALLOC_MIN_ALIGN, NULL);
                    114:         if (!detail) {
1.1.1.5 ! root      115:             *tempdetail.datainfo.pprev = tempdetail.datainfo.next;
1.1.1.3   root      116:             if (tempdetail.datainfo.next)
1.1.1.5 ! root      117:                 tempdetail.datainfo.next->pprev = tempdetail.datainfo.pprev;
1.1.1.3   root      118:             warn_noalloc();
                    119:             return;
                    120:         }
                    121:     }
                    122: 
                    123:     // Replace temp alloc space with final alloc space
1.1.1.5 ! root      124:     memcpy(&detail->datainfo, &tempdetail.datainfo, sizeof(detail->datainfo));
        !           125:     detail->handle = PMM_DEFAULT_HANDLE;
1.1.1.3   root      126: 
1.1.1.5 ! root      127:     *tempdetail.datainfo.pprev = &detail->datainfo;
1.1.1.3   root      128:     if (tempdetail.datainfo.next)
1.1.1.5 ! root      129:         tempdetail.datainfo.next->pprev = &detail->datainfo.next;
1.1.1.3   root      130: }
                    131: 
                    132: // Search all zones for an allocation obtained from allocSpace()
                    133: static struct allocinfo_s *
                    134: findAlloc(void *data)
                    135: {
                    136:     int i;
                    137:     for (i=0; i<ARRAY_SIZE(Zones); i++) {
1.1.1.5 ! root      138:         struct zone_s *zone = Zones[i];
1.1.1.3   root      139:         struct allocinfo_s *info;
1.1.1.5 ! root      140:         for (info = zone->info; info; info = info->next)
        !           141:             if (info->data == data)
1.1.1.3   root      142:                 return info;
                    143:     }
                    144:     return NULL;
                    145: }
                    146: 
                    147: // Return the last sentinal node of a zone
                    148: static struct allocinfo_s *
                    149: findLast(struct zone_s *zone)
                    150: {
1.1.1.5 ! root      151:     struct allocinfo_s *info = zone->info;
1.1.1.3   root      152:     if (!info)
                    153:         return NULL;
                    154:     for (;;) {
1.1.1.5 ! root      155:         struct allocinfo_s *next = info->next;
1.1.1.3   root      156:         if (!next)
                    157:             return info;
                    158:         info = next;
                    159:     }
                    160: }
                    161: 
                    162: 
                    163: /****************************************************************
                    164:  * Setup
                    165:  ****************************************************************/
                    166: 
                    167: void
                    168: malloc_setup(void)
                    169: {
                    170:     ASSERT32FLAT();
                    171:     dprintf(3, "malloc setup\n");
                    172: 
                    173:     // Populate temp high ram
                    174:     u32 highram = 0;
                    175:     int i;
                    176:     for (i=e820_count-1; i>=0; i--) {
                    177:         struct e820entry *en = &e820_list[i];
                    178:         u64 end = en->start + en->size;
                    179:         if (end < 1024*1024)
                    180:             break;
                    181:         if (en->type != E820_RAM || end > 0xffffffff)
                    182:             continue;
                    183:         u32 s = en->start, e = end;
                    184:         if (!highram) {
                    185:             u32 newe = ALIGN_DOWN(e - CONFIG_MAX_HIGHTABLE, MALLOC_MIN_ALIGN);
                    186:             if (newe <= e && newe >= s) {
                    187:                 highram = newe;
                    188:                 e = newe;
                    189:             }
                    190:         }
                    191:         addSpace(&ZoneTmpHigh, (void*)s, (void*)e);
                    192:     }
                    193: 
                    194:     // Populate other regions
                    195:     addSpace(&ZoneTmpLow, (void*)BUILD_STACK_ADDR, (void*)BUILD_EBDA_MINIMUM);
                    196:     addSpace(&ZoneFSeg, BiosTableSpace, &BiosTableSpace[CONFIG_MAX_BIOSTABLE]);
                    197:     addSpace(&ZoneLow, (void*)BUILD_LOWRAM_END, (void*)BUILD_LOWRAM_END);
                    198:     if (highram) {
                    199:         addSpace(&ZoneHigh, (void*)highram
                    200:                  , (void*)highram + CONFIG_MAX_HIGHTABLE);
                    201:         add_e820(highram, CONFIG_MAX_HIGHTABLE, E820_RESERVED);
                    202:     }
                    203: }
                    204: 
1.1.1.5 ! root      205: // Update pointers after code relocation.
        !           206: void
        !           207: malloc_fixupreloc(void)
        !           208: {
        !           209:     ASSERT32FLAT();
        !           210:     if (!CONFIG_RELOCATE_INIT)
        !           211:         return;
        !           212:     dprintf(3, "malloc fixup reloc\n");
        !           213: 
        !           214:     int i;
        !           215:     for (i=0; i<ARRAY_SIZE(Zones); i++) {
        !           216:         struct zone_s *zone = Zones[i];
        !           217:         zone->info->pprev = &zone->info;
        !           218:     }
        !           219: 
        !           220:     // Add space free'd during relocation in f-segment to ZoneFSeg
        !           221:     extern u8 code32init_end[];
        !           222:     if ((u32)code32init_end > BUILD_BIOS_ADDR) {
        !           223:         memset((void*)BUILD_BIOS_ADDR, 0, (u32)code32init_end - BUILD_BIOS_ADDR);
        !           224:         addSpace(&ZoneFSeg, (void*)BUILD_BIOS_ADDR, code32init_end);
        !           225:     }
        !           226: }
        !           227: 
1.1.1.3   root      228: void
                    229: malloc_finalize(void)
                    230: {
1.1.1.5 ! root      231:     ASSERT32FLAT();
1.1.1.3   root      232:     dprintf(3, "malloc finalize\n");
                    233: 
                    234:     // Reserve more low-mem if needed.
                    235:     u32 endlow = GET_BDA(mem_size_kb)*1024;
                    236:     add_e820(endlow, BUILD_LOWRAM_END-endlow, E820_RESERVED);
                    237: 
                    238:     // Give back unused high ram.
                    239:     struct allocinfo_s *info = findLast(&ZoneHigh);
                    240:     if (info) {
                    241:         u32 giveback = ALIGN_DOWN(info->allocend - info->dataend, PAGE_SIZE);
                    242:         add_e820((u32)info->dataend, giveback, E820_RAM);
                    243:         dprintf(1, "Returned %d bytes of ZoneHigh\n", giveback);
                    244:     }
                    245: }
                    246: 
                    247: 
                    248: /****************************************************************
1.1       root      249:  * ebda movement
                    250:  ****************************************************************/
                    251: 
                    252: // Move ebda
                    253: static int
                    254: relocate_ebda(u32 newebda, u32 oldebda, u8 ebda_size)
                    255: {
                    256:     u32 lowram = GET_BDA(mem_size_kb) * 1024;
                    257:     if (oldebda != lowram)
                    258:         // EBDA isn't at end of ram - give up.
                    259:         return -1;
                    260: 
1.1.1.5 ! root      261:     // Do copy
        !           262:     memmove((void*)newebda, (void*)oldebda, ebda_size * 1024);
1.1       root      263: 
                    264:     // Update indexes
                    265:     dprintf(1, "ebda moved from %x to %x\n", oldebda, newebda);
                    266:     SET_BDA(mem_size_kb, newebda / 1024);
                    267:     SET_BDA(ebda_seg, FLATPTR_TO_SEG(newebda));
                    268:     return 0;
                    269: }
                    270: 
                    271: // Support expanding the ZoneLow dynamically.
                    272: static void
                    273: zonelow_expand(u32 size, u32 align)
                    274: {
1.1.1.3   root      275:     struct allocinfo_s *info = findLast(&ZoneLow);
                    276:     if (!info)
                    277:         return;
1.1.1.5 ! root      278:     u32 oldpos = (u32)info->allocend;
1.1       root      279:     u32 newpos = ALIGN_DOWN(oldpos - size, align);
1.1.1.5 ! root      280:     u32 bottom = (u32)info->dataend;
1.1       root      281:     if (newpos >= bottom && newpos <= oldpos)
                    282:         // Space already present.
                    283:         return;
                    284:     u16 ebda_seg = get_ebda_seg();
                    285:     u32 ebda_pos = (u32)MAKE_FLATPTR(ebda_seg, 0);
                    286:     u8 ebda_size = GET_EBDA2(ebda_seg, size);
                    287:     u32 ebda_end = ebda_pos + ebda_size * 1024;
1.1.1.3   root      288:     if (ebda_end != bottom)
1.1       root      289:         // Something else is after ebda - can't use any existing space.
1.1.1.3   root      290:         newpos = ALIGN_DOWN(ebda_end - size, align);
1.1       root      291:     u32 newbottom = ALIGN_DOWN(newpos, 1024);
                    292:     u32 newebda = ALIGN_DOWN(newbottom - ebda_size * 1024, 1024);
                    293:     if (newebda < BUILD_EBDA_MINIMUM)
                    294:         // Not enough space.
                    295:         return;
                    296: 
                    297:     // Move ebda
                    298:     int ret = relocate_ebda(newebda, ebda_pos, ebda_size);
                    299:     if (ret)
                    300:         return;
                    301: 
                    302:     // Update zone
1.1.1.3   root      303:     if (ebda_end == bottom) {
1.1.1.5 ! root      304:         info->data = (void*)newbottom;
        !           305:         info->dataend = (void*)newbottom;
1.1.1.3   root      306:     } else
                    307:         addSpace(&ZoneLow, (void*)newbottom, (void*)ebda_end);
1.1       root      308: }
                    309: 
1.1.1.3   root      310: // Check if can expand the given zone to fulfill an allocation
1.1       root      311: static void *
1.1.1.3   root      312: allocExpandSpace(struct zone_s *zone, u32 size, u32 align
                    313:                  , struct allocinfo_s *fill)
1.1       root      314: {
1.1.1.3   root      315:     void *data = allocSpace(zone, size, align, fill);
                    316:     if (data || zone != &ZoneLow)
                    317:         return data;
                    318: 
                    319:     // Make sure to not move ebda while an optionrom is running.
                    320:     if (unlikely(wait_preempt())) {
                    321:         data = allocSpace(zone, size, align, fill);
                    322:         if (data)
                    323:             return data;
1.1       root      324:     }
                    325: 
1.1.1.3   root      326:     zonelow_expand(size, align);
                    327:     return allocSpace(zone, size, align, fill);
1.1       root      328: }
                    329: 
                    330: 
                    331: /****************************************************************
                    332:  * tracked memory allocations
                    333:  ****************************************************************/
                    334: 
                    335: // Allocate memory from the given zone and track it as a PMM allocation
1.1.1.3   root      336: void * __malloc
1.1       root      337: pmm_malloc(struct zone_s *zone, u32 handle, u32 size, u32 align)
                    338: {
1.1.1.5 ! root      339:     ASSERT32FLAT();
1.1.1.3   root      340:     if (!size)
                    341:         return NULL;
                    342: 
                    343:     // Find and reserve space for bookkeeping.
                    344:     struct allocdetail_s *detail = allocSpace(
                    345:         &ZoneTmpHigh, sizeof(*detail), MALLOC_MIN_ALIGN, NULL);
                    346:     if (!detail) {
                    347:         detail = allocSpace(&ZoneTmpLow, sizeof(*detail)
                    348:                             , MALLOC_MIN_ALIGN, NULL);
                    349:         if (!detail)
1.1       root      350:             return NULL;
                    351:     }
1.1.1.3   root      352: 
                    353:     // Find and reserve space for main allocation
                    354:     void *data = allocExpandSpace(zone, size, align, &detail->datainfo);
                    355:     if (!data) {
                    356:         freeSpace(&detail->detailinfo);
1.1       root      357:         return NULL;
                    358:     }
1.1.1.3   root      359: 
1.1       root      360:     dprintf(8, "pmm_malloc zone=%p handle=%x size=%d align=%x"
1.1.1.3   root      361:             " ret=%p (detail=%p)\n"
1.1       root      362:             , zone, handle, size, align
1.1.1.3   root      363:             , data, detail);
1.1.1.5 ! root      364:     detail->handle = handle;
1.1       root      365: 
1.1.1.3   root      366:     return data;
1.1       root      367: }
                    368: 
                    369: // Free a data block allocated with pmm_malloc
                    370: int
                    371: pmm_free(void *data)
                    372: {
1.1.1.5 ! root      373:     ASSERT32FLAT();
1.1.1.3   root      374:     struct allocinfo_s *info = findAlloc(data);
1.1.1.5 ! root      375:     if (!info || data == (void*)info || data == info->dataend)
1.1.1.3   root      376:         return -1;
                    377:     struct allocdetail_s *detail = container_of(
                    378:         info, struct allocdetail_s, datainfo);
                    379:     dprintf(8, "pmm_free %p (detail=%p)\n", data, detail);
                    380:     freeSpace(info);
                    381:     freeSpace(&detail->detailinfo);
                    382:     return 0;
1.1       root      383: }
                    384: 
                    385: // Find the amount of free space in a given zone.
                    386: static u32
                    387: pmm_getspace(struct zone_s *zone)
                    388: {
                    389:     // XXX - doesn't account for ZoneLow being able to grow.
1.1.1.3   root      390:     // XXX - results not reliable when CONFIG_THREAD_OPTIONROMS
                    391:     u32 maxspace = 0;
                    392:     struct allocinfo_s *info;
1.1.1.5 ! root      393:     for (info = zone->info; info; info = info->next) {
        !           394:         u32 space = info->allocend - info->dataend;
1.1.1.3   root      395:         if (space > maxspace)
                    396:             maxspace = space;
                    397:     }
                    398: 
1.1       root      399:     if (zone != &ZoneTmpHigh && zone != &ZoneTmpLow)
1.1.1.3   root      400:         return maxspace;
1.1       root      401:     // Account for space needed for PMM tracking.
1.1.1.3   root      402:     u32 reserve = ALIGN(sizeof(struct allocdetail_s), MALLOC_MIN_ALIGN);
                    403:     if (maxspace <= reserve)
1.1       root      404:         return 0;
1.1.1.3   root      405:     return maxspace - reserve;
1.1       root      406: }
                    407: 
                    408: // Find the data block allocated with pmm_malloc with a given handle.
                    409: static void *
                    410: pmm_find(u32 handle)
                    411: {
1.1.1.3   root      412:     int i;
                    413:     for (i=0; i<ARRAY_SIZE(Zones); i++) {
1.1.1.5 ! root      414:         struct zone_s *zone = Zones[i];
1.1.1.3   root      415:         struct allocinfo_s *info;
1.1.1.5 ! root      416:         for (info = zone->info; info; info = info->next) {
        !           417:             if (info->data != (void*)info)
1.1.1.3   root      418:                 continue;
                    419:             struct allocdetail_s *detail = container_of(
                    420:                 info, struct allocdetail_s, detailinfo);
1.1.1.5 ! root      421:             if (detail->handle == handle)
        !           422:                 return detail->datainfo.data;
1.1.1.3   root      423:         }
1.1       root      424:     }
1.1.1.3   root      425:     return NULL;
1.1       root      426: }
                    427: 
                    428: 
                    429: /****************************************************************
                    430:  * pmm interface
                    431:  ****************************************************************/
                    432: 
                    433: struct pmmheader {
                    434:     u32 signature;
                    435:     u8 version;
                    436:     u8 length;
                    437:     u8 checksum;
                    438:     u16 entry_offset;
                    439:     u16 entry_seg;
                    440:     u8 reserved[5];
                    441: } PACKED;
                    442: 
                    443: extern struct pmmheader PMMHEADER;
                    444: 
                    445: #define PMM_SIGNATURE 0x4d4d5024 // $PMM
                    446: 
                    447: #if CONFIG_PMM
                    448: struct pmmheader PMMHEADER __aligned(16) VAR16EXPORT = {
                    449:     .version = 0x01,
                    450:     .length = sizeof(PMMHEADER),
                    451:     .entry_seg = SEG_BIOS,
                    452: };
                    453: #endif
                    454: 
                    455: #define PMM_FUNCTION_NOT_SUPPORTED 0xffffffff
                    456: 
                    457: // PMM - allocate
                    458: static u32
                    459: handle_pmm00(u16 *args)
                    460: {
                    461:     u32 length = *(u32*)&args[1], handle = *(u32*)&args[3];
                    462:     u16 flags = args[5];
                    463:     dprintf(3, "pmm00: length=%x handle=%x flags=%x\n"
                    464:             , length, handle, flags);
                    465:     struct zone_s *lowzone = &ZoneTmpLow, *highzone = &ZoneTmpHigh;
                    466:     if (flags & 8) {
                    467:         // Permanent memory request.
                    468:         lowzone = &ZoneLow;
                    469:         highzone = &ZoneHigh;
                    470:     }
                    471:     if (!length) {
                    472:         // Memory size request
                    473:         switch (flags & 3) {
                    474:         default:
                    475:         case 0:
                    476:             return 0;
                    477:         case 1:
                    478:             return pmm_getspace(lowzone);
                    479:         case 2:
                    480:             return pmm_getspace(highzone);
                    481:         case 3: {
                    482:             u32 spacelow = pmm_getspace(lowzone);
                    483:             u32 spacehigh = pmm_getspace(highzone);
                    484:             if (spacelow > spacehigh)
                    485:                 return spacelow;
                    486:             return spacehigh;
                    487:         }
                    488:         }
                    489:     }
                    490:     u32 size = length * 16;
                    491:     if ((s32)size <= 0)
                    492:         return 0;
                    493:     u32 align = MALLOC_MIN_ALIGN;
                    494:     if (flags & 4) {
                    495:         align = 1<<__ffs(size);
                    496:         if (align < MALLOC_MIN_ALIGN)
                    497:             align = MALLOC_MIN_ALIGN;
                    498:     }
                    499:     switch (flags & 3) {
                    500:     default:
                    501:     case 0:
                    502:         return 0;
                    503:     case 1:
                    504:         return (u32)pmm_malloc(lowzone, handle, size, align);
                    505:     case 2:
                    506:         return (u32)pmm_malloc(highzone, handle, size, align);
                    507:     case 3: {
                    508:         void *data = pmm_malloc(lowzone, handle, size, align);
                    509:         if (data)
                    510:             return (u32)data;
                    511:         return (u32)pmm_malloc(highzone, handle, size, align);
                    512:     }
                    513:     }
                    514: }
                    515: 
                    516: // PMM - find
                    517: static u32
                    518: handle_pmm01(u16 *args)
                    519: {
                    520:     u32 handle = *(u32*)&args[1];
                    521:     dprintf(3, "pmm01: handle=%x\n", handle);
                    522:     if (handle == PMM_DEFAULT_HANDLE)
                    523:         return 0;
                    524:     return (u32)pmm_find(handle);
                    525: }
                    526: 
                    527: // PMM - deallocate
                    528: static u32
                    529: handle_pmm02(u16 *args)
                    530: {
                    531:     u32 buffer = *(u32*)&args[1];
                    532:     dprintf(3, "pmm02: buffer=%x\n", buffer);
                    533:     int ret = pmm_free((void*)buffer);
                    534:     if (ret)
                    535:         // Error
                    536:         return 1;
                    537:     return 0;
                    538: }
                    539: 
                    540: static u32
                    541: handle_pmmXX(u16 *args)
                    542: {
                    543:     return PMM_FUNCTION_NOT_SUPPORTED;
                    544: }
                    545: 
1.1.1.5 ! root      546: u32 VISIBLE32INIT
1.1       root      547: handle_pmm(u16 *args)
                    548: {
1.1.1.5 ! root      549:     ASSERT32FLAT();
1.1       root      550:     if (! CONFIG_PMM)
                    551:         return PMM_FUNCTION_NOT_SUPPORTED;
                    552: 
                    553:     u16 arg1 = args[0];
                    554:     dprintf(DEBUG_HDL_pmm, "pmm call arg1=%x\n", arg1);
                    555: 
1.1.1.5 ! root      556:     int oldpreempt;
        !           557:     if (CONFIG_THREAD_OPTIONROMS) {
        !           558:         // Not a preemption event - don't wait in wait_preempt()
        !           559:         oldpreempt = CanPreempt;
        !           560:         CanPreempt = 0;
        !           561:     }
        !           562: 
        !           563:     u32 ret;
1.1       root      564:     switch (arg1) {
1.1.1.5 ! root      565:     case 0x00: ret = handle_pmm00(args); break;
        !           566:     case 0x01: ret = handle_pmm01(args); break;
        !           567:     case 0x02: ret = handle_pmm02(args); break;
        !           568:     default:   ret = handle_pmmXX(args); break;
1.1       root      569:     }
1.1.1.5 ! root      570: 
        !           571:     if (CONFIG_THREAD_OPTIONROMS)
        !           572:         CanPreempt = oldpreempt;
        !           573: 
        !           574:     return ret;
1.1       root      575: }
                    576: 
                    577: // romlayout.S
1.1.1.2   root      578: extern void entry_pmm(void);
1.1       root      579: 
                    580: void
1.1.1.2   root      581: pmm_setup(void)
1.1       root      582: {
                    583:     if (! CONFIG_PMM)
                    584:         return;
                    585: 
                    586:     dprintf(3, "init PMM\n");
                    587: 
                    588:     PMMHEADER.signature = PMM_SIGNATURE;
                    589:     PMMHEADER.entry_offset = (u32)entry_pmm - BUILD_BIOS_ADDR;
                    590:     PMMHEADER.checksum -= checksum(&PMMHEADER, sizeof(PMMHEADER));
                    591: }
                    592: 
                    593: void
1.1.1.2   root      594: pmm_finalize(void)
1.1       root      595: {
                    596:     if (! CONFIG_PMM)
                    597:         return;
                    598: 
                    599:     dprintf(3, "finalize PMM\n");
                    600: 
                    601:     PMMHEADER.signature = 0;
                    602:     PMMHEADER.entry_offset = 0;
                    603: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.