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

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];
1.1.1.6 ! root      217:         if (zone->info)
        !           218:             zone->info->pprev = &zone->info;
1.1.1.5   root      219:     }
                    220: 
                    221:     // Add space free'd during relocation in f-segment to ZoneFSeg
                    222:     extern u8 code32init_end[];
                    223:     if ((u32)code32init_end > BUILD_BIOS_ADDR) {
                    224:         memset((void*)BUILD_BIOS_ADDR, 0, (u32)code32init_end - BUILD_BIOS_ADDR);
                    225:         addSpace(&ZoneFSeg, (void*)BUILD_BIOS_ADDR, code32init_end);
                    226:     }
                    227: }
                    228: 
1.1.1.3   root      229: void
                    230: malloc_finalize(void)
                    231: {
1.1.1.5   root      232:     ASSERT32FLAT();
1.1.1.3   root      233:     dprintf(3, "malloc finalize\n");
                    234: 
                    235:     // Reserve more low-mem if needed.
                    236:     u32 endlow = GET_BDA(mem_size_kb)*1024;
                    237:     add_e820(endlow, BUILD_LOWRAM_END-endlow, E820_RESERVED);
                    238: 
                    239:     // Give back unused high ram.
                    240:     struct allocinfo_s *info = findLast(&ZoneHigh);
                    241:     if (info) {
                    242:         u32 giveback = ALIGN_DOWN(info->allocend - info->dataend, PAGE_SIZE);
                    243:         add_e820((u32)info->dataend, giveback, E820_RAM);
                    244:         dprintf(1, "Returned %d bytes of ZoneHigh\n", giveback);
                    245:     }
                    246: }
                    247: 
                    248: 
                    249: /****************************************************************
1.1       root      250:  * ebda movement
                    251:  ****************************************************************/
                    252: 
                    253: // Move ebda
                    254: static int
                    255: relocate_ebda(u32 newebda, u32 oldebda, u8 ebda_size)
                    256: {
                    257:     u32 lowram = GET_BDA(mem_size_kb) * 1024;
                    258:     if (oldebda != lowram)
                    259:         // EBDA isn't at end of ram - give up.
                    260:         return -1;
                    261: 
1.1.1.5   root      262:     // Do copy
                    263:     memmove((void*)newebda, (void*)oldebda, ebda_size * 1024);
1.1       root      264: 
                    265:     // Update indexes
                    266:     dprintf(1, "ebda moved from %x to %x\n", oldebda, newebda);
                    267:     SET_BDA(mem_size_kb, newebda / 1024);
                    268:     SET_BDA(ebda_seg, FLATPTR_TO_SEG(newebda));
                    269:     return 0;
                    270: }
                    271: 
                    272: // Support expanding the ZoneLow dynamically.
                    273: static void
                    274: zonelow_expand(u32 size, u32 align)
                    275: {
1.1.1.3   root      276:     struct allocinfo_s *info = findLast(&ZoneLow);
                    277:     if (!info)
                    278:         return;
1.1.1.5   root      279:     u32 oldpos = (u32)info->allocend;
1.1       root      280:     u32 newpos = ALIGN_DOWN(oldpos - size, align);
1.1.1.5   root      281:     u32 bottom = (u32)info->dataend;
1.1       root      282:     if (newpos >= bottom && newpos <= oldpos)
                    283:         // Space already present.
                    284:         return;
                    285:     u16 ebda_seg = get_ebda_seg();
                    286:     u32 ebda_pos = (u32)MAKE_FLATPTR(ebda_seg, 0);
                    287:     u8 ebda_size = GET_EBDA2(ebda_seg, size);
                    288:     u32 ebda_end = ebda_pos + ebda_size * 1024;
1.1.1.3   root      289:     if (ebda_end != bottom)
1.1       root      290:         // Something else is after ebda - can't use any existing space.
1.1.1.3   root      291:         newpos = ALIGN_DOWN(ebda_end - size, align);
1.1       root      292:     u32 newbottom = ALIGN_DOWN(newpos, 1024);
                    293:     u32 newebda = ALIGN_DOWN(newbottom - ebda_size * 1024, 1024);
                    294:     if (newebda < BUILD_EBDA_MINIMUM)
                    295:         // Not enough space.
                    296:         return;
                    297: 
                    298:     // Move ebda
                    299:     int ret = relocate_ebda(newebda, ebda_pos, ebda_size);
                    300:     if (ret)
                    301:         return;
                    302: 
                    303:     // Update zone
1.1.1.3   root      304:     if (ebda_end == bottom) {
1.1.1.5   root      305:         info->data = (void*)newbottom;
                    306:         info->dataend = (void*)newbottom;
1.1.1.3   root      307:     } else
                    308:         addSpace(&ZoneLow, (void*)newbottom, (void*)ebda_end);
1.1       root      309: }
                    310: 
1.1.1.3   root      311: // Check if can expand the given zone to fulfill an allocation
1.1       root      312: static void *
1.1.1.3   root      313: allocExpandSpace(struct zone_s *zone, u32 size, u32 align
                    314:                  , struct allocinfo_s *fill)
1.1       root      315: {
1.1.1.3   root      316:     void *data = allocSpace(zone, size, align, fill);
                    317:     if (data || zone != &ZoneLow)
                    318:         return data;
                    319: 
                    320:     // Make sure to not move ebda while an optionrom is running.
                    321:     if (unlikely(wait_preempt())) {
                    322:         data = allocSpace(zone, size, align, fill);
                    323:         if (data)
                    324:             return data;
1.1       root      325:     }
                    326: 
1.1.1.3   root      327:     zonelow_expand(size, align);
                    328:     return allocSpace(zone, size, align, fill);
1.1       root      329: }
                    330: 
                    331: 
                    332: /****************************************************************
                    333:  * tracked memory allocations
                    334:  ****************************************************************/
                    335: 
                    336: // Allocate memory from the given zone and track it as a PMM allocation
1.1.1.3   root      337: void * __malloc
1.1       root      338: pmm_malloc(struct zone_s *zone, u32 handle, u32 size, u32 align)
                    339: {
1.1.1.5   root      340:     ASSERT32FLAT();
1.1.1.3   root      341:     if (!size)
                    342:         return NULL;
                    343: 
                    344:     // Find and reserve space for bookkeeping.
                    345:     struct allocdetail_s *detail = allocSpace(
                    346:         &ZoneTmpHigh, sizeof(*detail), MALLOC_MIN_ALIGN, NULL);
                    347:     if (!detail) {
                    348:         detail = allocSpace(&ZoneTmpLow, sizeof(*detail)
                    349:                             , MALLOC_MIN_ALIGN, NULL);
                    350:         if (!detail)
1.1       root      351:             return NULL;
                    352:     }
1.1.1.3   root      353: 
                    354:     // Find and reserve space for main allocation
                    355:     void *data = allocExpandSpace(zone, size, align, &detail->datainfo);
                    356:     if (!data) {
                    357:         freeSpace(&detail->detailinfo);
1.1       root      358:         return NULL;
                    359:     }
1.1.1.3   root      360: 
1.1       root      361:     dprintf(8, "pmm_malloc zone=%p handle=%x size=%d align=%x"
1.1.1.3   root      362:             " ret=%p (detail=%p)\n"
1.1       root      363:             , zone, handle, size, align
1.1.1.3   root      364:             , data, detail);
1.1.1.5   root      365:     detail->handle = handle;
1.1       root      366: 
1.1.1.3   root      367:     return data;
1.1       root      368: }
                    369: 
                    370: // Free a data block allocated with pmm_malloc
                    371: int
                    372: pmm_free(void *data)
                    373: {
1.1.1.5   root      374:     ASSERT32FLAT();
1.1.1.3   root      375:     struct allocinfo_s *info = findAlloc(data);
1.1.1.5   root      376:     if (!info || data == (void*)info || data == info->dataend)
1.1.1.3   root      377:         return -1;
                    378:     struct allocdetail_s *detail = container_of(
                    379:         info, struct allocdetail_s, datainfo);
                    380:     dprintf(8, "pmm_free %p (detail=%p)\n", data, detail);
                    381:     freeSpace(info);
                    382:     freeSpace(&detail->detailinfo);
                    383:     return 0;
1.1       root      384: }
                    385: 
                    386: // Find the amount of free space in a given zone.
                    387: static u32
                    388: pmm_getspace(struct zone_s *zone)
                    389: {
                    390:     // XXX - doesn't account for ZoneLow being able to grow.
1.1.1.3   root      391:     // XXX - results not reliable when CONFIG_THREAD_OPTIONROMS
                    392:     u32 maxspace = 0;
                    393:     struct allocinfo_s *info;
1.1.1.5   root      394:     for (info = zone->info; info; info = info->next) {
                    395:         u32 space = info->allocend - info->dataend;
1.1.1.3   root      396:         if (space > maxspace)
                    397:             maxspace = space;
                    398:     }
                    399: 
1.1       root      400:     if (zone != &ZoneTmpHigh && zone != &ZoneTmpLow)
1.1.1.3   root      401:         return maxspace;
1.1       root      402:     // Account for space needed for PMM tracking.
1.1.1.3   root      403:     u32 reserve = ALIGN(sizeof(struct allocdetail_s), MALLOC_MIN_ALIGN);
                    404:     if (maxspace <= reserve)
1.1       root      405:         return 0;
1.1.1.3   root      406:     return maxspace - reserve;
1.1       root      407: }
                    408: 
                    409: // Find the data block allocated with pmm_malloc with a given handle.
                    410: static void *
                    411: pmm_find(u32 handle)
                    412: {
1.1.1.3   root      413:     int i;
                    414:     for (i=0; i<ARRAY_SIZE(Zones); i++) {
1.1.1.5   root      415:         struct zone_s *zone = Zones[i];
1.1.1.3   root      416:         struct allocinfo_s *info;
1.1.1.5   root      417:         for (info = zone->info; info; info = info->next) {
                    418:             if (info->data != (void*)info)
1.1.1.3   root      419:                 continue;
                    420:             struct allocdetail_s *detail = container_of(
                    421:                 info, struct allocdetail_s, detailinfo);
1.1.1.5   root      422:             if (detail->handle == handle)
                    423:                 return detail->datainfo.data;
1.1.1.3   root      424:         }
1.1       root      425:     }
1.1.1.3   root      426:     return NULL;
1.1       root      427: }
                    428: 
                    429: 
                    430: /****************************************************************
                    431:  * pmm interface
                    432:  ****************************************************************/
                    433: 
                    434: struct pmmheader {
                    435:     u32 signature;
                    436:     u8 version;
                    437:     u8 length;
                    438:     u8 checksum;
                    439:     u16 entry_offset;
                    440:     u16 entry_seg;
                    441:     u8 reserved[5];
                    442: } PACKED;
                    443: 
                    444: extern struct pmmheader PMMHEADER;
                    445: 
                    446: #define PMM_SIGNATURE 0x4d4d5024 // $PMM
                    447: 
                    448: #if CONFIG_PMM
                    449: struct pmmheader PMMHEADER __aligned(16) VAR16EXPORT = {
                    450:     .version = 0x01,
                    451:     .length = sizeof(PMMHEADER),
                    452:     .entry_seg = SEG_BIOS,
                    453: };
                    454: #endif
                    455: 
                    456: #define PMM_FUNCTION_NOT_SUPPORTED 0xffffffff
                    457: 
                    458: // PMM - allocate
                    459: static u32
                    460: handle_pmm00(u16 *args)
                    461: {
                    462:     u32 length = *(u32*)&args[1], handle = *(u32*)&args[3];
                    463:     u16 flags = args[5];
                    464:     dprintf(3, "pmm00: length=%x handle=%x flags=%x\n"
                    465:             , length, handle, flags);
                    466:     struct zone_s *lowzone = &ZoneTmpLow, *highzone = &ZoneTmpHigh;
                    467:     if (flags & 8) {
                    468:         // Permanent memory request.
                    469:         lowzone = &ZoneLow;
                    470:         highzone = &ZoneHigh;
                    471:     }
                    472:     if (!length) {
                    473:         // Memory size request
                    474:         switch (flags & 3) {
                    475:         default:
                    476:         case 0:
                    477:             return 0;
                    478:         case 1:
                    479:             return pmm_getspace(lowzone);
                    480:         case 2:
                    481:             return pmm_getspace(highzone);
                    482:         case 3: {
                    483:             u32 spacelow = pmm_getspace(lowzone);
                    484:             u32 spacehigh = pmm_getspace(highzone);
                    485:             if (spacelow > spacehigh)
                    486:                 return spacelow;
                    487:             return spacehigh;
                    488:         }
                    489:         }
                    490:     }
                    491:     u32 size = length * 16;
                    492:     if ((s32)size <= 0)
                    493:         return 0;
                    494:     u32 align = MALLOC_MIN_ALIGN;
                    495:     if (flags & 4) {
                    496:         align = 1<<__ffs(size);
                    497:         if (align < MALLOC_MIN_ALIGN)
                    498:             align = MALLOC_MIN_ALIGN;
                    499:     }
                    500:     switch (flags & 3) {
                    501:     default:
                    502:     case 0:
                    503:         return 0;
                    504:     case 1:
                    505:         return (u32)pmm_malloc(lowzone, handle, size, align);
                    506:     case 2:
                    507:         return (u32)pmm_malloc(highzone, handle, size, align);
                    508:     case 3: {
                    509:         void *data = pmm_malloc(lowzone, handle, size, align);
                    510:         if (data)
                    511:             return (u32)data;
                    512:         return (u32)pmm_malloc(highzone, handle, size, align);
                    513:     }
                    514:     }
                    515: }
                    516: 
                    517: // PMM - find
                    518: static u32
                    519: handle_pmm01(u16 *args)
                    520: {
                    521:     u32 handle = *(u32*)&args[1];
                    522:     dprintf(3, "pmm01: handle=%x\n", handle);
                    523:     if (handle == PMM_DEFAULT_HANDLE)
                    524:         return 0;
                    525:     return (u32)pmm_find(handle);
                    526: }
                    527: 
                    528: // PMM - deallocate
                    529: static u32
                    530: handle_pmm02(u16 *args)
                    531: {
                    532:     u32 buffer = *(u32*)&args[1];
                    533:     dprintf(3, "pmm02: buffer=%x\n", buffer);
                    534:     int ret = pmm_free((void*)buffer);
                    535:     if (ret)
                    536:         // Error
                    537:         return 1;
                    538:     return 0;
                    539: }
                    540: 
                    541: static u32
                    542: handle_pmmXX(u16 *args)
                    543: {
                    544:     return PMM_FUNCTION_NOT_SUPPORTED;
                    545: }
                    546: 
1.1.1.5   root      547: u32 VISIBLE32INIT
1.1       root      548: handle_pmm(u16 *args)
                    549: {
1.1.1.5   root      550:     ASSERT32FLAT();
1.1       root      551:     if (! CONFIG_PMM)
                    552:         return PMM_FUNCTION_NOT_SUPPORTED;
                    553: 
                    554:     u16 arg1 = args[0];
                    555:     dprintf(DEBUG_HDL_pmm, "pmm call arg1=%x\n", arg1);
                    556: 
1.1.1.5   root      557:     int oldpreempt;
                    558:     if (CONFIG_THREAD_OPTIONROMS) {
                    559:         // Not a preemption event - don't wait in wait_preempt()
                    560:         oldpreempt = CanPreempt;
                    561:         CanPreempt = 0;
                    562:     }
                    563: 
                    564:     u32 ret;
1.1       root      565:     switch (arg1) {
1.1.1.5   root      566:     case 0x00: ret = handle_pmm00(args); break;
                    567:     case 0x01: ret = handle_pmm01(args); break;
                    568:     case 0x02: ret = handle_pmm02(args); break;
                    569:     default:   ret = handle_pmmXX(args); break;
1.1       root      570:     }
1.1.1.5   root      571: 
                    572:     if (CONFIG_THREAD_OPTIONROMS)
                    573:         CanPreempt = oldpreempt;
                    574: 
                    575:     return ret;
1.1       root      576: }
                    577: 
                    578: // romlayout.S
1.1.1.2   root      579: extern void entry_pmm(void);
1.1       root      580: 
                    581: void
1.1.1.2   root      582: pmm_setup(void)
1.1       root      583: {
                    584:     if (! CONFIG_PMM)
                    585:         return;
                    586: 
                    587:     dprintf(3, "init PMM\n");
                    588: 
                    589:     PMMHEADER.signature = PMM_SIGNATURE;
                    590:     PMMHEADER.entry_offset = (u32)entry_pmm - BUILD_BIOS_ADDR;
                    591:     PMMHEADER.checksum -= checksum(&PMMHEADER, sizeof(PMMHEADER));
                    592: }
                    593: 
                    594: void
1.1.1.2   root      595: pmm_finalize(void)
1.1       root      596: {
                    597:     if (! CONFIG_PMM)
                    598:         return;
                    599: 
                    600:     dprintf(3, "finalize PMM\n");
                    601: 
                    602:     PMMHEADER.signature = 0;
                    603:     PMMHEADER.entry_offset = 0;
                    604: }

unix.superglobalmegacorp.com

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