#else
#include "qemu-common.h"
#include "gdbstub.h"
+#include "hw/arm-misc.h"
#endif
#define SYS_OPEN 0x01
return syscall_err;
#endif
case SYS_GET_CMDLINE:
-#ifdef CONFIG_USER_ONLY
- /* Build a commandline from the original argv. */
{
- char *arm_cmdline_buffer;
- const char *host_cmdline_buffer;
+ /* Build a command-line from the original argv.
+ *
+ * The inputs are:
+ * * ARG(0), pointer to a buffer of at least the size
+ * specified in ARG(1).
+ * * ARG(1), size of the buffer pointed to by ARG(0) in
+ * bytes.
+ *
+ * The outputs are:
+ * * ARG(0), pointer to null-terminated string of the
+ * command line.
+ * * ARG(1), length of the string pointed to by ARG(0).
+ */
- unsigned int i;
- unsigned int arm_cmdline_len = ARG(1);
- unsigned int host_cmdline_len =
- ts->info->arg_end-ts->info->arg_start;
+ char *output_buffer;
+ size_t input_size = ARG(1);
+ size_t output_size;
+ int status = 0;
- if (!arm_cmdline_len || host_cmdline_len > arm_cmdline_len) {
- return -1; /* not enough space to store command line */
- }
+ /* Compute the size of the output string. */
+#if !defined(CONFIG_USER_ONLY)
+ output_size = strlen(ts->boot_info->kernel_filename)
+ + 1 /* Separating space. */
+ + strlen(ts->boot_info->kernel_cmdline)
+ + 1; /* Terminating null byte. */
+#else
+ unsigned int i;
- if (!host_cmdline_len) {
+ output_size = ts->info->arg_end - ts->info->arg_start;
+ if (!output_size) {
/* We special-case the "empty command line" case (argc==0).
Just provide the terminating 0. */
- arm_cmdline_buffer = lock_user(VERIFY_WRITE, ARG(0), 1, 0);
- arm_cmdline_buffer[0] = 0;
- unlock_user(arm_cmdline_buffer, ARG(0), 1);
+ output_size = 1;
+ }
+#endif
- /* Adjust the commandline length argument. */
- SET_ARG(1, 0);
- return 0;
+ if (output_size > input_size) {
+ /* Not enough space to store command-line arguments. */
+ return -1;
}
- /* lock the buffers on the ARM side */
- arm_cmdline_buffer =
- lock_user(VERIFY_WRITE, ARG(0), host_cmdline_len, 0);
- host_cmdline_buffer =
- lock_user(VERIFY_READ, ts->info->arg_start,
- host_cmdline_len, 1);
+ /* Adjust the command-line length. */
+ SET_ARG(1, output_size - 1);
- if (arm_cmdline_buffer && host_cmdline_buffer)
- {
- /* the last argument is zero-terminated;
- no need for additional termination */
- memcpy(arm_cmdline_buffer, host_cmdline_buffer,
- host_cmdline_len);
+ /* Lock the buffer on the ARM side. */
+ output_buffer = lock_user(VERIFY_WRITE, ARG(0), output_size, 0);
+ if (!output_buffer) {
+ return -1;
+ }
- /* separate arguments by white spaces */
- for (i = 0; i < host_cmdline_len-1; i++) {
- if (arm_cmdline_buffer[i] == 0) {
- arm_cmdline_buffer[i] = ' ';
- }
- }
+ /* Copy the command-line arguments. */
+#if !defined(CONFIG_USER_ONLY)
+ pstrcpy(output_buffer, output_size, ts->boot_info->kernel_filename);
+ pstrcat(output_buffer, output_size, " ");
+ pstrcat(output_buffer, output_size, ts->boot_info->kernel_cmdline);
+#else
+ if (output_size == 1) {
+ /* Empty command-line. */
+ output_buffer[0] = '\0';
+ goto out;
+ }
- /* Adjust the commandline length argument. */
- SET_ARG(1, host_cmdline_len-1);
+ if (copy_from_user(output_buffer, ts->info->arg_start,
+ output_size)) {
+ status = -1;
+ goto out;
}
- /* Unlock the buffers on the ARM side. */
- unlock_user(arm_cmdline_buffer, ARG(0), host_cmdline_len);
- unlock_user((void*)host_cmdline_buffer, ts->info->arg_start, 0);
+ /* Separate arguments by white spaces. */
+ for (i = 0; i < output_size - 1; i++) {
+ if (output_buffer[i] == 0) {
+ output_buffer[i] = ' ';
+ }
+ }
+ out:
+#endif
+ /* Unlock the buffer on the ARM side. */
+ unlock_user(output_buffer, ARG(0), output_size);
- /* Return success if we could return a commandline. */
- return (arm_cmdline_buffer && host_cmdline_buffer) ? 0 : -1;
+ return status;
}
-#else
- return -1;
-#endif
case SYS_HEAPINFO:
{
uint32_t *ptr;
#include <sys/dkio.h>
#endif
#ifdef __linux__
+#include <sys/types.h>
+#include <sys/stat.h>
#include <sys/ioctl.h>
#include <sys/param.h>
#include <linux/cdrom.h>
int fd, ret;
int prio = 0;
struct floppy_struct fdparam;
+ struct stat st;
if (strstart(filename, "/dev/fd", NULL))
prio = 50;
if (fd < 0) {
goto out;
}
+ ret = fstat(fd, &st);
+ if (ret == -1 || !S_ISBLK(st.st_mode)) {
+ goto outc;
+ }
/* Attempt to detect via a floppy specific ioctl */
ret = ioctl(fd, FDGETPRM, &fdparam);
if (ret >= 0)
prio = 100;
+outc:
close(fd);
out:
return prio;
{
int fd, ret;
int prio = 0;
+ struct stat st;
fd = open(filename, O_RDONLY | O_NONBLOCK);
if (fd < 0) {
goto out;
}
+ ret = fstat(fd, &st);
+ if (ret == -1 || !S_ISBLK(st.st_mode)) {
+ goto outc;
+ }
/* Attempt to detect via a CDROM specific ioctl */
ret = ioctl(fd, CDROM_DRIVE_STATUS, CDSL_CURRENT);
if (ret >= 0)
prio = 100;
+outc:
close(fd);
out:
return prio;
int ret;
translation = BIOS_ATA_TRANSLATION_AUTO;
-
- if (default_to_scsi) {
- type = IF_SCSI;
- pstrcpy(devname, sizeof(devname), "scsi");
- } else {
- type = IF_IDE;
- pstrcpy(devname, sizeof(devname), "ide");
- }
media = MEDIA_DISK;
/* extract parameters */
error_report("unsupported bus type '%s'", buf);
return NULL;
}
+ } else {
+ type = default_to_scsi ? IF_SCSI : IF_IDE;
+ pstrcpy(devname, sizeof(devname), if_name[type]);
}
+
max_devs = if_max_devs[type];
if (cyls || heads || secs) {
media = MEDIA_DISK;
} else if (!strcmp(buf, "cdrom")) {
if (cyls || secs || heads) {
- error_report("'%s' invalid physical CHS format", buf);
+ error_report("CHS can't be set with media=%s", buf);
return NULL;
}
media = MEDIA_CDROM;
uint32_t ldub_phys(target_phys_addr_t addr);
uint32_t lduw_phys(target_phys_addr_t addr);
+uint32_t lduw_le_phys(target_phys_addr_t addr);
+uint32_t lduw_be_phys(target_phys_addr_t addr);
uint32_t ldl_phys(target_phys_addr_t addr);
+uint32_t ldl_le_phys(target_phys_addr_t addr);
+uint32_t ldl_be_phys(target_phys_addr_t addr);
uint64_t ldq_phys(target_phys_addr_t addr);
+uint64_t ldq_le_phys(target_phys_addr_t addr);
+uint64_t ldq_be_phys(target_phys_addr_t addr);
void stl_phys_notdirty(target_phys_addr_t addr, uint32_t val);
void stq_phys_notdirty(target_phys_addr_t addr, uint64_t val);
void stb_phys(target_phys_addr_t addr, uint32_t val);
void stw_phys(target_phys_addr_t addr, uint32_t val);
+void stw_le_phys(target_phys_addr_t addr, uint32_t val);
+void stw_be_phys(target_phys_addr_t addr, uint32_t val);
void stl_phys(target_phys_addr_t addr, uint32_t val);
+void stl_le_phys(target_phys_addr_t addr, uint32_t val);
+void stl_be_phys(target_phys_addr_t addr, uint32_t val);
void stq_phys(target_phys_addr_t addr, uint64_t val);
+void stq_le_phys(target_phys_addr_t addr, uint64_t val);
+void stq_be_phys(target_phys_addr_t addr, uint64_t val);
void cpu_physical_memory_write_rom(target_phys_addr_t addr,
const uint8_t *buf, int len);
/* reset soft MMU for next block (it can currently
only be set by a memory fault) */
} /* for(;;) */
+ } else {
+ /* Reload env after longjmp - the compiler may have smashed all
+ * local variables as longjmp is marked 'noreturn'. */
+ env = cpu_single_env;
}
} /* for(;;) */
sigaddset(&set, SIGUSR2);
pthread_sigmask(SIG_UNBLOCK, &set, NULL);
+ /*
+ * SIG_IPI must be blocked in the main thread and must not be caught
+ * by sigwait() in the signal thread. Otherwise, the cpu thread will
+ * not catch it reliably.
+ */
+ sigemptyset(&set);
+ sigaddset(&set, SIG_IPI);
+ pthread_sigmask(SIG_BLOCK, &set, NULL);
+
sigemptyset(&set);
sigaddset(&set, SIGIO);
sigaddset(&set, SIGALRM);
- sigaddset(&set, SIG_IPI);
sigaddset(&set, SIGBUS);
- pthread_sigmask(SIG_BLOCK, &set, NULL);
#else
sigemptyset(&set);
sigaddset(&set, SIGBUS);
sigaddset(&set, SIGALRM);
}
#endif
+ pthread_sigmask(SIG_BLOCK, &set, NULL);
sigfd = qemu_signalfd(&set);
if (sigfd == -1) {
typedef struct TranslationBlock TranslationBlock;
/* XXX: make safe guess about sizes */
-#if (HOST_LONG_BITS == 32) && (TARGET_LONG_BITS == 64)
-#define MAX_OP_PER_INSTR 128
-#else
-#define MAX_OP_PER_INSTR 96
-#endif
+#define MAX_OP_PER_INSTR 208
#if HOST_LONG_BITS == 32
#define MAX_OPC_PARAM_PER_ARG 2
#endif
#endif /* !USE_STATIC_CODE_GEN_BUFFER */
map_exec(code_gen_prologue, sizeof(code_gen_prologue));
- code_gen_buffer_max_size = code_gen_buffer_size -
- (TCG_MAX_OP_SIZE * OPC_MAX_SIZE);
+ code_gen_buffer_max_size = code_gen_buffer_size -
+ (TCG_MAX_OP_SIZE * OPC_BUF_SIZE);
code_gen_max_blocks = code_gen_buffer_size / CODE_GEN_AVG_BLOCK_SIZE;
tbs = qemu_malloc(code_gen_max_blocks * sizeof(TranslationBlock));
}
}
/* warning: addr must be aligned */
-uint32_t ldl_phys(target_phys_addr_t addr)
+static inline uint32_t ldl_phys_internal(target_phys_addr_t addr,
+ enum device_endian endian)
{
int io_index;
uint8_t *ptr;
if (p)
addr = (addr & ~TARGET_PAGE_MASK) + p->region_offset;
val = io_mem_read[io_index][2](io_mem_opaque[io_index], addr);
+#if defined(TARGET_WORDS_BIGENDIAN)
+ if (endian == DEVICE_LITTLE_ENDIAN) {
+ val = bswap32(val);
+ }
+#else
+ if (endian == DEVICE_BIG_ENDIAN) {
+ val = bswap32(val);
+ }
+#endif
} else {
/* RAM case */
ptr = qemu_get_ram_ptr(pd & TARGET_PAGE_MASK) +
(addr & ~TARGET_PAGE_MASK);
- val = ldl_p(ptr);
+ switch (endian) {
+ case DEVICE_LITTLE_ENDIAN:
+ val = ldl_le_p(ptr);
+ break;
+ case DEVICE_BIG_ENDIAN:
+ val = ldl_be_p(ptr);
+ break;
+ default:
+ val = ldl_p(ptr);
+ break;
+ }
}
return val;
}
+uint32_t ldl_phys(target_phys_addr_t addr)
+{
+ return ldl_phys_internal(addr, DEVICE_NATIVE_ENDIAN);
+}
+
+uint32_t ldl_le_phys(target_phys_addr_t addr)
+{
+ return ldl_phys_internal(addr, DEVICE_LITTLE_ENDIAN);
+}
+
+uint32_t ldl_be_phys(target_phys_addr_t addr)
+{
+ return ldl_phys_internal(addr, DEVICE_BIG_ENDIAN);
+}
+
/* warning: addr must be aligned */
-uint64_t ldq_phys(target_phys_addr_t addr)
+static inline uint64_t ldq_phys_internal(target_phys_addr_t addr,
+ enum device_endian endian)
{
int io_index;
uint8_t *ptr;
io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
if (p)
addr = (addr & ~TARGET_PAGE_MASK) + p->region_offset;
+
+ /* XXX This is broken when device endian != cpu endian.
+ Fix and add "endian" variable check */
#ifdef TARGET_WORDS_BIGENDIAN
val = (uint64_t)io_mem_read[io_index][2](io_mem_opaque[io_index], addr) << 32;
val |= io_mem_read[io_index][2](io_mem_opaque[io_index], addr + 4);
/* RAM case */
ptr = qemu_get_ram_ptr(pd & TARGET_PAGE_MASK) +
(addr & ~TARGET_PAGE_MASK);
- val = ldq_p(ptr);
+ switch (endian) {
+ case DEVICE_LITTLE_ENDIAN:
+ val = ldq_le_p(ptr);
+ break;
+ case DEVICE_BIG_ENDIAN:
+ val = ldq_be_p(ptr);
+ break;
+ default:
+ val = ldq_p(ptr);
+ break;
+ }
}
return val;
}
+uint64_t ldq_phys(target_phys_addr_t addr)
+{
+ return ldq_phys_internal(addr, DEVICE_NATIVE_ENDIAN);
+}
+
+uint64_t ldq_le_phys(target_phys_addr_t addr)
+{
+ return ldq_phys_internal(addr, DEVICE_LITTLE_ENDIAN);
+}
+
+uint64_t ldq_be_phys(target_phys_addr_t addr)
+{
+ return ldq_phys_internal(addr, DEVICE_BIG_ENDIAN);
+}
+
/* XXX: optimize */
uint32_t ldub_phys(target_phys_addr_t addr)
{
}
/* warning: addr must be aligned */
-uint32_t lduw_phys(target_phys_addr_t addr)
+static inline uint32_t lduw_phys_internal(target_phys_addr_t addr,
+ enum device_endian endian)
{
int io_index;
uint8_t *ptr;
if (p)
addr = (addr & ~TARGET_PAGE_MASK) + p->region_offset;
val = io_mem_read[io_index][1](io_mem_opaque[io_index], addr);
+#if defined(TARGET_WORDS_BIGENDIAN)
+ if (endian == DEVICE_LITTLE_ENDIAN) {
+ val = bswap16(val);
+ }
+#else
+ if (endian == DEVICE_BIG_ENDIAN) {
+ val = bswap16(val);
+ }
+#endif
} else {
/* RAM case */
ptr = qemu_get_ram_ptr(pd & TARGET_PAGE_MASK) +
(addr & ~TARGET_PAGE_MASK);
- val = lduw_p(ptr);
+ switch (endian) {
+ case DEVICE_LITTLE_ENDIAN:
+ val = lduw_le_p(ptr);
+ break;
+ case DEVICE_BIG_ENDIAN:
+ val = lduw_be_p(ptr);
+ break;
+ default:
+ val = lduw_p(ptr);
+ break;
+ }
}
return val;
}
+uint32_t lduw_phys(target_phys_addr_t addr)
+{
+ return lduw_phys_internal(addr, DEVICE_NATIVE_ENDIAN);
+}
+
+uint32_t lduw_le_phys(target_phys_addr_t addr)
+{
+ return lduw_phys_internal(addr, DEVICE_LITTLE_ENDIAN);
+}
+
+uint32_t lduw_be_phys(target_phys_addr_t addr)
+{
+ return lduw_phys_internal(addr, DEVICE_BIG_ENDIAN);
+}
+
/* warning: addr must be aligned. The ram page is not masked as dirty
and the code inside is not invalidated. It is useful if the dirty
bits are used to track modified PTEs */
}
/* warning: addr must be aligned */
-void stl_phys(target_phys_addr_t addr, uint32_t val)
+static inline void stl_phys_internal(target_phys_addr_t addr, uint32_t val,
+ enum device_endian endian)
{
int io_index;
uint8_t *ptr;
io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
if (p)
addr = (addr & ~TARGET_PAGE_MASK) + p->region_offset;
+#if defined(TARGET_WORDS_BIGENDIAN)
+ if (endian == DEVICE_LITTLE_ENDIAN) {
+ val = bswap32(val);
+ }
+#else
+ if (endian == DEVICE_BIG_ENDIAN) {
+ val = bswap32(val);
+ }
+#endif
io_mem_write[io_index][2](io_mem_opaque[io_index], addr, val);
} else {
unsigned long addr1;
addr1 = (pd & TARGET_PAGE_MASK) + (addr & ~TARGET_PAGE_MASK);
/* RAM case */
ptr = qemu_get_ram_ptr(addr1);
- stl_p(ptr, val);
+ switch (endian) {
+ case DEVICE_LITTLE_ENDIAN:
+ stl_le_p(ptr, val);
+ break;
+ case DEVICE_BIG_ENDIAN:
+ stl_be_p(ptr, val);
+ break;
+ default:
+ stl_p(ptr, val);
+ break;
+ }
if (!cpu_physical_memory_is_dirty(addr1)) {
/* invalidate code */
tb_invalidate_phys_page_range(addr1, addr1 + 4, 0);
}
}
+void stl_phys(target_phys_addr_t addr, uint32_t val)
+{
+ stl_phys_internal(addr, val, DEVICE_NATIVE_ENDIAN);
+}
+
+void stl_le_phys(target_phys_addr_t addr, uint32_t val)
+{
+ stl_phys_internal(addr, val, DEVICE_LITTLE_ENDIAN);
+}
+
+void stl_be_phys(target_phys_addr_t addr, uint32_t val)
+{
+ stl_phys_internal(addr, val, DEVICE_BIG_ENDIAN);
+}
+
/* XXX: optimize */
void stb_phys(target_phys_addr_t addr, uint32_t val)
{
}
/* warning: addr must be aligned */
-void stw_phys(target_phys_addr_t addr, uint32_t val)
+static inline void stw_phys_internal(target_phys_addr_t addr, uint32_t val,
+ enum device_endian endian)
{
int io_index;
uint8_t *ptr;
io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
if (p)
addr = (addr & ~TARGET_PAGE_MASK) + p->region_offset;
+#if defined(TARGET_WORDS_BIGENDIAN)
+ if (endian == DEVICE_LITTLE_ENDIAN) {
+ val = bswap16(val);
+ }
+#else
+ if (endian == DEVICE_BIG_ENDIAN) {
+ val = bswap16(val);
+ }
+#endif
io_mem_write[io_index][1](io_mem_opaque[io_index], addr, val);
} else {
unsigned long addr1;
addr1 = (pd & TARGET_PAGE_MASK) + (addr & ~TARGET_PAGE_MASK);
/* RAM case */
ptr = qemu_get_ram_ptr(addr1);
- stw_p(ptr, val);
+ switch (endian) {
+ case DEVICE_LITTLE_ENDIAN:
+ stw_le_p(ptr, val);
+ break;
+ case DEVICE_BIG_ENDIAN:
+ stw_be_p(ptr, val);
+ break;
+ default:
+ stw_p(ptr, val);
+ break;
+ }
if (!cpu_physical_memory_is_dirty(addr1)) {
/* invalidate code */
tb_invalidate_phys_page_range(addr1, addr1 + 2, 0);
}
}
+void stw_phys(target_phys_addr_t addr, uint32_t val)
+{
+ stw_phys_internal(addr, val, DEVICE_NATIVE_ENDIAN);
+}
+
+void stw_le_phys(target_phys_addr_t addr, uint32_t val)
+{
+ stw_phys_internal(addr, val, DEVICE_LITTLE_ENDIAN);
+}
+
+void stw_be_phys(target_phys_addr_t addr, uint32_t val)
+{
+ stw_phys_internal(addr, val, DEVICE_BIG_ENDIAN);
+}
+
/* XXX: optimize */
void stq_phys(target_phys_addr_t addr, uint64_t val)
{
cpu_physical_memory_write(addr, &val, 8);
}
+void stq_le_phys(target_phys_addr_t addr, uint64_t val)
+{
+ val = cpu_to_le64(val);
+ cpu_physical_memory_write(addr, &val, 8);
+}
+
+void stq_be_phys(target_phys_addr_t addr, uint64_t val)
+{
+ val = cpu_to_be64(val);
+ cpu_physical_memory_write(addr, &val, 8);
+}
+
/* virtual memory access for debug (includes writing to ROM) */
int cpu_memory_rw_debug(CPUState *env, target_ulong addr,
uint8_t *buf, int len, int is_write)
s->ti_rptr = 0;
s->ti_wptr = 0;
- if (s->current_dev) {
+ if (s->current_req) {
/* Started a new command before the old one finished. Cancel it. */
scsi_req_cancel(s->current_req);
s->async_len = 0;
qemu_irq_lower(s->irqs[route]);
}
} else if (timer_fsb_route(timer)) {
- stl_phys(timer->fsb >> 32, timer->fsb & 0xffffffff);
+ stl_le_phys(timer->fsb >> 32, timer->fsb & 0xffffffff);
} else if (timer->config & HPET_TN_TYPE_LEVEL) {
s->isr |= mask;
qemu_irq_raise(s->irqs[route]);
};
static int ide_handle_rw_error(IDEState *s, int error, int op);
+static void ide_dummy_transfer_stop(IDEState *s);
static void padstr(char *str, const char *src, int len)
{
bus->cmd = val;
}
+/*
+ * Returns true if the running PIO transfer is a PIO out (i.e. data is
+ * transferred from the device to the guest), false if it's a PIO in
+ */
+static bool ide_is_pio_out(IDEState *s)
+{
+ if (s->end_transfer_func == ide_sector_write ||
+ s->end_transfer_func == ide_atapi_cmd) {
+ return false;
+ } else if (s->end_transfer_func == ide_sector_read ||
+ s->end_transfer_func == ide_transfer_stop ||
+ s->end_transfer_func == ide_atapi_cmd_reply_end ||
+ s->end_transfer_func == ide_dummy_transfer_stop) {
+ return true;
+ }
+
+ abort();
+}
+
void ide_data_writew(void *opaque, uint32_t addr, uint32_t val)
{
IDEBus *bus = opaque;
IDEState *s = idebus_active_if(bus);
uint8_t *p;
- /* PIO data access allowed only when DRQ bit is set */
- if (!(s->status & DRQ_STAT))
+ /* PIO data access allowed only when DRQ bit is set. The result of a write
+ * during PIO out is indeterminate, just ignore it. */
+ if (!(s->status & DRQ_STAT) || ide_is_pio_out(s)) {
return;
+ }
p = s->data_ptr;
*(uint16_t *)p = le16_to_cpu(val);
uint8_t *p;
int ret;
- /* PIO data access allowed only when DRQ bit is set */
- if (!(s->status & DRQ_STAT))
+ /* PIO data access allowed only when DRQ bit is set. The result of a read
+ * during PIO in is indeterminate, return 0 and don't move forward. */
+ if (!(s->status & DRQ_STAT) || !ide_is_pio_out(s)) {
return 0;
+ }
p = s->data_ptr;
ret = cpu_to_le16(*(uint16_t *)p);
IDEState *s = idebus_active_if(bus);
uint8_t *p;
- /* PIO data access allowed only when DRQ bit is set */
- if (!(s->status & DRQ_STAT))
+ /* PIO data access allowed only when DRQ bit is set. The result of a write
+ * during PIO out is indeterminate, just ignore it. */
+ if (!(s->status & DRQ_STAT) || ide_is_pio_out(s)) {
return;
+ }
p = s->data_ptr;
*(uint32_t *)p = le32_to_cpu(val);
uint8_t *p;
int ret;
- /* PIO data access allowed only when DRQ bit is set */
- if (!(s->status & DRQ_STAT))
+ /* PIO data access allowed only when DRQ bit is set. The result of a read
+ * during PIO in is indeterminate, return 0 and don't move forward. */
+ if (!(s->status & DRQ_STAT) || !ide_is_pio_out(s)) {
return 0;
+ }
p = s->data_ptr;
ret = cpu_to_le32(*(uint32_t *)p);
s->unit = unit;
s->drive_serial = drive_serial++;
/* we need at least 2k alignment for accessing CDROMs using O_DIRECT */
- s->io_buffer = qemu_memalign(2048, IDE_DMA_BUF_SECTORS*512 + 4);
s->io_buffer_total_len = IDE_DMA_BUF_SECTORS*512 + 4;
+ s->io_buffer = qemu_memalign(2048, s->io_buffer_total_len);
+ memset(s->io_buffer, 0, s->io_buffer_total_len);
+
s->smart_selftest_data = qemu_blockalign(s->bs, 512);
+ memset(s->smart_selftest_data, 0, 512);
+
s->sector_write_timer = qemu_new_timer_ns(vm_clock,
ide_sector_write_timer_cb, s);
}
return addr;
}
-static void stl_phys_le(target_phys_addr_t addr, uint32_t value)
-{
- uint32_t value_le = cpu_to_le32(value);
- cpu_physical_memory_write(addr, (uint8_t*)(&value_le), sizeof(value_le));
-}
-
-static uint32_t ldl_phys_le(target_phys_addr_t addr)
-{
- uint32_t value_le;
- cpu_physical_memory_read(addr, (uint8_t*)(&value_le), sizeof(value_le));
- return le32_to_cpu(value_le);
-}
-
static void intel_hda_update_int_sts(IntelHDAState *d)
{
uint32_t sts = 0;
rp = (d->corb_rp + 1) & 0xff;
addr = intel_hda_addr(d->corb_lbase, d->corb_ubase);
- verb = ldl_phys_le(addr + 4*rp);
+ verb = ldl_le_phys(addr + 4*rp);
d->corb_rp = rp;
dprint(d, 2, "%s: [rp 0x%x] verb 0x%08x\n", __FUNCTION__, rp, verb);
ex = (solicited ? 0 : (1 << 4)) | dev->cad;
wp = (d->rirb_wp + 1) & 0xff;
addr = intel_hda_addr(d->rirb_lbase, d->rirb_ubase);
- stl_phys_le(addr + 8*wp, response);
- stl_phys_le(addr + 8*wp + 4, ex);
+ stl_le_phys(addr + 8*wp, response);
+ stl_le_phys(addr + 8*wp + 4, ex);
d->rirb_wp = wp;
dprint(d, 2, "%s: [wp 0x%x] response 0x%x, extra 0x%x\n",
}
if (d->dp_lbase & 0x01) {
addr = intel_hda_addr(d->dp_lbase & ~0x01, d->dp_ubase);
- stl_phys_le(addr + 8*s, st->lpib);
+ stl_le_phys(addr + 8*s, st->lpib);
}
dprint(d, 3, "dma: --\n");
"notify vector 0x%x"
" address: 0x%"PRIx64" data: 0x%"PRIx32"\n",
vector, address, data);
- stl_phys(address, data);
+ stl_le_phys(address, data);
}
/* call this function after updating configs by pci_default_write_config(). */
address = pci_get_quad(table_entry + PCI_MSIX_ENTRY_LOWER_ADDR);
data = pci_get_long(table_entry + PCI_MSIX_ENTRY_DATA);
- stl_phys(address, data);
+ stl_le_phys(address, data);
}
void msix_reset(PCIDevice *dev)
#define PCI_DEVICE_ID_INTEL_82801I_EHCI1 0x293a
#define PCI_DEVICE_ID_INTEL_82801I_EHCI2 0x293c
-#define PCI_VENDOR_ID_XENSOURCE 0x5853
+#define PCI_VENDOR_ID_XEN 0x5853
+#define PCI_DEVICE_ID_XEN_PLATFORM 0x0001
.no_hotplug = 1,
.init = piix3_initfn,
.config_write = piix3_write_config_xen,
+ .vendor_id = PCI_VENDOR_ID_INTEL,
+ .device_id = PCI_DEVICE_ID_INTEL_82371SB_0, // 82371SB PIIX3 PCI-to-ISA bridge (Step A1)
+ .class_id = PCI_CLASS_BRIDGE_ISA,
},{
/* end of list */
}
if (size == 0) {
/* Transfer complete. */
if (ch->lli) {
- ch->src = ldl_phys(ch->lli);
- ch->dest = ldl_phys(ch->lli + 4);
- ch->ctrl = ldl_phys(ch->lli + 12);
- ch->lli = ldl_phys(ch->lli + 8);
+ ch->src = ldl_le_phys(ch->lli);
+ ch->dest = ldl_le_phys(ch->lli + 4);
+ ch->ctrl = ldl_le_phys(ch->lli + 12);
+ ch->lli = ldl_le_phys(ch->lli + 8);
} else {
ch->conf &= ~PL080_CCONF_E;
}
bdloc = 0x01000000UL - sizeof(struct ppc4xx_bd_info_t);
else
bdloc = bd->bi_memsize - sizeof(struct ppc4xx_bd_info_t);
- stl_phys(bdloc + 0x00, bd->bi_memstart);
- stl_phys(bdloc + 0x04, bd->bi_memsize);
- stl_phys(bdloc + 0x08, bd->bi_flashstart);
- stl_phys(bdloc + 0x0C, bd->bi_flashsize);
- stl_phys(bdloc + 0x10, bd->bi_flashoffset);
- stl_phys(bdloc + 0x14, bd->bi_sramstart);
- stl_phys(bdloc + 0x18, bd->bi_sramsize);
- stl_phys(bdloc + 0x1C, bd->bi_bootflags);
- stl_phys(bdloc + 0x20, bd->bi_ipaddr);
- for (i = 0; i < 6; i++)
+ stl_be_phys(bdloc + 0x00, bd->bi_memstart);
+ stl_be_phys(bdloc + 0x04, bd->bi_memsize);
+ stl_be_phys(bdloc + 0x08, bd->bi_flashstart);
+ stl_be_phys(bdloc + 0x0C, bd->bi_flashsize);
+ stl_be_phys(bdloc + 0x10, bd->bi_flashoffset);
+ stl_be_phys(bdloc + 0x14, bd->bi_sramstart);
+ stl_be_phys(bdloc + 0x18, bd->bi_sramsize);
+ stl_be_phys(bdloc + 0x1C, bd->bi_bootflags);
+ stl_be_phys(bdloc + 0x20, bd->bi_ipaddr);
+ for (i = 0; i < 6; i++) {
stb_phys(bdloc + 0x24 + i, bd->bi_enetaddr[i]);
- stw_phys(bdloc + 0x2A, bd->bi_ethspeed);
- stl_phys(bdloc + 0x2C, bd->bi_intfreq);
- stl_phys(bdloc + 0x30, bd->bi_busfreq);
- stl_phys(bdloc + 0x34, bd->bi_baudrate);
- for (i = 0; i < 4; i++)
+ }
+ stw_be_phys(bdloc + 0x2A, bd->bi_ethspeed);
+ stl_be_phys(bdloc + 0x2C, bd->bi_intfreq);
+ stl_be_phys(bdloc + 0x30, bd->bi_busfreq);
+ stl_be_phys(bdloc + 0x34, bd->bi_baudrate);
+ for (i = 0; i < 4; i++) {
stb_phys(bdloc + 0x38 + i, bd->bi_s_version[i]);
+ }
for (i = 0; i < 32; i++) {
stb_phys(bdloc + 0x3C + i, bd->bi_r_version[i]);
}
- stl_phys(bdloc + 0x5C, bd->bi_plb_busfreq);
- stl_phys(bdloc + 0x60, bd->bi_pci_busfreq);
- for (i = 0; i < 6; i++)
+ stl_be_phys(bdloc + 0x5C, bd->bi_plb_busfreq);
+ stl_be_phys(bdloc + 0x60, bd->bi_pci_busfreq);
+ for (i = 0; i < 6; i++) {
stb_phys(bdloc + 0x64 + i, bd->bi_pci_enetaddr[i]);
+ }
n = 0x6A;
if (flags & 0x00000001) {
for (i = 0; i < 6; i++)
stb_phys(bdloc + n++, bd->bi_pci_enetaddr2[i]);
}
- stl_phys(bdloc + n, bd->bi_opbfreq);
+ stl_be_phys(bdloc + n, bd->bi_opbfreq);
n += 4;
for (i = 0; i < 2; i++) {
- stl_phys(bdloc + n, bd->bi_iic_fast[i]);
+ stl_be_phys(bdloc + n, bd->bi_iic_fast[i]);
n += 4;
}
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
+#include "qemu-timer.h"
#include "qxl.h"
static const char *qxl_type[] = {
if (!qxl->cmdlog) {
return;
}
- fprintf(stderr, "qxl-%d/%s:", qxl->id, ring);
+ fprintf(stderr, "%ld qxl-%d/%s:", qemu_get_clock_ns(vm_clock),
+ qxl->id, ring);
fprintf(stderr, " cmd @ 0x%" PRIx64 " %s%s", ext->cmd.data,
qxl_name(qxl_type, ext->cmd.type),
compat ? "(compat)" : "");
info->n_surfaces = NUM_SURFACES;
}
+static const char *qxl_mode_to_string(int mode)
+{
+ switch (mode) {
+ case QXL_MODE_COMPAT:
+ return "compat";
+ case QXL_MODE_NATIVE:
+ return "native";
+ case QXL_MODE_UNDEFINED:
+ return "undefined";
+ case QXL_MODE_VGA:
+ return "vga";
+ }
+ return "INVALID";
+}
+
/* called from spice server thread context only */
static int interface_get_command(QXLInstance *sin, struct QXLCommandExt *ext)
{
}
qemu_mutex_unlock(&qxl->ssd.lock);
if (ret) {
+ dprint(qxl, 2, "%s %s\n", __FUNCTION__, qxl_mode_to_string(qxl->mode));
qxl_log_command(qxl, "vga", ext);
}
return ret;
case QXL_MODE_COMPAT:
case QXL_MODE_NATIVE:
case QXL_MODE_UNDEFINED:
- dprint(qxl, 2, "%s: %s\n", __FUNCTION__,
- qxl->cmdflags ? "compat" : "native");
+ dprint(qxl, 4, "%s: %s\n", __FUNCTION__, qxl_mode_to_string(qxl->mode));
ring = &qxl->ram->cmd_ring;
if (SPICE_RING_IS_EMPTY(ring)) {
return false;
}
+ dprint(qxl, 2, "%s: %s\n", __FUNCTION__, qxl_mode_to_string(qxl->mode));
SPICE_RING_CONS_ITEM(ring, cmd);
ext->cmd = *cmd;
ext->group_id = MEMSLOT_GROUP_GUEST;
case QXL_IO_MEMSLOT_ADD:
case QXL_IO_MEMSLOT_DEL:
case QXL_IO_CREATE_PRIMARY:
+ case QXL_IO_UPDATE_IRQ:
+ case QXL_IO_LOG:
break;
default:
if (d->mode == QXL_MODE_NATIVE || d->mode == QXL_MODE_COMPAT)
break;
case QXL_IO_LOG:
if (d->guestdebug) {
- fprintf(stderr, "qxl/guest: %s", d->ram->log_buf);
+ fprintf(stderr, "qxl/guest-%d: %ld: %s", d->id,
+ qemu_get_clock_ns(vm_clock), d->ram->log_buf);
}
break;
case QXL_IO_RESET:
break;
case QXL_IO_DESTROY_PRIMARY:
PANIC_ON(val != 0);
- dprint(d, 1, "QXL_IO_DESTROY_PRIMARY\n");
+ dprint(d, 1, "QXL_IO_DESTROY_PRIMARY (%s)\n", qxl_mode_to_string(d->mode));
qxl_destroy_primary(d);
break;
case QXL_IO_DESTROY_SURFACE_WAIT:
qemu_spice_vm_change_state_handler(&qxl->ssd, running, reason);
if (!running && qxl->mode == QXL_MODE_NATIVE) {
- /* dirty all vram (which holds surfaces) to make sure it is saved */
+ /* dirty all vram (which holds surfaces) and devram (primary surface)
+ * to make sure they are saved */
/* FIXME #1: should go out during "live" stage */
/* FIXME #2: we only need to save the areas which are actually used */
- ram_addr_t addr = qxl->vram_offset;
- qxl_set_dirty(addr, addr + qxl->vram_size);
+ ram_addr_t vram_addr = qxl->vram_offset;
+ ram_addr_t surface0_addr = qxl->vga.vram_offset + qxl->shadow_rom.draw_area_offset;
+ qxl_set_dirty(vram_addr, vram_addr + qxl->vram_size);
+ qxl_set_dirty(surface0_addr, surface0_addr + qxl->shadow_rom.surface0_area_size);
}
}
static int qxl_init_common(PCIQXLDevice *qxl)
{
uint8_t* config = qxl->pci.config;
- uint32_t pci_device_id;
uint32_t pci_device_rev;
uint32_t io_size;
switch (qxl->revision) {
case 1: /* spice 0.4 -- qxl-1 */
- pci_device_id = QXL_DEVICE_ID_STABLE;
pci_device_rev = QXL_REVISION_STABLE_V04;
break;
case 2: /* spice 0.6 -- qxl-2 */
- pci_device_id = QXL_DEVICE_ID_STABLE;
+ default:
pci_device_rev = QXL_REVISION_STABLE_V06;
break;
- default: /* experimental */
- pci_device_id = QXL_DEVICE_ID_DEVEL;
- pci_device_rev = 1;
- break;
}
- pci_config_set_device_id(config, pci_device_id);
pci_set_byte(&config[PCI_REVISION_ID], pci_device_rev);
pci_set_byte(&config[PCI_INTERRUPT_PIN], 1);
d->modes = (QXLModes*)((uint8_t*)d->rom + d->rom->modes_offset);
- dprint(d, 1, "%s: restore mode\n", __FUNCTION__);
+ dprint(d, 1, "%s: restore mode (%s)\n", __FUNCTION__,
+ qxl_mode_to_string(d->mode));
newmode = d->mode;
d->mode = QXL_MODE_UNDEFINED;
switch (newmode) {
.config_write = qxl_write_config,
.romfile = "vgabios-qxl.bin",
.vendor_id = REDHAT_PCI_VENDOR_ID,
+ .device_id = QXL_DEVICE_ID_STABLE,
.class_id = PCI_CLASS_DISPLAY_VGA,
.qdev.props = (Property[]) {
DEFINE_PROP_UINT32("ram_size", PCIQXLDevice, vga.vram_size, 64 * 1024 * 1024),
.qdev.vmsd = &qxl_vmstate,
.init = qxl_init_secondary,
.vendor_id = REDHAT_PCI_VENDOR_ID,
+ .device_id = QXL_DEVICE_ID_STABLE,
.class_id = PCI_CLASS_DISPLAY_OTHER,
.qdev.props = (Property[]) {
DEFINE_PROP_UINT32("ram_size", PCIQXLDevice, vga.vram_size, 64 * 1024 * 1024),
{
VirtIODevice *vdev;
- vdev = virtio_blk_init((DeviceState *)dev, &dev->block);
+ vdev = virtio_blk_init((DeviceState *)dev, &dev->block,
+ &dev->block_serial);
if (!vdev) {
return -1;
}
(vq * VIRTIO_VQCONFIG_LEN) +
VIRTIO_VQCONFIG_OFFS_TOKEN;
- return ldq_phys(token_off);
+ return ldq_be_phys(token_off);
}
static ram_addr_t s390_virtio_device_num_vq(VirtIOS390Device *dev)
vring = s390_virtio_next_ring(bus);
virtio_queue_set_addr(dev->vdev, i, vring);
virtio_queue_set_vector(dev->vdev, i, i);
- stq_phys(vq + VIRTIO_VQCONFIG_OFFS_ADDRESS, vring);
- stw_phys(vq + VIRTIO_VQCONFIG_OFFS_NUM, virtio_queue_get_num(dev->vdev, i));
+ stq_be_phys(vq + VIRTIO_VQCONFIG_OFFS_ADDRESS, vring);
+ stw_be_phys(vq + VIRTIO_VQCONFIG_OFFS_NUM, virtio_queue_get_num(dev->vdev, i));
}
cur_offs = dev->dev_offs;
cur_offs += num_vq * VIRTIO_VQCONFIG_LEN;
/* Sync feature bitmap */
- stl_phys(cur_offs, bswap32(dev->host_features));
+ stl_le_phys(cur_offs, dev->host_features);
dev->feat_offs = cur_offs + dev->feat_len;
cur_offs += dev->feat_len * 2;
/* Update guest supported feature bitmap */
- features = bswap32(ldl_phys(dev->feat_offs));
+ features = bswap32(ldl_be_phys(dev->feat_offs));
if (vdev->set_features) {
vdev->set_features(vdev, features);
}
.qdev.size = sizeof(VirtIOS390Device),
.qdev.props = (Property[]) {
DEFINE_BLOCK_PROPERTIES(VirtIOS390Device, block),
+ DEFINE_PROP_STRING("serial", VirtIOS390Device, block_serial),
DEFINE_PROP_END_OF_LIST(),
},
};
uint8_t feat_len;
VirtIODevice *vdev;
BlockConf block;
+ char *block_serial;
NICConf nic;
uint32_t host_features;
virtio_serial_conf serial;
if (kernel_filename) {
kernel_size = load_image(kernel_filename, qemu_get_ram_ptr(0));
- if (lduw_phys(KERN_IMAGE_START) != 0x0dd0) {
+ if (lduw_be_phys(KERN_IMAGE_START) != 0x0dd0) {
fprintf(stderr, "Specified image is not an s390 boot image\n");
exit(1);
}
}
initrd_size = load_image(initrd_filename, qemu_get_ram_ptr(initrd_offset));
- stq_phys(INITRD_PARM_START, initrd_offset);
- stq_phys(INITRD_PARM_SIZE, initrd_size);
+ stq_be_phys(INITRD_PARM_START, initrd_offset);
+ stq_be_phys(INITRD_PARM_SIZE, initrd_size);
}
if (kernel_cmdline) {
static inline uint32_t rtas_ld(target_ulong phys, int n)
{
- return ldl_phys(phys + 4*n);
+ return ldl_be_phys(phys + 4*n);
}
static inline void rtas_st(target_ulong phys, int n, uint32_t val)
{
- stl_phys(phys + 4*n, val);
+ stl_be_phys(phys + 4*n, val);
}
typedef void (*spapr_rtas_fn)(sPAPREnvironment *spapr, uint32_t token,
}
/* FIXME: bounds check the address */
- size = lduw_phys(vpa + 0x4);
+ size = lduw_be_phys(vpa + 0x4);
if (size < VPA_MIN_SIZE) {
return H_PARAMETER;
return H_HARDWARE;
}
- size = ldl_phys(addr + 0x4);
+ size = ldl_be_phys(addr + 0x4);
if (size < 0x8) {
return H_PARAMETER;
}
return H_HARDWARE;
}
- size = ldl_phys(addr + 0x4);
+ size = ldl_be_phys(addr + 0x4);
if (size < 48) {
return H_PARAMETER;
target_ulong opcode, target_ulong *args)
{
target_ulong rtas_r3 = args[0];
- uint32_t token = ldl_phys(rtas_r3);
- uint32_t nargs = ldl_phys(rtas_r3 + 4);
- uint32_t nret = ldl_phys(rtas_r3 + 8);
+ uint32_t token = ldl_be_phys(rtas_r3);
+ uint32_t nargs = ldl_be_phys(rtas_r3 + 4);
+ uint32_t nret = ldl_be_phys(rtas_r3 + 8);
return spapr_rtas_call(spapr, token, nargs, rtas_r3 + 12,
nret, rtas_r3 + 12 + 4*nargs);
hdev->started = false;
qemu_free(hdev->log);
+ hdev->log = NULL;
hdev->log_size = 0;
}
void *rq;
QEMUBH *bh;
BlockConf *conf;
+ char *serial;
unsigned short sector_mask;
- char sn[BLOCK_SERIAL_STRLEN];
DeviceState *qdev;
} VirtIOBlock;
} else if (type & VIRTIO_BLK_T_GET_ID) {
VirtIOBlock *s = req->dev;
- memcpy(req->elem.in_sg[0].iov_base, s->sn,
- MIN(req->elem.in_sg[0].iov_len, sizeof(s->sn)));
+ /*
+ * NB: per existing s/n string convention the string is
+ * terminated by '\0' only when shorter than buffer.
+ */
+ strncpy(req->elem.in_sg[0].iov_base,
+ s->serial ? s->serial : "",
+ MIN(req->elem.in_sg[0].iov_len, VIRTIO_BLK_ID_BYTES));
virtio_blk_req_complete(req, VIRTIO_BLK_S_OK);
} else if (type & VIRTIO_BLK_T_OUT) {
qemu_iovec_init_external(&req->qiov, &req->elem.out_sg[1],
}
}
-VirtIODevice *virtio_blk_init(DeviceState *dev, BlockConf *conf)
+VirtIODevice *virtio_blk_init(DeviceState *dev, BlockConf *conf,
+ char **serial)
{
VirtIOBlock *s;
int cylinders, heads, secs;
return NULL;
}
+ if (!*serial) {
+ /* try to fall back to value set with legacy -drive serial=... */
+ dinfo = drive_get_by_blockdev(conf->bs);
+ if (*dinfo->serial) {
+ *serial = strdup(dinfo->serial);
+ }
+ }
+
s = (VirtIOBlock *)virtio_common_init("virtio-blk", VIRTIO_ID_BLOCK,
sizeof(struct virtio_blk_config),
sizeof(VirtIOBlock));
s->vdev.reset = virtio_blk_reset;
s->bs = conf->bs;
s->conf = conf;
+ s->serial = *serial;
s->rq = NULL;
s->sector_mask = (s->conf->logical_block_size / BDRV_SECTOR_SIZE) - 1;
bdrv_guess_geometry(s->bs, &cylinders, &heads, &secs);
- /* NB: per existing s/n string convention the string is terminated
- * by '\0' only when less than sizeof (s->sn)
- */
- dinfo = drive_get_by_blockdev(s->bs);
- strncpy(s->sn, dinfo->serial, sizeof (s->sn));
-
s->vq = virtio_add_queue(&s->vdev, 128, virtio_blk_handle_output);
qemu_add_vm_change_state_handler(virtio_blk_dma_restart_cb, s);
#define VIRTIO_BLK_F_WCACHE 9 /* write cache enabled */
#define VIRTIO_BLK_F_TOPOLOGY 10 /* Topology information is available */
+#define VIRTIO_BLK_ID_BYTES 20 /* ID string length */
+
struct virtio_blk_config
{
uint64_t capacity;
#include "qemu-char.h"
#include "qemu-error.h"
+#include "trace.h"
#include "virtio-serial.h"
typedef struct VirtConsole {
static ssize_t flush_buf(VirtIOSerialPort *port, const uint8_t *buf, size_t len)
{
VirtConsole *vcon = DO_UPCAST(VirtConsole, port, port);
-
- return qemu_chr_write(vcon->chr, buf, len);
+ ssize_t ret;
+
+ ret = qemu_chr_write(vcon->chr, buf, len);
+ trace_virtio_console_flush_buf(port->id, len, ret);
+
+ if (ret < 0) {
+ /*
+ * Ideally we'd get a better error code than just -1, but
+ * that's what the chardev interface gives us right now. If
+ * we had a finer-grained message, like -EPIPE, we could close
+ * this connection. Absent such error messages, the most we
+ * can do is to return 0 here.
+ *
+ * This will prevent stray -1 values to go to
+ * virtio-serial-bus.c and cause abort()s in
+ * do_flush_queued_data().
+ */
+ ret = 0;
+ }
+ return ret;
}
/* Callback function that's called when the guest opens the port */
{
VirtConsole *vcon = opaque;
+ trace_virtio_console_chr_read(vcon->port.id, size);
virtio_serial_write(&vcon->port, buf, size);
}
{
VirtConsole *vcon = opaque;
+ trace_virtio_console_chr_event(vcon->port.id, event);
switch (event) {
case CHR_EVENT_OPENED:
virtio_serial_open(&vcon->port);
proxy->class_code != PCI_CLASS_STORAGE_OTHER)
proxy->class_code = PCI_CLASS_STORAGE_SCSI;
- vdev = virtio_blk_init(&pci_dev->qdev, &proxy->block);
+ vdev = virtio_blk_init(&pci_dev->qdev, &proxy->block,
+ &proxy->block_serial);
if (!vdev) {
return -1;
}
.qdev.props = (Property[]) {
DEFINE_PROP_HEX32("class", VirtIOPCIProxy, class_code, 0),
DEFINE_BLOCK_PROPERTIES(VirtIOPCIProxy, block),
+ DEFINE_PROP_STRING("serial", VirtIOPCIProxy, block_serial),
DEFINE_PROP_BIT("ioeventfd", VirtIOPCIProxy, flags,
VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, true),
DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 2),
uint32_t class_code;
uint32_t nvectors;
BlockConf block;
+ char *block_serial;
NICConf nic;
uint32_t host_features;
#ifdef CONFIG_LINUX
#include "monitor.h"
#include "qemu-queue.h"
#include "sysbus.h"
+#include "trace.h"
#include "virtio-serial.h"
/* The virtio-serial bus on top of which the ports will ride as devices */
stw_p(&cpkt.event, event);
stw_p(&cpkt.value, value);
+ trace_virtio_serial_send_control_event(port->id, event, value);
return send_control_msg(port, &cpkt, sizeof(cpkt));
}
return;
}
+ trace_virtio_serial_throttle_port(port->id, throttle);
port->throttled = throttle;
if (throttle) {
return;
cpkt.event = lduw_p(&gcpkt->event);
cpkt.value = lduw_p(&gcpkt->value);
+ trace_virtio_serial_handle_control_message(cpkt.event, cpkt.value);
+
if (cpkt.event == VIRTIO_CONSOLE_DEVICE_READY) {
if (!cpkt.value) {
error_report("virtio-serial-bus: Guest failure in adding device %s",
port = find_port_by_id(vser, ldl_p(&gcpkt->id));
if (!port) {
- error_report("virtio-serial-bus: Unexpected port id %u for device %s\n",
+ error_report("virtio-serial-bus: Unexpected port id %u for device %s",
ldl_p(&gcpkt->id), vser->bus.qbus.name);
return;
}
+ trace_virtio_serial_handle_control_message_port(port->id);
+
info = DO_UPCAST(VirtIOSerialPortInfo, qdev, port->dev.info);
switch(cpkt.event) {
struct iovec *sg;
if (vring_desc_flags(desc_pa, i) & VRING_DESC_F_WRITE) {
+ if (elem->in_num >= ARRAY_SIZE(elem->in_sg)) {
+ error_report("Too many write descriptors in indirect table");
+ exit(1);
+ }
elem->in_addr[elem->in_num] = vring_desc_addr(desc_pa, i);
sg = &elem->in_sg[elem->in_num++];
} else {
+ if (elem->out_num >= ARRAY_SIZE(elem->out_sg)) {
+ error_report("Too many read descriptors in indirect table");
+ exit(1);
+ }
elem->out_addr[elem->out_num] = vring_desc_addr(desc_pa, i);
sg = &elem->out_sg[elem->out_num++];
}
void *opaque);
/* Base devices. */
-VirtIODevice *virtio_blk_init(DeviceState *dev, BlockConf *conf);
+VirtIODevice *virtio_blk_init(DeviceState *dev, BlockConf *conf,
+ char **serial);
struct virtio_net_conf;
VirtIODevice *virtio_net_init(DeviceState *dev, NICConf *conf,
struct virtio_net_conf *net);
pci_conf = d->pci_dev.config;
- pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_XENSOURCE);
- pci_config_set_device_id(pci_conf, 0x0001);
- pci_set_word(pci_conf + PCI_SUBSYSTEM_VENDOR_ID, PCI_VENDOR_ID_XENSOURCE);
- pci_set_word(pci_conf + PCI_SUBSYSTEM_ID, 0x0001);
-
pci_set_word(pci_conf + PCI_COMMAND, PCI_COMMAND_IO | PCI_COMMAND_MEMORY);
- pci_config_set_revision(pci_conf, 1);
pci_config_set_prog_interface(pci_conf, 0);
- pci_config_set_class(pci_conf, PCI_CLASS_OTHERS << 8 | 0x80);
-
pci_conf[PCI_INTERRUPT_PIN] = 1;
pci_register_bar(&d->pci_dev, 0, 0x100,
.qdev.size = sizeof(PCIXenPlatformState),
.qdev.vmsd = &vmstate_xen_platform,
.qdev.reset = platform_reset,
+
+ .vendor_id = PCI_VENDOR_ID_XEN,
+ .device_id = PCI_DEVICE_ID_XEN_PLATFORM,
+ .class_id = PCI_CLASS_OTHERS << 8 | 0x80,
+ .subsystem_vendor_id = PCI_VENDOR_ID_XEN,
+ .subsystem_id = PCI_DEVICE_ID_XEN_PLATFORM,
+ .revision = 1,
};
static void xen_platform_register(void)
#define TARGET_NR_signalfd 476
#define TARGET_NR_timerfd 477
#define TARGET_NR_eventfd 478
-
+#define TARGET_NR_recvmmsg 479
+#define TARGET_NR_fallocate 480
+#define TARGET_NR_timerfd_create 481
+#define TARGET_NR_timerfd_settime 482
+#define TARGET_NR_timerfd_gettime 483
+#define TARGET_NR_signalfd4 484
+#define TARGET_NR_eventfd2 485
+#define TARGET_NR_epoll_create1 486
+#define TARGET_NR_dup3 487
+#define TARGET_NR_pipe2 488
+#define TARGET_NR_inotify_init1 489
+#define TARGET_NR_preadv 490
+#define TARGET_NR_pwritev 491
+#define TARGET_NR_rt_tgsigqueueinfo 492
+#define TARGET_NR_perf_event_open 493
+#define TARGET_NR_fanotify_init 494
+#define TARGET_NR_fanotify_mark 495
+#define TARGET_NR_prlimit64 496
+#define TARGET_NR_name_to_handle_at 497
+#define TARGET_NR_open_by_handle_at 498
+#define TARGET_NR_clock_adjtime 499
+#define TARGET_NR_syncfs 500
#define TARGET_NR_dup3 (358)
#define TARGET_NR_pipe2 (359)
#define TARGET_NR_inotify_init1 (360)
+#define TARGET_NR_preadv (361)
+#define TARGET_NR_pwritev (362)
+#define TARGET_NR_rt_tgsigqueueinfo (363)
+#define TARGET_NR_perf_event_open (364)
+#define TARGET_NR_recvmmsg (365)
+#define TARGET_NR_accept4 (366)
+#define TARGET_NR_fanotify_init (367)
+#define TARGET_NR_fanotify_mark (368)
+#define TARGET_NR_prlimit64 (369)
+#define TARGET_NR_name_to_handle_at (370)
+#define TARGET_NR_open_by_handle_at (371)
+#define TARGET_NR_clock_adjtime (372)
+#define TARGET_NR_syncfs (373)
#define TARGET_NR_dup3 330
#define TARGET_NR_pipe2 331
#define TARGET_NR_inotify_init1 332
+#define TARGET_NR_preadv 333
+#define TARGET_NR_pwritev 334
#ifdef TARGET_SPARC64
#define ELF_START_MMAP 0x80000000
-
+#define ELF_HWCAP (HWCAP_SPARC_FLUSH | HWCAP_SPARC_STBAR | HWCAP_SPARC_SWAP \
+ | HWCAP_SPARC_MULDIV | HWCAP_SPARC_V9)
#ifndef TARGET_ABI32
#define elf_check_arch(x) ( (x) == EM_SPARCV9 || (x) == EM_SPARC32PLUS )
#else
#else
#define ELF_START_MMAP 0x80000000
-
+#define ELF_HWCAP (HWCAP_SPARC_FLUSH | HWCAP_SPARC_STBAR | HWCAP_SPARC_SWAP \
+ | HWCAP_SPARC_MULDIV)
#define elf_check_arch(x) ( (x) == EM_SPARC )
#define ELF_CLASS ELFCLASS32
#define TARGET_NR_dup3 330
#define TARGET_NR_pipe2 331
#define TARGET_NR_inotify_init1 332
+#define TARGET_NR_preadv 333
+#define TARGET_NR_pwritev 334
+#define TARGET_NR_rt_tgsigqueueinfo 335
+#define TARGET_NR_perf_event_open 336
+#define TARGET_NR_recvmmsg 337
+#define TARGET_NR_fanotify_init 338
+#define TARGET_NR_fanotify_mark 339
+#define TARGET_NR_prlimit64 340
+#define TARGET_NR_name_to_handle_at 341
+#define TARGET_NR_open_by_handle_at 342
+#define TARGET_NR_clock_adjtime 343
+#define TARGET_NR_syncfs 344
IOCTL(KDSKBMODE, 0, TYPE_INT)
IOCTL(KDGKBENT, IOC_RW, MK_PTR(MK_STRUCT(STRUCT_kbentry)))
IOCTL(KDGKBSENT, IOC_RW, MK_PTR(MK_STRUCT(STRUCT_kbsentry)))
+ IOCTL(KDGKBLED, 0, TYPE_INT)
+ IOCTL(KDSKBLED, 0, TYPE_INT)
+ IOCTL(KDGETLED, 0, TYPE_INT)
+ IOCTL(KDSETLED, 0, TYPE_INT)
IOCTL(BLKROSET, IOC_W, MK_PTR(TYPE_INT))
IOCTL(BLKROGET, IOC_R, MK_PTR(TYPE_INT))
IOCTL(FBIOGET_FSCREENINFO, IOC_R, MK_PTR(MK_STRUCT(STRUCT_fb_fix_screeninfo)))
IOCTL(FBIOGET_VSCREENINFO, IOC_R, MK_PTR(MK_STRUCT(STRUCT_fb_var_screeninfo)))
IOCTL(FBIOPUT_VSCREENINFO, IOC_W, MK_PTR(MK_STRUCT(STRUCT_fb_var_screeninfo)))
+ IOCTL(FBIOGETCMAP, IOC_RW, MK_PTR(MK_STRUCT(STRUCT_fb_cmap)))
+ IOCTL(FBIOPUTCMAP, IOC_RW, MK_PTR(MK_STRUCT(STRUCT_fb_cmap)))
+ IOCTL(FBIOPAN_DISPLAY, IOC_RW, MK_PTR(MK_STRUCT(STRUCT_fb_var_screeninfo)))
+ IOCTL(FBIOGET_CON2FBMAP, IOC_RW, MK_PTR(MK_STRUCT(STRUCT_fb_con2fbmap)))
+ IOCTL(FBIOPUT_CON2FBMAP, IOC_RW, MK_PTR(MK_STRUCT(STRUCT_fb_con2fbmap)))
IOCTL(VT_OPENQRY, IOC_R, MK_PTR(TYPE_INT))
IOCTL(VT_GETSTATE, IOC_R, MK_PTR(MK_STRUCT(STRUCT_vt_stat)))
IOCTL(VT_WAITACTIVE, 0, TYPE_INT)
IOCTL(VT_LOCKSWITCH, 0, TYPE_INT)
IOCTL(VT_UNLOCKSWITCH, 0, TYPE_INT)
+ IOCTL(VT_GETMODE, IOC_RW, MK_PTR(MK_STRUCT(STRUCT_vt_mode)))
+ IOCTL(VT_SETMODE, IOC_RW, MK_PTR(MK_STRUCT(STRUCT_vt_mode)))
+ IOCTL(VT_RELDISP, 0, TYPE_INT)
+ IOCTL(VT_DISALLOCATE, 0, TYPE_INT)
#define TARGET_NR_dup3 326
#define TARGET_NR_pipe2 327
#define TARGET_NR_inotify_init1 328
+#define TARGET_NR_inotify_init1 328
+#define TARGET_NR_preadv 329
+#define TARGET_NR_pwritev 330
+#define TARGET_NR_rt_tgsigqueueinfo 331
+#define TARGET_NR_perf_event_open 332
+#define TARGET_NR_get_thread_area 333
+#define TARGET_NR_set_thread_area 334
+#define TARGET_NR_atomic_cmpxchg_32 335
+#define TARGET_NR_atomic_barrier 336
+#define TARGET_NR_fanotify_init 337
+#define TARGET_NR_fanotify_mark 338
+#define TARGET_NR_prlimit64 339
+#define TARGET_NR_name_to_handle_at 340
+#define TARGET_NR_open_by_handle_at 341
+#define TARGET_NR_clock_adjtime 342
+#define TARGET_NR_syncfs 343
MIPS_SYS(sys_getcwd , 2)
MIPS_SYS(sys_capget , 2)
MIPS_SYS(sys_capset , 2) /* 4205 */
- MIPS_SYS(sys_sigaltstack , 0)
+ MIPS_SYS(sys_sigaltstack , 2)
MIPS_SYS(sys_sendfile , 4)
MIPS_SYS(sys_ni_syscall , 0)
MIPS_SYS(sys_ni_syscall , 0)
MIPS_SYS(sys_epoll_pwait, 6)
MIPS_SYS(sys_ioprio_set, 3)
MIPS_SYS(sys_ioprio_get, 2)
+ MIPS_SYS(sys_utimensat, 4)
+ MIPS_SYS(sys_signalfd, 3)
+ MIPS_SYS(sys_ni_syscall, 0) /* was timerfd */
+ MIPS_SYS(sys_eventfd, 1)
+ MIPS_SYS(sys_fallocate, 6) /* 4320 */
+ MIPS_SYS(sys_timerfd_create, 2)
+ MIPS_SYS(sys_timerfd_gettime, 2)
+ MIPS_SYS(sys_timerfd_settime, 4)
+ MIPS_SYS(sys_signalfd4, 4)
+ MIPS_SYS(sys_eventfd2, 2) /* 4325 */
+ MIPS_SYS(sys_epoll_create1, 1)
+ MIPS_SYS(sys_dup3, 3)
+ MIPS_SYS(sys_pipe2, 2)
+ MIPS_SYS(sys_inotify_init1, 1)
+ MIPS_SYS(sys_preadv, 6) /* 4330 */
+ MIPS_SYS(sys_pwritev, 6)
+ MIPS_SYS(sys_rt_tgsigqueueinfo, 4)
+ MIPS_SYS(sys_perf_event_open, 5)
+ MIPS_SYS(sys_accept4, 4)
+ MIPS_SYS(sys_recvmmsg, 5) /* 4335 */
+ MIPS_SYS(sys_fanotify_init, 2)
+ MIPS_SYS(sys_fanotify_mark, 6)
+ MIPS_SYS(sys_prlimit64, 4)
+ MIPS_SYS(sys_name_to_handle_at, 5)
+ MIPS_SYS(sys_open_by_handle_at, 3) /* 4340 */
+ MIPS_SYS(sys_clock_adjtime, 2)
+ MIPS_SYS(sys_syncfs, 1)
};
#undef MIPS_SYS
syscall_num = env->active_tc.gpr[2] - 4000;
env->active_tc.PC += 4;
if (syscall_num >= sizeof(mips_syscall_args)) {
- ret = -ENOSYS;
+ ret = -TARGET_ENOSYS;
} else {
int nb_args;
abi_ulong sp_reg;
break;
case EXCP_TLBL:
case EXCP_TLBS:
+ case EXCP_AdEL:
+ case EXCP_AdES:
info.si_signo = TARGET_SIGSEGV;
info.si_errno = 0;
/* XXX: check env->error_code */
#define TARGET_NR_sendmsg 360 /* new */
#define TARGET_NR_recvmsg 361 /* new */
#define TARGET_NR_accept04 362 /* new */
-
-#define TARGET_NR_syscalls 363
+#define TARGET_NR_preadv 363 /* new */
+#define TARGET_NR_pwritev 364 /* new */
+#define TARGET_NR_rt_tgsigqueueinfo 365 /* new */
+#define TARGET_NR_perf_event_open 366 /* new */
+#define TARGET_NR_recvmmsg 367 /* new */
+#define TARGET_NR_fanotify_init 368
+#define TARGET_NR_fanotify_mark 369
+#define TARGET_NR_prlimit64 370
+#define TARGET_NR_name_to_handle_at 371
+#define TARGET_NR_open_by_handle_at 372
+#define TARGET_NR_clock_adjtime 373
+#define TARGET_NR_syncfs 374
#define TARGET_NR_dup3 (TARGET_NR_Linux + 327)
#define TARGET_NR_pipe2 (TARGET_NR_Linux + 328)
#define TARGET_NR_inotify_init1 (TARGET_NR_Linux + 329)
+#define TARGET_NR_preadv (TARGET_NR_Linux + 330)
+#define TARGET_NR_pwritev (TARGET_NR_Linux + 331)
+#define TARGET_NR_rt_tgsigqueueinfo (TARGET_NR_Linux + 332)
+#define TARGET_NR_perf_event_open (TARGET_NR_Linux + 333)
+#define TARGET_NR_accept4 (TARGET_NR_Linux + 334)
+#define TARGET_NR_recvmmsg (TARGET_NR_Linux + 335)
+#define TARGET_NR_fanotify_init (TARGET_NR_Linux + 336)
+#define TARGET_NR_fanotify_mark (TARGET_NR_Linux + 337)
+#define TARGET_NR_prlimit64 (TARGET_NR_Linux + 338)
+#define TARGET_NR_name_to_handle_at (TARGET_NR_Linux + 339)
+#define TARGET_NR_open_by_handle_at (TARGET_NR_Linux + 340)
+#define TARGET_NR_clock_adjtime (TARGET_NR_Linux + 341)
+#define TARGET_NR_syncfs (TARGET_NR_Linux + 342)
#define TARGET_NR_dup3 (TARGET_NR_Linux + 286)
#define TARGET_NR_pipe2 (TARGET_NR_Linux + 287)
#define TARGET_NR_inotify_init1 (TARGET_NR_Linux + 288)
+#define TARGET_NR_preadv (TARGET_NR_Linux + 289)
+#define TARGET_NR_pwritev (TARGET_NR_Linux + 290)
+#define TARGET_NR_rt_tgsigqueueinfo (TARGET_NR_Linux + 291)
+#define TARGET_NR_perf_event_open (TARGET_NR_Linux + 292)
+#define TARGET_NR_accept4 (TARGET_NR_Linux + 293)
+#define TARGET_NR_recvmmsg (TARGET_NR_Linux + 294)
+#define TARGET_NR_fanotify_init (TARGET_NR_Linux + 295)
+#define TARGET_NR_fanotify_mark (TARGET_NR_Linux + 296)
+#define TARGET_NR_prlimit64 (TARGET_NR_Linux + 297)
+#define TARGET_NR_name_to_handle_at (TARGET_NR_Linux + 298)
+#define TARGET_NR_open_by_handle_at (TARGET_NR_Linux + 299)
+#define TARGET_NR_clock_adjtime (TARGET_NR_Linux + 300)
+#define TARGET_NR_syncfs (TARGET_NR_Linux + 301)
#define TARGET_NR_dup3 (TARGET_NR_Linux + 290)
#define TARGET_NR_pipe2 (TARGET_NR_Linux + 291)
#define TARGET_NR_inotify_init1 (TARGET_NR_Linux + 292)
+#define TARGET_NR_preadv (TARGET_NR_Linux + 293)
+#define TARGET_NR_pwritev (TARGET_NR_Linux + 294)
+#define TARGET_NR_rt_tgsigqueueinfo (TARGET_NR_Linux + 295)
+#define TARGET_NR_perf_event_open (TARGET_NR_Linux + 296)
+#define TARGET_NR_accept4 (TARGET_NR_Linux + 297)
+#define TARGET_NR_recvmmsg (TARGET_NR_Linux + 298)
+#define TARGET_NR_getdents64 (TARGET_NR_Linux + 299)
+#define TARGET_NR_fanotify_init (TARGET_NR_Linux + 300)
+#define TARGET_NR_fanotify_mark (TARGET_NR_Linux + 301)
+#define TARGET_NR_prlimit64 (TARGET_NR_Linux + 302)
+#define TARGET_NR_name_to_handle_at (TARGET_NR_Linux + 303)
+#define TARGET_NR_open_by_handle_at (TARGET_NR_Linux + 304)
+#define TARGET_NR_clock_adjtime (TARGET_NR_Linux + 305)
+#define TARGET_NR_syncfs (TARGET_NR_Linux + 306)
#define TARGET_NR_dup3 316
#define TARGET_NR_pipe2 317
#define TARGET_NR_inotify_init1 318
+#define TARGET_NR_perf_event_open 319
+#define TARGET_NR_preadv 320
+#define TARGET_NR_pwritev 321
+#define TARGET_NR_rt_tgsigqueueinfo 322
+#define TARGET_NR_fanotify_init 323
+#define TARGET_NR_fanotify_mark 324
+#define TARGET_NR_prlimit64 325
+#define TARGET_NR_socket 326
+#define TARGET_NR_bind 327
+#define TARGET_NR_connect 328
+#define TARGET_NR_listen 329
+#define TARGET_NR_accept 330
+#define TARGET_NR_getsockname 331
+#define TARGET_NR_getpeername 332
+#define TARGET_NR_socketpair 333
+#define TARGET_NR_send 334
+#define TARGET_NR_sendto 335
+#define TARGET_NR_recv 336
+#define TARGET_NR_recvfrom 337
+#define TARGET_NR_shutdown 338
+#define TARGET_NR_setsockopt 339
+#define TARGET_NR_getsockopt 340
+#define TARGET_NR_sendmsg 341
+#define TARGET_NR_recvmsg 342
+#define TARGET_NR_recvmmsg 343
+#define TARGET_NR_accept4 344
+#define TARGET_NR_name_to_handle_at 345
+#define TARGET_NR_open_by_handle_at 346
+#define TARGET_NR_clock_adjtime 347
+#define TARGET_NR_syncfs 348
#define TARGET_NR_pipe2 325
#define TARGET_NR_dup3 326
#define TARGET_NR_epoll_create1 327
-#undef NR_syscalls
-#define NR_syscalls 328
+#define TARGET_NR_preadv 328
+#define TARGET_NR_pwritev 329
+#define TARGET_NR_rt_tgsigqueueinfo 330
+#define TARGET_NR_perf_event_open 331
+#define TARGET_NR_fanotify_init 332
+#define TARGET_NR_fanotify_mark 333
+#define TARGET_NR_prlimit64 334
+#define TARGET_NR_name_to_handle_at 335
+#define TARGET_NR_open_by_handle_at 336
+#define TARGET_NR_clock_adjtime 337
+#define TARGET_NR_syncfs 338
/*
* There are some system calls that are not present on 64 bit, some
#define TARGET_NR_clone 120
#define TARGET_NR_setdomainname 121
#define TARGET_NR_uname 122
-#define TARGET_NR_modify_ldt 123
+#define TARGET_NR_cacheflush 123
#define TARGET_NR_adjtimex 124
#define TARGET_NR_mprotect 125
#define TARGET_NR_sigprocmask 126
#define TARGET_NR_dup3 330
#define TARGET_NR_pipe2 331
#define TARGET_NR_inotify_init1 332
+#define TARGET_NR_preadv 333
+#define TARGET_NR_pwritev 334
+#define TARGET_NR_rt_tgsigqueueinfo 335
+#define TARGET_NR_perf_event_open 336
+#define TARGET_NR_fanotify_init 337
+#define TARGET_NR_fanotify_mark 338
+#define TARGET_NR_prlimit64 339
+
+/* Non-multiplexed socket family */
+#define TARGET_NR_socket 340
+#define TARGET_NR_bind 341
+#define TARGET_NR_connect 342
+#define TARGET_NR_listen 343
+#define TARGET_NR_accept 344
+#define TARGET_NR_getsockname 345
+#define TARGET_NR_getpeername 346
+#define TARGET_NR_socketpair 347
+#define TARGET_NR_send 348
+#define TARGET_NR_sendto 349
+#define TARGET_NR_recv 350
+#define TARGET_NR_recvfrom 351
+#define TARGET_NR_shutdown 352
+#define TARGET_NR_setsockopt 353
+#define TARGET_NR_getsockopt 354
+#define TARGET_NR_sendmsg 355
+#define TARGET_NR_recvmsg 356
+#define TARGET_NR_recvmmsg 357
+#define TARGET_NR_accept4 358
+#define TARGET_NR_name_to_handle_at 359
+#define TARGET_NR_open_by_handle_at 360
+#define TARGET_NR_clock_adjtime 361
+#define TARGET_NR_syncfs 362
} sigframe;
struct target_ucontext {
- target_ulong uc_flags;
- struct target_ucontext *uc_link;
- target_stack_t uc_stack;
- target_sigregs uc_mcontext;
- target_sigset_t uc_sigmask; /* mask last for extensibility */
+ target_ulong tuc_flags;
+ struct target_ucontext *tuc_link;
+ target_stack_t tuc_stack;
+ target_sigregs tuc_mcontext;
+ target_sigset_t tuc_sigmask; /* mask last for extensibility */
};
typedef struct {
}
/* Create the ucontext. */
- __put_user(0, &frame->uc.uc_flags);
- __put_user((abi_ulong)0, (abi_ulong *)&frame->uc.uc_link);
- __put_user(target_sigaltstack_used.ss_sp, &frame->uc.uc_stack.ss_sp);
+ __put_user(0, &frame->uc.tuc_flags);
+ __put_user((abi_ulong)0, (abi_ulong *)&frame->uc.tuc_link);
+ __put_user(target_sigaltstack_used.ss_sp, &frame->uc.tuc_stack.ss_sp);
__put_user(sas_ss_flags(get_sp_from_cpustate(env)),
- &frame->uc.uc_stack.ss_flags);
- __put_user(target_sigaltstack_used.ss_size, &frame->uc.uc_stack.ss_size);
- save_sigregs(env, &frame->uc.uc_mcontext);
+ &frame->uc.tuc_stack.ss_flags);
+ __put_user(target_sigaltstack_used.ss_size, &frame->uc.tuc_stack.ss_size);
+ save_sigregs(env, &frame->uc.tuc_mcontext);
for (i = 0; i < TARGET_NSIG_WORDS; i++) {
__put_user((abi_ulong)set->sig[i],
- (abi_ulong *)&frame->uc.uc_sigmask.sig[i]);
+ (abi_ulong *)&frame->uc.tuc_sigmask.sig[i]);
}
/* Set up to return from userspace. If provided, use a stub
if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) {
goto badframe;
}
- target_to_host_sigset(&set, &frame->uc.uc_sigmask);
+ target_to_host_sigset(&set, &frame->uc.tuc_sigmask);
sigprocmask(SIG_SETMASK, &set, NULL); /* ~_BLOCKABLE? */
- if (restore_sigregs(env, &frame->uc.uc_mcontext)) {
+ if (restore_sigregs(env, &frame->uc.tuc_mcontext)) {
goto badframe;
}
- if (do_sigaltstack(frame_addr + offsetof(rt_sigframe, uc.uc_stack), 0,
+ if (do_sigaltstack(frame_addr + offsetof(rt_sigframe, uc.tuc_stack), 0,
get_sp_from_cpustate(env)) == -EFAULT) {
goto badframe;
}
#define TARGET_NR_pipe2 321
#define TARGET_NR_inotify_init1 322
#define TARGET_NR_accept4 323
+#define TARGET_NR_preadv 324
+#define TARGET_NR_pwritev 325
+#define TARGET_NR_rt_tgsigqueueinfo 326
+#define TARGET_NR_perf_event_open 327
+#define TARGET_NR_recvmmsg 328
+#define TARGET_NR_fanotify_init 329
+#define TARGET_NR_fanotify_mark 330
+#define TARGET_NR_prlimit64 331
+#define TARGET_NR_name_to_handle_at 332
+#define TARGET_NR_open_by_handle_at 333
+#define TARGET_NR_clock_adjtime 334
+#define TARGET_NR_syncfs 335
#define TARGET_NR_pipe2 321
#define TARGET_NR_inotify_init1 322
#define TARGET_NR_accept4 323
+#define TARGET_NR_preadv 324
+#define TARGET_NR_pwritev 325
+#define TARGET_NR_rt_tgsigqueueinfo 326
+#define TARGET_NR_perf_event_open 327
+#define TARGET_NR_recvmmsg 328
+#define TARGET_NR_fanotify_init 329
+#define TARGET_NR_fanotify_mark 330
+#define TARGET_NR_prlimit64 331
+#define TARGET_NR_name_to_handle_at 332
+#define TARGET_NR_open_by_handle_at 333
+#define TARGET_NR_clock_adjtime 334
+#define TARGET_NR_syncfs 335
fd_set *, exceptfds, struct timespec *, timeout, void *, sig);
#endif
+#if defined(TARGET_NR_prlimit64)
+#ifndef __NR_prlimit64
+# define __NR_prlimit64 -1
+#endif
+#define __NR_sys_prlimit64 __NR_prlimit64
+/* The glibc rlimit structure may not be that used by the underlying syscall */
+struct host_rlimit64 {
+ uint64_t rlim_cur;
+ uint64_t rlim_max;
+};
+_syscall4(int, sys_prlimit64, pid_t, pid, int, resource,
+ const struct host_rlimit64 *, new_limit,
+ struct host_rlimit64 *, old_limit)
+#endif
+
extern int personality(int);
extern int flock(int, int);
extern int setfsuid(int);
extern int setfsgid(int);
extern int setgroups(int, gid_t *);
+/* ARM EABI and MIPS expect 64bit types aligned even on pairs or registers */
+#ifdef TARGET_ARM
+static inline int regpairs_aligned(void *cpu_env) {
+ return ((((CPUARMState *)cpu_env)->eabi) == 1) ;
+}
+#elif defined(TARGET_MIPS)
+static inline int regpairs_aligned(void *cpu_env) { return 1; }
+#else
+static inline int regpairs_aligned(void *cpu_env) { return 0; }
+#endif
+
#define ERRNO_TABLE_SIZE 1200
/* target_to_host_errno_table[] is initialized from
static inline rlim_t target_to_host_rlim(target_ulong target_rlim)
{
- if (target_rlim == TARGET_RLIM_INFINITY)
- return RLIM_INFINITY;
+ target_ulong target_rlim_swap;
+ rlim_t result;
+
+ target_rlim_swap = tswapl(target_rlim);
+ if (target_rlim_swap == TARGET_RLIM_INFINITY || target_rlim_swap != (rlim_t)target_rlim_swap)
+ result = RLIM_INFINITY;
else
- return tswapl(target_rlim);
+ result = target_rlim_swap;
+
+ return result;
}
static inline target_ulong host_to_target_rlim(rlim_t rlim)
{
+ target_ulong target_rlim_swap;
+ target_ulong result;
+
if (rlim == RLIM_INFINITY || rlim != (target_long)rlim)
- return TARGET_RLIM_INFINITY;
+ target_rlim_swap = TARGET_RLIM_INFINITY;
else
- return tswapl(rlim);
+ target_rlim_swap = rlim;
+ result = tswapl(target_rlim_swap);
+
+ return result;
+}
+
+static inline int target_to_host_resource(int code)
+{
+ switch (code) {
+ case TARGET_RLIMIT_AS:
+ return RLIMIT_AS;
+ case TARGET_RLIMIT_CORE:
+ return RLIMIT_CORE;
+ case TARGET_RLIMIT_CPU:
+ return RLIMIT_CPU;
+ case TARGET_RLIMIT_DATA:
+ return RLIMIT_DATA;
+ case TARGET_RLIMIT_FSIZE:
+ return RLIMIT_FSIZE;
+ case TARGET_RLIMIT_LOCKS:
+ return RLIMIT_LOCKS;
+ case TARGET_RLIMIT_MEMLOCK:
+ return RLIMIT_MEMLOCK;
+ case TARGET_RLIMIT_MSGQUEUE:
+ return RLIMIT_MSGQUEUE;
+ case TARGET_RLIMIT_NICE:
+ return RLIMIT_NICE;
+ case TARGET_RLIMIT_NOFILE:
+ return RLIMIT_NOFILE;
+ case TARGET_RLIMIT_NPROC:
+ return RLIMIT_NPROC;
+ case TARGET_RLIMIT_RSS:
+ return RLIMIT_RSS;
+ case TARGET_RLIMIT_RTPRIO:
+ return RLIMIT_RTPRIO;
+ case TARGET_RLIMIT_SIGPENDING:
+ return RLIMIT_SIGPENDING;
+ case TARGET_RLIMIT_STACK:
+ return RLIMIT_STACK;
+ default:
+ return code;
+ }
}
static inline abi_long copy_from_user_timeval(struct timeval *tv,
abi_long arg3,
abi_long arg4)
{
-#ifdef TARGET_ARM
- if (((CPUARMState *)cpu_env)->eabi)
- {
+ if (regpairs_aligned(cpu_env)) {
arg2 = arg3;
arg3 = arg4;
- }
-#endif
+ }
return get_errno(truncate64(arg1, target_offset64(arg2, arg3)));
}
#endif
abi_long arg3,
abi_long arg4)
{
-#ifdef TARGET_ARM
- if (((CPUARMState *)cpu_env)->eabi)
- {
+ if (regpairs_aligned(cpu_env)) {
arg2 = arg3;
arg3 = arg4;
- }
-#endif
+ }
return get_errno(ftruncate64(arg1, target_offset64(arg2, arg3)));
}
#endif
break;
case TARGET_NR_setrlimit:
{
- int resource = arg1;
+ int resource = target_to_host_resource(arg1);
struct target_rlimit *target_rlim;
struct rlimit rlim;
if (!lock_user_struct(VERIFY_READ, target_rlim, arg2, 1))
break;
case TARGET_NR_getrlimit:
{
- int resource = arg1;
+ int resource = target_to_host_resource(arg1);
struct target_rlimit *target_rlim;
struct rlimit rlim;
if (arg_sigset) {
sig.set = &set;
+ if (arg_sigsize != sizeof(*target_sigset)) {
+ /* Like the kernel, we enforce correct size sigsets */
+ ret = -TARGET_EINVAL;
+ goto fail;
+ }
target_sigset = lock_user(VERIFY_READ, arg_sigset,
sizeof(*target_sigset), 1);
if (!target_sigset) {
#endif
#ifdef TARGET_NR_pread
case TARGET_NR_pread:
-#ifdef TARGET_ARM
- if (((CPUARMState *)cpu_env)->eabi)
+ if (regpairs_aligned(cpu_env))
arg4 = arg5;
-#endif
if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
goto efault;
ret = get_errno(pread(arg1, p, arg3, arg4));
unlock_user(p, arg2, ret);
break;
case TARGET_NR_pwrite:
-#ifdef TARGET_ARM
- if (((CPUARMState *)cpu_env)->eabi)
+ if (regpairs_aligned(cpu_env))
arg4 = arg5;
-#endif
if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
goto efault;
ret = get_errno(pwrite(arg1, p, arg3, arg4));
case TARGET_NR_ugetrlimit:
{
struct rlimit rlim;
- ret = get_errno(getrlimit(arg1, &rlim));
+ int resource = target_to_host_resource(arg1);
+ ret = get_errno(getrlimit(resource, &rlim));
if (!is_error(ret)) {
struct target_rlimit *target_rlim;
if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
#ifdef TARGET_NR_readahead
case TARGET_NR_readahead:
#if TARGET_ABI_BITS == 32
-#ifdef TARGET_ARM
- if (((CPUARMState *)cpu_env)->eabi)
- {
+ if (regpairs_aligned(cpu_env)) {
arg2 = arg3;
arg3 = arg4;
arg4 = arg5;
}
-#endif
ret = get_errno(readahead(arg1, ((off64_t)arg3 << 32) | arg2, arg4));
#else
ret = get_errno(readahead(arg1, arg2, arg3));
break;
}
#endif
+#endif
+#ifdef TARGET_NR_prlimit64
+ case TARGET_NR_prlimit64:
+ {
+ /* args: pid, resource number, ptr to new rlimit, ptr to old rlimit */
+ struct target_rlimit64 *target_rnew, *target_rold;
+ struct host_rlimit64 rnew, rold, *rnewp = 0;
+ if (arg3) {
+ if (!lock_user_struct(VERIFY_READ, target_rnew, arg3, 1)) {
+ goto efault;
+ }
+ rnew.rlim_cur = tswap64(target_rnew->rlim_cur);
+ rnew.rlim_max = tswap64(target_rnew->rlim_max);
+ unlock_user_struct(target_rnew, arg3, 0);
+ rnewp = &rnew;
+ }
+
+ ret = get_errno(sys_prlimit64(arg1, arg2, rnewp, arg4 ? &rold : 0));
+ if (!is_error(ret) && arg4) {
+ if (!lock_user_struct(VERIFY_WRITE, target_rold, arg4, 1)) {
+ goto efault;
+ }
+ target_rold->rlim_cur = tswap64(rold.rlim_cur);
+ target_rold->rlim_max = tswap64(rold.rlim_max);
+ unlock_user_struct(target_rold, arg4, 1);
+ }
+ break;
+ }
#endif
default:
unimplemented:
#define TARGET_RLIM_INFINITY ((target_ulong)~0UL)
#endif
+#if defined(TARGET_MIPS)
+#define TARGET_RLIMIT_CPU 0
+#define TARGET_RLIMIT_FSIZE 1
+#define TARGET_RLIMIT_DATA 2
+#define TARGET_RLIMIT_STACK 3
+#define TARGET_RLIMIT_CORE 4
+#define TARGET_RLIMIT_RSS 7
+#define TARGET_RLIMIT_NPROC 8
+#define TARGET_RLIMIT_NOFILE 5
+#define TARGET_RLIMIT_MEMLOCK 9
+#define TARGET_RLIMIT_AS 6
+#define TARGET_RLIMIT_LOCKS 10
+#define TARGET_RLIMIT_SIGPENDING 11
+#define TARGET_RLIMIT_MSGQUEUE 12
+#define TARGET_RLIMIT_NICE 13
+#define TARGET_RLIMIT_RTPRIO 14
+#else
+#define TARGET_RLIMIT_CPU 0
+#define TARGET_RLIMIT_FSIZE 1
+#define TARGET_RLIMIT_DATA 2
+#define TARGET_RLIMIT_STACK 3
+#define TARGET_RLIMIT_CORE 4
+#define TARGET_RLIMIT_RSS 5
+#define TARGET_RLIMIT_NPROC 6
+#define TARGET_RLIMIT_NOFILE 7
+#define TARGET_RLIMIT_MEMLOCK 8
+#define TARGET_RLIMIT_AS 9
+#define TARGET_RLIMIT_LOCKS 10
+#define TARGET_RLIMIT_SIGPENDING 11
+#define TARGET_RLIMIT_MSGQUEUE 12
+#define TARGET_RLIMIT_NICE 13
+#define TARGET_RLIMIT_RTPRIO 14
+#endif
+
struct target_pollfd {
int fd; /* file descriptor */
short events; /* requested events */
#define TARGET_KDSKBMODE 0x4b45
#define TARGET_KDGKBENT 0x4B46 /* gets one entry in translation table */
#define TARGET_KDGKBSENT 0x4B48 /* gets one function key string entry */
+#define TARGET_KDGKBLED 0x4B64 /* get led flags (not lights) */
+#define TARGET_KDSKBLED 0x4B65 /* set led flags (not lights) */
+#define TARGET_KDGETLED 0x4B31 /* return current led state */
+#define TARGET_KDSETLED 0x4B32 /* set led state [lights, not flags] */
#define TARGET_SIOCATMARK 0x8905
#define TARGET_FBIOGET_VSCREENINFO 0x4600
#define TARGET_FBIOPUT_VSCREENINFO 0x4601
#define TARGET_FBIOGET_FSCREENINFO 0x4602
+#define TARGET_FBIOGETCMAP 0x4604
+#define TARGET_FBIOPUTCMAP 0x4605
+#define TARGET_FBIOPAN_DISPLAY 0x4606
+#define TARGET_FBIOGET_CON2FBMAP 0x460F
+#define TARGET_FBIOPUT_CON2FBMAP 0x4610
/* vt ioctls */
#define TARGET_VT_OPENQRY 0x5600
#define TARGET_VT_WAITACTIVE 0x5607
#define TARGET_VT_LOCKSWITCH 0x560b
#define TARGET_VT_UNLOCKSWITCH 0x560c
+#define TARGET_VT_GETMODE 0x5601
+#define TARGET_VT_SETMODE 0x5602
+#define TARGET_VT_RELDISP 0x5605
+#define TARGET_VT_DISALLOCATE 0x5608
/* from asm/termbits.h */
target_epoll_data_t data;
};
#endif
+struct target_rlimit64 {
+ uint64_t rlim_cur;
+ uint64_t rlim_max;
+};
TYPE_INT, /* rotate */
MK_ARRAY(TYPE_INT, 5)) /* reserved */
+STRUCT(fb_cmap,
+ TYPE_INT, /* start */
+ TYPE_INT, /* len */
+ TYPE_PTRVOID, /* red */
+ TYPE_PTRVOID, /* green */
+ TYPE_PTRVOID, /* blue */
+ TYPE_PTRVOID) /* transp */
+
+STRUCT(fb_con2fbmap,
+ TYPE_INT, /* console */
+ TYPE_INT) /* framebuffer */
+
+
STRUCT(vt_stat,
TYPE_SHORT, /* v_active */
TYPE_SHORT, /* v_signal */
TYPE_SHORT) /* v_state */
+STRUCT(vt_mode,
+ TYPE_CHAR, /* mode */
+ TYPE_CHAR, /* waitv */
+ TYPE_SHORT, /* relsig */
+ TYPE_SHORT, /* acqsig */
+ TYPE_SHORT) /* frsig */
+
STRUCT(fiemap_extent,
TYPE_ULONGLONG, /* fe_logical */
TYPE_ULONGLONG, /* fe_physical */
#define TARGET_NR_dup3 292
#define TARGET_NR_pipe2 293
#define TARGET_NR_inotify_init1 294
+#define TARGET_NR_preadv 295
+#define TARGET_NR_pwritev 296
+#define TARGET_NR_rt_tgsigqueueinfo 297
+#define TARGET_NR_perf_event_open 298
+#define TARGET_NR_recvmmsg 299
+#define TARGET_NR_fanotify_init 300
+#define TARGET_NR_fanotify_mark 301
+#define TARGET_NR_prlimit64 302
+#define TARGET_NR_name_to_handle_at 303
+#define TARGET_NR_open_by_handle_at 304
+#define TARGET_NR_clock_adjtime 305
+#define TARGET_NR_syncfs 306
/*needed for MAP_POPULATE before including qemu-options.h */
#include <sys/mman.h>
#include <pwd.h>
+#include <grp.h>
#include <libgen.h>
/* Needed early for CONFIG_BSD etc. */
fprintf(stderr, "Failed to setgid(%d)\n", user_pwd->pw_gid);
exit(1);
}
+ if (initgroups(user_pwd->pw_name, user_pwd->pw_gid) < 0) {
+ fprintf(stderr, "Failed to initgroups(\"%s\", %d)\n",
+ user_pwd->pw_name, user_pwd->pw_gid);
+ exit(1);
+ }
if (setuid(user_pwd->pw_uid) < 0) {
fprintf(stderr, "Failed to setuid(%d)\n", user_pwd->pw_uid);
exit(1);
/* FIXME: Remove NEED_CPU_H. */
#ifndef NEED_CPU_H
-#include <setjmp.h>
#include "osdep.h"
#include "bswap.h"
ETEXI
DEF("commit", img_commit,
- "commit [-f fmt] filename")
+ "commit [-f fmt] [-t cache] filename")
STEXI
@item commit [-f @var{fmt}] @var{filename}
ETEXI
DEF("convert", img_convert,
- "convert [-c] [-p] [-f fmt] [-O output_fmt] [-o options] [-s snapshot_name] filename [filename2 [...]] output_filename")
+ "convert [-c] [-p] [-f fmt] [-t cache] [-O output_fmt] [-o options] [-s snapshot_name] filename [filename2 [...]] output_filename")
STEXI
@item convert [-c] [-f @var{fmt}] [-O @var{output_fmt}] [-o @var{options}] [-s @var{snapshot_name}] @var{filename} [@var{filename2} [...]] @var{output_filename}
ETEXI
ETEXI
DEF("rebase", img_rebase,
- "rebase [-f fmt] [-p] [-u] -b backing_file [-F backing_fmt] filename")
+ "rebase [-f fmt] [-t cache] [-p] [-u] -b backing_file [-F backing_fmt] filename")
STEXI
@item rebase [-f @var{fmt}] [-u] -b @var{backing_file} [-F @var{backing_fmt}] @var{filename}
ETEXI
/* Default to cache=writeback as data integrity is not important for qemu-tcg. */
#define BDRV_O_FLAGS BDRV_O_CACHE_WB
+#define BDRV_DEFAULT_CACHE "writeback"
static void format_print(void *opaque, const char *name)
{
"Command parameters:\n"
" 'filename' is a disk image filename\n"
" 'fmt' is the disk image format. It is guessed automatically in most cases\n"
+ " 'cache' is the cache mode used to write the output disk image, the valid\n"
+ " options are: 'none', 'writeback' (default), 'writethrough' and 'unsafe'\n"
" 'size' is the disk image size in bytes. Optional suffixes\n"
" 'k' or 'K' (kilobyte, 1024), 'M' (megabyte, 1024k), 'G' (gigabyte, 1024M)\n"
" and T (terabyte, 1024G) are supported. 'b' is ignored.\n"
}
#endif
+static int set_cache_flag(const char *mode, int *flags)
+{
+ *flags &= ~BDRV_O_CACHE_MASK;
+
+ if (!strcmp(mode, "none") || !strcmp(mode, "off")) {
+ *flags |= BDRV_O_CACHE_WB;
+ *flags |= BDRV_O_NOCACHE;
+ } else if (!strcmp(mode, "writeback")) {
+ *flags |= BDRV_O_CACHE_WB;
+ } else if (!strcmp(mode, "unsafe")) {
+ *flags |= BDRV_O_CACHE_WB;
+ *flags |= BDRV_O_NO_FLUSH;
+ } else if (!strcmp(mode, "writethrough")) {
+ /* this is the default */
+ } else {
+ return -1;
+ }
+
+ return 0;
+}
+
static int print_block_option_help(const char *filename, const char *fmt)
{
BlockDriver *drv, *proto_drv;
static int img_commit(int argc, char **argv)
{
- int c, ret;
- const char *filename, *fmt;
+ int c, ret, flags;
+ const char *filename, *fmt, *cache;
BlockDriverState *bs;
fmt = NULL;
+ cache = BDRV_DEFAULT_CACHE;
for(;;) {
- c = getopt(argc, argv, "f:h");
+ c = getopt(argc, argv, "f:ht:");
if (c == -1) {
break;
}
case 'f':
fmt = optarg;
break;
+ case 't':
+ cache = optarg;
+ break;
}
}
if (optind >= argc) {
}
filename = argv[optind++];
- bs = bdrv_new_open(filename, fmt, BDRV_O_FLAGS | BDRV_O_RDWR);
+ flags = BDRV_O_RDWR;
+ ret = set_cache_flag(cache, &flags);
+ if (ret < 0) {
+ error_report("Invalid cache option: %s", cache);
+ return -1;
+ }
+
+ bs = bdrv_new_open(filename, fmt, flags);
if (!bs) {
return 1;
}
static int img_convert(int argc, char **argv)
{
int c, ret = 0, n, n1, bs_n, bs_i, compress, cluster_size, cluster_sectors;
- int progress = 0;
- const char *fmt, *out_fmt, *out_baseimg, *out_filename;
+ int progress = 0, flags;
+ const char *fmt, *out_fmt, *cache, *out_baseimg, *out_filename;
BlockDriver *drv, *proto_drv;
BlockDriverState **bs = NULL, *out_bs = NULL;
int64_t total_sectors, nb_sectors, sector_num, bs_offset;
fmt = NULL;
out_fmt = "raw";
+ cache = "unsafe";
out_baseimg = NULL;
compress = 0;
for(;;) {
- c = getopt(argc, argv, "f:O:B:s:hce6o:p");
+ c = getopt(argc, argv, "f:O:B:s:hce6o:pt:");
if (c == -1) {
break;
}
case 'p':
progress = 1;
break;
+ case 't':
+ cache = optarg;
+ break;
}
}
goto out;
}
- out_bs = bdrv_new_open(out_filename, out_fmt,
- BDRV_O_FLAGS | BDRV_O_RDWR | BDRV_O_NO_FLUSH);
+ flags = BDRV_O_RDWR;
+ ret = set_cache_flag(cache, &flags);
+ if (ret < 0) {
+ error_report("Invalid cache option: %s", cache);
+ return -1;
+ }
+
+ out_bs = bdrv_new_open(out_filename, out_fmt, flags);
if (!out_bs) {
ret = -1;
goto out;
BlockDriverState *bs, *bs_old_backing = NULL, *bs_new_backing = NULL;
BlockDriver *old_backing_drv, *new_backing_drv;
char *filename;
- const char *fmt, *out_basefmt, *out_baseimg;
+ const char *fmt, *cache, *out_basefmt, *out_baseimg;
int c, flags, ret;
int unsafe = 0;
int progress = 0;
/* Parse commandline parameters */
fmt = NULL;
+ cache = BDRV_DEFAULT_CACHE;
out_baseimg = NULL;
out_basefmt = NULL;
-
for(;;) {
- c = getopt(argc, argv, "uhf:F:b:p");
+ c = getopt(argc, argv, "uhf:F:b:pt:");
if (c == -1) {
break;
}
case 'p':
progress = 1;
break;
+ case 't':
+ cache = optarg;
+ break;
}
}
qemu_progress_init(progress, 2.0);
qemu_progress_print(0, 100);
+ flags = BDRV_O_RDWR | (unsafe ? BDRV_O_NO_BACKING : 0);
+ ret = set_cache_flag(cache, &flags);
+ if (ret < 0) {
+ error_report("Invalid cache option: %s", cache);
+ return -1;
+ }
+
/*
* Open the images.
*
* Ignore the old backing file for unsafe rebase in case we want to correct
* the reference to a renamed or moved backing file.
*/
- flags = BDRV_O_FLAGS | BDRV_O_RDWR | (unsafe ? BDRV_O_NO_BACKING : 0);
bs = bdrv_new_open(filename, fmt, flags);
if (!bs) {
return 1;
space. Use @code{qemu-img info} to know the real size used by the
image or @code{ls -ls} on Unix/Linux.
-@item host_device
-
-Host device format. This format should be used instead of raw when
-converting to block devices or other devices where "holes" are not
-supported.
-
@item qcow2
QEMU image format, the most versatile format. Use it to have smaller
images (useful if your filesystem does not supports holes, for example
#include "cpu-defs.h"
-#include <setjmp.h>
-
#include "softfloat.h"
#define TARGET_HAS_ICE 1
#include "cpu-defs.h"
-#include <setjmp.h>
-
#include "softfloat.h"
#define TARGET_HAS_ICE 1
#endif
}
-static inline int cpu_fpu_enabled(CPUState *env1)
-{
-#if defined(CONFIG_USER_ONLY)
- return 1;
-#elif !defined(TARGET_SPARC64)
- return env1->psref;
-#else
- return ((env1->pstate & PS_PEF) != 0) && ((env1->fprs & FPRS_FEF) != 0);
-#endif
-}
-
#if defined(CONFIG_USER_ONLY)
static inline void cpu_clone_regs(CPUState *env, target_ulong newsp)
{
trap_state* cpu_tsptr(CPUState* env);
#endif
+#define TB_FLAG_FPU_ENABLED (1 << 4)
+#define TB_FLAG_AM_ENABLED (1 << 5)
+
static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc,
target_ulong *cs_base, int *flags)
{
*cs_base = env->npc;
#ifdef TARGET_SPARC64
// AM . Combined FPU enable bits . PRIV . DMMU enabled . IMMU enabled
- *flags = ((env->pstate & PS_AM) << 2) /* 5 */
- | (((env->pstate & PS_PEF) >> 1) /* 3 */
- | ((env->fprs & FPRS_FEF) << 2)) /* 4 */
- | (env->pstate & PS_PRIV) /* 2 */
+ *flags = (env->pstate & PS_PRIV) /* 2 */
| ((env->lsu & (DMMU_E | IMMU_E)) >> 2) /* 1, 0 */
| ((env->tl & 0xff) << 8)
| (env->dmmu.mmu_primary_context << 16); /* 16... */
+ if (env->pstate & PS_AM) {
+ *flags |= TB_FLAG_AM_ENABLED;
+ }
+ if ((env->def->features & CPU_FEATURE_FLOAT) && (env->pstate & PS_PEF)
+ && (env->fprs & FPRS_FEF)) {
+ *flags |= TB_FLAG_FPU_ENABLED;
+ }
#else
// FPU enable . Supervisor
- *flags = (env->psref << 4) | env->psrs;
+ *flags = env->psrs;
+ if ((env->def->features & CPU_FEATURE_FLOAT) && env->psref) {
+ *flags |= TB_FLAG_FPU_ENABLED;
+ }
+#endif
+}
+
+static inline bool tb_fpu_enabled(int tb_flags)
+{
+#if defined(CONFIG_USER_ONLY)
+ return true;
+#else
+ return tb_flags & TB_FLAG_FPU_ENABLED;
+#endif
+}
+
+static inline bool tb_am_enabled(int tb_flags)
+{
+#ifndef TARGET_SPARC64
+ return false;
+#else
+ return tb_flags & TB_FLAG_AM_ENABLED;
#endif
}
void helper_ldf_asi(target_ulong addr, int asi, int size, int rd)
{
unsigned int i;
- target_ulong val;
+ CPU_DoubleU u;
helper_check_align(addr, 3);
addr = asi_address_mask(env, asi, addr);
switch (asi) {
- case 0xf0: // Block load primary
- case 0xf1: // Block load secondary
- case 0xf8: // Block load primary LE
- case 0xf9: // Block load secondary LE
+ case 0xf0: /* UA2007/JPS1 Block load primary */
+ case 0xf1: /* UA2007/JPS1 Block load secondary */
+ case 0xf8: /* UA2007/JPS1 Block load primary LE */
+ case 0xf9: /* UA2007/JPS1 Block load secondary LE */
if (rd & 7) {
raise_exception(TT_ILL_INSN);
return;
}
return;
- case 0x70: // Block load primary, user privilege
- case 0x71: // Block load secondary, user privilege
+ case 0x16: /* UA2007 Block load primary, user privilege */
+ case 0x17: /* UA2007 Block load secondary, user privilege */
+ case 0x1e: /* UA2007 Block load primary LE, user privilege */
+ case 0x1f: /* UA2007 Block load secondary LE, user privilege */
+ case 0x70: /* JPS1 Block load primary, user privilege */
+ case 0x71: /* JPS1 Block load secondary, user privilege */
+ case 0x78: /* JPS1 Block load primary LE, user privilege */
+ case 0x79: /* JPS1 Block load secondary LE, user privilege */
if (rd & 7) {
raise_exception(TT_ILL_INSN);
return;
}
helper_check_align(addr, 0x3f);
for (i = 0; i < 16; i++) {
- *(uint32_t *)&env->fpr[rd++] = helper_ld_asi(addr, asi & 0x1f, 4,
+ *(uint32_t *)&env->fpr[rd++] = helper_ld_asi(addr, asi & 0x19, 4,
0);
addr += 4;
}
break;
}
- val = helper_ld_asi(addr, asi, size, 0);
switch(size) {
default:
case 4:
- *((uint32_t *)&env->fpr[rd]) = val;
+ *((uint32_t *)&env->fpr[rd]) = helper_ld_asi(addr, asi, size, 0);
break;
case 8:
- *((int64_t *)&DT0) = val;
+ u.ll = helper_ld_asi(addr, asi, size, 0);
+ *((uint32_t *)&env->fpr[rd++]) = u.l.upper;
+ *((uint32_t *)&env->fpr[rd++]) = u.l.lower;
break;
case 16:
- // XXX
+ u.ll = helper_ld_asi(addr, asi, 8, 0);
+ *((uint32_t *)&env->fpr[rd++]) = u.l.upper;
+ *((uint32_t *)&env->fpr[rd++]) = u.l.lower;
+ u.ll = helper_ld_asi(addr + 8, asi, 8, 0);
+ *((uint32_t *)&env->fpr[rd++]) = u.l.upper;
+ *((uint32_t *)&env->fpr[rd++]) = u.l.lower;
break;
}
}
{
unsigned int i;
target_ulong val = 0;
+ CPU_DoubleU u;
helper_check_align(addr, 3);
addr = asi_address_mask(env, asi, addr);
switch (asi) {
- case 0xe0: // UA2007 Block commit store primary (cache flush)
- case 0xe1: // UA2007 Block commit store secondary (cache flush)
- case 0xf0: // Block store primary
- case 0xf1: // Block store secondary
- case 0xf8: // Block store primary LE
- case 0xf9: // Block store secondary LE
+ case 0xe0: /* UA2007/JPS1 Block commit store primary (cache flush) */
+ case 0xe1: /* UA2007/JPS1 Block commit store secondary (cache flush) */
+ case 0xf0: /* UA2007/JPS1 Block store primary */
+ case 0xf1: /* UA2007/JPS1 Block store secondary */
+ case 0xf8: /* UA2007/JPS1 Block store primary LE */
+ case 0xf9: /* UA2007/JPS1 Block store secondary LE */
if (rd & 7) {
raise_exception(TT_ILL_INSN);
return;
}
return;
- case 0x70: // Block store primary, user privilege
- case 0x71: // Block store secondary, user privilege
+ case 0x16: /* UA2007 Block load primary, user privilege */
+ case 0x17: /* UA2007 Block load secondary, user privilege */
+ case 0x1e: /* UA2007 Block load primary LE, user privilege */
+ case 0x1f: /* UA2007 Block load secondary LE, user privilege */
+ case 0x70: /* JPS1 Block store primary, user privilege */
+ case 0x71: /* JPS1 Block store secondary, user privilege */
+ case 0x78: /* JPS1 Block load primary LE, user privilege */
+ case 0x79: /* JPS1 Block load secondary LE, user privilege */
if (rd & 7) {
raise_exception(TT_ILL_INSN);
return;
helper_check_align(addr, 0x3f);
for (i = 0; i < 16; i++) {
val = *(uint32_t *)&env->fpr[rd++];
- helper_st_asi(addr, val, asi & 0x1f, 4);
+ helper_st_asi(addr, val, asi & 0x19, 4);
addr += 4;
}
switch(size) {
default:
case 4:
- val = *((uint32_t *)&env->fpr[rd]);
+ helper_st_asi(addr, *(uint32_t *)&env->fpr[rd], asi, size);
break;
case 8:
- val = *((int64_t *)&DT0);
+ u.l.upper = *(uint32_t *)&env->fpr[rd++];
+ u.l.lower = *(uint32_t *)&env->fpr[rd++];
+ helper_st_asi(addr, u.ll, asi, size);
break;
case 16:
- // XXX
+ u.l.upper = *(uint32_t *)&env->fpr[rd++];
+ u.l.lower = *(uint32_t *)&env->fpr[rd++];
+ helper_st_asi(addr, u.ll, asi, 8);
+ u.l.upper = *(uint32_t *)&env->fpr[rd++];
+ u.l.lower = *(uint32_t *)&env->fpr[rd++];
+ helper_st_asi(addr + 8, u.ll, asi, 8);
break;
}
- helper_st_asi(addr, val, asi, size);
}
target_ulong helper_cas_asi(target_ulong addr, target_ulong val1,
case 0x2d: /* V9 prefetch, no effect */
goto skip_move;
case 0x30: /* V9 ldfa */
+ if (gen_trap_ifnofpu(dc, cpu_cond)) {
+ goto jmp_insn;
+ }
save_state(dc, cpu_cond);
gen_ldf_asi(cpu_addr, insn, 4, rd);
goto skip_move;
case 0x33: /* V9 lddfa */
+ if (gen_trap_ifnofpu(dc, cpu_cond)) {
+ goto jmp_insn;
+ }
save_state(dc, cpu_cond);
gen_ldf_asi(cpu_addr, insn, 8, DFPREG(rd));
goto skip_move;
goto skip_move;
case 0x32: /* V9 ldqfa */
CHECK_FPU_FEATURE(dc, FLOAT128);
+ if (gen_trap_ifnofpu(dc, cpu_cond)) {
+ goto jmp_insn;
+ }
save_state(dc, cpu_cond);
gen_ldf_asi(cpu_addr, insn, 16, QFPREG(rd));
goto skip_move;
switch (xop) {
#ifdef TARGET_SPARC64
case 0x34: /* V9 stfa */
+ if (gen_trap_ifnofpu(dc, cpu_cond)) {
+ goto jmp_insn;
+ }
gen_stf_asi(cpu_addr, insn, 4, rd);
break;
case 0x36: /* V9 stqfa */
TCGv_i32 r_const;
CHECK_FPU_FEATURE(dc, FLOAT128);
+ if (gen_trap_ifnofpu(dc, cpu_cond)) {
+ goto jmp_insn;
+ }
r_const = tcg_const_i32(7);
gen_helper_check_align(cpu_addr, r_const);
tcg_temp_free_i32(r_const);
- gen_op_load_fpr_QT0(QFPREG(rd));
gen_stf_asi(cpu_addr, insn, 16, QFPREG(rd));
}
break;
case 0x37: /* V9 stdfa */
- gen_op_load_fpr_DT0(DFPREG(rd));
+ if (gen_trap_ifnofpu(dc, cpu_cond)) {
+ goto jmp_insn;
+ }
gen_stf_asi(cpu_addr, insn, 8, DFPREG(rd));
break;
case 0x3c: /* V9 casa */
dc->cc_op = CC_OP_DYNAMIC;
dc->mem_idx = cpu_mmu_index(env);
dc->def = env->def;
- if ((dc->def->features & CPU_FEATURE_FLOAT))
- dc->fpu_enabled = cpu_fpu_enabled(env);
- else
- dc->fpu_enabled = 0;
-#ifdef TARGET_SPARC64
- dc->address_mask_32bit = env->pstate & PS_AM;
-#endif
+ dc->fpu_enabled = tb_fpu_enabled(tb->flags);
+ dc->address_mask_32bit = tb_am_enabled(tb->flags);
dc->singlestep = (env->singlestep_enabled || singlestep);
gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
- Don't hesitate to use helpers for complicated or seldom used target
instructions. There is little performance advantage in using TCG to
implement target instructions taking more than about twenty TCG
- instructions.
+ instructions. Note that this rule of thumb is more applicable to
+ helpers doing complex logic or arithmetic, where the C compiler has
+ scope to do a good job of optimisation; it is less relevant where
+ the instruction is mostly doing loads and stores, and in those cases
+ inline TCG may still be faster for longer sequences.
+
+- The hard limit on the number of TCG instructions you can generate
+ per target instruction is set by MAX_OP_PER_INSTR in exec-all.h --
+ you cannot exceed this without risking a buffer overrun.
- Use the 'discard' instruction if you know that TCG won't be able to
prove that a given global is "dead" at a given program point. The
disable virtio_irq(void *vq) "vq %p"
disable virtio_notify(void *vdev, void *vq) "vdev %p vq %p"
+# hw/virtio-serial-bus.c
+disable virtio_serial_send_control_event(unsigned int port, uint16_t event, uint16_t value) "port %u, event %u, value %u"
+disable virtio_serial_throttle_port(unsigned int port, bool throttle) "port %u, throttle %d"
+disable virtio_serial_handle_control_message(uint16_t event, uint16_t value) "event %u, value %u"
+disable virtio_serial_handle_control_message_port(unsigned int port) "port %u"
+
+# hw/virtio-console.c
+disable virtio_console_flush_buf(unsigned int port, size_t len, ssize_t ret) "port %u, in_len %zu, out_len %zd"
+disable virtio_console_chr_read(unsigned int port, int size) "port %u, size %d"
+disable virtio_console_chr_event(unsigned int port, int event) "port %u, event %d"
+
# block.c
disable multiwrite_cb(void *mcb, int ret) "mcb %p ret %d"
disable bdrv_aio_multiwrite(void *mcb, int num_callbacks, int num_reqs) "mcb %p num_callbacks %d num_reqs %d"
qemu_opt_foreach(opts, add_channel, NULL, 0);
- spice_server_init(spice_server, &core_interface);
+ if (0 != spice_server_init(spice_server, &core_interface)) {
+ fprintf(stderr, "failed to initialize spice server");
+ exit(1);
+ };
using_spice = 1;
migration_state.notify = migration_state_notifier;
QXLCommand *cmd;
uint8_t *src, *dst;
int by, bw, bh;
+ struct timespec time_space;
if (qemu_spice_rect_is_empty(&ssd->dirty)) {
return NULL;
drawable->surfaces_dest[0] = -1;
drawable->surfaces_dest[1] = -1;
drawable->surfaces_dest[2] = -1;
+ clock_gettime(CLOCK_MONOTONIC, &time_space);
+ /* time in milliseconds from epoch. */
+ drawable->mm_time = time_space.tv_sec * 1000
+ + time_space.tv_nsec / 1000 / 1000;
drawable->u.copy.rop_descriptor = SPICE_ROPD_OP_PUT;
drawable->u.copy.src_bitmap = (intptr_t)image;