File:  [Qemu by Fabrice Bellard] / qemu / arch_init.c
Revision 1.1.1.3 (vendor branch): download - view: text, annotated - select for diffs
Tue Apr 24 18:56:42 2018 UTC (3 years, 1 month ago) by root
Branches: qemu, MAIN
CVS tags: qemu1000, qemu0151, HEAD
qemu 0.15.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: #endif
   82: 
   83: const uint32_t arch_type = QEMU_ARCH;
   84: 
   85: /***********************************************************/
   86: /* ram save/restore */
   87: 
   88: #define RAM_SAVE_FLAG_FULL     0x01 /* Obsolete, not used anymore */
   89: #define RAM_SAVE_FLAG_COMPRESS 0x02
   90: #define RAM_SAVE_FLAG_MEM_SIZE 0x04
   91: #define RAM_SAVE_FLAG_PAGE     0x08
   92: #define RAM_SAVE_FLAG_EOS      0x10
   93: #define RAM_SAVE_FLAG_CONTINUE 0x20
   94: 
   95: static int is_dup_page(uint8_t *page, uint8_t ch)
   96: {
   97:     uint32_t val = ch << 24 | ch << 16 | ch << 8 | ch;
   98:     uint32_t *array = (uint32_t *)page;
   99:     int i;
  100: 
  101:     for (i = 0; i < (TARGET_PAGE_SIZE / 4); i++) {
  102:         if (array[i] != val) {
  103:             return 0;
  104:         }
  105:     }
  106: 
  107:     return 1;
  108: }
  109: 
  110: static RAMBlock *last_block;
  111: static ram_addr_t last_offset;
  112: 
  113: static int ram_save_block(QEMUFile *f)
  114: {
  115:     RAMBlock *block = last_block;
  116:     ram_addr_t offset = last_offset;
  117:     ram_addr_t current_addr;
  118:     int bytes_sent = 0;
  119: 
  120:     if (!block)
  121:         block = QLIST_FIRST(&ram_list.blocks);
  122: 
  123:     current_addr = block->offset + offset;
  124: 
  125:     do {
  126:         if (cpu_physical_memory_get_dirty(current_addr, MIGRATION_DIRTY_FLAG)) {
  127:             uint8_t *p;
  128:             int cont = (block == last_block) ? RAM_SAVE_FLAG_CONTINUE : 0;
  129: 
  130:             cpu_physical_memory_reset_dirty(current_addr,
  131:                                             current_addr + TARGET_PAGE_SIZE,
  132:                                             MIGRATION_DIRTY_FLAG);
  133: 
  134:             p = block->host + offset;
  135: 
  136:             if (is_dup_page(p, *p)) {
  137:                 qemu_put_be64(f, offset | cont | RAM_SAVE_FLAG_COMPRESS);
  138:                 if (!cont) {
  139:                     qemu_put_byte(f, strlen(block->idstr));
  140:                     qemu_put_buffer(f, (uint8_t *)block->idstr,
  141:                                     strlen(block->idstr));
  142:                 }
  143:                 qemu_put_byte(f, *p);
  144:                 bytes_sent = 1;
  145:             } else {
  146:                 qemu_put_be64(f, offset | cont | RAM_SAVE_FLAG_PAGE);
  147:                 if (!cont) {
  148:                     qemu_put_byte(f, strlen(block->idstr));
  149:                     qemu_put_buffer(f, (uint8_t *)block->idstr,
  150:                                     strlen(block->idstr));
  151:                 }
  152:                 qemu_put_buffer(f, p, TARGET_PAGE_SIZE);
  153:                 bytes_sent = TARGET_PAGE_SIZE;
  154:             }
  155: 
  156:             break;
  157:         }
  158: 
  159:         offset += TARGET_PAGE_SIZE;
  160:         if (offset >= block->length) {
  161:             offset = 0;
  162:             block = QLIST_NEXT(block, next);
  163:             if (!block)
  164:                 block = QLIST_FIRST(&ram_list.blocks);
  165:         }
  166: 
  167:         current_addr = block->offset + offset;
  168: 
  169:     } while (current_addr != last_block->offset + last_offset);
  170: 
  171:     last_block = block;
  172:     last_offset = offset;
  173: 
  174:     return bytes_sent;
  175: }
  176: 
  177: static uint64_t bytes_transferred;
  178: 
  179: static ram_addr_t ram_save_remaining(void)
  180: {
  181:     RAMBlock *block;
  182:     ram_addr_t count = 0;
  183: 
  184:     QLIST_FOREACH(block, &ram_list.blocks, next) {
  185:         ram_addr_t addr;
  186:         for (addr = block->offset; addr < block->offset + block->length;
  187:              addr += TARGET_PAGE_SIZE) {
  188:             if (cpu_physical_memory_get_dirty(addr, MIGRATION_DIRTY_FLAG)) {
  189:                 count++;
  190:             }
  191:         }
  192:     }
  193: 
  194:     return count;
  195: }
  196: 
  197: uint64_t ram_bytes_remaining(void)
  198: {
  199:     return ram_save_remaining() * TARGET_PAGE_SIZE;
  200: }
  201: 
  202: uint64_t ram_bytes_transferred(void)
  203: {
  204:     return bytes_transferred;
  205: }
  206: 
  207: uint64_t ram_bytes_total(void)
  208: {
  209:     RAMBlock *block;
  210:     uint64_t total = 0;
  211: 
  212:     QLIST_FOREACH(block, &ram_list.blocks, next)
  213:         total += block->length;
  214: 
  215:     return total;
  216: }
  217: 
  218: static int block_compar(const void *a, const void *b)
  219: {
  220:     RAMBlock * const *ablock = a;
  221:     RAMBlock * const *bblock = b;
  222:     if ((*ablock)->offset < (*bblock)->offset) {
  223:         return -1;
  224:     } else if ((*ablock)->offset > (*bblock)->offset) {
  225:         return 1;
  226:     }
  227:     return 0;
  228: }
  229: 
  230: static void sort_ram_list(void)
  231: {
  232:     RAMBlock *block, *nblock, **blocks;
  233:     int n;
  234:     n = 0;
  235:     QLIST_FOREACH(block, &ram_list.blocks, next) {
  236:         ++n;
  237:     }
  238:     blocks = qemu_malloc(n * sizeof *blocks);
  239:     n = 0;
  240:     QLIST_FOREACH_SAFE(block, &ram_list.blocks, next, nblock) {
  241:         blocks[n++] = block;
  242:         QLIST_REMOVE(block, next);
  243:     }
  244:     qsort(blocks, n, sizeof *blocks, block_compar);
  245:     while (--n >= 0) {
  246:         QLIST_INSERT_HEAD(&ram_list.blocks, blocks[n], next);
  247:     }
  248:     qemu_free(blocks);
  249: }
  250: 
  251: int ram_save_live(Monitor *mon, QEMUFile *f, int stage, void *opaque)
  252: {
  253:     ram_addr_t addr;
  254:     uint64_t bytes_transferred_last;
  255:     double bwidth = 0;
  256:     uint64_t expected_time = 0;
  257: 
  258:     if (stage < 0) {
  259:         cpu_physical_memory_set_dirty_tracking(0);
  260:         return 0;
  261:     }
  262: 
  263:     if (cpu_physical_sync_dirty_bitmap(0, TARGET_PHYS_ADDR_MAX) != 0) {
  264:         qemu_file_set_error(f);
  265:         return 0;
  266:     }
  267: 
  268:     if (stage == 1) {
  269:         RAMBlock *block;
  270:         bytes_transferred = 0;
  271:         last_block = NULL;
  272:         last_offset = 0;
  273:         sort_ram_list();
  274: 
  275:         /* Make sure all dirty bits are set */
  276:         QLIST_FOREACH(block, &ram_list.blocks, next) {
  277:             for (addr = block->offset; addr < block->offset + block->length;
  278:                  addr += TARGET_PAGE_SIZE) {
  279:                 if (!cpu_physical_memory_get_dirty(addr,
  280:                                                    MIGRATION_DIRTY_FLAG)) {
  281:                     cpu_physical_memory_set_dirty(addr);
  282:                 }
  283:             }
  284:         }
  285: 
  286:         /* Enable dirty memory tracking */
  287:         cpu_physical_memory_set_dirty_tracking(1);
  288: 
  289:         qemu_put_be64(f, ram_bytes_total() | RAM_SAVE_FLAG_MEM_SIZE);
  290: 
  291:         QLIST_FOREACH(block, &ram_list.blocks, next) {
  292:             qemu_put_byte(f, strlen(block->idstr));
  293:             qemu_put_buffer(f, (uint8_t *)block->idstr, strlen(block->idstr));
  294:             qemu_put_be64(f, block->length);
  295:         }
  296:     }
  297: 
  298:     bytes_transferred_last = bytes_transferred;
  299:     bwidth = qemu_get_clock_ns(rt_clock);
  300: 
  301:     while (!qemu_file_rate_limit(f)) {
  302:         int bytes_sent;
  303: 
  304:         bytes_sent = ram_save_block(f);
  305:         bytes_transferred += bytes_sent;
  306:         if (bytes_sent == 0) { /* no more blocks */
  307:             break;
  308:         }
  309:     }
  310: 
  311:     bwidth = qemu_get_clock_ns(rt_clock) - bwidth;
  312:     bwidth = (bytes_transferred - bytes_transferred_last) / bwidth;
  313: 
  314:     /* if we haven't transferred anything this round, force expected_time to a
  315:      * a very high value, but without crashing */
  316:     if (bwidth == 0) {
  317:         bwidth = 0.000001;
  318:     }
  319: 
  320:     /* try transferring iterative blocks of memory */
  321:     if (stage == 3) {
  322:         int bytes_sent;
  323: 
  324:         /* flush all remaining blocks regardless of rate limiting */
  325:         while ((bytes_sent = ram_save_block(f)) != 0) {
  326:             bytes_transferred += bytes_sent;
  327:         }
  328:         cpu_physical_memory_set_dirty_tracking(0);
  329:     }
  330: 
  331:     qemu_put_be64(f, RAM_SAVE_FLAG_EOS);
  332: 
  333:     expected_time = ram_save_remaining() * TARGET_PAGE_SIZE / bwidth;
  334: 
  335:     return (stage == 2) && (expected_time <= migrate_max_downtime());
  336: }
  337: 
  338: static inline void *host_from_stream_offset(QEMUFile *f,
  339:                                             ram_addr_t offset,
  340:                                             int flags)
  341: {
  342:     static RAMBlock *block = NULL;
  343:     char id[256];
  344:     uint8_t len;
  345: 
  346:     if (flags & RAM_SAVE_FLAG_CONTINUE) {
  347:         if (!block) {
  348:             fprintf(stderr, "Ack, bad migration stream!\n");
  349:             return NULL;
  350:         }
  351: 
  352:         return block->host + offset;
  353:     }
  354: 
  355:     len = qemu_get_byte(f);
  356:     qemu_get_buffer(f, (uint8_t *)id, len);
  357:     id[len] = 0;
  358: 
  359:     QLIST_FOREACH(block, &ram_list.blocks, next) {
  360:         if (!strncmp(id, block->idstr, sizeof(id)))
  361:             return block->host + offset;
  362:     }
  363: 
  364:     fprintf(stderr, "Can't find block %s!\n", id);
  365:     return NULL;
  366: }
  367: 
  368: int ram_load(QEMUFile *f, void *opaque, int version_id)
  369: {
  370:     ram_addr_t addr;
  371:     int flags;
  372: 
  373:     if (version_id < 3 || version_id > 4) {
  374:         return -EINVAL;
  375:     }
  376: 
  377:     do {
  378:         addr = qemu_get_be64(f);
  379: 
  380:         flags = addr & ~TARGET_PAGE_MASK;
  381:         addr &= TARGET_PAGE_MASK;
  382: 
  383:         if (flags & RAM_SAVE_FLAG_MEM_SIZE) {
  384:             if (version_id == 3) {
  385:                 if (addr != ram_bytes_total()) {
  386:                     return -EINVAL;
  387:                 }
  388:             } else {
  389:                 /* Synchronize RAM block list */
  390:                 char id[256];
  391:                 ram_addr_t length;
  392:                 ram_addr_t total_ram_bytes = addr;
  393: 
  394:                 while (total_ram_bytes) {
  395:                     RAMBlock *block;
  396:                     uint8_t len;
  397: 
  398:                     len = qemu_get_byte(f);
  399:                     qemu_get_buffer(f, (uint8_t *)id, len);
  400:                     id[len] = 0;
  401:                     length = qemu_get_be64(f);
  402: 
  403:                     QLIST_FOREACH(block, &ram_list.blocks, next) {
  404:                         if (!strncmp(id, block->idstr, sizeof(id))) {
  405:                             if (block->length != length)
  406:                                 return -EINVAL;
  407:                             break;
  408:                         }
  409:                     }
  410: 
  411:                     if (!block) {
  412:                         fprintf(stderr, "Unknown ramblock \"%s\", cannot "
  413:                                 "accept migration\n", id);
  414:                         return -EINVAL;
  415:                     }
  416: 
  417:                     total_ram_bytes -= length;
  418:                 }
  419:             }
  420:         }
  421: 
  422:         if (flags & RAM_SAVE_FLAG_COMPRESS) {
  423:             void *host;
  424:             uint8_t ch;
  425: 
  426:             if (version_id == 3)
  427:                 host = qemu_get_ram_ptr(addr);
  428:             else
  429:                 host = host_from_stream_offset(f, addr, flags);
  430:             if (!host) {
  431:                 return -EINVAL;
  432:             }
  433: 
  434:             ch = qemu_get_byte(f);
  435:             memset(host, ch, TARGET_PAGE_SIZE);
  436: #ifndef _WIN32
  437:             if (ch == 0 &&
  438:                 (!kvm_enabled() || kvm_has_sync_mmu())) {
  439:                 qemu_madvise(host, TARGET_PAGE_SIZE, QEMU_MADV_DONTNEED);
  440:             }
  441: #endif
  442:         } else if (flags & RAM_SAVE_FLAG_PAGE) {
  443:             void *host;
  444: 
  445:             if (version_id == 3)
  446:                 host = qemu_get_ram_ptr(addr);
  447:             else
  448:                 host = host_from_stream_offset(f, addr, flags);
  449: 
  450:             qemu_get_buffer(f, host, TARGET_PAGE_SIZE);
  451:         }
  452:         if (qemu_file_has_error(f)) {
  453:             return -EIO;
  454:         }
  455:     } while (!(flags & RAM_SAVE_FLAG_EOS));
  456: 
  457:     return 0;
  458: }
  459: 
  460: void qemu_service_io(void)
  461: {
  462:     qemu_notify_event();
  463: }
  464: 
  465: #ifdef HAS_AUDIO
  466: struct soundhw {
  467:     const char *name;
  468:     const char *descr;
  469:     int enabled;
  470:     int isa;
  471:     union {
  472:         int (*init_isa) (qemu_irq *pic);
  473:         int (*init_pci) (PCIBus *bus);
  474:     } init;
  475: };
  476: 
  477: static struct soundhw soundhw[] = {
  478: #ifdef HAS_AUDIO_CHOICE
  479: #if defined(TARGET_I386) || defined(TARGET_MIPS)
  480:     {
  481:         "pcspk",
  482:         "PC speaker",
  483:         0,
  484:         1,
  485:         { .init_isa = pcspk_audio_init }
  486:     },
  487: #endif
  488: 
  489: #ifdef CONFIG_SB16
  490:     {
  491:         "sb16",
  492:         "Creative Sound Blaster 16",
  493:         0,
  494:         1,
  495:         { .init_isa = SB16_init }
  496:     },
  497: #endif
  498: 
  499: #ifdef CONFIG_CS4231A
  500:     {
  501:         "cs4231a",
  502:         "CS4231A",
  503:         0,
  504:         1,
  505:         { .init_isa = cs4231a_init }
  506:     },
  507: #endif
  508: 
  509: #ifdef CONFIG_ADLIB
  510:     {
  511:         "adlib",
  512: #ifdef HAS_YMF262
  513:         "Yamaha YMF262 (OPL3)",
  514: #else
  515:         "Yamaha YM3812 (OPL2)",
  516: #endif
  517:         0,
  518:         1,
  519:         { .init_isa = Adlib_init }
  520:     },
  521: #endif
  522: 
  523: #ifdef CONFIG_GUS
  524:     {
  525:         "gus",
  526:         "Gravis Ultrasound GF1",
  527:         0,
  528:         1,
  529:         { .init_isa = GUS_init }
  530:     },
  531: #endif
  532: 
  533: #ifdef CONFIG_AC97
  534:     {
  535:         "ac97",
  536:         "Intel 82801AA AC97 Audio",
  537:         0,
  538:         0,
  539:         { .init_pci = ac97_init }
  540:     },
  541: #endif
  542: 
  543: #ifdef CONFIG_ES1370
  544:     {
  545:         "es1370",
  546:         "ENSONIQ AudioPCI ES1370",
  547:         0,
  548:         0,
  549:         { .init_pci = es1370_init }
  550:     },
  551: #endif
  552: 
  553: #ifdef CONFIG_HDA
  554:     {
  555:         "hda",
  556:         "Intel HD Audio",
  557:         0,
  558:         0,
  559:         { .init_pci = intel_hda_and_codec_init }
  560:     },
  561: #endif
  562: 
  563: #endif /* HAS_AUDIO_CHOICE */
  564: 
  565:     { NULL, NULL, 0, 0, { NULL } }
  566: };
  567: 
  568: void select_soundhw(const char *optarg)
  569: {
  570:     struct soundhw *c;
  571: 
  572:     if (*optarg == '?') {
  573:     show_valid_cards:
  574: 
  575:         printf("Valid sound card names (comma separated):\n");
  576:         for (c = soundhw; c->name; ++c) {
  577:             printf ("%-11s %s\n", c->name, c->descr);
  578:         }
  579:         printf("\n-soundhw all will enable all of the above\n");
  580:         exit(*optarg != '?');
  581:     }
  582:     else {
  583:         size_t l;
  584:         const char *p;
  585:         char *e;
  586:         int bad_card = 0;
  587: 
  588:         if (!strcmp(optarg, "all")) {
  589:             for (c = soundhw; c->name; ++c) {
  590:                 c->enabled = 1;
  591:             }
  592:             return;
  593:         }
  594: 
  595:         p = optarg;
  596:         while (*p) {
  597:             e = strchr(p, ',');
  598:             l = !e ? strlen(p) : (size_t) (e - p);
  599: 
  600:             for (c = soundhw; c->name; ++c) {
  601:                 if (!strncmp(c->name, p, l) && !c->name[l]) {
  602:                     c->enabled = 1;
  603:                     break;
  604:                 }
  605:             }
  606: 
  607:             if (!c->name) {
  608:                 if (l > 80) {
  609:                     fprintf(stderr,
  610:                             "Unknown sound card name (too big to show)\n");
  611:                 }
  612:                 else {
  613:                     fprintf(stderr, "Unknown sound card name `%.*s'\n",
  614:                             (int) l, p);
  615:                 }
  616:                 bad_card = 1;
  617:             }
  618:             p += l + (e != NULL);
  619:         }
  620: 
  621:         if (bad_card) {
  622:             goto show_valid_cards;
  623:         }
  624:     }
  625: }
  626: 
  627: void audio_init(qemu_irq *isa_pic, PCIBus *pci_bus)
  628: {
  629:     struct soundhw *c;
  630: 
  631:     for (c = soundhw; c->name; ++c) {
  632:         if (c->enabled) {
  633:             if (c->isa) {
  634:                 if (isa_pic) {
  635:                     c->init.init_isa(isa_pic);
  636:                 }
  637:             } else {
  638:                 if (pci_bus) {
  639:                     c->init.init_pci(pci_bus);
  640:                 }
  641:             }
  642:         }
  643:     }
  644: }
  645: #else
  646: void select_soundhw(const char *optarg)
  647: {
  648: }
  649: void audio_init(qemu_irq *isa_pic, PCIBus *pci_bus)
  650: {
  651: }
  652: #endif
  653: 
  654: int qemu_uuid_parse(const char *str, uint8_t *uuid)
  655: {
  656:     int ret;
  657: 
  658:     if (strlen(str) != 36) {
  659:         return -1;
  660:     }
  661: 
  662:     ret = sscanf(str, UUID_FMT, &uuid[0], &uuid[1], &uuid[2], &uuid[3],
  663:                  &uuid[4], &uuid[5], &uuid[6], &uuid[7], &uuid[8], &uuid[9],
  664:                  &uuid[10], &uuid[11], &uuid[12], &uuid[13], &uuid[14],
  665:                  &uuid[15]);
  666: 
  667:     if (ret != 16) {
  668:         return -1;
  669:     }
  670: #ifdef TARGET_I386
  671:     smbios_add_field(1, offsetof(struct smbios_type_1, uuid), 16, uuid);
  672: #endif
  673:     return 0;
  674: }
  675: 
  676: void do_acpitable_option(const char *optarg)
  677: {
  678: #ifdef TARGET_I386
  679:     if (acpi_table_add(optarg) < 0) {
  680:         fprintf(stderr, "Wrong acpi table provided\n");
  681:         exit(1);
  682:     }
  683: #endif
  684: }
  685: 
  686: void do_smbios_option(const char *optarg)
  687: {
  688: #ifdef TARGET_I386
  689:     if (smbios_entry_add(optarg) < 0) {
  690:         fprintf(stderr, "Wrong smbios provided\n");
  691:         exit(1);
  692:     }
  693: #endif
  694: }
  695: 
  696: void cpudef_init(void)
  697: {
  698: #if defined(cpudef_setup)
  699:     cpudef_setup(); /* parse cpu definitions in target config file */
  700: #endif
  701: }
  702: 
  703: int audio_available(void)
  704: {
  705: #ifdef HAS_AUDIO
  706:     return 1;
  707: #else
  708:     return 0;
  709: #endif
  710: }
  711: 
  712: int tcg_available(void)
  713: {
  714:     return 1;
  715: }
  716: 
  717: int kvm_available(void)
  718: {
  719: #ifdef CONFIG_KVM
  720:     return 1;
  721: #else
  722:     return 0;
  723: #endif
  724: }
  725: 
  726: int xen_available(void)
  727: {
  728: #ifdef CONFIG_XEN
  729:     return 1;
  730: #else
  731:     return 0;
  732: #endif
  733: }

unix.superglobalmegacorp.com