/* Saves a single BootProperty to file. */ static int boot_property_save_property( QEMUFile *f, BootProperty *p ) { /* split in key and value, so we can re-use boot_property_add (and its * sanity checks) when loading */ char *split = strchr(p->property, '='); if (split == NULL) { D("%s: save failed: illegal key/value pair \"%s\" (missing '=')\n", __FUNCTION__, p->property); qemu_file_set_error(f, -EINVAL); return -1; } *split = '\0'; /* p->property is now "<key>\0<value>\0" */ uint32_t key_buf_len = (split - p->property) + 1; // +1: '\0' terminator qemu_put_be32(f, key_buf_len); qemu_put_buffer(f, (uint8_t*) p->property, key_buf_len); uint32_t value_buf_len = p->length - key_buf_len + 1; // +1: '\0' terminator qemu_put_be32(f, value_buf_len); qemu_put_buffer(f, (uint8_t*) split + 1, value_buf_len); *split = '='; /* restore property to "<key>=<value>\0" */ return 0; }
static int boot_property_save_property( QEMUFile *f, BootProperty *p ) { char *split = strchr(p->property, '='); if (split == NULL) { D("%s: save failed: illegal key/value pair \"%s\" (missing '=')\n", __FUNCTION__, p->property); qemu_file_set_error(f); return -1; } *split = '\0'; uint32_t key_buf_len = (split - p->property) + 1; qemu_put_be32(f, key_buf_len); qemu_put_buffer(f, (uint8_t*) p->property, key_buf_len); uint32_t value_buf_len = p->length - key_buf_len + 1; qemu_put_be32(f, value_buf_len); qemu_put_buffer(f, (uint8_t*) split + 1, value_buf_len); *split = '='; return 0; }
static void smc91c111_save(QEMUFile *f, void *opaque) { smc91c111_state *s = opaque; qemu_put_be16(f, s->tcr); qemu_put_be16(f, s->rcr); qemu_put_be16(f, s->cr); qemu_put_be16(f, s->ctr); qemu_put_be16(f, s->gpr); qemu_put_be16(f, s->ptr); qemu_put_be16(f, s->ercv); qemu_put_be32(f, s->bank); qemu_put_be32(f, s->packet_num); qemu_put_be32(f, s->tx_alloc); qemu_put_be32(f, s->allocated); qemu_put_be32(f, s->tx_fifo_len); qemu_put_buffer(f, (uint8_t*) s->tx_fifo, sizeof(s->tx_fifo)); qemu_put_be32(f, s->rx_fifo_len); qemu_put_buffer(f, (uint8_t*) s->rx_fifo, sizeof(s->rx_fifo)); qemu_put_be32(f, s->tx_fifo_done_len); qemu_put_buffer(f, (uint8_t*) s->tx_fifo_done, sizeof(s->tx_fifo_done)); qemu_put_buffer(f, (uint8_t*) s->data, sizeof(s->data)); qemu_put_byte(f, s->int_level); qemu_put_byte(f, s->int_mask); }
void msix_save(PCIDevice *dev, QEMUFile *f) { unsigned n = dev->msix_entries_nr; if (!(dev->cap_present & QEMU_PCI_CAP_MSIX)) { return; } qemu_put_buffer(f, dev->msix_table_page, n * MSIX_ENTRY_SIZE); qemu_put_buffer(f, dev->msix_table_page + MSIX_PAGE_PENDING, (n + 7) / 8); }
void msix_save(PCIDevice *dev, QEMUFile *f) { unsigned n = dev->msix_entries_nr; if (!msix_present(dev)) { return; } qemu_put_buffer(f, dev->msix_table, n * PCI_MSIX_ENTRY_SIZE); qemu_put_buffer(f, dev->msix_pba, (n + 7) / 8); }
static void mipsnet_save(QEMUFile *f, void *opaque) { MIPSnetState *s = opaque; qemu_put_be32s(f, &s->busy); qemu_put_be32s(f, &s->rx_count); qemu_put_be32s(f, &s->rx_read); qemu_put_be32s(f, &s->tx_count); qemu_put_be32s(f, &s->tx_written); qemu_put_be32s(f, &s->intctl); qemu_put_buffer(f, s->rx_buffer, MAX_ETH_FRAME_SIZE); qemu_put_buffer(f, s->tx_buffer, MAX_ETH_FRAME_SIZE); }
static void slavio_serial_save_chn(QEMUFile *f, ChannelState *s) { qemu_put_be32s(f, &s->irq); qemu_put_be32s(f, &s->reg); qemu_put_be32s(f, &s->rxint); qemu_put_be32s(f, &s->txint); qemu_put_be32s(f, &s->rxint_under_svc); qemu_put_be32s(f, &s->txint_under_svc); qemu_put_8s(f, &s->rx); qemu_put_8s(f, &s->tx); qemu_put_buffer(f, s->wregs, 16); qemu_put_buffer(f, s->rregs, 16); }
static void tcx_save(QEMUFile *f, void *opaque) { TCXState *s = opaque; qemu_put_be16s(f, &s->height); qemu_put_be16s(f, &s->width); qemu_put_be16s(f, &s->depth); qemu_put_buffer(f, s->r, 256); qemu_put_buffer(f, s->g, 256); qemu_put_buffer(f, s->b, 256); qemu_put_8s(f, &s->dac_index); qemu_put_8s(f, &s->dac_state); }
static void slavio_serial_save_chn(QEMUFile *f, ChannelState *s) { int tmp; tmp = 0; qemu_put_be32s(f, &tmp); /* unused, was IRQ. */ qemu_put_be32s(f, &s->reg); qemu_put_be32s(f, &s->rxint); qemu_put_be32s(f, &s->txint); qemu_put_be32s(f, &s->rxint_under_svc); qemu_put_be32s(f, &s->txint_under_svc); qemu_put_8s(f, &s->rx); qemu_put_8s(f, &s->tx); qemu_put_buffer(f, s->wregs, SERIAL_REGS); qemu_put_buffer(f, s->rregs, SERIAL_REGS); }
static int save_xbzrle_page(QEMUFile *f, uint8_t **current_data, ram_addr_t current_addr, RAMBlock *block, ram_addr_t offset, int cont, bool last_stage) { int encoded_len = 0, bytes_sent = -1; uint8_t *prev_cached_page; if (!cache_is_cached(XBZRLE.cache, current_addr)) { acct_info.xbzrle_cache_miss++; if (!last_stage) { if (cache_insert(XBZRLE.cache, current_addr, *current_data) == -1) { return -1; } else { /* update *current_data when the page has been inserted into cache */ *current_data = get_cached_data(XBZRLE.cache, current_addr); } } return -1; } prev_cached_page = get_cached_data(XBZRLE.cache, current_addr); /* save current buffer into memory */ memcpy(XBZRLE.current_buf, *current_data, TARGET_PAGE_SIZE); /* XBZRLE encoding (if there is no overflow) */ encoded_len = xbzrle_encode_buffer(prev_cached_page, XBZRLE.current_buf, TARGET_PAGE_SIZE, XBZRLE.encoded_buf, TARGET_PAGE_SIZE); if (encoded_len == 0) { DPRINTF("Skipping unmodified page\n"); return 0; } else if (encoded_len == -1) { DPRINTF("Overflow\n"); acct_info.xbzrle_overflows++; /* update data in the cache */ if (!last_stage) { memcpy(prev_cached_page, *current_data, TARGET_PAGE_SIZE); *current_data = prev_cached_page; } return -1; } /* we need to update the data in the cache, in order to get the same data */ if (!last_stage) { memcpy(prev_cached_page, XBZRLE.current_buf, TARGET_PAGE_SIZE); } /* Send XBZRLE based compressed page */ bytes_sent = save_block_hdr(f, block, offset, cont, RAM_SAVE_FLAG_XBZRLE); qemu_put_byte(f, ENCODING_FLAG_XBZRLE); qemu_put_be16(f, encoded_len); qemu_put_buffer(f, XBZRLE.encoded_buf, encoded_len); bytes_sent += encoded_len + 1 + 2; acct_info.xbzrle_pages++; acct_info.xbzrle_bytes += bytes_sent; return bytes_sent; }
static int put_buffer(QEMUFile *f, void *pv, size_t size, VMStateField *field, QJSON *vmdesc) { uint8_t *v = pv; qemu_put_buffer(f, v, size); return 0; }
static int ram_save_block(QEMUFile *f) { static ram_addr_t current_addr = 0; ram_addr_t saved_addr = current_addr; ram_addr_t addr = 0; int found = 0; while (addr < last_ram_offset) { if (cpu_physical_memory_get_dirty(current_addr, MIGRATION_DIRTY_FLAG)) { uint8_t *p; cpu_physical_memory_reset_dirty(current_addr, current_addr + TARGET_PAGE_SIZE, MIGRATION_DIRTY_FLAG); p = qemu_get_ram_ptr(current_addr); if (is_dup_page(p, *p)) { qemu_put_be64(f, current_addr | RAM_SAVE_FLAG_COMPRESS); qemu_put_byte(f, *p); } else { qemu_put_be64(f, current_addr | RAM_SAVE_FLAG_PAGE); qemu_put_buffer(f, p, TARGET_PAGE_SIZE); } found = 1; break; } addr += TARGET_PAGE_SIZE; current_addr = (saved_addr + addr) % last_ram_offset; } return found; }
/* Initialisation routine */ void *ds1225y_init(target_phys_addr_t mem_base, const char *filename) { ds1225y_t *s; int mem_indexRW, mem_indexRP; QEMUFile *file; s = qemu_mallocz(sizeof(ds1225y_t)); s->chip_size = 0x2000; /* Fixed for ds1225y chip: 8 KiB */ s->contents = qemu_mallocz(s->chip_size); s->protection = 7; /* Read current file */ file = qemu_fopen(filename, "rb"); if (file) { /* Read nvram contents */ qemu_get_buffer(file, s->contents, s->chip_size); qemu_fclose(file); } s->file = qemu_fopen(filename, "wb"); if (s->file) { /* Write back contents, as 'wb' mode cleaned the file */ qemu_put_buffer(s->file, s->contents, s->chip_size); qemu_fflush(s->file); } /* Read/write memory */ mem_indexRW = cpu_register_io_memory(nvram_read, nvram_write, s); cpu_register_physical_memory(mem_base, s->chip_size, mem_indexRW); /* Read/write protected memory */ mem_indexRP = cpu_register_io_memory(nvram_read, nvram_write_protected, s); cpu_register_physical_memory(mem_base + s->chip_size, s->chip_size, mem_indexRP); return s; }
void virtio_save(VirtIODevice *vdev, QEMUFile *f) { int i; if (vdev->binding->save_config) vdev->binding->save_config(vdev->binding_opaque, f); qemu_put_8s(f, &vdev->status); qemu_put_8s(f, &vdev->isr); qemu_put_be16s(f, &vdev->queue_sel); qemu_put_be32s(f, &vdev->guest_features); qemu_put_be32(f, vdev->config_len); qemu_put_buffer(f, vdev->config, vdev->config_len); for (i = 0; i < VIRTIO_PCI_QUEUE_MAX; i++) { if (vdev->vq[i].vring.num == 0) break; } qemu_put_be32(f, i); for (i = 0; i < VIRTIO_PCI_QUEUE_MAX; i++) { if (vdev->vq[i].vring.num == 0) break; qemu_put_be32(f, vdev->vq[i].vring.num); qemu_put_be64(f, vdev->vq[i].pa); qemu_put_be16s(f, &vdev->vq[i].last_avail_idx); if (vdev->binding->save_queue) vdev->binding->save_queue(vdev->binding_opaque, i, f); } }
static void wav_capture (void *opaque, void *buf, int size) { WAVState *wav = opaque; qemu_put_buffer (wav->f, buf, size); wav->bytes += size; }
static void rtc_save(QEMUFile *f, void *opaque) { RTCState *s = opaque; qemu_put_buffer(f, s->cmos_data, 128); qemu_put_8s(f, &s->cmos_index); }
static void pxa2xx_lcdc_save(QEMUFile *f, void *opaque) { PXA2xxLCDState *s = (PXA2xxLCDState *) opaque; int i; qemu_put_be32(f, s->irqlevel); qemu_put_be32(f, s->transp); for (i = 0; i < 6; i ++) qemu_put_be32s(f, &s->control[i]); for (i = 0; i < 2; i ++) qemu_put_be32s(f, &s->status[i]); for (i = 0; i < 2; i ++) qemu_put_be32s(f, &s->ovl1c[i]); for (i = 0; i < 2; i ++) qemu_put_be32s(f, &s->ovl2c[i]); qemu_put_be32s(f, &s->ccr); qemu_put_be32s(f, &s->cmdcr); qemu_put_be32s(f, &s->trgbr); qemu_put_be32s(f, &s->tcr); qemu_put_be32s(f, &s->liidr); qemu_put_8s(f, &s->bscntr); for (i = 0; i < 7; i ++) { qemu_put_betl(f, s->dma_ch[i].branch); qemu_put_byte(f, s->dma_ch[i].up); qemu_put_buffer(f, s->dma_ch[i].pbuffer, sizeof(s->dma_ch[i].pbuffer)); qemu_put_betl(f, s->dma_ch[i].descriptor); qemu_put_betl(f, s->dma_ch[i].source); qemu_put_be32s(f, &s->dma_ch[i].id); qemu_put_be32s(f, &s->dma_ch[i].command); } }
static void goldfish_audio_buff_put( struct goldfish_audio_buff* b, QEMUFile* f ) { qemu_put_be32(f, b->address ); qemu_put_be32(f, b->length ); qemu_put_be32(f, b->offset ); qemu_put_buffer(f, b->data, b->length ); }
static void ps2_common_save (QEMUFile *f, PS2State *s) { qemu_put_be32 (f, s->write_cmd); qemu_put_be32 (f, s->queue.rptr); qemu_put_be32 (f, s->queue.wptr); qemu_put_be32 (f, s->queue.count); qemu_put_buffer (f, s->queue.data, sizeof (s->queue.data)); }
static int shpc_save(QEMUFile *f, void *pv, size_t size, const VMStateField *field, QJSON *vmdesc) { PCIDevice *d = container_of(pv, PCIDevice, shpc); qemu_put_buffer(f, d->shpc->config, SHPC_SIZEOF(d)); return 0; }
void generic_usb_save(QEMUFile* f, void *opaque) { USBDevice *s = (USBDevice*)opaque; qemu_put_be32s(f, &s->speed); qemu_put_8s(f, &s->addr); qemu_put_be32s(f, &s->state); qemu_put_buffer(f, s->setup_buf, 8); qemu_put_buffer(f, s->data_buf, 1024); qemu_put_be32s(f, &s->remote_wakeup); qemu_put_be32s(f, &s->setup_state); qemu_put_be32s(f, &s->setup_len); qemu_put_be32s(f, &s->setup_index); }
static void esp_save(QEMUFile *f, void *opaque) { ESPState *s = opaque; qemu_put_buffer(f, s->rregs, ESP_REGS); qemu_put_buffer(f, s->wregs, ESP_REGS); qemu_put_sbe32s(f, &s->ti_size); qemu_put_be32s(f, &s->ti_rptr); qemu_put_be32s(f, &s->ti_wptr); qemu_put_buffer(f, s->ti_buf, TI_BUFSZ); qemu_put_be32s(f, &s->sense); qemu_put_be32s(f, &s->dma); qemu_put_buffer(f, s->cmdbuf, TI_BUFSZ); qemu_put_be32s(f, &s->cmdlen); qemu_put_be32s(f, &s->do_cmd); qemu_put_be32s(f, &s->dma_left); // There should be no transfers in progress, so dma_counter is not saved }
static void virtio_net_save(QEMUFile *f, void *opaque) { VirtIONet *n = opaque; virtio_save(&n->vdev, f); qemu_put_buffer(f, n->mac, 6); qemu_put_be32(f, n->tx_timer_active); }
static void cs_save(QEMUFile *f, void *opaque) { CSState *s = opaque; unsigned int i; for (i = 0; i < CS_REGS; i++) qemu_put_be32s(f, &s->regs[i]); qemu_put_buffer(f, s->dregs, CS_DREGS); }
static void scsi_generic_save_request(QEMUFile *f, SCSIRequest *req) { SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req); qemu_put_sbe32s(f, &r->buflen); if (r->buflen && r->req.cmd.mode == SCSI_XFER_TO_DEV) { assert(!r->req.sg); qemu_put_buffer(f, r->buf, r->req.cmd.xfer); } }
static void goldfish_tty_save(QEMUFile* f, void* opaque) { struct tty_state* s = opaque; qemu_put_be32( f, s->ptr ); qemu_put_be32( f, s->ptr_len ); qemu_put_byte( f, s->ready ); qemu_put_byte( f, s->data_count ); qemu_put_buffer( f, s->data, s->data_count ); }
static void goldfish_tty_save(QEMUFile* f, void* opaque) { struct tty_state* s = opaque; qemu_put_be32( f, s->ptr ); qemu_put_be32( f, s->ptr_len ); qemu_put_byte( f, (s_tty.int_mask & DEV_MASK(s->dev.id)) ? 1 : 0 ); qemu_put_byte( f, s->data_count ); qemu_put_buffer( f, s->data, s->data_count ); }
static void eeprom_save(QEMUFile *f, void *opaque) { /* Save EEPROM data. */ unsigned address; eeprom_t *eeprom = (eeprom_t *)opaque; qemu_put_buffer(f, (uint8_t *)eeprom, sizeof(*eeprom) - 2); qemu_put_be16(f, eeprom->data); for (address = 0; address < eeprom->size; address++) { qemu_put_be16(f, eeprom->contents[address]); } }
void qemu_put_string(QEMUFile *f, const char* str) { /* We will encode NULL and the empty string in the same way */ int slen; if (str == NULL) { str = ""; } slen = strlen(str); qemu_put_be32(f, slen); qemu_put_buffer(f, (const uint8_t*)str, slen); }
static void put_unused_buffer(QEMUFile *f, void *pv, size_t size) { static const uint8_t buf[1024]; int block_len; while (size > 0) { block_len = MIN(sizeof(buf), size); size -= block_len; qemu_put_buffer(f, buf, block_len); } }