File:  [Qemu by Fabrice Bellard] / qemu / arch_init.c
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs
Tue Apr 24 18:34:25 2018 UTC (3 years, 1 month ago) by root
Branches: qemu, MAIN
CVS tags: qemu0150, qemu0141, qemu0140, HEAD
qemu 0.14.0

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

unix.superglobalmegacorp.com