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

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: 
                     13: 
1.1.1.2   root       14: #if MODESEGMENT
1.1       root       15: // The 16bit pmm entry points runs in "big real" mode, and can
                     16: // therefore read/write to the 32bit malloc variables.
1.1.1.2   root       17: #define GET_PMMVAR(var) ({                      \
                     18:             SET_SEG(ES, 0);                     \
                     19:             __GET_VAR("addr32 ", ES, (var)); })
                     20: #define SET_PMMVAR(var, val) do {               \
                     21:         SET_SEG(ES, 0);                         \
                     22:         __SET_VAR("addr32 ", ES, (var), (val)); \
                     23:     } while (0)
1.1       root       24: #else
                     25: #define GET_PMMVAR(var) (var)
                     26: #define SET_PMMVAR(var, val) do { (var) = (val); } while (0)
                     27: #endif
                     28: 
1.1.1.3   root       29: // Information on a reserved area.
                     30: struct allocinfo_s {
                     31:     struct allocinfo_s *next, **pprev;
                     32:     void *data, *dataend, *allocend;
                     33: };
                     34: 
                     35: // Information on a tracked memory allocation.
                     36: struct allocdetail_s {
                     37:     struct allocinfo_s detailinfo;
                     38:     struct allocinfo_s datainfo;
                     39:     u32 handle;
                     40: };
                     41: 
                     42: // The various memory zones.
1.1       root       43: struct zone_s {
1.1.1.3   root       44:     struct allocinfo_s *info;
1.1       root       45: };
                     46: 
1.1.1.3   root       47: struct zone_s ZoneLow VAR32FLATVISIBLE;
                     48: struct zone_s ZoneHigh VAR32FLATVISIBLE;
1.1.1.2   root       49: struct zone_s ZoneFSeg VAR32FLATVISIBLE;
1.1.1.3   root       50: struct zone_s ZoneTmpLow VAR32FLATVISIBLE;
                     51: struct zone_s ZoneTmpHigh VAR32FLATVISIBLE;
1.1       root       52: 
1.1.1.2   root       53: struct zone_s *Zones[] VAR32FLATVISIBLE = {
1.1       root       54:     &ZoneTmpLow, &ZoneLow, &ZoneFSeg, &ZoneTmpHigh, &ZoneHigh
                     55: };
                     56: 
                     57: 
                     58: /****************************************************************
1.1.1.3   root       59:  * low-level memory reservations
                     60:  ****************************************************************/
                     61: 
                     62: // Find and reserve space from a given zone
                     63: static void *
                     64: allocSpace(struct zone_s *zone, u32 size, u32 align, struct allocinfo_s *fill)
                     65: {
                     66:     struct allocinfo_s *info;
                     67:     for (info = GET_PMMVAR(zone->info); info; info = GET_PMMVAR(info->next)) {
                     68:         void *dataend = GET_PMMVAR(info->dataend);
                     69:         void *allocend = GET_PMMVAR(info->allocend);
                     70:         void *newallocend = (void*)ALIGN_DOWN((u32)allocend - size, align);
                     71:         if (newallocend >= dataend && newallocend <= allocend) {
                     72:             // Found space - now reserve it.
                     73:             struct allocinfo_s **pprev = GET_PMMVAR(info->pprev);
                     74:             if (!fill)
                     75:                 fill = newallocend;
                     76:             SET_PMMVAR(fill->next, info);
                     77:             SET_PMMVAR(fill->pprev, pprev);
                     78:             SET_PMMVAR(fill->data, newallocend);
                     79:             SET_PMMVAR(fill->dataend, newallocend + size);
                     80:             SET_PMMVAR(fill->allocend, allocend);
                     81: 
                     82:             SET_PMMVAR(info->allocend, newallocend);
                     83:             SET_PMMVAR(info->pprev, &fill->next);
                     84:             SET_PMMVAR(*pprev, fill);
                     85:             return newallocend;
                     86:         }
                     87:     }
                     88:     return NULL;
                     89: }
                     90: 
                     91: // Release space allocated with allocSpace()
                     92: static void
                     93: freeSpace(struct allocinfo_s *info)
                     94: {
                     95:     struct allocinfo_s *next = GET_PMMVAR(info->next);
                     96:     struct allocinfo_s **pprev = GET_PMMVAR(info->pprev);
                     97:     SET_PMMVAR(*pprev, next);
                     98:     if (next) {
                     99:         if (GET_PMMVAR(next->allocend) == GET_PMMVAR(info->data))
                    100:             SET_PMMVAR(next->allocend, GET_PMMVAR(info->allocend));
                    101:         SET_PMMVAR(next->pprev, pprev);
                    102:     }
                    103: }
                    104: 
                    105: // Add new memory to a zone
                    106: static void
                    107: addSpace(struct zone_s *zone, void *start, void *end)
                    108: {
                    109:     // Find position to add space
                    110:     struct allocinfo_s **pprev = &zone->info, *info;
                    111:     for (;;) {
                    112:         info = GET_PMMVAR(*pprev);
                    113:         if (!info || GET_PMMVAR(info->data) < start)
                    114:             break;
                    115:         pprev = &info->next;
                    116:     }
                    117: 
                    118:     // Add space using temporary allocation info.
                    119:     struct allocdetail_s tempdetail;
                    120:     tempdetail.datainfo.next = info;
                    121:     tempdetail.datainfo.pprev = pprev;
                    122:     tempdetail.datainfo.data = tempdetail.datainfo.dataend = start;
                    123:     tempdetail.datainfo.allocend = end;
                    124:     struct allocdetail_s *tempdetailp = MAKE_FLATPTR(GET_SEG(SS), &tempdetail);
                    125:     SET_PMMVAR(*pprev, &tempdetailp->datainfo);
                    126:     if (info)
                    127:         SET_PMMVAR(info->pprev, &tempdetailp->datainfo.next);
                    128: 
                    129:     // Allocate final allocation info.
                    130:     struct allocdetail_s *detail = allocSpace(
                    131:         &ZoneTmpHigh, sizeof(*detail), MALLOC_MIN_ALIGN, NULL);
                    132:     if (!detail) {
                    133:         detail = allocSpace(&ZoneTmpLow, sizeof(*detail)
                    134:                             , MALLOC_MIN_ALIGN, NULL);
                    135:         if (!detail) {
                    136:             SET_PMMVAR(*tempdetail.datainfo.pprev, tempdetail.datainfo.next);
                    137:             if (tempdetail.datainfo.next)
                    138:                 SET_PMMVAR(tempdetail.datainfo.next->pprev
                    139:                            , tempdetail.datainfo.pprev);
                    140:             warn_noalloc();
                    141:             return;
                    142:         }
                    143:     }
                    144: 
                    145:     // Replace temp alloc space with final alloc space
                    146:     memcpy_fl(&detail->datainfo, &tempdetailp->datainfo
                    147:               , sizeof(detail->datainfo));
                    148:     SET_PMMVAR(detail->handle, PMM_DEFAULT_HANDLE);
                    149: 
                    150:     SET_PMMVAR(*tempdetail.datainfo.pprev, &detail->datainfo);
                    151:     if (tempdetail.datainfo.next)
                    152:         SET_PMMVAR(tempdetail.datainfo.next->pprev, &detail->datainfo.next);
                    153: }
                    154: 
                    155: // Search all zones for an allocation obtained from allocSpace()
                    156: static struct allocinfo_s *
                    157: findAlloc(void *data)
                    158: {
                    159:     int i;
                    160:     for (i=0; i<ARRAY_SIZE(Zones); i++) {
                    161:         struct zone_s *zone = GET_PMMVAR(Zones[i]);
                    162:         struct allocinfo_s *info;
                    163:         for (info = GET_PMMVAR(zone->info); info; info = GET_PMMVAR(info->next))
                    164:             if (GET_PMMVAR(info->data) == data)
                    165:                 return info;
                    166:     }
                    167:     return NULL;
                    168: }
                    169: 
                    170: // Return the last sentinal node of a zone
                    171: static struct allocinfo_s *
                    172: findLast(struct zone_s *zone)
                    173: {
                    174:     struct allocinfo_s *info = GET_PMMVAR(zone->info);
                    175:     if (!info)
                    176:         return NULL;
                    177:     for (;;) {
                    178:         struct allocinfo_s *next = GET_PMMVAR(info->next);
                    179:         if (!next)
                    180:             return info;
                    181:         info = next;
                    182:     }
                    183: }
                    184: 
                    185: 
                    186: /****************************************************************
                    187:  * Setup
                    188:  ****************************************************************/
                    189: 
                    190: void
                    191: malloc_setup(void)
                    192: {
                    193:     ASSERT32FLAT();
                    194:     dprintf(3, "malloc setup\n");
                    195: 
                    196:     // Populate temp high ram
                    197:     u32 highram = 0;
                    198:     int i;
                    199:     for (i=e820_count-1; i>=0; i--) {
                    200:         struct e820entry *en = &e820_list[i];
                    201:         u64 end = en->start + en->size;
                    202:         if (end < 1024*1024)
                    203:             break;
                    204:         if (en->type != E820_RAM || end > 0xffffffff)
                    205:             continue;
                    206:         u32 s = en->start, e = end;
                    207:         if (!highram) {
                    208:             u32 newe = ALIGN_DOWN(e - CONFIG_MAX_HIGHTABLE, MALLOC_MIN_ALIGN);
                    209:             if (newe <= e && newe >= s) {
                    210:                 highram = newe;
                    211:                 e = newe;
                    212:             }
                    213:         }
                    214:         addSpace(&ZoneTmpHigh, (void*)s, (void*)e);
                    215:     }
                    216: 
                    217:     // Populate other regions
                    218:     addSpace(&ZoneTmpLow, (void*)BUILD_STACK_ADDR, (void*)BUILD_EBDA_MINIMUM);
                    219:     addSpace(&ZoneFSeg, BiosTableSpace, &BiosTableSpace[CONFIG_MAX_BIOSTABLE]);
                    220:     addSpace(&ZoneLow, (void*)BUILD_LOWRAM_END, (void*)BUILD_LOWRAM_END);
                    221:     if (highram) {
                    222:         addSpace(&ZoneHigh, (void*)highram
                    223:                  , (void*)highram + CONFIG_MAX_HIGHTABLE);
                    224:         add_e820(highram, CONFIG_MAX_HIGHTABLE, E820_RESERVED);
                    225:     }
                    226: }
                    227: 
                    228: void
                    229: malloc_finalize(void)
                    230: {
                    231:     dprintf(3, "malloc finalize\n");
                    232: 
                    233:     // Reserve more low-mem if needed.
                    234:     u32 endlow = GET_BDA(mem_size_kb)*1024;
                    235:     add_e820(endlow, BUILD_LOWRAM_END-endlow, E820_RESERVED);
                    236: 
                    237:     // Give back unused high ram.
                    238:     struct allocinfo_s *info = findLast(&ZoneHigh);
                    239:     if (info) {
                    240:         u32 giveback = ALIGN_DOWN(info->allocend - info->dataend, PAGE_SIZE);
                    241:         add_e820((u32)info->dataend, giveback, E820_RAM);
                    242:         dprintf(1, "Returned %d bytes of ZoneHigh\n", giveback);
                    243:     }
                    244: }
                    245: 
                    246: 
                    247: /****************************************************************
1.1       root      248:  * ebda movement
                    249:  ****************************************************************/
                    250: 
                    251: // Move ebda
                    252: static int
                    253: relocate_ebda(u32 newebda, u32 oldebda, u8 ebda_size)
                    254: {
                    255:     u32 lowram = GET_BDA(mem_size_kb) * 1024;
                    256:     if (oldebda != lowram)
                    257:         // EBDA isn't at end of ram - give up.
                    258:         return -1;
                    259: 
1.1.1.3   root      260:     // Do copy (this assumes memcpy copies forward - otherwise memmove
                    261:     // is needed)
                    262:     memcpy_fl((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;
                    278:     u32 oldpos = (u32)GET_PMMVAR(info->allocend);
1.1       root      279:     u32 newpos = ALIGN_DOWN(oldpos - size, align);
1.1.1.3   root      280:     u32 bottom = (u32)GET_PMMVAR(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) {
                    304:         SET_PMMVAR(info->data, (void*)newbottom);
                    305:         SET_PMMVAR(info->dataend, (void*)newbottom);
                    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.3   root      339:     if (!size)
                    340:         return NULL;
                    341: 
                    342:     // Find and reserve space for bookkeeping.
                    343:     struct allocdetail_s *detail = allocSpace(
                    344:         &ZoneTmpHigh, sizeof(*detail), MALLOC_MIN_ALIGN, NULL);
                    345:     if (!detail) {
                    346:         detail = allocSpace(&ZoneTmpLow, sizeof(*detail)
                    347:                             , MALLOC_MIN_ALIGN, NULL);
                    348:         if (!detail)
1.1       root      349:             return NULL;
                    350:     }
1.1.1.3   root      351: 
                    352:     // Find and reserve space for main allocation
                    353:     void *data = allocExpandSpace(zone, size, align, &detail->datainfo);
                    354:     if (!data) {
                    355:         freeSpace(&detail->detailinfo);
1.1       root      356:         return NULL;
                    357:     }
1.1.1.3   root      358: 
1.1       root      359:     dprintf(8, "pmm_malloc zone=%p handle=%x size=%d align=%x"
1.1.1.3   root      360:             " ret=%p (detail=%p)\n"
1.1       root      361:             , zone, handle, size, align
1.1.1.3   root      362:             , data, detail);
                    363:     SET_PMMVAR(detail->handle, handle);
1.1       root      364: 
1.1.1.3   root      365:     return data;
1.1       root      366: }
                    367: 
                    368: // Free a data block allocated with pmm_malloc
                    369: int
                    370: pmm_free(void *data)
                    371: {
1.1.1.3   root      372:     struct allocinfo_s *info = findAlloc(data);
                    373:     if (!info || data == (void*)info || data == GET_PMMVAR(info->dataend))
                    374:         return -1;
                    375:     struct allocdetail_s *detail = container_of(
                    376:         info, struct allocdetail_s, datainfo);
                    377:     dprintf(8, "pmm_free %p (detail=%p)\n", data, detail);
                    378:     freeSpace(info);
                    379:     freeSpace(&detail->detailinfo);
                    380:     return 0;
1.1       root      381: }
                    382: 
                    383: // Find the amount of free space in a given zone.
                    384: static u32
                    385: pmm_getspace(struct zone_s *zone)
                    386: {
                    387:     // XXX - doesn't account for ZoneLow being able to grow.
1.1.1.3   root      388:     // XXX - results not reliable when CONFIG_THREAD_OPTIONROMS
                    389:     u32 maxspace = 0;
                    390:     struct allocinfo_s *info;
                    391:     for (info = GET_PMMVAR(zone->info); info; info = GET_PMMVAR(info->next)) {
                    392:         u32 space = GET_PMMVAR(info->allocend) - GET_PMMVAR(info->dataend);
                    393:         if (space > maxspace)
                    394:             maxspace = space;
                    395:     }
                    396: 
1.1       root      397:     if (zone != &ZoneTmpHigh && zone != &ZoneTmpLow)
1.1.1.3   root      398:         return maxspace;
1.1       root      399:     // Account for space needed for PMM tracking.
1.1.1.3   root      400:     u32 reserve = ALIGN(sizeof(struct allocdetail_s), MALLOC_MIN_ALIGN);
                    401:     if (maxspace <= reserve)
1.1       root      402:         return 0;
1.1.1.3   root      403:     return maxspace - reserve;
1.1       root      404: }
                    405: 
                    406: // Find the data block allocated with pmm_malloc with a given handle.
                    407: static void *
                    408: pmm_find(u32 handle)
                    409: {
1.1.1.3   root      410:     int i;
                    411:     for (i=0; i<ARRAY_SIZE(Zones); i++) {
                    412:         struct zone_s *zone = GET_PMMVAR(Zones[i]);
                    413:         struct allocinfo_s *info;
                    414:         for (info = GET_PMMVAR(zone->info); info
                    415:                  ; info = GET_PMMVAR(info->next)) {
                    416:             if (GET_PMMVAR(info->data) != (void*)info)
                    417:                 continue;
                    418:             struct allocdetail_s *detail = container_of(
                    419:                 info, struct allocdetail_s, detailinfo);
                    420:             if (GET_PMMVAR(detail->handle) == handle)
                    421:                 return GET_PMMVAR(detail->datainfo.data);
                    422:         }
1.1       root      423:     }
1.1.1.3   root      424:     return NULL;
1.1       root      425: }
                    426: 
                    427: 
                    428: /****************************************************************
                    429:  * pmm interface
                    430:  ****************************************************************/
                    431: 
                    432: struct pmmheader {
                    433:     u32 signature;
                    434:     u8 version;
                    435:     u8 length;
                    436:     u8 checksum;
                    437:     u16 entry_offset;
                    438:     u16 entry_seg;
                    439:     u8 reserved[5];
                    440: } PACKED;
                    441: 
                    442: extern struct pmmheader PMMHEADER;
                    443: 
                    444: #define PMM_SIGNATURE 0x4d4d5024 // $PMM
                    445: 
                    446: #if CONFIG_PMM
                    447: struct pmmheader PMMHEADER __aligned(16) VAR16EXPORT = {
                    448:     .version = 0x01,
                    449:     .length = sizeof(PMMHEADER),
                    450:     .entry_seg = SEG_BIOS,
                    451: };
                    452: #endif
                    453: 
                    454: #define PMM_FUNCTION_NOT_SUPPORTED 0xffffffff
                    455: 
                    456: // PMM - allocate
                    457: static u32
                    458: handle_pmm00(u16 *args)
                    459: {
                    460:     u32 length = *(u32*)&args[1], handle = *(u32*)&args[3];
                    461:     u16 flags = args[5];
                    462:     dprintf(3, "pmm00: length=%x handle=%x flags=%x\n"
                    463:             , length, handle, flags);
                    464:     struct zone_s *lowzone = &ZoneTmpLow, *highzone = &ZoneTmpHigh;
                    465:     if (flags & 8) {
                    466:         // Permanent memory request.
                    467:         lowzone = &ZoneLow;
                    468:         highzone = &ZoneHigh;
                    469:     }
                    470:     if (!length) {
                    471:         // Memory size request
                    472:         switch (flags & 3) {
                    473:         default:
                    474:         case 0:
                    475:             return 0;
                    476:         case 1:
                    477:             return pmm_getspace(lowzone);
                    478:         case 2:
                    479:             return pmm_getspace(highzone);
                    480:         case 3: {
                    481:             u32 spacelow = pmm_getspace(lowzone);
                    482:             u32 spacehigh = pmm_getspace(highzone);
                    483:             if (spacelow > spacehigh)
                    484:                 return spacelow;
                    485:             return spacehigh;
                    486:         }
                    487:         }
                    488:     }
                    489:     u32 size = length * 16;
                    490:     if ((s32)size <= 0)
                    491:         return 0;
                    492:     u32 align = MALLOC_MIN_ALIGN;
                    493:     if (flags & 4) {
                    494:         align = 1<<__ffs(size);
                    495:         if (align < MALLOC_MIN_ALIGN)
                    496:             align = MALLOC_MIN_ALIGN;
                    497:     }
                    498:     switch (flags & 3) {
                    499:     default:
                    500:     case 0:
                    501:         return 0;
                    502:     case 1:
                    503:         return (u32)pmm_malloc(lowzone, handle, size, align);
                    504:     case 2:
                    505:         return (u32)pmm_malloc(highzone, handle, size, align);
                    506:     case 3: {
                    507:         void *data = pmm_malloc(lowzone, handle, size, align);
                    508:         if (data)
                    509:             return (u32)data;
                    510:         return (u32)pmm_malloc(highzone, handle, size, align);
                    511:     }
                    512:     }
                    513: }
                    514: 
                    515: // PMM - find
                    516: static u32
                    517: handle_pmm01(u16 *args)
                    518: {
                    519:     u32 handle = *(u32*)&args[1];
                    520:     dprintf(3, "pmm01: handle=%x\n", handle);
                    521:     if (handle == PMM_DEFAULT_HANDLE)
                    522:         return 0;
                    523:     return (u32)pmm_find(handle);
                    524: }
                    525: 
                    526: // PMM - deallocate
                    527: static u32
                    528: handle_pmm02(u16 *args)
                    529: {
                    530:     u32 buffer = *(u32*)&args[1];
                    531:     dprintf(3, "pmm02: buffer=%x\n", buffer);
                    532:     int ret = pmm_free((void*)buffer);
                    533:     if (ret)
                    534:         // Error
                    535:         return 1;
                    536:     return 0;
                    537: }
                    538: 
                    539: static u32
                    540: handle_pmmXX(u16 *args)
                    541: {
                    542:     return PMM_FUNCTION_NOT_SUPPORTED;
                    543: }
                    544: 
                    545: u32 VISIBLE16
                    546: handle_pmm(u16 *args)
                    547: {
                    548:     if (! CONFIG_PMM)
                    549:         return PMM_FUNCTION_NOT_SUPPORTED;
                    550: 
                    551:     u16 arg1 = args[0];
                    552:     dprintf(DEBUG_HDL_pmm, "pmm call arg1=%x\n", arg1);
                    553: 
                    554:     switch (arg1) {
                    555:     case 0x00: return handle_pmm00(args);
                    556:     case 0x01: return handle_pmm01(args);
                    557:     case 0x02: return handle_pmm02(args);
                    558:     default:   return handle_pmmXX(args);
                    559:     }
                    560: }
                    561: 
                    562: // romlayout.S
1.1.1.2   root      563: extern void entry_pmm(void);
1.1       root      564: 
                    565: void
1.1.1.2   root      566: pmm_setup(void)
1.1       root      567: {
                    568:     if (! CONFIG_PMM)
                    569:         return;
                    570: 
                    571:     dprintf(3, "init PMM\n");
                    572: 
                    573:     PMMHEADER.signature = PMM_SIGNATURE;
                    574:     PMMHEADER.entry_offset = (u32)entry_pmm - BUILD_BIOS_ADDR;
                    575:     PMMHEADER.checksum -= checksum(&PMMHEADER, sizeof(PMMHEADER));
                    576: }
                    577: 
                    578: void
1.1.1.2   root      579: pmm_finalize(void)
1.1       root      580: {
                    581:     if (! CONFIG_PMM)
                    582:         return;
                    583: 
                    584:     dprintf(3, "finalize PMM\n");
                    585: 
                    586:     PMMHEADER.signature = 0;
                    587:     PMMHEADER.entry_offset = 0;
                    588: }

unix.superglobalmegacorp.com

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