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