File:  [Qemu by Fabrice Bellard] / qemu / arch_init.c
Revision 1.1.1.4 (vendor branch): download - view: text, annotated - select for diffs
Tue Apr 24 19:17:50 2018 UTC (3 years, 1 month ago) by root
Branches: qemu, MAIN
CVS tags: qemu1001, HEAD
qemu 1.0.1

    1: /*
    2:  * QEMU System Emulator
    3:  *
    4:  * Copyright (c) 2003-2008 Fabrice Bellard
    5:  *
    6:  * Permission is hereby granted, free of charge, to any person obtaining a copy
    7:  * of this software and associated documentation files (the "Software"), to deal
    8:  * in the Software without restriction, including without limitation the rights
    9:  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
   10:  * copies of the Software, and to permit persons to whom the Software is
   11:  * furnished to do so, subject to the following conditions:
   12:  *
   13:  * The above copyright notice and this permission notice shall be included in
   14:  * all copies or substantial portions of the Software.
   15:  *
   16:  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   17:  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   18:  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
   19:  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   20:  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
   21:  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
   22:  * THE SOFTWARE.
   23:  */
   24: #include <stdint.h>
   25: #include <stdarg.h>
   26: #include <stdlib.h>
   27: #ifndef _WIN32
   28: #include <sys/types.h>
   29: #include <sys/mman.h>
   30: #endif
   31: #include "config.h"
   32: #include "monitor.h"
   33: #include "sysemu.h"
   34: #include "arch_init.h"
   35: #include "audio/audio.h"
   36: #include "hw/pc.h"
   37: #include "hw/pci.h"
   38: #include "hw/audiodev.h"
   39: #include "kvm.h"
   40: #include "migration.h"
   41: #include "net.h"
   42: #include "gdbstub.h"
   43: #include "hw/smbios.h"
   44: 
   45: #ifdef TARGET_SPARC
   46: int graphic_width = 1024;
   47: int graphic_height = 768;
   48: int graphic_depth = 8;
   49: #else
   50: int graphic_width = 800;
   51: int graphic_height = 600;
   52: int graphic_depth = 15;
   53: #endif
   54: 
   55: const char arch_config_name[] = CONFIG_QEMU_CONFDIR "/target-" TARGET_ARCH ".conf";
   56: 
   57: #if defined(TARGET_ALPHA)
   58: #define QEMU_ARCH QEMU_ARCH_ALPHA
   59: #elif defined(TARGET_ARM)
   60: #define QEMU_ARCH QEMU_ARCH_ARM
   61: #elif defined(TARGET_CRIS)
   62: #define QEMU_ARCH QEMU_ARCH_CRIS
   63: #elif defined(TARGET_I386)
   64: #define QEMU_ARCH QEMU_ARCH_I386
   65: #elif defined(TARGET_M68K)
   66: #define QEMU_ARCH QEMU_ARCH_M68K
   67: #elif defined(TARGET_LM32)
   68: #define QEMU_ARCH QEMU_ARCH_LM32
   69: #elif defined(TARGET_MICROBLAZE)
   70: #define QEMU_ARCH QEMU_ARCH_MICROBLAZE
   71: #elif defined(TARGET_MIPS)
   72: #define QEMU_ARCH QEMU_ARCH_MIPS
   73: #elif defined(TARGET_PPC)
   74: #define QEMU_ARCH QEMU_ARCH_PPC
   75: #elif defined(TARGET_S390X)
   76: #define QEMU_ARCH QEMU_ARCH_S390X
   77: #elif defined(TARGET_SH4)
   78: #define QEMU_ARCH QEMU_ARCH_SH4
   79: #elif defined(TARGET_SPARC)
   80: #define QEMU_ARCH QEMU_ARCH_SPARC
   81: #elif defined(TARGET_XTENSA)
   82: #define QEMU_ARCH QEMU_ARCH_XTENSA
   83: #endif
   84: 
   85: const uint32_t arch_type = QEMU_ARCH;
   86: 
   87: /***********************************************************/
   88: /* ram save/restore */
   89: 
   90: #define RAM_SAVE_FLAG_FULL     0x01 /* Obsolete, not used anymore */
   91: #define RAM_SAVE_FLAG_COMPRESS 0x02
   92: #define RAM_SAVE_FLAG_MEM_SIZE 0x04
   93: #define RAM_SAVE_FLAG_PAGE     0x08
   94: #define RAM_SAVE_FLAG_EOS      0x10
   95: #define RAM_SAVE_FLAG_CONTINUE 0x20
   96: 
   97: static int is_dup_page(uint8_t *page, uint8_t ch)
   98: {
   99:     uint32_t val = ch << 24 | ch << 16 | ch << 8 | ch;
  100:     uint32_t *array = (uint32_t *)page;
  101:     int i;
  102: 
  103:     for (i = 0; i < (TARGET_PAGE_SIZE / 4); i++) {
  104:         if (array[i] != val) {
  105:             return 0;
  106:         }
  107:     }
  108: 
  109:     return 1;
  110: }
  111: 
  112: static RAMBlock *last_block;
  113: static ram_addr_t last_offset;
  114: 
  115: static int ram_save_block(QEMUFile *f)
  116: {
  117:     RAMBlock *block = last_block;
  118:     ram_addr_t offset = last_offset;
  119:     ram_addr_t current_addr;
  120:     int bytes_sent = 0;
  121: 
  122:     if (!block)
  123:         block = QLIST_FIRST(&ram_list.blocks);
  124: 
  125:     current_addr = block->offset + offset;
  126: 
  127:     do {
  128:         if (cpu_physical_memory_get_dirty(current_addr, MIGRATION_DIRTY_FLAG)) {
  129:             uint8_t *p;
  130:             int cont = (block == last_block) ? RAM_SAVE_FLAG_CONTINUE : 0;
  131: 
  132:             cpu_physical_memory_reset_dirty(current_addr,
  133:                                             current_addr + TARGET_PAGE_SIZE,
  134:                                             MIGRATION_DIRTY_FLAG);
  135: 
  136:             p = block->host + offset;
  137: 
  138:             if (is_dup_page(p, *p)) {
  139:                 qemu_put_be64(f, offset | cont | RAM_SAVE_FLAG_COMPRESS);
  140:                 if (!cont) {
  141:                     qemu_put_byte(f, strlen(block->idstr));
  142:                     qemu_put_buffer(f, (uint8_t *)block->idstr,
  143:                                     strlen(block->idstr));
  144:                 }
  145:                 qemu_put_byte(f, *p);
  146:                 bytes_sent = 1;
  147:             } else {
  148:                 qemu_put_be64(f, offset | cont | RAM_SAVE_FLAG_PAGE);
  149:                 if (!cont) {
  150:                     qemu_put_byte(f, strlen(block->idstr));
  151:                     qemu_put_buffer(f, (uint8_t *)block->idstr,
  152:                                     strlen(block->idstr));
  153:                 }
  154:                 qemu_put_buffer(f, p, TARGET_PAGE_SIZE);
  155:                 bytes_sent = TARGET_PAGE_SIZE;
  156:             }
  157: 
  158:             break;
  159:         }
  160: 
  161:         offset += TARGET_PAGE_SIZE;
  162:         if (offset >= block->length) {
  163:             offset = 0;
  164:             block = QLIST_NEXT(block, next);
  165:             if (!block)
  166:                 block = QLIST_FIRST(&ram_list.blocks);
  167:         }
  168: 
  169:         current_addr = block->offset + offset;
  170: 
  171:     } while (current_addr != last_block->offset + last_offset);
  172: 
  173:     last_block = block;
  174:     last_offset = offset;
  175: 
  176:     return bytes_sent;
  177: }
  178: 
  179: static uint64_t bytes_transferred;
  180: 
  181: static ram_addr_t ram_save_remaining(void)
  182: {
  183:     RAMBlock *block;
  184:     ram_addr_t count = 0;
  185: 
  186:     QLIST_FOREACH(block, &ram_list.blocks, next) {
  187:         ram_addr_t addr;
  188:         for (addr = block->offset; addr < block->offset + block->length;
  189:              addr += TARGET_PAGE_SIZE) {
  190:             if (cpu_physical_memory_get_dirty(addr, MIGRATION_DIRTY_FLAG)) {
  191:                 count++;
  192:             }
  193:         }
  194:     }
  195: 
  196:     return count;
  197: }
  198: 
  199: uint64_t ram_bytes_remaining(void)
  200: {
  201:     return ram_save_remaining() * TARGET_PAGE_SIZE;
  202: }
  203: 
  204: uint64_t ram_bytes_transferred(void)
  205: {
  206:     return bytes_transferred;
  207: }
  208: 
  209: uint64_t ram_bytes_total(void)
  210: {
  211:     RAMBlock *block;
  212:     uint64_t total = 0;
  213: 
  214:     QLIST_FOREACH(block, &ram_list.blocks, next)
  215:         total += block->length;
  216: 
  217:     return total;
  218: }
  219: 
  220: static int block_compar(const void *a, const void *b)
  221: {
  222:     RAMBlock * const *ablock = a;
  223:     RAMBlock * const *bblock = b;
  224:     if ((*ablock)->offset < (*bblock)->offset) {
  225:         return -1;
  226:     } else if ((*ablock)->offset > (*bblock)->offset) {
  227:         return 1;
  228:     }
  229:     return 0;
  230: }
  231: 
  232: static void sort_ram_list(void)
  233: {
  234:     RAMBlock *block, *nblock, **blocks;
  235:     int n;
  236:     n = 0;
  237:     QLIST_FOREACH(block, &ram_list.blocks, next) {
  238:         ++n;
  239:     }
  240:     blocks = g_malloc(n * sizeof *blocks);
  241:     n = 0;
  242:     QLIST_FOREACH_SAFE(block, &ram_list.blocks, next, nblock) {
  243:         blocks[n++] = block;
  244:         QLIST_REMOVE(block, next);
  245:     }
  246:     qsort(blocks, n, sizeof *blocks, block_compar);
  247:     while (--n >= 0) {
  248:         QLIST_INSERT_HEAD(&ram_list.blocks, blocks[n], next);
  249:     }
  250:     g_free(blocks);
  251: }
  252: 
  253: int ram_save_live(Monitor *mon, QEMUFile *f, int stage, void *opaque)
  254: {
  255:     ram_addr_t addr;
  256:     uint64_t bytes_transferred_last;
  257:     double bwidth = 0;
  258:     uint64_t expected_time = 0;
  259:     int ret;
  260: 
  261:     if (stage < 0) {
  262:         cpu_physical_memory_set_dirty_tracking(0);
  263:         return 0;
  264:     }
  265: 
  266:     if (cpu_physical_sync_dirty_bitmap(0, TARGET_PHYS_ADDR_MAX) != 0) {
  267:         qemu_file_set_error(f, -EINVAL);
  268:         return -EINVAL;
  269:     }
  270: 
  271:     if (stage == 1) {
  272:         RAMBlock *block;
  273:         bytes_transferred = 0;
  274:         last_block = NULL;
  275:         last_offset = 0;
  276:         sort_ram_list();
  277: 
  278:         /* Make sure all dirty bits are set */
  279:         QLIST_FOREACH(block, &ram_list.blocks, next) {
  280:             for (addr = block->offset; addr < block->offset + block->length;
  281:                  addr += TARGET_PAGE_SIZE) {
  282:                 if (!cpu_physical_memory_get_dirty(addr,
  283:                                                    MIGRATION_DIRTY_FLAG)) {
  284:                     cpu_physical_memory_set_dirty(addr);
  285:                 }
  286:             }
  287:         }
  288: 
  289:         /* Enable dirty memory tracking */
  290:         cpu_physical_memory_set_dirty_tracking(1);
  291: 
  292:         qemu_put_be64(f, ram_bytes_total() | RAM_SAVE_FLAG_MEM_SIZE);
  293: 
  294:         QLIST_FOREACH(block, &ram_list.blocks, next) {
  295:             qemu_put_byte(f, strlen(block->idstr));
  296:             qemu_put_buffer(f, (uint8_t *)block->idstr, strlen(block->idstr));
  297:             qemu_put_be64(f, block->length);
  298:         }
  299:     }
  300: 
  301:     bytes_transferred_last = bytes_transferred;
  302:     bwidth = qemu_get_clock_ns(rt_clock);
  303: 
  304:     while ((ret = qemu_file_rate_limit(f)) == 0) {
  305:         int bytes_sent;
  306: 
  307:         bytes_sent = ram_save_block(f);
  308:         bytes_transferred += bytes_sent;
  309:         if (bytes_sent == 0) { /* no more blocks */
  310:             break;
  311:         }
  312:     }
  313: 
  314:     if (ret < 0) {
  315:         return ret;
  316:     }
  317: 
  318:     bwidth = qemu_get_clock_ns(rt_clock) - bwidth;
  319:     bwidth = (bytes_transferred - bytes_transferred_last) / bwidth;
  320: 
  321:     /* if we haven't transferred anything this round, force expected_time to a
  322:      * a very high value, but without crashing */
  323:     if (bwidth == 0) {
  324:         bwidth = 0.000001;
  325:     }
  326: 
  327:     /* try transferring iterative blocks of memory */
  328:     if (stage == 3) {
  329:         int bytes_sent;
  330: 
  331:         /* flush all remaining blocks regardless of rate limiting */
  332:         while ((bytes_sent = ram_save_block(f)) != 0) {
  333:             bytes_transferred += bytes_sent;
  334:         }
  335:         cpu_physical_memory_set_dirty_tracking(0);
  336:     }
  337: 
  338:     qemu_put_be64(f, RAM_SAVE_FLAG_EOS);
  339: 
  340:     expected_time = ram_save_remaining() * TARGET_PAGE_SIZE / bwidth;
  341: 
  342:     return (stage == 2) && (expected_time <= migrate_max_downtime());
  343: }
  344: 
  345: static inline void *host_from_stream_offset(QEMUFile *f,
  346:                                             ram_addr_t offset,
  347:                                             int flags)
  348: {
  349:     static RAMBlock *block = NULL;
  350:     char id[256];
  351:     uint8_t len;
  352: 
  353:     if (flags & RAM_SAVE_FLAG_CONTINUE) {
  354:         if (!block) {
  355:             fprintf(stderr, "Ack, bad migration stream!\n");
  356:             return NULL;
  357:         }
  358: 
  359:         return block->host + offset;
  360:     }
  361: 
  362:     len = qemu_get_byte(f);
  363:     qemu_get_buffer(f, (uint8_t *)id, len);
  364:     id[len] = 0;
  365: 
  366:     QLIST_FOREACH(block, &ram_list.blocks, next) {
  367:         if (!strncmp(id, block->idstr, sizeof(id)))
  368:             return block->host + offset;
  369:     }
  370: 
  371:     fprintf(stderr, "Can't find block %s!\n", id);
  372:     return NULL;
  373: }
  374: 
  375: int ram_load(QEMUFile *f, void *opaque, int version_id)
  376: {
  377:     ram_addr_t addr;
  378:     int flags;
  379:     int error;
  380: 
  381:     if (version_id < 3 || version_id > 4) {
  382:         return -EINVAL;
  383:     }
  384: 
  385:     do {
  386:         addr = qemu_get_be64(f);
  387: 
  388:         flags = addr & ~TARGET_PAGE_MASK;
  389:         addr &= TARGET_PAGE_MASK;
  390: 
  391:         if (flags & RAM_SAVE_FLAG_MEM_SIZE) {
  392:             if (version_id == 3) {
  393:                 if (addr != ram_bytes_total()) {
  394:                     return -EINVAL;
  395:                 }
  396:             } else {
  397:                 /* Synchronize RAM block list */
  398:                 char id[256];
  399:                 ram_addr_t length;
  400:                 ram_addr_t total_ram_bytes = addr;
  401: 
  402:                 while (total_ram_bytes) {
  403:                     RAMBlock *block;
  404:                     uint8_t len;
  405: 
  406:                     len = qemu_get_byte(f);
  407:                     qemu_get_buffer(f, (uint8_t *)id, len);
  408:                     id[len] = 0;
  409:                     length = qemu_get_be64(f);
  410: 
  411:                     QLIST_FOREACH(block, &ram_list.blocks, next) {
  412:                         if (!strncmp(id, block->idstr, sizeof(id))) {
  413:                             if (block->length != length)
  414:                                 return -EINVAL;
  415:                             break;
  416:                         }
  417:                     }
  418: 
  419:                     if (!block) {
  420:                         fprintf(stderr, "Unknown ramblock \"%s\", cannot "
  421:                                 "accept migration\n", id);
  422:                         return -EINVAL;
  423:                     }
  424: 
  425:                     total_ram_bytes -= length;
  426:                 }
  427:             }
  428:         }
  429: 
  430:         if (flags & RAM_SAVE_FLAG_COMPRESS) {
  431:             void *host;
  432:             uint8_t ch;
  433: 
  434:             if (version_id == 3)
  435:                 host = qemu_get_ram_ptr(addr);
  436:             else
  437:                 host = host_from_stream_offset(f, addr, flags);
  438:             if (!host) {
  439:                 return -EINVAL;
  440:             }
  441: 
  442:             ch = qemu_get_byte(f);
  443:             memset(host, ch, TARGET_PAGE_SIZE);
  444: #ifndef _WIN32
  445:             if (ch == 0 &&
  446:                 (!kvm_enabled() || kvm_has_sync_mmu())) {
  447:                 qemu_madvise(host, TARGET_PAGE_SIZE, QEMU_MADV_DONTNEED);
  448:             }
  449: #endif
  450:         } else if (flags & RAM_SAVE_FLAG_PAGE) {
  451:             void *host;
  452: 
  453:             if (version_id == 3)
  454:                 host = qemu_get_ram_ptr(addr);
  455:             else
  456:                 host = host_from_stream_offset(f, addr, flags);
  457: 
  458:             qemu_get_buffer(f, host, TARGET_PAGE_SIZE);
  459:         }
  460:         error = qemu_file_get_error(f);
  461:         if (error) {
  462:             return error;
  463:         }
  464:     } while (!(flags & RAM_SAVE_FLAG_EOS));
  465: 
  466:     return 0;
  467: }
  468: 
  469: #ifdef HAS_AUDIO
  470: struct soundhw {
  471:     const char *name;
  472:     const char *descr;
  473:     int enabled;
  474:     int isa;
  475:     union {
  476:         int (*init_isa) (qemu_irq *pic);
  477:         int (*init_pci) (PCIBus *bus);
  478:     } init;
  479: };
  480: 
  481: static struct soundhw soundhw[] = {
  482: #ifdef HAS_AUDIO_CHOICE
  483: #if defined(TARGET_I386) || defined(TARGET_MIPS)
  484:     {
  485:         "pcspk",
  486:         "PC speaker",
  487:         0,
  488:         1,
  489:         { .init_isa = pcspk_audio_init }
  490:     },
  491: #endif
  492: 
  493: #ifdef CONFIG_SB16
  494:     {
  495:         "sb16",
  496:         "Creative Sound Blaster 16",
  497:         0,
  498:         1,
  499:         { .init_isa = SB16_init }
  500:     },
  501: #endif
  502: 
  503: #ifdef CONFIG_CS4231A
  504:     {
  505:         "cs4231a",
  506:         "CS4231A",
  507:         0,
  508:         1,
  509:         { .init_isa = cs4231a_init }
  510:     },
  511: #endif
  512: 
  513: #ifdef CONFIG_ADLIB
  514:     {
  515:         "adlib",
  516: #ifdef HAS_YMF262
  517:         "Yamaha YMF262 (OPL3)",
  518: #else
  519:         "Yamaha YM3812 (OPL2)",
  520: #endif
  521:         0,
  522:         1,
  523:         { .init_isa = Adlib_init }
  524:     },
  525: #endif
  526: 
  527: #ifdef CONFIG_GUS
  528:     {
  529:         "gus",
  530:         "Gravis Ultrasound GF1",
  531:         0,
  532:         1,
  533:         { .init_isa = GUS_init }
  534:     },
  535: #endif
  536: 
  537: #ifdef CONFIG_AC97
  538:     {
  539:         "ac97",
  540:         "Intel 82801AA AC97 Audio",
  541:         0,
  542:         0,
  543:         { .init_pci = ac97_init }
  544:     },
  545: #endif
  546: 
  547: #ifdef CONFIG_ES1370
  548:     {
  549:         "es1370",
  550:         "ENSONIQ AudioPCI ES1370",
  551:         0,
  552:         0,
  553:         { .init_pci = es1370_init }
  554:     },
  555: #endif
  556: 
  557: #ifdef CONFIG_HDA
  558:     {
  559:         "hda",
  560:         "Intel HD Audio",
  561:         0,
  562:         0,
  563:         { .init_pci = intel_hda_and_codec_init }
  564:     },
  565: #endif
  566: 
  567: #endif /* HAS_AUDIO_CHOICE */
  568: 
  569:     { NULL, NULL, 0, 0, { NULL } }
  570: };
  571: 
  572: void select_soundhw(const char *optarg)
  573: {
  574:     struct soundhw *c;
  575: 
  576:     if (*optarg == '?') {
  577:     show_valid_cards:
  578: 
  579:         printf("Valid sound card names (comma separated):\n");
  580:         for (c = soundhw; c->name; ++c) {
  581:             printf ("%-11s %s\n", c->name, c->descr);
  582:         }
  583:         printf("\n-soundhw all will enable all of the above\n");
  584:         exit(*optarg != '?');
  585:     }
  586:     else {
  587:         size_t l;
  588:         const char *p;
  589:         char *e;
  590:         int bad_card = 0;
  591: 
  592:         if (!strcmp(optarg, "all")) {
  593:             for (c = soundhw; c->name; ++c) {
  594:                 c->enabled = 1;
  595:             }
  596:             return;
  597:         }
  598: 
  599:         p = optarg;
  600:         while (*p) {
  601:             e = strchr(p, ',');
  602:             l = !e ? strlen(p) : (size_t) (e - p);
  603: 
  604:             for (c = soundhw; c->name; ++c) {
  605:                 if (!strncmp(c->name, p, l) && !c->name[l]) {
  606:                     c->enabled = 1;
  607:                     break;
  608:                 }
  609:             }
  610: 
  611:             if (!c->name) {
  612:                 if (l > 80) {
  613:                     fprintf(stderr,
  614:                             "Unknown sound card name (too big to show)\n");
  615:                 }
  616:                 else {
  617:                     fprintf(stderr, "Unknown sound card name `%.*s'\n",
  618:                             (int) l, p);
  619:                 }
  620:                 bad_card = 1;
  621:             }
  622:             p += l + (e != NULL);
  623:         }
  624: 
  625:         if (bad_card) {
  626:             goto show_valid_cards;
  627:         }
  628:     }
  629: }
  630: 
  631: void audio_init(qemu_irq *isa_pic, PCIBus *pci_bus)
  632: {
  633:     struct soundhw *c;
  634: 
  635:     for (c = soundhw; c->name; ++c) {
  636:         if (c->enabled) {
  637:             if (c->isa) {
  638:                 if (isa_pic) {
  639:                     c->init.init_isa(isa_pic);
  640:                 }
  641:             } else {
  642:                 if (pci_bus) {
  643:                     c->init.init_pci(pci_bus);
  644:                 }
  645:             }
  646:         }
  647:     }
  648: }
  649: #else
  650: void select_soundhw(const char *optarg)
  651: {
  652: }
  653: void audio_init(qemu_irq *isa_pic, PCIBus *pci_bus)
  654: {
  655: }
  656: #endif
  657: 
  658: int qemu_uuid_parse(const char *str, uint8_t *uuid)
  659: {
  660:     int ret;
  661: 
  662:     if (strlen(str) != 36) {
  663:         return -1;
  664:     }
  665: 
  666:     ret = sscanf(str, UUID_FMT, &uuid[0], &uuid[1], &uuid[2], &uuid[3],
  667:                  &uuid[4], &uuid[5], &uuid[6], &uuid[7], &uuid[8], &uuid[9],
  668:                  &uuid[10], &uuid[11], &uuid[12], &uuid[13], &uuid[14],
  669:                  &uuid[15]);
  670: 
  671:     if (ret != 16) {
  672:         return -1;
  673:     }
  674: #ifdef TARGET_I386
  675:     smbios_add_field(1, offsetof(struct smbios_type_1, uuid), 16, uuid);
  676: #endif
  677:     return 0;
  678: }
  679: 
  680: void do_acpitable_option(const char *optarg)
  681: {
  682: #ifdef TARGET_I386
  683:     if (acpi_table_add(optarg) < 0) {
  684:         fprintf(stderr, "Wrong acpi table provided\n");
  685:         exit(1);
  686:     }
  687: #endif
  688: }
  689: 
  690: void do_smbios_option(const char *optarg)
  691: {
  692: #ifdef TARGET_I386
  693:     if (smbios_entry_add(optarg) < 0) {
  694:         fprintf(stderr, "Wrong smbios provided\n");
  695:         exit(1);
  696:     }
  697: #endif
  698: }
  699: 
  700: void cpudef_init(void)
  701: {
  702: #if defined(cpudef_setup)
  703:     cpudef_setup(); /* parse cpu definitions in target config file */
  704: #endif
  705: }
  706: 
  707: int audio_available(void)
  708: {
  709: #ifdef HAS_AUDIO
  710:     return 1;
  711: #else
  712:     return 0;
  713: #endif
  714: }
  715: 
  716: int tcg_available(void)
  717: {
  718:     return 1;
  719: }
  720: 
  721: int kvm_available(void)
  722: {
  723: #ifdef CONFIG_KVM
  724:     return 1;
  725: #else
  726:     return 0;
  727: #endif
  728: }
  729: 
  730: int xen_available(void)
  731: {
  732: #ifdef CONFIG_XEN
  733:     return 1;
  734: #else
  735:     return 0;
  736: #endif
  737: }

unix.superglobalmegacorp.com