Annotation of qemu/roms/seabios/src/coreboot.c, revision 1.1

1.1     ! root        1: // Coreboot interface support.
        !             2: //
        !             3: // Copyright (C) 2008,2009  Kevin O'Connor <[email protected]>
        !             4: //
        !             5: // This file may be distributed under the terms of the GNU LGPLv3 license.
        !             6: 
        !             7: #include "memmap.h" // add_e820
        !             8: #include "util.h" // dprintf
        !             9: #include "pci.h" // struct pir_header
        !            10: #include "acpi.h" // struct rsdp_descriptor
        !            11: #include "mptable.h" // MPTABLE_SIGNATURE
        !            12: #include "biosvar.h" // GET_EBDA
        !            13: #include "lzmadecode.h" // LzmaDecode
        !            14: #include "smbios.h" // smbios_init
        !            15: 
        !            16: 
        !            17: /****************************************************************
        !            18:  * Memory map
        !            19:  ****************************************************************/
        !            20: 
        !            21: struct cb_header {
        !            22:     u32 signature;
        !            23:     u32 header_bytes;
        !            24:     u32 header_checksum;
        !            25:     u32 table_bytes;
        !            26:     u32 table_checksum;
        !            27:     u32 table_entries;
        !            28: };
        !            29: 
        !            30: #define CB_SIGNATURE 0x4f49424C // "LBIO"
        !            31: 
        !            32: struct cb_memory_range {
        !            33:     u64 start;
        !            34:     u64 size;
        !            35:     u32 type;
        !            36: };
        !            37: 
        !            38: #define CB_MEM_TABLE    16
        !            39: 
        !            40: struct cb_memory {
        !            41:     u32 tag;
        !            42:     u32 size;
        !            43:     struct cb_memory_range map[0];
        !            44: };
        !            45: 
        !            46: #define CB_TAG_MEMORY 0x01
        !            47: 
        !            48: #define MEM_RANGE_COUNT(_rec) \
        !            49:         (((_rec)->size - sizeof(*(_rec))) / sizeof((_rec)->map[0]))
        !            50: 
        !            51: struct cb_mainboard {
        !            52:     u32 tag;
        !            53:     u32 size;
        !            54:     u8  vendor_idx;
        !            55:     u8  part_idx;
        !            56:     char  strings[0];
        !            57: };
        !            58: 
        !            59: #define CB_TAG_MAINBOARD 0x0003
        !            60: 
        !            61: struct cb_forward {
        !            62:     u32 tag;
        !            63:     u32 size;
        !            64:     u64 forward;
        !            65: };
        !            66: 
        !            67: #define CB_TAG_FORWARD 0x11
        !            68: 
        !            69: static u16
        !            70: ipchksum(char *buf, int count)
        !            71: {
        !            72:     u16 *p = (u16*)buf;
        !            73:     u32 sum = 0;
        !            74:     while (count > 1) {
        !            75:         sum += *p++;
        !            76:         count -= 2;
        !            77:     }
        !            78:     if (count)
        !            79:         sum += *(u8*)p;
        !            80:     sum = (sum >> 16) + (sum & 0xffff);
        !            81:     sum += (sum >> 16);
        !            82:     return ~sum;
        !            83: }
        !            84: 
        !            85: // Try to locate the coreboot header in a given address range.
        !            86: static struct cb_header *
        !            87: find_cb_header(char *addr, int len)
        !            88: {
        !            89:     char *end = addr + len;
        !            90:     for (; addr < end; addr += 16) {
        !            91:         struct cb_header *cbh = (struct cb_header *)addr;
        !            92:         if (cbh->signature != CB_SIGNATURE)
        !            93:             continue;
        !            94:         if (! cbh->table_bytes)
        !            95:             continue;
        !            96:         if (ipchksum(addr, sizeof(*cbh)) != 0)
        !            97:             continue;
        !            98:         if (ipchksum(addr + sizeof(*cbh), cbh->table_bytes)
        !            99:             != cbh->table_checksum)
        !           100:             continue;
        !           101:         return cbh;
        !           102:     }
        !           103:     return NULL;
        !           104: }
        !           105: 
        !           106: // Try to find the coreboot memory table in the given coreboot table.
        !           107: static void *
        !           108: find_cb_subtable(struct cb_header *cbh, u32 tag)
        !           109: {
        !           110:     char *tbl = (char *)cbh + sizeof(*cbh);
        !           111:     int i;
        !           112:     for (i=0; i<cbh->table_entries; i++) {
        !           113:         struct cb_memory *cbm = (struct cb_memory *)tbl;
        !           114:         tbl += cbm->size;
        !           115:         if (cbm->tag == tag)
        !           116:             return cbm;
        !           117:     }
        !           118:     return NULL;
        !           119: }
        !           120: 
        !           121: static struct cb_memory *CBMemTable;
        !           122: 
        !           123: // Populate max ram and e820 map info by scanning for a coreboot table.
        !           124: static void
        !           125: coreboot_fill_map()
        !           126: {
        !           127:     dprintf(3, "Attempting to find coreboot table\n");
        !           128: 
        !           129:     CBMemTable = NULL;
        !           130: 
        !           131:     // Find coreboot table.
        !           132:     struct cb_header *cbh = find_cb_header(0, 0x1000);
        !           133:     if (!cbh)
        !           134:         goto fail;
        !           135:     struct cb_forward *cbf = find_cb_subtable(cbh, CB_TAG_FORWARD);
        !           136:     if (cbf) {
        !           137:         dprintf(3, "Found coreboot table forwarder.\n");
        !           138:         cbh = find_cb_header((char *)((u32)cbf->forward), 0x100);
        !           139:         if (!cbh)
        !           140:             goto fail;
        !           141:     }
        !           142:     dprintf(3, "Now attempting to find coreboot memory map\n");
        !           143:     struct cb_memory *cbm = CBMemTable = find_cb_subtable(cbh, CB_TAG_MEMORY);
        !           144:     if (!cbm)
        !           145:         goto fail;
        !           146: 
        !           147:     u64 maxram = 0, maxram_over4G = 0;
        !           148:     int i, count = MEM_RANGE_COUNT(cbm);
        !           149:     for (i=0; i<count; i++) {
        !           150:         struct cb_memory_range *m = &cbm->map[i];
        !           151:         u32 type = m->type;
        !           152:         if (type == CB_MEM_TABLE) {
        !           153:             type = E820_RESERVED;
        !           154:         } else if (type == E820_ACPI || type == E820_RAM) {
        !           155:             u64 end = m->start + m->size;
        !           156:             if (end > 0x100000000ull) {
        !           157:                 end -= 0x100000000ull;
        !           158:                 if (end > maxram_over4G)
        !           159:                     maxram_over4G = end;
        !           160:             } else if (end > maxram)
        !           161:                 maxram = end;
        !           162:         }
        !           163:         add_e820(m->start, m->size, type);
        !           164:     }
        !           165: 
        !           166:     RamSize = maxram;
        !           167:     RamSizeOver4G = maxram_over4G;
        !           168: 
        !           169:     // Ughh - coreboot likes to set a map at 0x0000-0x1000, but this
        !           170:     // confuses grub.  So, override it.
        !           171:     add_e820(0, 16*1024, E820_RAM);
        !           172: 
        !           173:     struct cb_mainboard *cbmb = find_cb_subtable(cbh, CB_TAG_MAINBOARD);
        !           174:     if (cbmb) {
        !           175:         const char *vendor = &cbmb->strings[cbmb->vendor_idx];
        !           176:         const char *part = &cbmb->strings[cbmb->part_idx];
        !           177:         dprintf(1, "Found mainboard %s %s\n", vendor, part);
        !           178: 
        !           179:         vgahook_setup(vendor, part);
        !           180:     }
        !           181: 
        !           182:     return;
        !           183: 
        !           184: fail:
        !           185:     // No table found..  Use 16Megs as a dummy value.
        !           186:     dprintf(1, "Unable to find coreboot table!\n");
        !           187:     RamSize = 16*1024*1024;
        !           188:     RamSizeOver4G = 0;
        !           189:     add_e820(0, 16*1024*1024, E820_RAM);
        !           190:     return;
        !           191: }
        !           192: 
        !           193: 
        !           194: /****************************************************************
        !           195:  * BIOS table copying
        !           196:  ****************************************************************/
        !           197: 
        !           198: static void
        !           199: copy_pir(void *pos)
        !           200: {
        !           201:     struct pir_header *p = pos;
        !           202:     if (p->signature != PIR_SIGNATURE)
        !           203:         return;
        !           204:     if (PirOffset)
        !           205:         return;
        !           206:     if (p->size < sizeof(*p))
        !           207:         return;
        !           208:     if (checksum(pos, p->size) != 0)
        !           209:         return;
        !           210:     void *newpos = malloc_fseg(p->size);
        !           211:     if (!newpos) {
        !           212:         dprintf(1, "No room to copy PIR table!\n");
        !           213:         return;
        !           214:     }
        !           215:     dprintf(1, "Copying PIR from %p to %p\n", pos, newpos);
        !           216:     memcpy(newpos, pos, p->size);
        !           217:     PirOffset = (u32)newpos - BUILD_BIOS_ADDR;
        !           218: }
        !           219: 
        !           220: static void
        !           221: copy_mptable(void *pos)
        !           222: {
        !           223:     struct mptable_floating_s *p = pos;
        !           224:     if (p->signature != MPTABLE_SIGNATURE)
        !           225:         return;
        !           226:     if (!p->physaddr)
        !           227:         return;
        !           228:     if (checksum(pos, sizeof(*p)) != 0)
        !           229:         return;
        !           230:     u32 length = p->length * 16;
        !           231:     u16 mpclength = ((struct mptable_config_s *)p->physaddr)->length;
        !           232:     struct mptable_floating_s *newpos = malloc_fseg(length + mpclength);
        !           233:     if (!newpos) {
        !           234:         dprintf(1, "No room to copy MPTABLE!\n");
        !           235:         return;
        !           236:     }
        !           237:     dprintf(1, "Copying MPTABLE from %p/%x to %p\n", pos, p->physaddr, newpos);
        !           238:     memcpy(newpos, pos, length);
        !           239:     newpos->physaddr = (u32)newpos + length;
        !           240:     newpos->checksum -= checksum(newpos, sizeof(*newpos));
        !           241:     memcpy((void*)newpos + length, (void*)p->physaddr, mpclength);
        !           242: }
        !           243: 
        !           244: static void
        !           245: copy_acpi_rsdp(void *pos)
        !           246: {
        !           247:     if (RsdpAddr)
        !           248:         return;
        !           249:     struct rsdp_descriptor *p = pos;
        !           250:     if (p->signature != RSDP_SIGNATURE)
        !           251:         return;
        !           252:     u32 length = 20;
        !           253:     if (checksum(pos, length) != 0)
        !           254:         return;
        !           255:     if (p->revision > 1) {
        !           256:         length = p->length;
        !           257:         if (checksum(pos, length) != 0)
        !           258:             return;
        !           259:     }
        !           260:     void *newpos = malloc_fseg(length);
        !           261:     if (!newpos) {
        !           262:         dprintf(1, "No room to copy ACPI RSDP table!\n");
        !           263:         return;
        !           264:     }
        !           265:     dprintf(1, "Copying ACPI RSDP from %p to %p\n", pos, newpos);
        !           266:     memcpy(newpos, pos, length);
        !           267:     RsdpAddr = newpos;
        !           268: }
        !           269: 
        !           270: // Attempt to find (and relocate) any standard bios tables found in a
        !           271: // given address range.
        !           272: static void
        !           273: scan_tables(u32 start, u32 size)
        !           274: {
        !           275:     void *p = (void*)ALIGN(start, 16);
        !           276:     void *end = (void*)start + size;
        !           277:     for (; p<end; p += 16) {
        !           278:         copy_pir(p);
        !           279:         copy_mptable(p);
        !           280:         copy_acpi_rsdp(p);
        !           281:     }
        !           282: }
        !           283: 
        !           284: void
        !           285: coreboot_copy_biostable()
        !           286: {
        !           287:     struct cb_memory *cbm = CBMemTable;
        !           288:     if (! CONFIG_COREBOOT || !cbm)
        !           289:         return;
        !           290: 
        !           291:     dprintf(3, "Relocating coreboot bios tables\n");
        !           292: 
        !           293:     // Init variables set in coreboot table memory scan.
        !           294:     PirOffset = 0;
        !           295:     RsdpAddr = 0;
        !           296: 
        !           297:     // Scan CB_MEM_TABLE areas for bios tables.
        !           298:     int i, count = MEM_RANGE_COUNT(cbm);
        !           299:     for (i=0; i<count; i++) {
        !           300:         struct cb_memory_range *m = &cbm->map[i];
        !           301:         if (m->type == CB_MEM_TABLE)
        !           302:             scan_tables(m->start, m->size);
        !           303:     }
        !           304: 
        !           305:     // XXX - just create dummy smbios table for now - should detect if
        !           306:     // smbios/dmi table is found from coreboot and use that instead.
        !           307:     smbios_init();
        !           308: }
        !           309: 
        !           310: 
        !           311: /****************************************************************
        !           312:  * ulzma
        !           313:  ****************************************************************/
        !           314: 
        !           315: // Uncompress data in flash to an area of memory.
        !           316: static int
        !           317: ulzma(u8 *dst, u32 maxlen, const u8 *src, u32 srclen)
        !           318: {
        !           319:     dprintf(3, "Uncompressing data %d@%p to %d@%p\n", srclen, src, maxlen, dst);
        !           320:     CLzmaDecoderState state;
        !           321:     int ret = LzmaDecodeProperties(&state.Properties, src, LZMA_PROPERTIES_SIZE);
        !           322:     if (ret != LZMA_RESULT_OK) {
        !           323:         dprintf(1, "LzmaDecodeProperties error - %d\n", ret);
        !           324:         return -1;
        !           325:     }
        !           326:     u8 scratch[15980];
        !           327:     int need = (LzmaGetNumProbs(&state.Properties) * sizeof(CProb));
        !           328:     if (need > sizeof(scratch)) {
        !           329:         dprintf(1, "LzmaDecode need %d have %d\n", need, sizeof(scratch));
        !           330:         return -1;
        !           331:     }
        !           332:     state.Probs = (CProb *)scratch;
        !           333: 
        !           334:     u32 dstlen = *(u32*)(src + LZMA_PROPERTIES_SIZE);
        !           335:     if (dstlen > maxlen) {
        !           336:         dprintf(1, "LzmaDecode too large (max %d need %d)\n", maxlen, dstlen);
        !           337:         return -1;
        !           338:     }
        !           339:     u32 inProcessed, outProcessed;
        !           340:     ret = LzmaDecode(&state, src + LZMA_PROPERTIES_SIZE + 8, srclen
        !           341:                      , &inProcessed, dst, dstlen, &outProcessed);
        !           342:     if (ret) {
        !           343:         dprintf(1, "LzmaDecode returned %d\n", ret);
        !           344:         return -1;
        !           345:     }
        !           346:     return dstlen;
        !           347: }
        !           348: 
        !           349: 
        !           350: /****************************************************************
        !           351:  * Coreboot flash format
        !           352:  ****************************************************************/
        !           353: 
        !           354: #define CBFS_HEADER_MAGIC 0x4F524243
        !           355: #define CBFS_HEADPTR_ADDR 0xFFFFFFFc
        !           356: #define CBFS_VERSION1 0x31313131
        !           357: 
        !           358: struct cbfs_header {
        !           359:     u32 magic;
        !           360:     u32 version;
        !           361:     u32 romsize;
        !           362:     u32 bootblocksize;
        !           363:     u32 align;
        !           364:     u32 offset;
        !           365:     u32 pad[2];
        !           366: } PACKED;
        !           367: 
        !           368: static struct cbfs_header *CBHDR;
        !           369: 
        !           370: static void
        !           371: cbfs_setup()
        !           372: {
        !           373:     if (! CONFIG_COREBOOT_FLASH)
        !           374:         return;
        !           375: 
        !           376:     CBHDR = *(void **)CBFS_HEADPTR_ADDR;
        !           377:     if (CBHDR->magic != htonl(CBFS_HEADER_MAGIC)) {
        !           378:         dprintf(1, "Unable to find CBFS (got %x not %x)\n"
        !           379:                 , CBHDR->magic, htonl(CBFS_HEADER_MAGIC));
        !           380:         CBHDR = NULL;
        !           381:         return;
        !           382:     }
        !           383: 
        !           384:     dprintf(1, "Found CBFS header at %p\n", CBHDR);
        !           385: }
        !           386: 
        !           387: #define CBFS_FILE_MAGIC 0x455649484352414cLL // LARCHIVE
        !           388: 
        !           389: struct cbfs_file {
        !           390:     u64 magic;
        !           391:     u32 len;
        !           392:     u32 type;
        !           393:     u32 checksum;
        !           394:     u32 offset;
        !           395:     char filename[0];
        !           396: } PACKED;
        !           397: 
        !           398: // Verify a cbfs entry looks valid.
        !           399: static struct cbfs_file *
        !           400: cbfs_verify(struct cbfs_file *file)
        !           401: {
        !           402:     if (file < (struct cbfs_file *)(0xFFFFFFFF - ntohl(CBHDR->romsize)))
        !           403:         return NULL;
        !           404:     u64 magic = file->magic;
        !           405:     if (magic == CBFS_FILE_MAGIC) {
        !           406:         dprintf(5, "Found CBFS file %s\n", file->filename);
        !           407:         return file;
        !           408:     }
        !           409:     return NULL;
        !           410: }
        !           411: 
        !           412: // Return the first file in the CBFS archive
        !           413: static struct cbfs_file *
        !           414: cbfs_getfirst()
        !           415: {
        !           416:     if (! CBHDR)
        !           417:         return NULL;
        !           418:     return cbfs_verify((void *)(0 - ntohl(CBHDR->romsize) + ntohl(CBHDR->offset)));
        !           419: }
        !           420: 
        !           421: // Return the file after the given file.
        !           422: static struct cbfs_file *
        !           423: cbfs_getnext(struct cbfs_file *file)
        !           424: {
        !           425:     file = (void*)file + ALIGN(ntohl(file->len) + ntohl(file->offset), ntohl(CBHDR->align));
        !           426:     return cbfs_verify(file);
        !           427: }
        !           428: 
        !           429: // Find the file with the given filename.
        !           430: struct cbfs_file *
        !           431: cbfs_findfile(const char *fname)
        !           432: {
        !           433:     dprintf(3, "Searching CBFS for %s\n", fname);
        !           434:     struct cbfs_file *file;
        !           435:     for (file = cbfs_getfirst(); file; file = cbfs_getnext(file))
        !           436:         if (strcmp(fname, file->filename) == 0)
        !           437:             return file;
        !           438:     return NULL;
        !           439: }
        !           440: 
        !           441: // Find next file with the given filename prefix.
        !           442: struct cbfs_file *
        !           443: cbfs_findprefix(const char *prefix, struct cbfs_file *last)
        !           444: {
        !           445:     if (! CONFIG_COREBOOT_FLASH)
        !           446:         return NULL;
        !           447: 
        !           448:     dprintf(3, "Searching CBFS for prefix %s\n", prefix);
        !           449:     int len = strlen(prefix);
        !           450:     struct cbfs_file *file;
        !           451:     if (! last)
        !           452:         file = cbfs_getfirst();
        !           453:     else
        !           454:         file = cbfs_getnext(last);
        !           455:     for (; file; file = cbfs_getnext(file))
        !           456:         if (memcmp(prefix, file->filename, len) == 0)
        !           457:             return file;
        !           458:     return NULL;
        !           459: }
        !           460: 
        !           461: // Find a file with the given filename (possibly with ".lzma" extension).
        !           462: static struct cbfs_file *
        !           463: cbfs_finddatafile(const char *fname)
        !           464: {
        !           465:     int fnlen = strlen(fname);
        !           466:     struct cbfs_file *file = NULL;
        !           467:     for (;;) {
        !           468:         file = cbfs_findprefix(fname, file);
        !           469:         if (!file)
        !           470:             return NULL;
        !           471:         if (file->filename[fnlen] == '\0'
        !           472:             || strcmp(&file->filename[fnlen], ".lzma") == 0)
        !           473:             return file;
        !           474:     }
        !           475: }
        !           476: 
        !           477: // Determine whether the file has a ".lzma" extension.
        !           478: static int
        !           479: cbfs_iscomp(struct cbfs_file *file)
        !           480: {
        !           481:     int fnamelen = strlen(file->filename);
        !           482:     return fnamelen > 5 && strcmp(&file->filename[fnamelen-5], ".lzma") == 0;
        !           483: }
        !           484: 
        !           485: // Return the filename of a given file.
        !           486: const char *
        !           487: cbfs_filename(struct cbfs_file *file)
        !           488: {
        !           489:     return file->filename;
        !           490: }
        !           491: 
        !           492: // Determine the uncompressed size of a datafile.
        !           493: u32
        !           494: cbfs_datasize(struct cbfs_file *file)
        !           495: {
        !           496:     void *src = (void*)file + ntohl(file->offset);
        !           497:     if (cbfs_iscomp(file))
        !           498:         return *(u32*)(src + LZMA_PROPERTIES_SIZE);
        !           499:     return ntohl(file->len);
        !           500: }
        !           501: 
        !           502: // Copy a file to memory (uncompressing if necessary)
        !           503: int
        !           504: cbfs_copyfile(struct cbfs_file *file, void *dst, u32 maxlen)
        !           505: {
        !           506:     if (! CONFIG_COREBOOT_FLASH || !file)
        !           507:         return -1;
        !           508: 
        !           509:     u32 size = ntohl(file->len);
        !           510:     void *src = (void*)file + ntohl(file->offset);
        !           511:     if (cbfs_iscomp(file)) {
        !           512:         // Compressed - copy to temp ram and uncompress it.
        !           513:         u32 asize = ALIGN(size, 4);
        !           514:         void *temp = malloc_tmphigh(asize);
        !           515:         if (!temp)
        !           516:             return -1;
        !           517:         iomemcpy(temp, src, asize);
        !           518:         int ret = ulzma(dst, maxlen, temp, size);
        !           519:         yield();
        !           520:         free(temp);
        !           521:         return ret;
        !           522:     }
        !           523: 
        !           524:     // Not compressed.
        !           525:     dprintf(3, "Copying data %d@%p to %d@%p\n", size, src, maxlen, dst);
        !           526:     if (size > maxlen) {
        !           527:         dprintf(1, "File too big to copy\n");
        !           528:         return -1;
        !           529:     }
        !           530:     iomemcpy(dst, src, size);
        !           531:     return size;
        !           532: }
        !           533: 
        !           534: // Find and copy the optionrom for the given vendor/device id.
        !           535: int
        !           536: cbfs_copy_optionrom(void *dst, u32 maxlen, u32 vendev)
        !           537: {
        !           538:     if (! CONFIG_COREBOOT_FLASH)
        !           539:         return -1;
        !           540: 
        !           541:     char fname[17];
        !           542:     snprintf(fname, sizeof(fname), "pci%04x,%04x.rom"
        !           543:              , (u16)vendev, vendev >> 16);
        !           544:     return cbfs_copyfile(cbfs_finddatafile(fname), dst, maxlen);
        !           545: }
        !           546: 
        !           547: struct cbfs_payload_segment {
        !           548:     u32 type;
        !           549:     u32 compression;
        !           550:     u32 offset;
        !           551:     u64 load_addr;
        !           552:     u32 len;
        !           553:     u32 mem_len;
        !           554: } PACKED;
        !           555: 
        !           556: #define PAYLOAD_SEGMENT_BSS    0x20535342
        !           557: #define PAYLOAD_SEGMENT_ENTRY  0x52544E45
        !           558: 
        !           559: #define CBFS_COMPRESS_NONE  0
        !           560: #define CBFS_COMPRESS_LZMA  1
        !           561: 
        !           562: struct cbfs_payload {
        !           563:     struct cbfs_payload_segment segments[1];
        !           564: };
        !           565: 
        !           566: void
        !           567: cbfs_run_payload(struct cbfs_file *file)
        !           568: {
        !           569:     if (!CONFIG_COREBOOT_FLASH || !file)
        !           570:         return;
        !           571:     dprintf(1, "Run %s\n", file->filename);
        !           572:     struct cbfs_payload *pay = (void*)file + ntohl(file->offset);
        !           573:     struct cbfs_payload_segment *seg = pay->segments;
        !           574:     for (;;) {
        !           575:         void *src = (void*)pay + ntohl(seg->offset);
        !           576:         void *dest = (void*)ntohl((u32)seg->load_addr);
        !           577:         u32 src_len = ntohl(seg->len);
        !           578:         u32 dest_len = ntohl(seg->mem_len);
        !           579:         switch (seg->type) {
        !           580:         case PAYLOAD_SEGMENT_BSS:
        !           581:             dprintf(3, "BSS segment %d@%p\n", dest_len, dest);
        !           582:             memset(dest, 0, dest_len);
        !           583:             break;
        !           584:         case PAYLOAD_SEGMENT_ENTRY: {
        !           585:             dprintf(1, "Calling addr %p\n", dest);
        !           586:             void (*func)() = dest;
        !           587:             func();
        !           588:             return;
        !           589:         }
        !           590:         default:
        !           591:             dprintf(3, "Segment %x %d@%p -> %d@%p\n"
        !           592:                     , seg->type, src_len, src, dest_len, dest);
        !           593:             if (seg->compression == htonl(CBFS_COMPRESS_NONE)) {
        !           594:                 if (src_len > dest_len)
        !           595:                     src_len = dest_len;
        !           596:                 memcpy(dest, src, src_len);
        !           597:             } else if (CONFIG_LZMA
        !           598:                        && seg->compression == htonl(CBFS_COMPRESS_LZMA)) {
        !           599:                 int ret = ulzma(dest, dest_len, src, src_len);
        !           600:                 if (ret < 0)
        !           601:                     return;
        !           602:                 src_len = ret;
        !           603:             } else {
        !           604:                 dprintf(1, "No support for compression type %x\n"
        !           605:                         , seg->compression);
        !           606:                 return;
        !           607:             }
        !           608:             if (dest_len > src_len)
        !           609:                 memset(dest + src_len, 0, dest_len - src_len);
        !           610:             break;
        !           611:         }
        !           612:         seg++;
        !           613:     }
        !           614: }
        !           615: 
        !           616: void
        !           617: coreboot_setup(void)
        !           618: {
        !           619:     coreboot_fill_map();
        !           620:     cbfs_setup();
        !           621: }

unix.superglobalmegacorp.com

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