diff options
Diffstat (limited to 'hw')
-rw-r--r-- | hw/i386/pc.c | 46 | ||||
-rw-r--r-- | hw/ide/core.c | 24 | ||||
-rw-r--r-- | hw/intc/arm_gicv3_redist.c | 4 | ||||
-rw-r--r-- | hw/net/Makefile.objs | 1 | ||||
-rw-r--r-- | hw/net/e1000e_core.c | 4 | ||||
-rw-r--r-- | hw/scsi/megasas.c | 6 |
6 files changed, 72 insertions, 13 deletions
diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 1b8baa8fee..719884ff88 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -812,11 +812,26 @@ static long get_file_size(FILE *f) return size; } +/* setup_data types */ +#define SETUP_NONE 0 +#define SETUP_E820_EXT 1 +#define SETUP_DTB 2 +#define SETUP_PCI 3 +#define SETUP_EFI 4 + +struct setup_data { + uint64_t next; + uint32_t type; + uint32_t len; + uint8_t data[0]; +} __attribute__((packed)); + static void load_linux(PCMachineState *pcms, FWCfgState *fw_cfg) { uint16_t protocol; int setup_size, kernel_size, initrd_size = 0, cmdline_size; + int dtb_size, setup_data_offset; uint32_t initrd_max; uint8_t header[8192], *setup, *kernel, *initrd_data; hwaddr real_addr, prot_addr, cmdline_addr, initrd_addr = 0; @@ -824,8 +839,10 @@ static void load_linux(PCMachineState *pcms, char *vmode; MachineState *machine = MACHINE(pcms); PCMachineClass *pcmc = PC_MACHINE_GET_CLASS(pcms); + struct setup_data *setup_data; const char *kernel_filename = machine->kernel_filename; const char *initrd_filename = machine->initrd_filename; + const char *dtb_filename = machine->dtb; const char *kernel_cmdline = machine->kernel_cmdline; /* Align to 16 bytes as a paranoia measure */ @@ -988,6 +1005,35 @@ static void load_linux(PCMachineState *pcms, exit(1); } fclose(f); + + /* append dtb to kernel */ + if (dtb_filename) { + if (protocol < 0x209) { + fprintf(stderr, "qemu: Linux kernel too old to load a dtb\n"); + exit(1); + } + + dtb_size = get_image_size(dtb_filename); + if (dtb_size <= 0) { + fprintf(stderr, "qemu: error reading dtb %s: %s\n", + dtb_filename, strerror(errno)); + exit(1); + } + + setup_data_offset = QEMU_ALIGN_UP(kernel_size, 16); + kernel_size = setup_data_offset + sizeof(struct setup_data) + dtb_size; + kernel = g_realloc(kernel, kernel_size); + + stq_p(header+0x250, prot_addr + setup_data_offset); + + setup_data = (struct setup_data *)(kernel + setup_data_offset); + setup_data->next = 0; + setup_data->type = cpu_to_le32(SETUP_DTB); + setup_data->len = cpu_to_le32(dtb_size); + + load_image_size(dtb_filename, setup_data->data, dtb_size); + } + memcpy(setup, header, MIN(sizeof(header), setup_size)); fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_ADDR, prot_addr); diff --git a/hw/ide/core.c b/hw/ide/core.c index f2d131b0d3..b1daf967d6 100644 --- a/hw/ide/core.c +++ b/hw/ide/core.c @@ -466,6 +466,20 @@ void ide_abort_command(IDEState *s) s->error = ABRT_ERR; } +static void ide_set_retry(IDEState *s) +{ + s->bus->retry_unit = s->unit; + s->bus->retry_sector_num = ide_get_sector(s); + s->bus->retry_nsector = s->nsector; +} + +static void ide_clear_retry(IDEState *s) +{ + s->bus->retry_unit = -1; + s->bus->retry_sector_num = 0; + s->bus->retry_nsector = 0; +} + /* prepare data transfer and tell what to do after */ void ide_transfer_start(IDEState *s, uint8_t *buf, int size, EndTransferFunc *end_transfer_func) @@ -473,6 +487,7 @@ void ide_transfer_start(IDEState *s, uint8_t *buf, int size, s->end_transfer_func = end_transfer_func; s->data_ptr = buf; s->data_end = buf + size; + ide_set_retry(s); if (!(s->status & ERR_STAT)) { s->status |= DRQ_STAT; } @@ -756,9 +771,7 @@ void dma_buf_commit(IDEState *s, uint32_t tx_bytes) void ide_set_inactive(IDEState *s, bool more) { s->bus->dma->aiocb = NULL; - s->bus->retry_unit = -1; - s->bus->retry_sector_num = 0; - s->bus->retry_nsector = 0; + ide_clear_retry(s); if (s->bus->dma->ops->set_inactive) { s->bus->dma->ops->set_inactive(s->bus->dma, more); } @@ -914,9 +927,7 @@ static void ide_sector_start_dma(IDEState *s, enum ide_dma_cmd dma_cmd) void ide_start_dma(IDEState *s, BlockCompletionFunc *cb) { s->io_buffer_index = 0; - s->bus->retry_unit = s->unit; - s->bus->retry_sector_num = ide_get_sector(s); - s->bus->retry_nsector = s->nsector; + ide_set_retry(s); if (s->bus->dma->ops->start_dma) { s->bus->dma->ops->start_dma(s->bus->dma, s, cb); } @@ -1046,6 +1057,7 @@ static void ide_flush_cache(IDEState *s) } s->status |= BUSY_STAT; + ide_set_retry(s); block_acct_start(blk_get_stats(s->blk), &s->acct, 0, BLOCK_ACCT_FLUSH); s->pio_aiocb = blk_aio_flush(s->blk, ide_flush_cb, s); } diff --git a/hw/intc/arm_gicv3_redist.c b/hw/intc/arm_gicv3_redist.c index 2f60096e6e..77e5cfa327 100644 --- a/hw/intc/arm_gicv3_redist.c +++ b/hw/intc/arm_gicv3_redist.c @@ -420,6 +420,8 @@ MemTxResult gicv3_redist_read(void *opaque, hwaddr offset, uint64_t *data, MemTxResult r; int cpuidx; + assert((offset & (size - 1)) == 0); + /* This region covers all the redistributor pages; there are * (for GICv3) two 64K pages per CPU. At the moment they are * all contiguous (ie in this one region), though we might later @@ -468,6 +470,8 @@ MemTxResult gicv3_redist_write(void *opaque, hwaddr offset, uint64_t data, MemTxResult r; int cpuidx; + assert((offset & (size - 1)) == 0); + /* This region covers all the redistributor pages; there are * (for GICv3) two 64K pages per CPU. At the moment they are * all contiguous (ie in this one region), though we might later diff --git a/hw/net/Makefile.objs b/hw/net/Makefile.objs index fe61e9fb2b..610ed3e7ae 100644 --- a/hw/net/Makefile.objs +++ b/hw/net/Makefile.objs @@ -7,6 +7,7 @@ common-obj-$(CONFIG_EEPRO100_PCI) += eepro100.o common-obj-$(CONFIG_PCNET_PCI) += pcnet-pci.o common-obj-$(CONFIG_PCNET_COMMON) += pcnet.o common-obj-$(CONFIG_E1000_PCI) += e1000.o e1000x_common.o +common-obj-$(CONFIG_E1000E_PCI) += net_tx_pkt.o net_rx_pkt.o common-obj-$(CONFIG_E1000E_PCI) += e1000e.o e1000e_core.o e1000x_common.o common-obj-$(CONFIG_RTL8139_PCI) += rtl8139.o common-obj-$(CONFIG_VMXNET3_PCI) += net_tx_pkt.o net_rx_pkt.o diff --git a/hw/net/e1000e_core.c b/hw/net/e1000e_core.c index 6050d8b7f8..badb1feb7d 100644 --- a/hw/net/e1000e_core.c +++ b/hw/net/e1000e_core.c @@ -281,7 +281,7 @@ e1000e_intrmgr_delay_rx_causes(E1000ECore *core, uint32_t *causes) /* Check if delayed RX interrupts disabled by client or if there are causes that cannot be delayed */ - if ((rdtr == 0) || (causes != 0)) { + if ((rdtr == 0) || (*causes != 0)) { return false; } @@ -322,7 +322,7 @@ e1000e_intrmgr_delay_tx_causes(E1000ECore *core, uint32_t *causes) *causes &= ~delayable_causes; /* If there are causes that cannot be delayed */ - if (causes != 0) { + if (*causes != 0) { return false; } diff --git a/hw/scsi/megasas.c b/hw/scsi/megasas.c index 52a41239cf..e968302fdc 100644 --- a/hw/scsi/megasas.c +++ b/hw/scsi/megasas.c @@ -1981,11 +1981,7 @@ static void megasas_handle_frame(MegasasState *s, uint64_t frame_addr, break; } if (frame_status != MFI_STAT_INVALID_STATUS) { - if (cmd->frame) { - cmd->frame->header.cmd_status = frame_status; - } else { - megasas_frame_set_cmd_status(s, frame_addr, frame_status); - } + cmd->frame->header.cmd_status = frame_status; megasas_unmap_frame(s, cmd); megasas_complete_frame(s, cmd->context); } |