]> git.proxmox.com Git - mirror_qemu.git/commitdiff
Merge remote-tracking branch 'stefanha/block' into staging
authorAnthony Liguori <aliguori@amazon.com>
Sat, 7 Dec 2013 15:35:31 +0000 (07:35 -0800)
committerAnthony Liguori <aliguori@amazon.com>
Sat, 7 Dec 2013 15:35:31 +0000 (07:35 -0800)
# By Paolo Bonzini (17) and others
# Via Stefan Hajnoczi
* stefanha/block: (48 commits)
  qemu-iotests: filter QEMU monitor \r\n
  aio: make aio_poll(ctx, true) block with no fds
  block: clean up bdrv_drain_all() throttling comments
  qcow2: use start_of_cluster() and offset_into_cluster() everywhere
  qemu-img: decrease progress update interval on convert
  qemu-img: round down request length to an aligned sector
  qemu-img: dynamically adjust iobuffer size during convert
  block/iscsi: set bs->bl.opt_transfer_length
  block: add opt_transfer_length to BlockLimits
  block/iscsi: set bdi->cluster_size
  qemu-img: fix usage instruction for qemu-img convert
  qemu-img: add support for skipping zeroes in input during convert
  qemu-nbd: add doc for option -f
  qemu-iotests: add test for snapshot in qemu-img convert
  qemu-img: add -l for snapshot in convert
  qemu-iotests: add 058 internal snapshot export with qemu-nbd case
  qemu-nbd: support internal snapshot export
  snapshot: distinguish id and name in load_tmp
  qemu-iotests: Split qcow2 only cases in 048
  qemu-iotests: Clean up spaces in usage output
  ...

Message-id: 1386347807-27359-1-git-send-email-stefanha@redhat.com
Signed-off-by: Anthony Liguori <aliguori@amazon.com>
95 files changed:
.gitignore
exec.c
hw/char/cadence_uart.c
hw/display/vmware_vga.c
hw/i386/acpi-build.c
hw/i386/pc_piix.c
hw/i386/pc_q35.c
hw/net/virtio-net.c
hw/nvram/eeprom93xx.c
hw/ppc/mac.h
hw/ppc/ppc.c
hw/ppc/ppc405_uc.c
hw/ppc/ppc_booke.c
hw/scsi/scsi-bus.c
hw/timer/m48t59.c
hw/usb/bus.c
hw/usb/core.c
hw/usb/desc.c
hw/usb/desc.h
hw/usb/dev-hid.c
hw/usb/dev-uas.c
hw/usb/hcd-ehci.c
hw/usb/hcd-ehci.h
hw/usb/hcd-xhci.c
hw/xen/xen_pt.c
hw/xen/xen_pvdevice.c
include/elf.h
include/hw/char/serial.h
include/hw/pci/pci_ids.h
include/hw/ppc/ppc.h
include/hw/scsi/scsi.h
include/hw/usb.h
include/qemu/cache-utils.h
include/qemu/osdep.h
include/ui/console.h
kvm-all.c
libcacard/cac.c
libcacard/vcard_emul_nss.c
linux-user/aarch64/target_structs.h [new file with mode: 0644]
linux-user/alpha/target_structs.h [new file with mode: 0644]
linux-user/arm/target_structs.h [new file with mode: 0644]
linux-user/cris/target_structs.h [new file with mode: 0644]
linux-user/flatload.c
linux-user/i386/target_structs.h [new file with mode: 0644]
linux-user/m68k/target_structs.h [new file with mode: 0644]
linux-user/main.c
linux-user/microblaze/target_structs.h [new file with mode: 0644]
linux-user/mips/target_structs.h [new file with mode: 0644]
linux-user/mips64/target_cpu.h
linux-user/mips64/target_structs.h [new file with mode: 0644]
linux-user/openrisc/target_structs.h [new file with mode: 0644]
linux-user/ppc/target_structs.h [new file with mode: 0644]
linux-user/qemu.h
linux-user/s390x/target_structs.h [new file with mode: 0644]
linux-user/sh4/target_structs.h [new file with mode: 0644]
linux-user/sparc/target_structs.h [new file with mode: 0644]
linux-user/sparc64/target_structs.h [new file with mode: 0644]
linux-user/syscall.c
linux-user/syscall_defs.h
linux-user/unicore32/target_structs.h [new file with mode: 0644]
linux-user/x86_64/target_structs.h [new file with mode: 0644]
pc-bios/acpi-dsdt.aml
pc-bios/bios-256k.bin [new file with mode: 0644]
pc-bios/bios.bin
pc-bios/q35-acpi-dsdt.aml
pc-bios/vgabios-cirrus.bin
pc-bios/vgabios-qxl.bin
pc-bios/vgabios-stdvga.bin
pc-bios/vgabios-vmware.bin
pc-bios/vgabios.bin
qemu-options.hx
qemu-seccomp.c
qobject/qerror.c
roms/Makefile
roms/config.seabios [deleted file]
roms/config.seabios-128k [new file with mode: 0644]
roms/config.seabios-256k [new file with mode: 0644]
roms/seabios
target-alpha/cpu-qom.h
target-i386/cpu.c
target-mips/cpu.h
target-openrisc/cpu.h
target-sparc/cpu.h
tcg/arm/tcg-target.c
tcg/ppc64/tcg-target.c
tcg/s390/tcg-target.c
trace-events
ui/console.c
ui/gtk.c
ui/input.c
util/Makefile.objs
util/cache-utils.c
util/getauxval.c [new file with mode: 0644]
vl.c
xen-all.c

index 5584b5fcb0dbd039bf13af3c1992977e5afa08c5..1c9d63d65172c7c65aeefcfd0ca9e646f8a16c9b 100644 (file)
@@ -3,6 +3,7 @@ config-all-devices.*
 config-all-disas.*
 config-host.*
 config-target.*
+config.status
 trace/generated-tracers.h
 trace/generated-tracers.c
 trace/generated-tracers-dtrace.h
diff --git a/exec.c b/exec.c
index 95c4356c65a006e1f992e193bd19c45c9f593255..f4b9ef25f5c5bd8c3935fa46528dd63923f4b713 100644 (file)
--- a/exec.c
+++ b/exec.c
@@ -904,6 +904,13 @@ static long gethugepagesize(const char *path)
     return fs.f_bsize;
 }
 
+static sigjmp_buf sigjump;
+
+static void sigbus_handler(int signal)
+{
+    siglongjmp(sigjump, 1);
+}
+
 static void *file_ram_alloc(RAMBlock *block,
                             ram_addr_t memory,
                             const char *path)
@@ -913,9 +920,6 @@ static void *file_ram_alloc(RAMBlock *block,
     char *c;
     void *area;
     int fd;
-#ifdef MAP_POPULATE
-    int flags;
-#endif
     unsigned long hpagesize;
 
     hpagesize = gethugepagesize(path);
@@ -963,21 +967,52 @@ static void *file_ram_alloc(RAMBlock *block,
     if (ftruncate(fd, memory))
         perror("ftruncate");
 
-#ifdef MAP_POPULATE
-    /* NB: MAP_POPULATE won't exhaustively alloc all phys pages in the case
-     * MAP_PRIVATE is requested.  For mem_prealloc we mmap as MAP_SHARED
-     * to sidestep this quirk.
-     */
-    flags = mem_prealloc ? MAP_POPULATE | MAP_SHARED : MAP_PRIVATE;
-    area = mmap(0, memory, PROT_READ | PROT_WRITE, flags, fd, 0);
-#else
     area = mmap(0, memory, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
-#endif
     if (area == MAP_FAILED) {
         perror("file_ram_alloc: can't mmap RAM pages");
         close(fd);
         return (NULL);
     }
+
+    if (mem_prealloc) {
+        int ret, i;
+        struct sigaction act, oldact;
+        sigset_t set, oldset;
+
+        memset(&act, 0, sizeof(act));
+        act.sa_handler = &sigbus_handler;
+        act.sa_flags = 0;
+
+        ret = sigaction(SIGBUS, &act, &oldact);
+        if (ret) {
+            perror("file_ram_alloc: failed to install signal handler");
+            exit(1);
+        }
+
+        /* unblock SIGBUS */
+        sigemptyset(&set);
+        sigaddset(&set, SIGBUS);
+        pthread_sigmask(SIG_UNBLOCK, &set, &oldset);
+
+        if (sigsetjmp(sigjump, 1)) {
+            fprintf(stderr, "file_ram_alloc: failed to preallocate pages\n");
+            exit(1);
+        }
+
+        /* MAP_POPULATE silently ignores failures */
+        for (i = 0; i < (memory/hpagesize)-1; i++) {
+            memset(area + (hpagesize*i), 0, 1);
+        }
+
+        ret = sigaction(SIGBUS, &oldact, NULL);
+        if (ret) {
+            perror("file_ram_alloc: failed to reinstall signal handler");
+            exit(1);
+        }
+
+        pthread_sigmask(SIG_SETMASK, &oldset, NULL);
+    }
+
     block->fd = fd;
     return area;
 }
index f8ccbdd13a6d336d2dc9d4e9d40c8dfdeadcb980..f18db53bca11250e8839319371fdd1d39443a504 100644 (file)
@@ -120,8 +120,8 @@ typedef struct {
     uint64_t char_tx_time;
     CharDriverState *chr;
     qemu_irq irq;
-    struct QEMUTimer *fifo_trigger_handle;
-    struct QEMUTimer *tx_time_handle;
+    QEMUTimer *fifo_trigger_handle;
+    QEMUTimer *tx_time_handle;
 } UartState;
 
 static void uart_update_status(UartState *s)
index a6a8cdc2e18cd8f61052f5d76b7732aba5d3dbec..aba292ccde1630d89bec5042f13ea8bb7f6a5f6c 100644 (file)
@@ -23,6 +23,7 @@
  */
 #include "hw/hw.h"
 #include "hw/loader.h"
+#include "trace.h"
 #include "ui/console.h"
 #include "hw/pci/pci.h"
 
index 1f22fb60a4bd6ce1b9572634389d3785aac5e98d..befc39f253c7e65a1fbf5c22e7d2ada2b2ebf52e 100644 (file)
@@ -285,7 +285,8 @@ static inline void build_append_array(GArray *array, GArray *val)
     g_array_append_vals(array, val->data, val->len);
 }
 
-static void build_append_nameseg(GArray *array, const char *format, ...)
+static void GCC_FMT_ATTR(2, 3)
+build_append_nameseg(GArray *array, const char *format, ...)
 {
     /* It would be nicer to use g_string_vprintf but it's only there in 2.22 */
     char s[] = "XXXX";
@@ -630,7 +631,7 @@ build_append_notify(GArray *device, const char *name,
     GArray *method = build_alloc_array();
     uint8_t op = 0x14; /* MethodOp */
 
-    build_append_nameseg(method, name);
+    build_append_nameseg(method, "%s", name);
     build_append_byte(method, 0x02); /* MethodFlags: ArgCount */
     for (i = skip; i < count; i++) {
         GArray *target = build_alloc_array();
index 2111f0192ce0d6880aea2bbe7c8818e6da42f267..ab562853b89283f3b6bd769d5f9e382454f4f058 100644 (file)
@@ -339,13 +339,24 @@ static void pc_xen_hvm_init(QEMUMachineInitArgs *args)
     .desc = "Standard PC (i440FX + PIIX, 1996)", \
     .hot_add_cpu = pc_hot_add_cpu
 
+#define PC_I440FX_2_0_MACHINE_OPTIONS                           \
+    PC_I440FX_MACHINE_OPTIONS,                                  \
+    .default_machine_opts = "firmware=bios-256k.bin"
+
+static QEMUMachine pc_i440fx_machine_v2_0 = {
+    PC_I440FX_2_0_MACHINE_OPTIONS,
+    .name = "pc-i440fx-2.0",
+    .alias = "pc",
+    .init = pc_init_pci,
+    .is_default = 1,
+};
+
 #define PC_I440FX_1_7_MACHINE_OPTIONS PC_I440FX_MACHINE_OPTIONS
+
 static QEMUMachine pc_i440fx_machine_v1_7 = {
     PC_I440FX_1_7_MACHINE_OPTIONS,
     .name = "pc-i440fx-1.7",
-    .alias = "pc",
     .init = pc_init_pci,
-    .is_default = 1,
 };
 
 #define PC_I440FX_1_6_MACHINE_OPTIONS PC_I440FX_MACHINE_OPTIONS
@@ -747,6 +758,7 @@ static QEMUMachine xenfv_machine = {
 
 static void pc_machine_init(void)
 {
+    qemu_register_machine(&pc_i440fx_machine_v2_0);
     qemu_register_machine(&pc_i440fx_machine_v1_7);
     qemu_register_machine(&pc_i440fx_machine_v1_6);
     qemu_register_machine(&pc_i440fx_machine_v1_5);
index 600fc02ebe5faa96dcfba307cb6171316276241b..97aa84264c1b023e2450a1d8e3776a3fb2c69f98 100644 (file)
@@ -259,12 +259,22 @@ static void pc_q35_init_1_4(QEMUMachineInitArgs *args)
     .desc = "Standard PC (Q35 + ICH9, 2009)", \
     .hot_add_cpu = pc_hot_add_cpu
 
+#define PC_Q35_2_0_MACHINE_OPTIONS                      \
+    PC_Q35_MACHINE_OPTIONS,                             \
+    .default_machine_opts = "firmware=bios-256k.bin"
+
+static QEMUMachine pc_q35_machine_v2_0 = {
+    PC_Q35_2_0_MACHINE_OPTIONS,
+    .name = "pc-q35-2.0",
+    .alias = "q35",
+    .init = pc_q35_init,
+};
+
 #define PC_Q35_1_7_MACHINE_OPTIONS PC_Q35_MACHINE_OPTIONS
 
 static QEMUMachine pc_q35_machine_v1_7 = {
     PC_Q35_1_7_MACHINE_OPTIONS,
     .name = "pc-q35-1.7",
-    .alias = "q35",
     .init = pc_q35_init,
 };
 
@@ -306,6 +316,7 @@ static QEMUMachine pc_q35_machine_v1_4 = {
 
 static void pc_q35_machine_init(void)
 {
+    qemu_register_machine(&pc_q35_machine_v2_0);
     qemu_register_machine(&pc_q35_machine_v1_7);
     qemu_register_machine(&pc_q35_machine_v1_6);
     qemu_register_machine(&pc_q35_machine_v1_5);
index b75c753305f2bf697e98bf456c967440fbdc8627..90eca9a87efd2807079c66e48cf09cf21b4a6a48 100644 (file)
@@ -1428,7 +1428,7 @@ static NetClientInfo net_virtio_info = {
     .size = sizeof(NICState),
     .can_receive = virtio_net_can_receive,
     .receive = virtio_net_receive,
-        .cleanup = virtio_net_cleanup,
+    .cleanup = virtio_net_cleanup,
     .link_status_changed = virtio_net_set_link_status,
     .query_rx_filter = virtio_net_query_rxfilter,
 };
index 08f4df586cdf3b17ad9c14dfc05b1c2c29779d37..a98f924b817a4ca026804b8bf9dc8c535b6133cb 100644 (file)
@@ -126,7 +126,7 @@ static const VMStateDescription vmstate_eeprom = {
     .version_id = EEPROM_VERSION,
     .minimum_version_id = OLD_EEPROM_VERSION,
     .minimum_version_id_old = OLD_EEPROM_VERSION,
-    .fields      = (VMStateField []) {
+    .fields      = (VMStateField[]) {
         VMSTATE_UINT8(tick, eeprom_t),
         VMSTATE_UINT8(address, eeprom_t),
         VMSTATE_UINT8(command, eeprom_t),
@@ -157,13 +157,13 @@ void eeprom93xx_write(eeprom_t *eeprom, int eecs, int eesk, int eedi)
     logout("CS=%u SK=%u DI=%u DO=%u, tick = %u\n",
            eecs, eesk, eedi, eedo, tick);
 
-    if (! eeprom->eecs && eecs) {
+    if (!eeprom->eecs && eecs) {
         /* Start chip select cycle. */
         logout("Cycle start, waiting for 1st start bit (0)\n");
         tick = 0;
         command = 0x0;
         address = 0x0;
-    } else if (eeprom->eecs && ! eecs) {
+    } else if (eeprom->eecs && !eecs) {
         /* End chip select cycle. This triggers write / erase. */
         if (eeprom->writable) {
             uint8_t subcommand = address >> (eeprom->addrbits - 2);
@@ -189,7 +189,7 @@ void eeprom93xx_write(eeprom_t *eeprom, int eecs, int eesk, int eedi)
         }
         /* Output DO is tristate, read results in 1. */
         eedo = 1;
-    } else if (eecs && ! eeprom->eesk && eesk) {
+    } else if (eecs && !eeprom->eesk && eesk) {
         /* Raising edge of clock shifts data in. */
         if (tick == 0) {
             /* Wait for 1st start bit. */
@@ -230,20 +230,20 @@ void eeprom93xx_write(eeprom_t *eeprom, int eecs, int eesk, int eedi)
                 if (command == 0) {
                     /* Command code in upper 2 bits of address. */
                     switch (address >> (eeprom->addrbits - 2)) {
-                        case 0:
-                            logout("write disable command\n");
-                            eeprom->writable = 0;
-                            break;
-                        case 1:
-                            logout("write all command\n");
-                            break;
-                        case 2:
-                            logout("erase all command\n");
-                            break;
-                        case 3:
-                            logout("write enable command\n");
-                            eeprom->writable = 1;
-                            break;
+                    case 0:
+                        logout("write disable command\n");
+                        eeprom->writable = 0;
+                        break;
+                    case 1:
+                        logout("write all command\n");
+                        break;
+                    case 2:
+                        logout("erase all command\n");
+                        break;
+                    case 3:
+                        logout("write enable command\n");
+                        eeprom->writable = 1;
+                        break;
                     }
                 } else {
                     /* Read, write or erase word. */
@@ -276,7 +276,7 @@ uint16_t eeprom93xx_read(eeprom_t *eeprom)
 {
     /* Return status of pin DO (0 or 1). */
     logout("CS=%u DO=%u\n", eeprom->eecs, eeprom->eedo);
-    return (eeprom->eedo);
+    return eeprom->eedo;
 }
 
 #if 0
@@ -296,18 +296,18 @@ eeprom_t *eeprom93xx_new(DeviceState *dev, uint16_t nwords)
     uint8_t addrbits;
 
     switch (nwords) {
-        case 16:
-        case 64:
-            addrbits = 6;
-            break;
-        case 128:
-        case 256:
-            addrbits = 8;
-            break;
-        default:
-            assert(!"Unsupported EEPROM size, fallback to 64 words!");
-            nwords = 64;
-            addrbits = 6;
+    case 16:
+    case 64:
+        addrbits = 6;
+        break;
+    case 128:
+    case 256:
+        addrbits = 8;
+        break;
+    default:
+        assert(!"Unsupported EEPROM size, fallback to 64 words!");
+        nwords = 64;
+        addrbits = 6;
     }
 
     eeprom = (eeprom_t *)g_malloc0(sizeof(*eeprom) + nwords * 2);
index 1e578dd59dacc9d6f83f4795acabe9f95cabadbb..c1faf9ce27f7349c5fb4da342f1bed31b0d2fce1 100644 (file)
@@ -34,7 +34,6 @@
 #define MAX_CPUS 1
 
 #define BIOS_SIZE     (1024 * 1024)
-#define BIOS_FILENAME "ppc_rom.bin"
 #define NVRAM_SIZE        0x2000
 #define PROM_FILENAME    "openbios-ppc"
 #define PROM_ADDR         0xfff00000
index bf2d3d4b350430b98bb358cd648d9d0cf61f42f8..114be64480a086f852e6a3d5938d258307affdef 100644 (file)
@@ -684,7 +684,7 @@ static inline void cpu_ppc_hdecr_excp(PowerPCCPU *cpu)
 }
 
 static void __cpu_ppc_store_decr(PowerPCCPU *cpu, uint64_t *nextp,
-                                 struct QEMUTimer *timer,
+                                 QEMUTimer *timer,
                                  void (*raise_excp)(PowerPCCPU *),
                                  uint32_t decr, uint32_t value,
                                  int is_excp)
@@ -856,9 +856,9 @@ typedef struct ppc40x_timer_t ppc40x_timer_t;
 struct ppc40x_timer_t {
     uint64_t pit_reload;  /* PIT auto-reload value        */
     uint64_t fit_next;    /* Tick for next FIT interrupt  */
-    struct QEMUTimer *fit_timer;
+    QEMUTimer *fit_timer;
     uint64_t wdt_next;    /* Tick for next WDT interrupt  */
-    struct QEMUTimer *wdt_timer;
+    QEMUTimer *wdt_timer;
 
     /* 405 have the PIT, 440 have a DECR.  */
     unsigned int decr_excp;
index 6d6a7f12033bedd71776f67a55f5e2eaeb2e1350..8109f9220046dc762e6bc3e6a366335bd3b39fea 100644 (file)
@@ -1234,7 +1234,7 @@ struct ppc4xx_gpt_t {
     MemoryRegion iomem;
     int64_t tb_offset;
     uint32_t tb_freq;
-    struct QEMUTimer *timer;
+    QEMUTimer *timer;
     qemu_irq irqs[5];
     uint32_t oe;
     uint32_t ol;
index b421620708eec9829382c280fa15befb25dbbdf2..d8399602d63c8e5802b1c2b076c64e6b7bf0ec70 100644 (file)
@@ -64,10 +64,10 @@ typedef struct booke_timer_t booke_timer_t;
 struct booke_timer_t {
 
     uint64_t fit_next;
-    struct QEMUTimer *fit_timer;
+    QEMUTimer *fit_timer;
 
     uint64_t wdt_next;
-    struct QEMUTimer *wdt_timer;
+    QEMUTimer *wdt_timer;
 
     uint32_t flags;
 };
index ea916d14663674a446441b80807ebdb58038d5b9..3e5e31da8fd9c18e31685c34e234b4ef9317f112 100644 (file)
@@ -1293,6 +1293,11 @@ const struct SCSISense sense_code_ILLEGAL_REQ_REMOVAL_PREVENTED = {
     .key = ILLEGAL_REQUEST, .asc = 0x53, .ascq = 0x02
 };
 
+/* Illegal request, Invalid Transfer Tag */
+const struct SCSISense sense_code_INVALID_TAG = {
+    .key = ILLEGAL_REQUEST, .asc = 0x4b, .ascq = 0x01
+};
+
 /* Command aborted, I/O process terminated */
 const struct SCSISense sense_code_IO_ERROR = {
     .key = ABORTED_COMMAND, .asc = 0x00, .ascq = 0x06
@@ -1308,6 +1313,11 @@ const struct SCSISense sense_code_LUN_FAILURE = {
     .key = ABORTED_COMMAND, .asc = 0x3e, .ascq = 0x01
 };
 
+/* Command aborted, Overlapped Commands Attempted */
+const struct SCSISense sense_code_OVERLAPPED_COMMANDS = {
+    .key = ABORTED_COMMAND, .asc = 0x4e, .ascq = 0x00
+};
+
 /* Unit attention, Capacity data has changed */
 const struct SCSISense sense_code_CAPACITY_CHANGED = {
     .key = UNIT_ATTENTION, .asc = 0x2a, .ascq = 0x09
index d3d78ec5a87903a30ca7f9e0567acd204566d402..be0592b53dcb8d4f0cb4bb18092faa262e66aa19 100644 (file)
@@ -61,8 +61,8 @@ struct M48t59State {
     time_t   stop_time;
     /* Alarm & watchdog */
     struct tm alarm;
-    struct QEMUTimer *alrm_timer;
-    struct QEMUTimer *wd_timer;
+    QEMUTimer *alrm_timer;
+    QEMUTimer *wd_timer;
     /* NVRAM storage */
     uint8_t *buffer;
     /* Model parameters */
index ca329bef295ffbc090750c68ad79ff799c41f463..09848c632000920cf17cdc4531dc849bebd135dd 100644 (file)
@@ -203,6 +203,24 @@ void usb_device_ep_stopped(USBDevice *dev, USBEndpoint *ep)
     }
 }
 
+int usb_device_alloc_streams(USBDevice *dev, USBEndpoint **eps, int nr_eps,
+                             int streams)
+{
+    USBDeviceClass *klass = USB_DEVICE_GET_CLASS(dev);
+    if (klass->alloc_streams) {
+        return klass->alloc_streams(dev, eps, nr_eps, streams);
+    }
+    return 0;
+}
+
+void usb_device_free_streams(USBDevice *dev, USBEndpoint **eps, int nr_eps)
+{
+    USBDeviceClass *klass = USB_DEVICE_GET_CLASS(dev);
+    if (klass->free_streams) {
+        klass->free_streams(dev, eps, nr_eps);
+    }
+}
+
 static int usb_qdev_init(DeviceState *qdev)
 {
     USBDevice *dev = USB_DEVICE(qdev);
index cf59a1abcf2ac2aa3c9b371bd3d9af1727dc3470..67ba7d6018fb772a80faf7a4e8b13781220000ba 100644 (file)
@@ -623,6 +623,7 @@ void usb_ep_reset(USBDevice *dev)
     dev->ep_ctl.type = USB_ENDPOINT_XFER_CONTROL;
     dev->ep_ctl.ifnum = 0;
     dev->ep_ctl.max_packet_size = 64;
+    dev->ep_ctl.max_streams = 0;
     dev->ep_ctl.dev = dev;
     dev->ep_ctl.pipeline = false;
     for (ep = 0; ep < USB_MAX_ENDPOINTS; ep++) {
@@ -636,6 +637,8 @@ void usb_ep_reset(USBDevice *dev)
         dev->ep_out[ep].ifnum = USB_INTERFACE_INVALID;
         dev->ep_in[ep].max_packet_size = 0;
         dev->ep_out[ep].max_packet_size = 0;
+        dev->ep_in[ep].max_streams = 0;
+        dev->ep_out[ep].max_streams = 0;
         dev->ep_in[ep].dev = dev;
         dev->ep_out[ep].dev = dev;
         dev->ep_in[ep].pipeline = false;
@@ -764,6 +767,25 @@ int usb_ep_get_max_packet_size(USBDevice *dev, int pid, int ep)
     return uep->max_packet_size;
 }
 
+void usb_ep_set_max_streams(USBDevice *dev, int pid, int ep, uint8_t raw)
+{
+    struct USBEndpoint *uep = usb_ep_get(dev, pid, ep);
+    int MaxStreams;
+
+    MaxStreams = raw & 0x1f;
+    if (MaxStreams) {
+        uep->max_streams = 1 << MaxStreams;
+    } else {
+        uep->max_streams = 0;
+    }
+}
+
+int usb_ep_get_max_streams(USBDevice *dev, int pid, int ep)
+{
+    struct USBEndpoint *uep = usb_ep_get(dev, pid, ep);
+    return uep->max_streams;
+}
+
 void usb_ep_set_pipeline(USBDevice *dev, int pid, int ep, bool enabled)
 {
     struct USBEndpoint *uep = usb_ep_get(dev, pid, ep);
index bf6c522682b2fdf4c48d7580924f4dea7afee8a7..f18a0435003a8f4442b98bfc14dbfa85459a07bf 100644 (file)
@@ -6,16 +6,6 @@
 
 /* ------------------------------------------------------------------ */
 
-static uint8_t usb_lo(uint16_t val)
-{
-    return val & 0xff;
-}
-
-static uint8_t usb_hi(uint16_t val)
-{
-    return (val >> 8) & 0xff;
-}
-
 int usb_desc_device(const USBDescID *id, const USBDescDevice *dev,
                     uint8_t *dest, size_t len)
 {
@@ -385,6 +375,8 @@ static void usb_desc_ep_init(USBDevice *dev)
             usb_ep_set_ifnum(dev, pid, ep, iface->bInterfaceNumber);
             usb_ep_set_max_packet_size(dev, pid, ep,
                                        iface->eps[e].wMaxPacketSize);
+            usb_ep_set_max_streams(dev, pid, ep,
+                                   iface->eps[e].bmAttributes_super);
         }
     }
 }
index ddd3e7485c7c1887b163914ec403360c877b9f1e..81327b0e74986affaef49121cfa0a72de7ec62a2 100644 (file)
@@ -194,6 +194,17 @@ struct USBDesc {
 
 #define USB_DESC_FLAG_SUPER (1 << 1)
 
+/* little helpers */
+static inline uint8_t usb_lo(uint16_t val)
+{
+    return val & 0xff;
+}
+
+static inline uint8_t usb_hi(uint16_t val)
+{
+    return (val >> 8) & 0xff;
+}
+
 /* generate usb packages from structs */
 int usb_desc_device(const USBDescID *id, const USBDescDevice *dev,
                     uint8_t *dest, size_t len);
index 59567200ae063ecd0eb5996d93c1f44ed9cecef9..5e667f01999b7934f0a2d2a6852d5af2574a6593 100644 (file)
@@ -236,7 +236,7 @@ static const USBDescDevice desc_device_tablet2 = {
             .bNumInterfaces        = 1,
             .bConfigurationValue   = 1,
             .iConfiguration        = STR_CONFIG_TABLET,
-            .bmAttributes          = 0x80,
+            .bmAttributes          = 0xa0,
             .bMaxPower             = 50,
             .nif = 1,
             .ifs = &desc_iface_tablet2,
index 70ed2d1dbd2a61a2808384c9b46041ca187d902f..997b715952f688faef912a874b0b002055972086 100644 (file)
@@ -55,7 +55,7 @@ typedef struct {
     uint8_t    id;
     uint8_t    reserved;
     uint16_t   tag;
-} QEMU_PACKED  uas_ui_header;
+} QEMU_PACKED  uas_iu_header;
 
 typedef struct {
     uint8_t    prio_taskattr;   /* 6:3 priority, 2:0 task attribute   */
@@ -65,7 +65,7 @@ typedef struct {
     uint64_t   lun;
     uint8_t    cdb[16];
     uint8_t    add_cdb[];
-} QEMU_PACKED  uas_ui_command;
+} QEMU_PACKED  uas_iu_command;
 
 typedef struct {
     uint16_t   status_qualifier;
@@ -73,29 +73,29 @@ typedef struct {
     uint8_t    reserved[7];
     uint16_t   sense_length;
     uint8_t    sense_data[18];
-} QEMU_PACKED  uas_ui_sense;
+} QEMU_PACKED  uas_iu_sense;
 
 typedef struct {
-    uint16_t   add_response_info;
+    uint8_t    add_response_info[3];
     uint8_t    response_code;
-} QEMU_PACKED  uas_ui_response;
+} QEMU_PACKED  uas_iu_response;
 
 typedef struct {
     uint8_t    function;
     uint8_t    reserved;
     uint16_t   task_tag;
     uint64_t   lun;
-} QEMU_PACKED  uas_ui_task_mgmt;
+} QEMU_PACKED  uas_iu_task_mgmt;
 
 typedef struct {
-    uas_ui_header  hdr;
+    uas_iu_header  hdr;
     union {
-        uas_ui_command   command;
-        uas_ui_sense     sense;
-        uas_ui_task_mgmt task;
-        uas_ui_response  response;
+        uas_iu_command   command;
+        uas_iu_sense     sense;
+        uas_iu_task_mgmt task;
+        uas_iu_response  response;
     };
-} QEMU_PACKED  uas_ui;
+} QEMU_PACKED  uas_iu;
 
 /* --------------------------------------------------------------------- */
 
@@ -122,8 +122,8 @@ struct UASDevice {
     UASRequest                *dataout2;
 
     /* usb 3.0 only */
-    USBPacket                 *data3[UAS_MAX_STREAMS];
-    USBPacket                 *status3[UAS_MAX_STREAMS];
+    USBPacket                 *data3[UAS_MAX_STREAMS + 1];
+    USBPacket                 *status3[UAS_MAX_STREAMS + 1];
 };
 
 struct UASRequest {
@@ -145,7 +145,7 @@ struct UASRequest {
 
 struct UASStatus {
     uint32_t                  stream;
-    uas_ui                    status;
+    uas_iu                    status;
     uint32_t                  length;
     QTAILQ_ENTRY(UASStatus)   next;
 };
@@ -338,7 +338,7 @@ static UASStatus *usb_uas_alloc_status(UASDevice *uas, uint8_t id, uint16_t tag)
 
     st->status.hdr.id = id;
     st->status.hdr.tag = cpu_to_be16(tag);
-    st->length = sizeof(uas_ui_header);
+    st->length = sizeof(uas_iu_header);
     if (uas_using_streams(uas)) {
         st->stream = tag;
     }
@@ -392,15 +392,13 @@ static void usb_uas_queue_status(UASDevice *uas, UASStatus *st, int length)
     }
 }
 
-static void usb_uas_queue_response(UASDevice *uas, uint16_t tag,
-                                   uint8_t code, uint16_t add_info)
+static void usb_uas_queue_response(UASDevice *uas, uint16_t tag, uint8_t code)
 {
     UASStatus *st = usb_uas_alloc_status(uas, UAS_UI_RESPONSE, tag);
 
     trace_usb_uas_response(uas->dev.addr, tag, code);
     st->status.response.response_code = code;
-    st->status.response.add_response_info = cpu_to_be16(add_info);
-    usb_uas_queue_status(uas, st, sizeof(uas_ui_response));
+    usb_uas_queue_status(uas, st, sizeof(uas_iu_response));
 }
 
 static void usb_uas_queue_sense(UASRequest *req, uint8_t status)
@@ -416,10 +414,28 @@ static void usb_uas_queue_sense(UASRequest *req, uint8_t status)
                                   sizeof(st->status.sense.sense_data));
         st->status.sense.sense_length = cpu_to_be16(slen);
     }
-    len = sizeof(uas_ui_sense) - sizeof(st->status.sense.sense_data) + slen;
+    len = sizeof(uas_iu_sense) - sizeof(st->status.sense.sense_data) + slen;
     usb_uas_queue_status(req->uas, st, len);
 }
 
+static void usb_uas_queue_fake_sense(UASDevice *uas, uint16_t tag,
+                                     struct SCSISense sense)
+{
+    UASStatus *st = usb_uas_alloc_status(uas, UAS_UI_SENSE, tag);
+    int len, slen = 0;
+
+    st->status.sense.status = CHECK_CONDITION;
+    st->status.sense.status_qualifier = cpu_to_be16(0);
+    st->status.sense.sense_data[0] = 0x70;
+    st->status.sense.sense_data[2] = sense.key;
+    st->status.sense.sense_data[7] = 10;
+    st->status.sense.sense_data[12] = sense.asc;
+    st->status.sense.sense_data[13] = sense.ascq;
+    slen = 18;
+    len = sizeof(uas_iu_sense) - sizeof(st->status.sense.sense_data) + slen;
+    usb_uas_queue_status(uas, st, len);
+}
+
 static void usb_uas_queue_read_ready(UASRequest *req)
 {
     UASStatus *st = usb_uas_alloc_status(req->uas, UAS_UI_READ_READY,
@@ -518,14 +534,14 @@ static void usb_uas_start_next_transfer(UASDevice *uas)
     }
 }
 
-static UASRequest *usb_uas_alloc_request(UASDevice *uas, uas_ui *ui)
+static UASRequest *usb_uas_alloc_request(UASDevice *uas, uas_iu *iu)
 {
     UASRequest *req;
 
     req = g_new0(UASRequest, 1);
     req->uas = uas;
-    req->tag = be16_to_cpu(ui->hdr.tag);
-    req->lun = be64_to_cpu(ui->command.lun);
+    req->tag = be16_to_cpu(iu->hdr.tag);
+    req->lun = be64_to_cpu(iu->command.lun);
     req->dev = usb_uas_get_dev(req->uas, req->lun);
     return req;
 }
@@ -648,7 +664,7 @@ static void usb_uas_cancel_io(USBDevice *dev, USBPacket *p)
         return;
     }
     if (uas_using_streams(uas)) {
-        for (i = 0; i < UAS_MAX_STREAMS; i++) {
+        for (i = 0; i <= UAS_MAX_STREAMS; i++) {
             if (uas->status3[i] == p) {
                 uas->status3[i] = NULL;
                 return;
@@ -668,16 +684,20 @@ static void usb_uas_cancel_io(USBDevice *dev, USBPacket *p)
     assert(!"canceled usb packet not found");
 }
 
-static void usb_uas_command(UASDevice *uas, uas_ui *ui)
+static void usb_uas_command(UASDevice *uas, uas_iu *iu)
 {
     UASRequest *req;
     uint32_t len;
+    uint16_t tag = be16_to_cpu(iu->hdr.tag);
 
-    req = usb_uas_find_request(uas, be16_to_cpu(ui->hdr.tag));
+    if (uas_using_streams(uas) && tag > UAS_MAX_STREAMS) {
+        goto invalid_tag;
+    }
+    req = usb_uas_find_request(uas, tag);
     if (req) {
         goto overlapped_tag;
     }
-    req = usb_uas_alloc_request(uas, ui);
+    req = usb_uas_alloc_request(uas, iu);
     if (req->dev == NULL) {
         goto bad_target;
     }
@@ -694,7 +714,7 @@ static void usb_uas_command(UASDevice *uas, uas_ui *ui)
 
     req->req = scsi_req_new(req->dev, req->tag,
                             usb_uas_get_lun(req->lun),
-                            ui->command.cdb, req);
+                            iu->command.cdb, req);
     if (uas->requestlog) {
         scsi_req_print(req->req);
     }
@@ -705,105 +725,97 @@ static void usb_uas_command(UASDevice *uas, uas_ui *ui)
     }
     return;
 
+invalid_tag:
+    usb_uas_queue_fake_sense(uas, tag, sense_code_INVALID_TAG);
+    return;
+
 overlapped_tag:
-    usb_uas_queue_response(uas, req->tag, UAS_RC_OVERLAPPED_TAG, 0);
+    usb_uas_queue_fake_sense(uas, tag, sense_code_OVERLAPPED_COMMANDS);
     return;
 
 bad_target:
-    /*
-     * FIXME: Seems to upset linux, is this wrong?
-     * NOTE: Happens only with no scsi devices at the bus, not sure
-     *       this is a valid UAS setup in the first place.
-     */
-    usb_uas_queue_response(uas, req->tag, UAS_RC_INVALID_INFO_UNIT, 0);
+    usb_uas_queue_fake_sense(uas, tag, sense_code_LUN_NOT_SUPPORTED);
     g_free(req);
 }
 
-static void usb_uas_task(UASDevice *uas, uas_ui *ui)
+static void usb_uas_task(UASDevice *uas, uas_iu *iu)
 {
-    uint16_t tag = be16_to_cpu(ui->hdr.tag);
-    uint64_t lun64 = be64_to_cpu(ui->task.lun);
+    uint16_t tag = be16_to_cpu(iu->hdr.tag);
+    uint64_t lun64 = be64_to_cpu(iu->task.lun);
     SCSIDevice *dev = usb_uas_get_dev(uas, lun64);
     int lun = usb_uas_get_lun(lun64);
     UASRequest *req;
     uint16_t task_tag;
 
-    req = usb_uas_find_request(uas, be16_to_cpu(ui->hdr.tag));
+    if (uas_using_streams(uas) && tag > UAS_MAX_STREAMS) {
+        goto invalid_tag;
+    }
+    req = usb_uas_find_request(uas, be16_to_cpu(iu->hdr.tag));
     if (req) {
         goto overlapped_tag;
     }
+    if (dev == NULL) {
+        goto incorrect_lun;
+    }
 
-    switch (ui->task.function) {
+    switch (iu->task.function) {
     case UAS_TMF_ABORT_TASK:
-        task_tag = be16_to_cpu(ui->task.task_tag);
+        task_tag = be16_to_cpu(iu->task.task_tag);
         trace_usb_uas_tmf_abort_task(uas->dev.addr, tag, task_tag);
-        if (dev == NULL) {
-            goto bad_target;
-        }
-        if (dev->lun != lun) {
-            goto incorrect_lun;
-        }
         req = usb_uas_find_request(uas, task_tag);
         if (req && req->dev == dev) {
             scsi_req_cancel(req->req);
         }
-        usb_uas_queue_response(uas, tag, UAS_RC_TMF_COMPLETE, 0);
+        usb_uas_queue_response(uas, tag, UAS_RC_TMF_COMPLETE);
         break;
 
     case UAS_TMF_LOGICAL_UNIT_RESET:
         trace_usb_uas_tmf_logical_unit_reset(uas->dev.addr, tag, lun);
-        if (dev == NULL) {
-            goto bad_target;
-        }
-        if (dev->lun != lun) {
-            goto incorrect_lun;
-        }
         qdev_reset_all(&dev->qdev);
-        usb_uas_queue_response(uas, tag, UAS_RC_TMF_COMPLETE, 0);
+        usb_uas_queue_response(uas, tag, UAS_RC_TMF_COMPLETE);
         break;
 
     default:
-        trace_usb_uas_tmf_unsupported(uas->dev.addr, tag, ui->task.function);
-        usb_uas_queue_response(uas, tag, UAS_RC_TMF_NOT_SUPPORTED, 0);
+        trace_usb_uas_tmf_unsupported(uas->dev.addr, tag, iu->task.function);
+        usb_uas_queue_response(uas, tag, UAS_RC_TMF_NOT_SUPPORTED);
         break;
     }
     return;
 
-overlapped_tag:
-    usb_uas_queue_response(uas, req->tag, UAS_RC_OVERLAPPED_TAG, 0);
+invalid_tag:
+    usb_uas_queue_response(uas, tag, UAS_RC_INVALID_INFO_UNIT);
     return;
 
-bad_target:
-    /* FIXME: correct?  [see long comment in usb_uas_command()] */
-    usb_uas_queue_response(uas, tag, UAS_RC_INVALID_INFO_UNIT, 0);
+overlapped_tag:
+    usb_uas_queue_response(uas, req->tag, UAS_RC_OVERLAPPED_TAG);
     return;
 
 incorrect_lun:
-    usb_uas_queue_response(uas, tag, UAS_RC_INCORRECT_LUN, 0);
+    usb_uas_queue_response(uas, tag, UAS_RC_INCORRECT_LUN);
 }
 
 static void usb_uas_handle_data(USBDevice *dev, USBPacket *p)
 {
     UASDevice *uas = DO_UPCAST(UASDevice, dev, dev);
-    uas_ui ui;
+    uas_iu iu;
     UASStatus *st;
     UASRequest *req;
     int length;
 
     switch (p->ep->nr) {
     case UAS_PIPE_ID_COMMAND:
-        length = MIN(sizeof(ui), p->iov.size);
-        usb_packet_copy(p, &ui, length);
-        switch (ui.hdr.id) {
+        length = MIN(sizeof(iu), p->iov.size);
+        usb_packet_copy(p, &iu, length);
+        switch (iu.hdr.id) {
         case UAS_UI_COMMAND:
-            usb_uas_command(uas, &ui);
+            usb_uas_command(uas, &iu);
             break;
         case UAS_UI_TASK_MGMT:
-            usb_uas_task(uas, &ui);
+            usb_uas_task(uas, &iu);
             break;
         default:
-            fprintf(stderr, "%s: unknown command ui: id 0x%x\n",
-                    __func__, ui.hdr.id);
+            fprintf(stderr, "%s: unknown command iu: id 0x%x\n",
+                    __func__, iu.hdr.id);
             p->status = USB_RET_STALL;
             break;
         }
index 22bdbf4a7d9d8c610329681f3954bbc35310fd12..355bbd6bed1cc7a38540b092a402347dd7ec889c 100644 (file)
@@ -28,6 +28,7 @@
  */
 
 #include "hw/usb/hcd-ehci.h"
+#include "trace.h"
 
 /* Capability Registers Base Address - section 2.2 */
 #define CAPLENGTH        0x0000  /* 1-byte, 0x0001 reserved */
@@ -826,9 +827,9 @@ static void ehci_child_detach(USBPort *port, USBDevice *child)
 static void ehci_wakeup(USBPort *port)
 {
     EHCIState *s = port->opaque;
-    uint32_t portsc = s->portsc[port->index];
+    uint32_t *portsc = &s->portsc[port->index];
 
-    if (portsc & PORTSC_POWNER) {
+    if (*portsc & PORTSC_POWNER) {
         USBPort *companion = s->companion_ports[port->index];
         if (companion->ops->wakeup) {
             companion->ops->wakeup(companion);
@@ -836,6 +837,12 @@ static void ehci_wakeup(USBPort *port)
         return;
     }
 
+    if (*portsc & PORTSC_SUSPEND) {
+        trace_usb_ehci_port_wakeup(port->index);
+        *portsc |= PORTSC_FPRES;
+        ehci_raise_irq(s, USBSTS_PCD);
+    }
+
     qemu_bh_schedule(s->async_bh);
 }
 
@@ -1067,6 +1074,14 @@ static void ehci_port_write(void *ptr, hwaddr addr,
         }
     }
 
+    if ((val & PORTSC_SUSPEND) && !(*portsc & PORTSC_SUSPEND)) {
+        trace_usb_ehci_port_suspend(port);
+    }
+    if (!(val & PORTSC_FPRES) && (*portsc & PORTSC_FPRES)) {
+        trace_usb_ehci_port_resume(port);
+        val &= ~PORTSC_SUSPEND;
+    }
+
     *portsc &= ~PORTSC_RO_MASK;
     *portsc |= val;
     trace_usb_ehci_portsc_change(addr + s->portscbase, addr >> 2, *portsc, old);
index 065c9fa7415752039a4021166d737e2bad80757d..1ad4b96cce3f8ae9bb10f1c12f41c951577b582c 100644 (file)
@@ -21,7 +21,6 @@
 #include "qemu/timer.h"
 #include "hw/usb.h"
 #include "monitor/monitor.h"
-#include "trace.h"
 #include "sysemu/dma.h"
 #include "sysemu/sysemu.h"
 #include "hw/pci/pci.h"
index 835f65ed81602b7fe132bb874d16d4f4b2f7b8c4..bafe08590b02f9c3b1243807765c891981bd3831 100644 (file)
@@ -1150,6 +1150,111 @@ static void xhci_free_streams(XHCIEPContext *epctx)
     epctx->nr_pstreams = 0;
 }
 
+static int xhci_epmask_to_eps_with_streams(XHCIState *xhci,
+                                           unsigned int slotid,
+                                           uint32_t epmask,
+                                           XHCIEPContext **epctxs,
+                                           USBEndpoint **eps)
+{
+    XHCISlot *slot;
+    XHCIEPContext *epctx;
+    USBEndpoint *ep;
+    int i, j;
+
+    assert(slotid >= 1 && slotid <= xhci->numslots);
+
+    slot = &xhci->slots[slotid - 1];
+
+    for (i = 2, j = 0; i <= 31; i++) {
+        if (!(epmask & (1 << i))) {
+            continue;
+        }
+
+        epctx = slot->eps[i - 1];
+        ep = xhci_epid_to_usbep(xhci, slotid, i);
+        if (!epctx || !epctx->nr_pstreams || !ep) {
+            continue;
+        }
+
+        if (epctxs) {
+            epctxs[j] = epctx;
+        }
+        eps[j++] = ep;
+    }
+    return j;
+}
+
+static void xhci_free_device_streams(XHCIState *xhci, unsigned int slotid,
+                                     uint32_t epmask)
+{
+    USBEndpoint *eps[30];
+    int nr_eps;
+
+    nr_eps = xhci_epmask_to_eps_with_streams(xhci, slotid, epmask, NULL, eps);
+    if (nr_eps) {
+        usb_device_free_streams(eps[0]->dev, eps, nr_eps);
+    }
+}
+
+static TRBCCode xhci_alloc_device_streams(XHCIState *xhci, unsigned int slotid,
+                                          uint32_t epmask)
+{
+    XHCIEPContext *epctxs[30];
+    USBEndpoint *eps[30];
+    int i, r, nr_eps, req_nr_streams, dev_max_streams;
+
+    nr_eps = xhci_epmask_to_eps_with_streams(xhci, slotid, epmask, epctxs,
+                                             eps);
+    if (nr_eps == 0) {
+        return CC_SUCCESS;
+    }
+
+    req_nr_streams = epctxs[0]->nr_pstreams;
+    dev_max_streams = eps[0]->max_streams;
+
+    for (i = 1; i < nr_eps; i++) {
+        /*
+         * HdG: I don't expect these to ever trigger, but if they do we need
+         * to come up with another solution, ie group identical endpoints
+         * together and make an usb_device_alloc_streams call per group.
+         */
+        if (epctxs[i]->nr_pstreams != req_nr_streams) {
+            FIXME("guest streams config not identical for all eps");
+            return CC_RESOURCE_ERROR;
+        }
+        if (eps[i]->max_streams != dev_max_streams) {
+            FIXME("device streams config not identical for all eps");
+            return CC_RESOURCE_ERROR;
+        }
+    }
+
+    /*
+     * max-streams in both the device descriptor and in the controller is a
+     * power of 2. But stream id 0 is reserved, so if a device can do up to 4
+     * streams the guest will ask for 5 rounded up to the next power of 2 which
+     * becomes 8. For emulated devices usb_device_alloc_streams is a nop.
+     *
+     * For redirected devices however this is an issue, as there we must ask
+     * the real xhci controller to alloc streams, and the host driver for the
+     * real xhci controller will likely disallow allocating more streams then
+     * the device can handle.
+     *
+     * So we limit the requested nr_streams to the maximum number the device
+     * can handle.
+     */
+    if (req_nr_streams > dev_max_streams) {
+        req_nr_streams = dev_max_streams;
+    }
+
+    r = usb_device_alloc_streams(eps[0]->dev, eps, nr_eps, req_nr_streams);
+    if (r != 0) {
+        fprintf(stderr, "xhci: alloc streams failed\n");
+        return CC_RESOURCE_ERROR;
+    }
+
+    return CC_SUCCESS;
+}
+
 static XHCIStreamContext *xhci_find_stream(XHCIEPContext *epctx,
                                            unsigned int streamid,
                                            uint32_t *cc_error)
@@ -1495,7 +1600,8 @@ static TRBCCode xhci_reset_ep(XHCIState *xhci, unsigned int slotid,
     }
 
     if (!xhci->slots[slotid-1].uport ||
-        !xhci->slots[slotid-1].uport->dev) {
+        !xhci->slots[slotid-1].uport->dev ||
+        !xhci->slots[slotid-1].uport->dev->attached) {
         return CC_USB_TRANSACTION_ERROR;
     }
 
@@ -1982,6 +2088,14 @@ static void xhci_kick_ep(XHCIState *xhci, unsigned int slotid,
         return;
     }
 
+    /* If the device has been detached, but the guest has not noticed this
+       yet the 2 above checks will succeed, but we must NOT continue */
+    if (!xhci->slots[slotid - 1].uport ||
+        !xhci->slots[slotid - 1].uport->dev ||
+        !xhci->slots[slotid - 1].uport->dev->attached) {
+        return;
+    }
+
     if (epctx->retry) {
         XHCITransfer *xfer = epctx->retry;
 
@@ -2206,7 +2320,7 @@ static TRBCCode xhci_address_slot(XHCIState *xhci, unsigned int slotid,
     trace_usb_xhci_slot_address(slotid, uport->path);
 
     dev = uport->dev;
-    if (!dev) {
+    if (!dev || !dev->attached) {
         fprintf(stderr, "xhci: port %s not connected\n", uport->path);
         return CC_USB_TRANSACTION_ERROR;
     }
@@ -2313,6 +2427,8 @@ static TRBCCode xhci_configure_slot(XHCIState *xhci, unsigned int slotid,
         return CC_CONTEXT_STATE_ERROR;
     }
 
+    xhci_free_device_streams(xhci, slotid, ictl_ctx[0] | ictl_ctx[1]);
+
     for (i = 2; i <= 31; i++) {
         if (ictl_ctx[0] & (1<<i)) {
             xhci_disable_ep(xhci, slotid, i);
@@ -2334,6 +2450,16 @@ static TRBCCode xhci_configure_slot(XHCIState *xhci, unsigned int slotid,
         }
     }
 
+    res = xhci_alloc_device_streams(xhci, slotid, ictl_ctx[1]);
+    if (res != CC_SUCCESS) {
+        for (i = 2; i <= 31; i++) {
+            if (ictl_ctx[1] & (1 << i)) {
+                xhci_disable_ep(xhci, slotid, i);
+            }
+        }
+        return res;
+    }
+
     slot_ctx[3] &= ~(SLOT_STATE_MASK << SLOT_STATE_SHIFT);
     slot_ctx[3] |= SLOT_CONFIGURED << SLOT_STATE_SHIFT;
     slot_ctx[0] &= ~(SLOT_CONTEXT_ENTRIES_MASK << SLOT_CONTEXT_ENTRIES_SHIFT);
@@ -3016,6 +3142,14 @@ static void xhci_oper_write(void *ptr, hwaddr reg,
         } else if (!(val & USBCMD_RS) && (xhci->usbcmd & USBCMD_RS)) {
             xhci_stop(xhci);
         }
+        if (val & USBCMD_CSS) {
+            /* save state */
+            xhci->usbsts &= ~USBSTS_SRE;
+        }
+        if (val & USBCMD_CRS) {
+            /* restore state */
+            xhci->usbsts |= USBSTS_SRE;
+        }
         xhci->usbcmd = val & 0xc0f;
         xhci_mfwrap_update(xhci);
         if (val & USBCMD_HCRST) {
index ca2d4607857e7febdd4e5063ceb19bc6d400e519..d58cb616b1d5043c407f8f6006f0da6574503204 100644 (file)
@@ -570,7 +570,8 @@ static void xen_pt_region_update(XenPCIPassthroughState *s,
     if (args.rc) {
         XEN_PT_WARN(d, "Region: %d (addr: %#"FMT_PCIBUS
                     ", len: %#"FMT_PCIBUS") is overlapped.\n",
-                    bar, sec->offset_within_address_space, sec->size);
+                    bar, sec->offset_within_address_space,
+                    int128_get64(sec->size));
     }
 
     if (d->io_regions[bar].type & PCI_BASE_ADDRESS_SPACE_IO) {
index 1132c8934f4537bd98e6cf5c332628bfccacd883..c2189473bac8d666e1df6766ef732c392b32fa5b 100644 (file)
@@ -74,6 +74,10 @@ static int xen_pv_init(PCIDevice *pci_dev)
     XenPVDevice *d = XEN_PV_DEVICE(pci_dev);
     uint8_t *pci_conf;
 
+    /* device-id property must always be supplied */
+    if (d->device_id == 0xffff)
+           return -1;
+
     pci_conf = pci_dev->config;
 
     pci_set_word(pci_conf + PCI_VENDOR_ID, d->vendor_id);
@@ -99,7 +103,7 @@ static int xen_pv_init(PCIDevice *pci_dev)
 
 static Property xen_pv_props[] = {
     DEFINE_PROP_UINT16("vendor-id", XenPVDevice, vendor_id, PCI_VENDOR_ID_XEN),
-    DEFINE_PROP_UINT16("device-id", XenPVDevice, device_id, PCI_DEVICE_ID_XEN_PVDEVICE),
+    DEFINE_PROP_UINT16("device-id", XenPVDevice, device_id, 0xffff),
     DEFINE_PROP_UINT8("revision", XenPVDevice, revision, 0x01),
     DEFINE_PROP_UINT32("size", XenPVDevice, size, 0x400000),
     DEFINE_PROP_END_OF_LIST()
index b818091c7b4c54348968ef3b93c487540bb5e911..667af6fc63bcb1f45eaf80545abe8c5e5e1628ca 100644 (file)
@@ -411,6 +411,65 @@ typedef struct {
 #define R_SPARC_5              44
 #define R_SPARC_6              45
 
+/* Bits present in AT_HWCAP for ARM.  */
+
+#define HWCAP_ARM_SWP           (1 << 0)
+#define HWCAP_ARM_HALF          (1 << 1)
+#define HWCAP_ARM_THUMB         (1 << 2)
+#define HWCAP_ARM_26BIT         (1 << 3)
+#define HWCAP_ARM_FAST_MULT     (1 << 4)
+#define HWCAP_ARM_FPA           (1 << 5)
+#define HWCAP_ARM_VFP           (1 << 6)
+#define HWCAP_ARM_EDSP          (1 << 7)
+#define HWCAP_ARM_JAVA          (1 << 8)
+#define HWCAP_ARM_IWMMXT        (1 << 9)
+#define HWCAP_ARM_CRUNCH        (1 << 10)
+#define HWCAP_ARM_THUMBEE       (1 << 11)
+#define HWCAP_ARM_NEON          (1 << 12)
+#define HWCAP_ARM_VFPv3         (1 << 13)
+#define HWCAP_ARM_VFPv3D16      (1 << 14)       /* also set for VFPv4-D16 */
+#define HWCAP_ARM_TLS           (1 << 15)
+#define HWCAP_ARM_VFPv4         (1 << 16)
+#define HWCAP_ARM_IDIVA         (1 << 17)
+#define HWCAP_ARM_IDIVT         (1 << 18)
+#define HWCAP_IDIV              (HWCAP_IDIVA | HWCAP_IDIVT)
+#define HWCAP_VFPD32            (1 << 19)       /* set if VFP has 32 regs */
+#define HWCAP_LPAE              (1 << 20)
+
+/* Bits present in AT_HWCAP for PowerPC.  */
+
+#define PPC_FEATURE_32                  0x80000000
+#define PPC_FEATURE_64                  0x40000000
+#define PPC_FEATURE_601_INSTR           0x20000000
+#define PPC_FEATURE_HAS_ALTIVEC         0x10000000
+#define PPC_FEATURE_HAS_FPU             0x08000000
+#define PPC_FEATURE_HAS_MMU             0x04000000
+#define PPC_FEATURE_HAS_4xxMAC          0x02000000
+#define PPC_FEATURE_UNIFIED_CACHE       0x01000000
+#define PPC_FEATURE_HAS_SPE             0x00800000
+#define PPC_FEATURE_HAS_EFP_SINGLE      0x00400000
+#define PPC_FEATURE_HAS_EFP_DOUBLE      0x00200000
+#define PPC_FEATURE_NO_TB               0x00100000
+#define PPC_FEATURE_POWER4              0x00080000
+#define PPC_FEATURE_POWER5              0x00040000
+#define PPC_FEATURE_POWER5_PLUS         0x00020000
+#define PPC_FEATURE_CELL                0x00010000
+#define PPC_FEATURE_BOOKE               0x00008000
+#define PPC_FEATURE_SMT                 0x00004000
+#define PPC_FEATURE_ICACHE_SNOOP        0x00002000
+#define PPC_FEATURE_ARCH_2_05           0x00001000
+#define PPC_FEATURE_PA6T                0x00000800
+#define PPC_FEATURE_HAS_DFP             0x00000400
+#define PPC_FEATURE_POWER6_EXT          0x00000200
+#define PPC_FEATURE_ARCH_2_06           0x00000100
+#define PPC_FEATURE_HAS_VSX             0x00000080
+
+#define PPC_FEATURE_PSERIES_PERFMON_COMPAT \
+                                        0x00000040
+
+#define PPC_FEATURE_TRUE_LE             0x00000002
+#define PPC_FEATURE_PPC_LE              0x00000001
+
 /* Bits present in AT_HWCAP, primarily for Sparc32.  */
 
 #define HWCAP_SPARC_FLUSH       1    /* CPU supports flush instruction. */
@@ -420,6 +479,20 @@ typedef struct {
 #define HWCAP_SPARC_V9         16
 #define HWCAP_SPARC_ULTRA3     32
 
+/* Bits present in AT_HWCAP for s390.  */
+
+#define HWCAP_S390_ESAN3        1
+#define HWCAP_S390_ZARCH        2
+#define HWCAP_S390_STFLE        4
+#define HWCAP_S390_MSA          8
+#define HWCAP_S390_LDISP        16
+#define HWCAP_S390_EIMM         32
+#define HWCAP_S390_DFP          64
+#define HWCAP_S390_HPAGE        128
+#define HWCAP_S390_ETF3EH       256
+#define HWCAP_S390_HIGH_GPRS    512
+#define HWCAP_S390_TE           1024
+
 /*
  * 68k ELF relocation types
  */
index 85f58acd51c679f8a4d634d59b4a88109ca1e495..f431764bf5f14a841660d12cc6c183dc31df2424 100644 (file)
@@ -65,13 +65,13 @@ struct SerialState {
     /* Interrupt trigger level for recv_fifo */
     uint8_t recv_fifo_itl;
 
-    struct QEMUTimer *fifo_timeout_timer;
+    QEMUTimer *fifo_timeout_timer;
     int timeout_ipending;           /* timeout interrupt pending state */
 
     uint64_t char_transmit_time;    /* time to transmit a char in ticks */
     int poll_msl;
 
-    struct QEMUTimer *modem_status_poll;
+    QEMUTimer *modem_status_poll;
     MemoryRegion io;
 };
 
index 4c0002beca0d61a02198fab722b1f981e014db7f..e597070ab8e251f82a1ca8bd06889c41c68fab74 100644 (file)
 
 #define PCI_VENDOR_ID_XEN                0x5853
 #define PCI_DEVICE_ID_XEN_PLATFORM       0x0001
-#define PCI_DEVICE_ID_XEN_PVDEVICE       0x0002
 
 #define PCI_VENDOR_ID_NEC                0x1033
 #define PCI_DEVICE_ID_NEC_UPD720200      0x0194
index 132ab97b58f5b75646c4d61408f1ef417169239b..835418aeb02c5a2e095d903bc3f9ac74148924e9 100644 (file)
@@ -24,10 +24,10 @@ struct ppc_tb_t {
     /* Decrementer management */
     uint64_t decr_next;    /* Tick for next decr interrupt    */
     uint32_t decr_freq;    /* decrementer frequency           */
-    struct QEMUTimer *decr_timer;
+    QEMUTimer *decr_timer;
     /* Hypervisor decrementer management */
     uint64_t hdecr_next;    /* Tick for next hdecr interrupt  */
-    struct QEMUTimer *hdecr_timer;
+    QEMUTimer *hdecr_timer;
     uint64_t purr_load;
     uint64_t purr_start;
     void *opaque;
index 76f6ac24a7a83a01dbae9c2043e1545b31c3519a..bf6da3d632c8d9afc6f28939d48ad6d638a70dd6 100644 (file)
@@ -199,12 +199,16 @@ extern const struct SCSISense sense_code_SAVING_PARAMS_NOT_SUPPORTED;
 extern const struct SCSISense sense_code_INCOMPATIBLE_FORMAT;
 /* Illegal request, medium removal prevented */
 extern const struct SCSISense sense_code_ILLEGAL_REQ_REMOVAL_PREVENTED;
+/* Illegal request, Invalid Transfer Tag */
+extern const struct SCSISense sense_code_INVALID_TAG;
 /* Command aborted, I/O process terminated */
 extern const struct SCSISense sense_code_IO_ERROR;
 /* Command aborted, I_T Nexus loss occurred */
 extern const struct SCSISense sense_code_I_T_NEXUS_LOSS;
 /* Command aborted, Logical Unit failure */
 extern const struct SCSISense sense_code_LUN_FAILURE;
+/* Command aborted, Overlapped Commands Attempted */
+extern const struct SCSISense sense_code_OVERLAPPED_COMMANDS;
 /* LUN not ready, Capacity data has changed */
 extern const struct SCSISense sense_code_CAPACITY_CHANGED;
 /* LUN not ready, Medium not present */
index a7680d4e8a284e04a5a6813512437019cd38b9ab..2a3ea0c92ee67516f797d01e97d5cd226694f5ab 100644 (file)
 
 #define DeviceRequest ((USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_DEVICE)<<8)
 #define DeviceOutRequest ((USB_DIR_OUT|USB_TYPE_STANDARD|USB_RECIP_DEVICE)<<8)
-#define InterfaceRequest \
+#define VendorDeviceRequest ((USB_DIR_IN|USB_TYPE_VENDOR|USB_RECIP_DEVICE)<<8)
+#define VendorDeviceOutRequest \
+        ((USB_DIR_OUT|USB_TYPE_VENDOR|USB_RECIP_DEVICE)<<8)
+
+#define InterfaceRequest                                        \
         ((USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_INTERFACE)<<8)
 #define InterfaceOutRequest \
         ((USB_DIR_OUT|USB_TYPE_STANDARD|USB_RECIP_INTERFACE)<<8)
-#define EndpointRequest ((USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_ENDPOINT)<<8)
-#define EndpointOutRequest \
-        ((USB_DIR_OUT|USB_TYPE_STANDARD|USB_RECIP_ENDPOINT)<<8)
 #define ClassInterfaceRequest \
         ((USB_DIR_IN|USB_TYPE_CLASS|USB_RECIP_INTERFACE)<<8)
 #define ClassInterfaceOutRequest \
         ((USB_DIR_OUT|USB_TYPE_CLASS|USB_RECIP_INTERFACE)<<8)
+#define VendorInterfaceRequest \
+        ((USB_DIR_IN|USB_TYPE_VENDOR|USB_RECIP_INTERFACE)<<8)
+#define VendorInterfaceOutRequest \
+        ((USB_DIR_OUT|USB_TYPE_VENDOR|USB_RECIP_INTERFACE)<<8)
+
+#define EndpointRequest ((USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_ENDPOINT)<<8)
+#define EndpointOutRequest \
+        ((USB_DIR_OUT|USB_TYPE_STANDARD|USB_RECIP_ENDPOINT)<<8)
 
 #define USB_REQ_GET_STATUS             0x00
 #define USB_REQ_CLEAR_FEATURE          0x01
@@ -189,6 +198,7 @@ struct USBEndpoint {
     uint8_t type;
     uint8_t ifnum;
     int max_packet_size;
+    int max_streams;
     bool pipeline;
     bool halted;
     USBDevice *dev;
@@ -314,6 +324,14 @@ typedef struct USBDeviceClass {
      */
     void (*ep_stopped)(USBDevice *dev, USBEndpoint *ep);
 
+    /*
+     * Called by the hcd to alloc / free streams on a bulk endpoint.
+     * Optional may be NULL.
+     */
+    int (*alloc_streams)(USBDevice *dev, USBEndpoint **eps, int nr_eps,
+                         int streams);
+    void (*free_streams)(USBDevice *dev, USBEndpoint **eps, int nr_eps);
+
     const char *product_desc;
     const USBDesc *usb_desc;
 } USBDeviceClass;
@@ -421,6 +439,8 @@ void usb_ep_set_ifnum(USBDevice *dev, int pid, int ep, uint8_t ifnum);
 void usb_ep_set_max_packet_size(USBDevice *dev, int pid, int ep,
                                 uint16_t raw);
 int usb_ep_get_max_packet_size(USBDevice *dev, int pid, int ep);
+void usb_ep_set_max_streams(USBDevice *dev, int pid, int ep, uint8_t raw);
+int usb_ep_get_max_streams(USBDevice *dev, int pid, int ep);
 void usb_ep_set_pipeline(USBDevice *dev, int pid, int ep, bool enabled);
 void usb_ep_set_halted(USBDevice *dev, int pid, int ep, bool halted);
 USBPacket *usb_ep_find_packet_by_id(USBDevice *dev, int pid, int ep,
@@ -550,6 +570,10 @@ void usb_device_flush_ep_queue(USBDevice *dev, USBEndpoint *ep);
 
 void usb_device_ep_stopped(USBDevice *dev, USBEndpoint *ep);
 
+int usb_device_alloc_streams(USBDevice *dev, USBEndpoint **eps, int nr_eps,
+                             int streams);
+void usb_device_free_streams(USBDevice *dev, USBEndpoint **eps, int nr_eps);
+
 const char *usb_device_get_product_desc(USBDevice *dev);
 
 const USBDesc *usb_device_get_usb_desc(USBDevice *dev);
index 2c57f78fc19984c0ecd79d87b0ce1cee3fa34312..211245bea071ba9fca2ea4b723ef64afee1580ae 100644 (file)
@@ -12,7 +12,7 @@ struct qemu_cache_conf {
 
 extern struct qemu_cache_conf qemu_cache_conf;
 
-void qemu_cache_utils_init(char **envp);
+void qemu_cache_utils_init(void);
 
 /* mildly adjusted code from tcg-dyngen.c */
 static inline void flush_icache_range(uintptr_t start, uintptr_t stop)
@@ -38,7 +38,7 @@ static inline void flush_icache_range(uintptr_t start, uintptr_t stop)
 }
 
 #else
-#define qemu_cache_utils_init(envp) do { (void) (envp); } while (0)
+#define qemu_cache_utils_init() do { } while (0)
 #endif
 
 #endif /* QEMU_CACHE_UTILS_H */
index 26136f16ecd1a22336f63f3e6a739685c9b4d403..b3e2b6d8ea16a71c51a5dc8905ed63493b771d20 100644 (file)
@@ -215,4 +215,29 @@ bool fips_get_state(void);
  */
 char *qemu_get_local_state_pathname(const char *relative_pathname);
 
+/**
+ * qemu_getauxval:
+ * @type: the auxiliary vector key to lookup
+ *
+ * Search the auxiliary vector for @type, returning the value
+ * or 0 if @type is not present.
+ */
+#if defined(CONFIG_GETAUXVAL) || defined(__linux__)
+unsigned long qemu_getauxval(unsigned long type);
+#else
+static inline unsigned long qemu_getauxval(unsigned long type) { return 0; }
+#endif
+
+/**
+ * qemu_init_auxval:
+ * @envp: the third argument to main
+ *
+ * If supported and required, locate the auxiliary vector at program startup.
+ */
+#if defined(CONFIG_GETAUXVAL) || !defined(__linux__)
+static inline void qemu_init_auxval(char **envp) { }
+#else
+void qemu_init_auxval(char **envp);
+#endif
+
 #endif
index 98edf413a6e8f9d687b1d4ac6c9ce0a4cd2e47aa..4156a876e1881ef1089b13070b816ad490d31d55 100644 (file)
@@ -6,7 +6,6 @@
 #include "qapi/qmp/qdict.h"
 #include "qemu/notify.h"
 #include "monitor/monitor.h"
-#include "trace.h"
 #include "qapi-types.h"
 #include "qapi/error.h"
 
index 4478969ed2e0ee34b83e57b4e554242a36d26674..393775459d9fd6b5d71eaa6a29ec3c9b92c342fa 100644 (file)
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -72,7 +72,8 @@ typedef struct kvm_dirty_log KVMDirtyLog;
 
 struct KVMState
 {
-    KVMSlot slots[32];
+    KVMSlot *slots;
+    int nr_slots;
     int fd;
     int vmfd;
     int coalesced_mmio;
@@ -125,7 +126,7 @@ static KVMSlot *kvm_alloc_slot(KVMState *s)
 {
     int i;
 
-    for (i = 0; i < ARRAY_SIZE(s->slots); i++) {
+    for (i = 0; i < s->nr_slots; i++) {
         if (s->slots[i].memory_size == 0) {
             return &s->slots[i];
         }
@@ -141,7 +142,7 @@ static KVMSlot *kvm_lookup_matching_slot(KVMState *s,
 {
     int i;
 
-    for (i = 0; i < ARRAY_SIZE(s->slots); i++) {
+    for (i = 0; i < s->nr_slots; i++) {
         KVMSlot *mem = &s->slots[i];
 
         if (start_addr == mem->start_addr &&
@@ -163,7 +164,7 @@ static KVMSlot *kvm_lookup_overlapping_slot(KVMState *s,
     KVMSlot *found = NULL;
     int i;
 
-    for (i = 0; i < ARRAY_SIZE(s->slots); i++) {
+    for (i = 0; i < s->nr_slots; i++) {
         KVMSlot *mem = &s->slots[i];
 
         if (mem->memory_size == 0 ||
@@ -185,7 +186,7 @@ int kvm_physical_memory_addr_from_host(KVMState *s, void *ram,
 {
     int i;
 
-    for (i = 0; i < ARRAY_SIZE(s->slots); i++) {
+    for (i = 0; i < s->nr_slots; i++) {
         KVMSlot *mem = &s->slots[i];
 
         if (ram >= mem->ram && ram < mem->ram + mem->memory_size) {
@@ -357,7 +358,7 @@ static int kvm_set_migration_log(int enable)
 
     s->migration_log = enable;
 
-    for (i = 0; i < ARRAY_SIZE(s->slots); i++) {
+    for (i = 0; i < s->nr_slots; i++) {
         mem = &s->slots[i];
 
         if (!mem->memory_size) {
@@ -1383,9 +1384,6 @@ int kvm_init(void)
 #ifdef KVM_CAP_SET_GUEST_DEBUG
     QTAILQ_INIT(&s->kvm_sw_breakpoints);
 #endif
-    for (i = 0; i < ARRAY_SIZE(s->slots); i++) {
-        s->slots[i].slot = i;
-    }
     s->vmfd = -1;
     s->fd = qemu_open("/dev/kvm", O_RDWR);
     if (s->fd == -1) {
@@ -1409,6 +1407,19 @@ int kvm_init(void)
         goto err;
     }
 
+    s->nr_slots = kvm_check_extension(s, KVM_CAP_NR_MEMSLOTS);
+
+    /* If unspecified, use the default value */
+    if (!s->nr_slots) {
+        s->nr_slots = 32;
+    }
+
+    s->slots = g_malloc0(s->nr_slots * sizeof(KVMSlot));
+
+    for (i = 0; i < s->nr_slots; i++) {
+        s->slots[i].slot = i;
+    }
+
     /* check the vcpu limits */
     soft_vcpus_limit = kvm_recommended_vcpus(s);
     hard_vcpus_limit = kvm_max_vcpus(s);
@@ -1527,6 +1538,7 @@ err:
     if (s->fd != -1) {
         close(s->fd);
     }
+    g_free(s->slots);
     g_free(s);
 
     return ret;
index 7a06b5a31bca05f04d0df50baf0fcff4813d8b90..74ef3e3cec12a71a537d90ccd407fffadf76cf6f 100644 (file)
@@ -189,7 +189,6 @@ cac_applet_pki_process_apdu(VCard *card, VCardAPDU *apdu,
             pki_applet->sign_buffer = sign_buffer;
             pki_applet->sign_buffer_len = size;
             *response = vcard_make_response(VCARD7816_STATUS_SUCCESS);
-            ret = VCARD_DONE;
             break;
         case 0x00:
             /* we now have the whole buffer, do the operation, result will be
index fb429b1f825c5061c2b0bc33add3f4defcd305d7..ee2dfaee82a3cd230217b3d0b542a8b41cc3c499 100644 (file)
@@ -934,7 +934,6 @@ vcard_emul_init(const VCardEmulOptions *options)
         vreader = vreader_new(options->vreader[i].vname, vreader_emul,
                               vreader_emul_delete);
         vreader_add_reader(vreader);
-        cert_count = options->vreader[i].cert_count;
 
         vcard_emul_alloc_arrays(&certs, &cert_len, &keys,
                                 options->vreader[i].cert_count);
diff --git a/linux-user/aarch64/target_structs.h b/linux-user/aarch64/target_structs.h
new file mode 100644 (file)
index 0000000..21c1f2c
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * ARM AArch64 specific structures for linux-user
+ *
+ * Copyright (c) 2013 Fabrice Bellard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef TARGET_STRUCTS_H
+#define TARGET_STRUCTS_H
+
+struct target_ipc_perm {
+    abi_int __key;                      /* Key.  */
+    abi_uint uid;                       /* Owner's user ID.  */
+    abi_uint gid;                       /* Owner's group ID.  */
+    abi_uint cuid;                      /* Creator's user ID.  */
+    abi_uint cgid;                      /* Creator's group ID.  */
+    abi_ushort mode;                    /* Read/write permission.  */
+    abi_ushort __pad1;
+    abi_ushort __seq;                   /* Sequence number.  */
+    abi_ushort __pad2;
+    abi_ulong __unused1;
+    abi_ulong __unused2;
+};
+
+struct target_shmid_ds {
+    struct target_ipc_perm shm_perm;    /* operation permission struct */
+    abi_long shm_segsz;                 /* size of segment in bytes */
+    abi_ulong shm_atime;                /* time of last shmat() */
+#if TARGET_ABI_BITS == 32
+    abi_ulong __unused1;
+#endif
+    abi_ulong shm_dtime;                /* time of last shmdt() */
+#if TARGET_ABI_BITS == 32
+    abi_ulong __unused2;
+#endif
+    abi_ulong shm_ctime;                /* time of last change by shmctl() */
+#if TARGET_ABI_BITS == 32
+    abi_ulong __unused3;
+#endif
+    abi_int shm_cpid;                   /* pid of creator */
+    abi_int shm_lpid;                   /* pid of last shmop */
+    abi_ulong shm_nattch;               /* number of current attaches */
+    abi_ulong __unused4;
+    abi_ulong __unused5;
+};
+
+#endif
diff --git a/linux-user/alpha/target_structs.h b/linux-user/alpha/target_structs.h
new file mode 100644 (file)
index 0000000..50e7708
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Alpha specific structures for linux-user
+ *
+ * Copyright (c) 2013 Fabrice Bellard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef TARGET_STRUCTS_H
+#define TARGET_STRUCTS_H
+
+struct target_ipc_perm {
+    abi_int __key;                      /* Key.  */
+    abi_uint uid;                       /* Owner's user ID.  */
+    abi_uint gid;                       /* Owner's group ID.  */
+    abi_uint cuid;                      /* Creator's user ID.  */
+    abi_uint cgid;                      /* Creator's group ID.  */
+    abi_uint mode;                      /* Read/write permission.  */
+    abi_ushort __seq;                   /* Sequence number.  */
+    abi_ushort __pad1;
+    abi_ulong __unused1;
+    abi_ulong __unused2;
+};
+
+struct target_shmid_ds {
+    struct target_ipc_perm shm_perm;    /* operation permission struct */
+    abi_long shm_segsz;                 /* size of segment in bytes */
+    abi_ulong shm_atime;                /* time of last shmat() */
+    abi_ulong shm_dtime;                /* time of last shmdt() */
+    abi_ulong shm_ctime;                /* time of last change by shmctl() */
+    abi_int shm_cpid;                   /* pid of creator */
+    abi_int shm_lpid;                   /* pid of last shmop */
+    abi_ulong shm_nattch;               /* number of current attaches */
+    abi_ulong __unused1;
+    abi_ulong __unused2;
+};
+
+#endif
diff --git a/linux-user/arm/target_structs.h b/linux-user/arm/target_structs.h
new file mode 100644 (file)
index 0000000..f3c85d4
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * ARM specific structures for linux-user
+ *
+ * Copyright (c) 2013 Fabrice Bellard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef TARGET_STRUCTS_H
+#define TARGET_STRUCTS_H
+
+struct target_ipc_perm {
+    abi_int __key;                      /* Key.  */
+    abi_uint uid;                       /* Owner's user ID.  */
+    abi_uint gid;                       /* Owner's group ID.  */
+    abi_uint cuid;                      /* Creator's user ID.  */
+    abi_uint cgid;                      /* Creator's group ID.  */
+    abi_ushort mode;                    /* Read/write permission.  */
+    abi_ushort __pad1;
+    abi_ushort __seq;                   /* Sequence number.  */
+    abi_ushort __pad2;
+    abi_ulong __unused1;
+    abi_ulong __unused2;
+};
+
+struct target_shmid_ds {
+    struct target_ipc_perm shm_perm;    /* operation permission struct */
+    abi_long shm_segsz;                 /* size of segment in bytes */
+    abi_ulong shm_atime;                /* time of last shmat() */
+    abi_ulong __unused1;
+    abi_ulong shm_dtime;                /* time of last shmdt() */
+    abi_ulong __unused2;
+    abi_ulong shm_ctime;                /* time of last change by shmctl() */
+    abi_ulong __unused3;
+    abi_int shm_cpid;                   /* pid of creator */
+    abi_int shm_lpid;                   /* pid of last shmop */
+    abi_ulong shm_nattch;               /* number of current attaches */
+    abi_ulong __unused4;
+    abi_ulong __unused5;
+};
+
+#endif
diff --git a/linux-user/cris/target_structs.h b/linux-user/cris/target_structs.h
new file mode 100644 (file)
index 0000000..e4a1ffb
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * CRIS specific structures for linux-user
+ *
+ * Copyright (c) 2013 Fabrice Bellard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef TARGET_STRUCTS_H
+#define TARGET_STRUCTS_H
+
+struct target_ipc_perm {
+    abi_int __key;                      /* Key.  */
+    abi_uint uid;                       /* Owner's user ID.  */
+    abi_uint gid;                       /* Owner's group ID.  */
+    abi_uint cuid;                      /* Creator's user ID.  */
+    abi_uint cgid;                      /* Creator's group ID.  */
+    abi_ushort mode;                    /* Read/write permission.  */
+    abi_ushort __pad1;
+    abi_ushort __seq;                   /* Sequence number.  */
+    abi_ushort __pad2;
+    abi_ulong __unused1;
+    abi_ulong __unused2;
+};
+
+struct target_shmid_ds {
+    struct target_ipc_perm shm_perm;    /* operation permission struct */
+    abi_long shm_segsz;                 /* size of segment in bytes */
+    abi_ulong shm_atime;                /* time of last shmat() */
+#if TARGET_ABI_BITS == 32
+    abi_ulong __unused1;
+#endif
+    abi_ulong shm_dtime;                /* time of last shmdt() */
+#if TARGET_ABI_BITS == 32
+    abi_ulong __unused2;
+#endif
+    abi_ulong shm_ctime;                /* time of last change by shmctl() */
+#if TARGET_ABI_BITS == 32
+    abi_ulong __unused3;
+#endif
+    abi_int shm_cpid;                   /* pid of creator */
+    abi_int shm_lpid;                   /* pid of last shmop */
+    abi_ulong shm_nattch;               /* number of current attaches */
+    abi_ulong __unused4;
+    abi_ulong __unused5;
+};
+
+#endif
index 58f679e07282acacde4c9ec20eec6c56d79e2b1b..ceb89bb6eaafc58822616b15e4475c02ae218eb4 100644 (file)
@@ -633,7 +633,7 @@ static int load_flat_file(struct linux_binprm * bprm,
             /* Get the pointer's value.  */
             if (get_user_ual(addr, rp))
                 return -EFAULT;
-            addr = flat_get_addr_from_rp(rp, relval, flags, &persistent);
+            addr = flat_get_addr_from_rp(addr, relval, flags, &persistent);
             if (addr != 0) {
                 /*
                  * Do the relocation.  PIC relocs in the data section are
diff --git a/linux-user/i386/target_structs.h b/linux-user/i386/target_structs.h
new file mode 100644 (file)
index 0000000..65f535e
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * i386 specific structures for linux-user
+ *
+ * Copyright (c) 2013 Fabrice Bellard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef TARGET_STRUCTS_H
+#define TARGET_STRUCTS_H
+
+struct target_ipc_perm {
+    abi_int __key;                      /* Key.  */
+    abi_uint uid;                       /* Owner's user ID.  */
+    abi_uint gid;                       /* Owner's group ID.  */
+    abi_uint cuid;                      /* Creator's user ID.  */
+    abi_uint cgid;                      /* Creator's group ID.  */
+    abi_ushort mode;                    /* Read/write permission.  */
+    abi_ushort __pad1;
+    abi_ushort __seq;                   /* Sequence number.  */
+    abi_ushort __pad2;
+    abi_ulong __unused1;
+    abi_ulong __unused2;
+};
+
+struct target_shmid_ds {
+    struct target_ipc_perm shm_perm;    /* operation permission struct */
+    abi_long shm_segsz;                 /* size of segment in bytes */
+    abi_ulong shm_atime;                /* time of last shmat() */
+#if TARGET_ABI_BITS == 32
+    abi_ulong __unused1;
+#endif
+    abi_ulong shm_dtime;                /* time of last shmdt() */
+#if TARGET_ABI_BITS == 32
+    abi_ulong __unused2;
+#endif
+    abi_ulong shm_ctime;                /* time of last change by shmctl() */
+#if TARGET_ABI_BITS == 32
+    abi_ulong __unused3;
+#endif
+    abi_int shm_cpid;                   /* pid of creator */
+    abi_int shm_lpid;                   /* pid of last shmop */
+    abi_ulong shm_nattch;               /* number of current attaches */
+    abi_ulong __unused4;
+    abi_ulong __unused5;
+};
+
+#endif
diff --git a/linux-user/m68k/target_structs.h b/linux-user/m68k/target_structs.h
new file mode 100644 (file)
index 0000000..de257c9
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * m68k specific structures for linux-user
+ *
+ * Copyright (c) 2013 Fabrice Bellard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef TARGET_STRUCTS_H
+#define TARGET_STRUCTS_H
+
+struct target_ipc_perm {
+    abi_int __key;                      /* Key.  */
+    abi_uint uid;                       /* Owner's user ID.  */
+    abi_uint gid;                       /* Owner's group ID.  */
+    abi_uint cuid;                      /* Creator's user ID.  */
+    abi_uint cgid;                      /* Creator's group ID.  */
+    abi_ushort mode;                    /* Read/write permission.  */
+    abi_ushort __pad1;
+    abi_ushort __seq;                   /* Sequence number.  */
+    abi_ushort __pad2;
+    abi_ulong __unused1;
+    abi_ulong __unused2;
+};
+
+struct target_shmid_ds {
+    struct target_ipc_perm shm_perm;    /* operation permission struct */
+    abi_long shm_segsz;                 /* size of segment in bytes */
+    abi_ulong shm_atime;                /* time of last shmat() */
+#if TARGET_ABI_BITS == 32
+    abi_ulong __unused1;
+#endif
+    abi_ulong shm_dtime;                /* time of last shmdt() */
+#if TARGET_ABI_BITS == 32
+    abi_ulong __unused2;
+#endif
+    abi_ulong shm_ctime;                /* time of last change by shmctl() */
+#if TARGET_ABI_BITS == 32
+    abi_ulong __unused3;
+#endif
+    abi_int shm_cpid;                   /* pid of creator */
+    abi_int shm_lpid;                   /* pid of last shmop */
+    abi_ulong shm_nattch;               /* number of current attaches */
+    abi_ulong __unused4;
+    abi_ulong __unused5;
+};
+
+#endif
index 6b4ab0930e46483cd4053a5365742d447f8376f1..54f71fe8f69204f2f1cd95937e9c91000d712559 100644 (file)
@@ -3663,26 +3663,6 @@ static int parse_args(int argc, char **argv)
     return optind;
 }
 
-static int get_execfd(char **envp)
-{
-    typedef struct {
-        long a_type;
-        long a_val;
-    } auxv_t;
-    auxv_t *auxv;
-
-    while (*envp++ != NULL) {
-        ;
-    }
-
-    for (auxv = (auxv_t *)envp; auxv->a_type != AT_NULL; auxv++) {
-        if (auxv->a_type == AT_EXECFD) {
-            return auxv->a_val;
-        }
-    }
-    return -1;
-}
-
 int main(int argc, char **argv, char **envp)
 {
     struct target_pt_regs regs1, *regs = &regs1;
@@ -3701,7 +3681,8 @@ int main(int argc, char **argv, char **envp)
 
     module_call_init(MODULE_INIT_QOM);
 
-    qemu_cache_utils_init(envp);
+    qemu_init_auxval(envp);
+    qemu_cache_utils_init();
 
     if ((envlist = envlist_create()) == NULL) {
         (void) fprintf(stderr, "Unable to allocate envlist\n");
@@ -3875,13 +3856,13 @@ int main(int argc, char **argv, char **envp)
     env->opaque = ts;
     task_settid(ts);
 
-    execfd = get_execfd(envp);
-    if (execfd < 0) {
+    execfd = qemu_getauxval(AT_EXECFD);
+    if (execfd == 0) {
         execfd = open(filename, O_RDONLY);
-    }
-    if (execfd < 0) {
-        printf("Error while loading %s: %s\n", filename, strerror(-execfd));
-        _exit(1);
+        if (execfd < 0) {
+            printf("Error while loading %s: %s\n", filename, strerror(errno));
+            _exit(1);
+        }
     }
 
     ret = loader_exec(execfd, filename, target_argv, target_environ, regs,
diff --git a/linux-user/microblaze/target_structs.h b/linux-user/microblaze/target_structs.h
new file mode 100644 (file)
index 0000000..325e2f6
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * MicroBlaze specific structures for linux-user
+ *
+ * Copyright (c) 2013 Fabrice Bellard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef TARGET_STRUCTS_H
+#define TARGET_STRUCTS_H
+
+struct target_ipc_perm {
+    abi_int __key;                      /* Key.  */
+    abi_uint uid;                       /* Owner's user ID.  */
+    abi_uint gid;                       /* Owner's group ID.  */
+    abi_uint cuid;                      /* Creator's user ID.  */
+    abi_uint cgid;                      /* Creator's group ID.  */
+    abi_ushort mode;                    /* Read/write permission.  */
+    abi_ushort __pad1;
+    abi_ushort __seq;                   /* Sequence number.  */
+    abi_ushort __pad2;
+    abi_ulong __unused1;
+    abi_ulong __unused2;
+};
+
+struct target_shmid_ds {
+    struct target_ipc_perm shm_perm;    /* operation permission struct */
+    abi_long shm_segsz;                 /* size of segment in bytes */
+    abi_ulong shm_atime;                /* time of last shmat() */
+#if TARGET_ABI_BITS == 32
+    abi_ulong __unused1;
+#endif
+    abi_ulong shm_dtime;                /* time of last shmdt() */
+#if TARGET_ABI_BITS == 32
+    abi_ulong __unused2;
+#endif
+    abi_ulong shm_ctime;                /* time of last change by shmctl() */
+#if TARGET_ABI_BITS == 32
+    abi_ulong __unused3;
+#endif
+    abi_int shm_cpid;                   /* pid of creator */
+    abi_int shm_lpid;                   /* pid of last shmop */
+    abi_ulong shm_nattch;               /* number of current attaches */
+    abi_ulong __unused4;
+    abi_ulong __unused5;
+};
+
+#endif
diff --git a/linux-user/mips/target_structs.h b/linux-user/mips/target_structs.h
new file mode 100644 (file)
index 0000000..16021e8
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * MIPS specific structures for linux-user
+ *
+ * Copyright (c) 2013 Fabrice Bellard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef TARGET_STRUCTS_H
+#define TARGET_STRUCTS_H
+
+struct target_ipc_perm {
+    abi_int __key;                      /* Key.  */
+    abi_uint uid;                       /* Owner's user ID.  */
+    abi_uint gid;                       /* Owner's group ID.  */
+    abi_uint cuid;                      /* Creator's user ID.  */
+    abi_uint cgid;                      /* Creator's group ID.  */
+    abi_uint mode;                      /* Read/write permission.  */
+    abi_ushort __seq;                   /* Sequence number.  */
+    abi_ushort __pad1;
+    abi_ulong __unused1;
+    abi_ulong __unused2;
+};
+
+struct target_shmid_ds {
+    struct target_ipc_perm shm_perm;    /* operation permission struct */
+    abi_long shm_segsz;                 /* size of segment in bytes */
+    abi_ulong shm_atime;                /* time of last shmat() */
+    abi_ulong shm_dtime;                /* time of last shmdt() */
+    abi_ulong shm_ctime;                /* time of last change by shmctl() */
+    abi_int shm_cpid;                   /* pid of creator */
+    abi_int shm_lpid;                   /* pid of last shmop */
+    abi_ulong shm_nattch;               /* number of current attaches */
+    abi_ulong __unused1;
+    abi_ulong __unused2;
+};
+
+#endif
index fa36407c680996975cdff37962588a73949c7b1d..f16991b4ef83f3c89d04c264666cfdbd58dd149d 100644 (file)
@@ -1 +1,19 @@
+/*
+ * MIPS64 specific structures for linux-user
+ *
+ * Copyright (c) 2013 Fabrice Bellard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
 #include "../mips/target_cpu.h"
diff --git a/linux-user/mips64/target_structs.h b/linux-user/mips64/target_structs.h
new file mode 100644 (file)
index 0000000..a4f619e
--- /dev/null
@@ -0,0 +1,2 @@
+#include "../mips/target_structs.h"
+
diff --git a/linux-user/openrisc/target_structs.h b/linux-user/openrisc/target_structs.h
new file mode 100644 (file)
index 0000000..f4d560f
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * OpenRISC specific structures for linux-user
+ *
+ * Copyright (c) 2013 Fabrice Bellard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef TARGET_STRUCTS_H
+#define TARGET_STRUCTS_H
+
+struct target_ipc_perm {
+    abi_int __key;                      /* Key.  */
+    abi_uint uid;                       /* Owner's user ID.  */
+    abi_uint gid;                       /* Owner's group ID.  */
+    abi_uint cuid;                      /* Creator's user ID.  */
+    abi_uint cgid;                      /* Creator's group ID.  */
+    abi_ushort mode;                    /* Read/write permission.  */
+    abi_ushort __pad1;
+    abi_ushort __seq;                   /* Sequence number.  */
+    abi_ushort __pad2;
+    abi_ulong __unused1;
+    abi_ulong __unused2;
+};
+
+struct target_shmid_ds {
+    struct target_ipc_perm shm_perm;    /* operation permission struct */
+    abi_long shm_segsz;                 /* size of segment in bytes */
+    abi_ulong shm_atime;                /* time of last shmat() */
+#if TARGET_ABI_BITS == 32
+    abi_ulong __unused1;
+#endif
+    abi_ulong shm_dtime;                /* time of last shmdt() */
+#if TARGET_ABI_BITS == 32
+    abi_ulong __unused2;
+#endif
+    abi_ulong shm_ctime;                /* time of last change by shmctl() */
+#if TARGET_ABI_BITS == 32
+    abi_ulong __unused3;
+#endif
+    abi_int shm_cpid;                   /* pid of creator */
+    abi_int shm_lpid;                   /* pid of last shmop */
+    abi_ulong shm_nattch;               /* number of current attaches */
+    abi_ulong __unused4;
+    abi_ulong __unused5;
+};
+
+#endif
diff --git a/linux-user/ppc/target_structs.h b/linux-user/ppc/target_structs.h
new file mode 100644 (file)
index 0000000..2b87613
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * PowerPC specific structures for linux-user
+ *
+ * Copyright (c) 2013 Fabrice Bellard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef TARGET_STRUCTS_H
+#define TARGET_STRUCTS_H
+
+struct target_ipc_perm {
+    abi_int __key;                      /* Key.  */
+    abi_uint uid;                       /* Owner's user ID.  */
+    abi_uint gid;                       /* Owner's group ID.  */
+    abi_uint cuid;                      /* Creator's user ID.  */
+    abi_uint cgid;                      /* Creator's group ID.  */
+    abi_uint mode;                      /* Read/write permission.  */
+    uint32_t __seq;                     /* Sequence number.  */
+    uint32_t __pad1;
+    uint64_t __unused1;
+    uint64_t __unused2;
+};
+
+struct target_shmid_ds {
+    struct target_ipc_perm shm_perm;    /* operation permission struct */
+#if TARGET_ABI_BITS == 32
+    abi_uint __unused1;
+#endif
+    abi_ulong shm_atime;                /* time of last shmat() */
+#if TARGET_ABI_BITS == 32
+    abi_uint __unused2;
+#endif
+    abi_ulong shm_dtime;                /* time of last shmdt() */
+#if TARGET_ABI_BITS == 32
+    abi_uint __unused3;
+#endif
+    abi_ulong shm_ctime;                /* time of last change by shmctl() */
+#if TARGET_ABI_BITS == 32
+    abi_uint __unused4;
+#endif
+    abi_long shm_segsz;                 /* size of segment in bytes */
+    abi_int shm_cpid;                   /* pid of creator */
+    abi_int shm_lpid;                   /* pid of last shmop */
+    abi_ulong shm_nattch;               /* number of current attaches */
+    abi_ulong __unused5;
+    abi_ulong __unused6;
+};
+
+#endif
index da64e877c7c8e0bee8e83fa286acf612a14b28d3..e2717e077580ce339a373ac70964da6f2003a102 100644 (file)
@@ -452,5 +452,6 @@ static inline void *lock_user_string(abi_ulong guest_addr)
  */
 #include "target_cpu.h"
 #include "target_signal.h"
+#include "target_structs.h"
 
 #endif /* QEMU_H */
diff --git a/linux-user/s390x/target_structs.h b/linux-user/s390x/target_structs.h
new file mode 100644 (file)
index 0000000..6b6f5b5
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * S/390 specific structures for linux-user
+ *
+ * Copyright (c) 2013 Fabrice Bellard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef TARGET_STRUCTS_H
+#define TARGET_STRUCTS_H
+
+
+struct target_ipc_perm {
+    abi_int __key;                       /* Key.  */
+    abi_uint uid;                        /* Owner's user ID.  */
+    abi_uint gid;                        /* Owner's group ID.  */
+    abi_uint cuid;                       /* Creator's user ID.  */
+    abi_uint cgid;                       /* Creator's group ID.  */
+#if TARGET_ABI_BITS == 64
+    abi_uint mode;                       /* Read/write permission.  */
+#else
+    abi_ushort mode;                     /* Read/write permission.  */
+    abi_ushort __pad1;
+#endif
+    abi_ushort __seq;                    /* Sequence number.  */
+    abi_ushort __pad2;
+    abi_ulong __unused1;
+    abi_ulong __unused2;
+};
+
+struct target_shmid_ds {
+    struct target_ipc_perm shm_perm;    /* operation permission struct */
+    abi_long shm_segsz;                 /* size of segment in bytes */
+    abi_ulong shm_atime;                /* time of last shmat() */
+#if TARGET_ABI_BITS == 32
+    abi_ulong __unused1;
+#endif
+    abi_ulong shm_dtime;                /* time of last shmdt() */
+#if TARGET_ABI_BITS == 32
+    abi_ulong __unused2;
+#endif
+    abi_ulong shm_ctime;                /* time of last change by shmctl() */
+#if TARGET_ABI_BITS == 32
+    abi_ulong __unused3;
+#endif
+    abi_int shm_cpid;                   /* pid of creator */
+    abi_int shm_lpid;                   /* pid of last shmop */
+    abi_ulong shm_nattch;               /* number of current attaches */
+    abi_ulong __unused4;
+    abi_ulong __unused5;
+};
+
+#endif
diff --git a/linux-user/sh4/target_structs.h b/linux-user/sh4/target_structs.h
new file mode 100644 (file)
index 0000000..32b235e
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * SH4 specific structures for linux-user
+ *
+ * Copyright (c) 2013 Fabrice Bellard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef TARGET_STRUCTS_H
+#define TARGET_STRUCTS_H
+
+struct target_ipc_perm {
+    abi_int __key;                      /* Key.  */
+    abi_uint uid;                       /* Owner's user ID.  */
+    abi_uint gid;                       /* Owner's group ID.  */
+    abi_uint cuid;                      /* Creator's user ID.  */
+    abi_uint cgid;                      /* Creator's group ID.  */
+    abi_ushort mode;                    /* Read/write permission.  */
+    abi_ushort __pad1;
+    abi_ushort __seq;                   /* Sequence number.  */
+    abi_ushort __pad2;
+    abi_ulong __unused1;
+    abi_ulong __unused2;
+};
+
+struct target_shmid_ds {
+    struct target_ipc_perm shm_perm;    /* operation permission struct */
+    abi_long shm_segsz;                 /* size of segment in bytes */
+    abi_ulong shm_atime;                /* time of last shmat() */
+#if TARGET_ABI_BITS == 32
+    abi_ulong __unused1;
+#endif
+    abi_ulong shm_dtime;                /* time of last shmdt() */
+#if TARGET_ABI_BITS == 32
+    abi_ulong __unused2;
+#endif
+    abi_ulong shm_ctime;                /* time of last change by shmctl() */
+#if TARGET_ABI_BITS == 32
+    abi_ulong __unused3;
+#endif
+    abi_int shm_cpid;                   /* pid of creator */
+    abi_int shm_lpid;                   /* pid of last shmop */
+    abi_ulong shm_nattch;               /* number of current attaches */
+    abi_ulong __unused4;
+    abi_ulong __unused5;
+};
+
+#endif
diff --git a/linux-user/sparc/target_structs.h b/linux-user/sparc/target_structs.h
new file mode 100644 (file)
index 0000000..c139e09
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * SPARC specific structures for linux-user
+ *
+ * Copyright (c) 2013 Fabrice Bellard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef TARGET_STRUCTS_H
+#define TARGET_STRUCTS_H
+
+struct target_ipc_perm {
+    abi_int __key;                      /* Key.  */
+    abi_uint uid;                       /* Owner's user ID.  */
+    abi_uint gid;                       /* Owner's group ID.  */
+    abi_uint cuid;                      /* Creator's user ID.  */
+    abi_uint cgid;                      /* Creator's group ID.  */
+#if TARGET_ABI_BITS == 32
+    abi_ushort __pad1;
+    abi_ushort mode;                    /* Read/write permission.  */
+    abi_ushort __pad2;
+#else
+    abi_ushort mode;
+    abi_ushort __pad1;
+#endif
+    abi_ushort __seq;                   /* Sequence number.  */
+    uint64_t __unused1;
+    uint64_t __unused2;
+};
+
+struct target_shmid_ds {
+    struct target_ipc_perm shm_perm;    /* operation permission struct */
+#if TARGET_ABI_BITS == 32
+    abi_uint __pad1;
+#endif
+    abi_ulong shm_atime;                /* time of last shmat() */
+#if TARGET_ABI_BITS == 32
+    abi_uint __pad2;
+#endif
+    abi_ulong shm_dtime;                /* time of last shmdt() */
+#if TARGET_ABI_BITS == 32
+    abi_uint __pad3;
+#endif
+    abi_ulong shm_ctime;                /* time of last change by shmctl() */
+    abi_long shm_segsz;                 /* size of segment in bytes */
+    abi_ulong shm_cpid;                 /* pid of creator */
+    abi_ulong shm_lpid;                 /* pid of last shmop */
+    abi_long shm_nattch;                /* number of current attaches */
+    abi_ulong __unused1;
+    abi_ulong __unused2;
+};
+
+#endif
diff --git a/linux-user/sparc64/target_structs.h b/linux-user/sparc64/target_structs.h
new file mode 100644 (file)
index 0000000..fc17290
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * SPARC64 specific structures for linux-user
+ *
+ * Copyright (c) 2013 Fabrice Bellard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef TARGET_STRUCTS_H
+#define TARGET_STRUCTS_H
+
+struct target_ipc_perm {
+    abi_int __key;                      /* Key.  */
+    abi_uint uid;                       /* Owner's user ID.  */
+    abi_uint gid;                       /* Owner's group ID.  */
+    abi_uint cuid;                      /* Creator's user ID.  */
+    abi_uint cgid;                      /* Creator's group ID.  */
+    abi_ushort mode;                    /* Read/write permission.  */
+    abi_ushort __pad1;
+    abi_ushort __seq;                   /* Sequence number.  */
+    abi_ushort __pad2;
+    abi_ulong __unused1;
+    abi_ulong __unused2;
+};
+
+struct target_shmid_ds {
+    struct target_ipc_perm shm_perm;    /* operation permission struct */
+    abi_long shm_segsz;                 /* size of segment in bytes */
+    abi_ulong shm_atime;                /* time of last shmat() */
+#if TARGET_ABI_BITS == 32
+    abi_ulong __unused1;
+#endif
+    abi_ulong shm_dtime;                /* time of last shmdt() */
+#if TARGET_ABI_BITS == 32
+    abi_ulong __unused2;
+#endif
+    abi_ulong shm_ctime;                /* time of last change by shmctl() */
+#if TARGET_ABI_BITS == 32
+    abi_ulong __unused3;
+#endif
+    abi_int shm_cpid;                   /* pid of creator */
+    abi_int shm_lpid;                   /* pid of last shmop */
+    abi_ulong shm_nattch;               /* number of current attaches */
+    abi_ulong __unused4;
+    abi_ulong __unused5;
+};
+
+#endif
index eaaf00ddd002597e90cf291e23c2e66b6d583521..efd1453987b0856c359ea2947138c02e95987de2 100644 (file)
@@ -428,6 +428,25 @@ _syscall4(int, sys_prlimit64, pid_t, pid, int, resource,
           struct host_rlimit64 *, old_limit)
 #endif
 
+
+#if defined(TARGET_NR_timer_create)
+/* Maxiumum of 32 active POSIX timers allowed at any one time. */
+static timer_t g_posix_timers[32] = { 0, } ;
+
+static inline int next_free_host_timer(void)
+{
+    int k ;
+    /* FIXME: Does finding the next free slot require a lock? */
+    for (k = 0; k < ARRAY_SIZE(g_posix_timers); k++) {
+        if (g_posix_timers[k] == 0) {
+            g_posix_timers[k] = (timer_t) 1;
+            return k;
+        }
+    }
+    return -1;
+}
+#endif
+
 /* ARM EABI and MIPS expect 64bit types aligned even on pairs or registers */
 #ifdef TARGET_ARM
 static inline int regpairs_aligned(void *cpu_env) {
@@ -2417,21 +2436,6 @@ static struct shm_region {
     abi_ulong  size;
 } shm_regions[N_SHM_REGIONS];
 
-struct target_ipc_perm
-{
-    abi_long __key;
-    abi_ulong uid;
-    abi_ulong gid;
-    abi_ulong cuid;
-    abi_ulong cgid;
-    unsigned short int mode;
-    unsigned short int __pad1;
-    unsigned short int __seq;
-    unsigned short int __pad2;
-    abi_ulong __unused1;
-    abi_ulong __unused2;
-};
-
 struct target_semid_ds
 {
   struct target_ipc_perm sem_perm;
@@ -2453,12 +2457,21 @@ static inline abi_long target_to_host_ipc_perm(struct ipc_perm *host_ip,
     if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
         return -TARGET_EFAULT;
     target_ip = &(target_sd->sem_perm);
-    host_ip->__key = tswapal(target_ip->__key);
-    host_ip->uid = tswapal(target_ip->uid);
-    host_ip->gid = tswapal(target_ip->gid);
-    host_ip->cuid = tswapal(target_ip->cuid);
-    host_ip->cgid = tswapal(target_ip->cgid);
+    host_ip->__key = tswap32(target_ip->__key);
+    host_ip->uid = tswap32(target_ip->uid);
+    host_ip->gid = tswap32(target_ip->gid);
+    host_ip->cuid = tswap32(target_ip->cuid);
+    host_ip->cgid = tswap32(target_ip->cgid);
+#if defined(TARGET_ALPHA) || defined(TARGET_MIPS) || defined(TARGET_PPC)
+    host_ip->mode = tswap32(target_ip->mode);
+#else
     host_ip->mode = tswap16(target_ip->mode);
+#endif
+#if defined(TARGET_PPC)
+    host_ip->__seq = tswap32(target_ip->__seq);
+#else
+    host_ip->__seq = tswap16(target_ip->__seq);
+#endif
     unlock_user_struct(target_sd, target_addr, 0);
     return 0;
 }
@@ -2472,12 +2485,21 @@ static inline abi_long host_to_target_ipc_perm(abi_ulong target_addr,
     if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
         return -TARGET_EFAULT;
     target_ip = &(target_sd->sem_perm);
-    target_ip->__key = tswapal(host_ip->__key);
-    target_ip->uid = tswapal(host_ip->uid);
-    target_ip->gid = tswapal(host_ip->gid);
-    target_ip->cuid = tswapal(host_ip->cuid);
-    target_ip->cgid = tswapal(host_ip->cgid);
+    target_ip->__key = tswap32(host_ip->__key);
+    target_ip->uid = tswap32(host_ip->uid);
+    target_ip->gid = tswap32(host_ip->gid);
+    target_ip->cuid = tswap32(host_ip->cuid);
+    target_ip->cgid = tswap32(host_ip->cgid);
+#if defined(TARGET_ALPHA) || defined(TARGET_MIPS) || defined(TARGET_PPC)
+    target_ip->mode = tswap32(host_ip->mode);
+#else
     target_ip->mode = tswap16(host_ip->mode);
+#endif
+#if defined(TARGET_PPC)
+    target_ip->__seq = tswap32(host_ip->__seq);
+#else
+    target_ip->__seq = tswap16(host_ip->__seq);
+#endif
     unlock_user_struct(target_sd, target_addr, 1);
     return 0;
 }
@@ -2908,29 +2930,6 @@ end:
     return ret;
 }
 
-struct target_shmid_ds
-{
-    struct target_ipc_perm shm_perm;
-    abi_ulong shm_segsz;
-    abi_ulong shm_atime;
-#if TARGET_ABI_BITS == 32
-    abi_ulong __unused1;
-#endif
-    abi_ulong shm_dtime;
-#if TARGET_ABI_BITS == 32
-    abi_ulong __unused2;
-#endif
-    abi_ulong shm_ctime;
-#if TARGET_ABI_BITS == 32
-    abi_ulong __unused3;
-#endif
-    int shm_cpid;
-    int shm_lpid;
-    abi_ulong shm_nattch;
-    unsigned long int __unused4;
-    unsigned long int __unused5;
-};
-
 static inline abi_long target_to_host_shmid_ds(struct shmid_ds *host_sd,
                                                abi_ulong target_addr)
 {
@@ -3216,7 +3215,7 @@ static abi_long do_ipc(unsigned int call, int first,
 
        /* IPC_* and SHM_* command values are the same on all linux platforms */
     case IPCOP_shmctl:
-        ret = do_shmctl(first, second, third);
+        ret = do_shmctl(first, second, ptr);
         break;
     default:
        gemu_log("Unsupported ipc call: %d (version %d)\n", call, version);
@@ -4838,6 +4837,45 @@ static inline abi_long host_to_target_timespec(abi_ulong target_addr,
     return 0;
 }
 
+static inline abi_long target_to_host_itimerspec(struct itimerspec *host_itspec,
+                                                 abi_ulong target_addr)
+{
+    struct target_itimerspec *target_itspec;
+
+    if (!lock_user_struct(VERIFY_READ, target_itspec, target_addr, 1)) {
+        return -TARGET_EFAULT;
+    }
+
+    host_itspec->it_interval.tv_sec =
+                            tswapal(target_itspec->it_interval.tv_sec);
+    host_itspec->it_interval.tv_nsec =
+                            tswapal(target_itspec->it_interval.tv_nsec);
+    host_itspec->it_value.tv_sec = tswapal(target_itspec->it_value.tv_sec);
+    host_itspec->it_value.tv_nsec = tswapal(target_itspec->it_value.tv_nsec);
+
+    unlock_user_struct(target_itspec, target_addr, 1);
+    return 0;
+}
+
+static inline abi_long host_to_target_itimerspec(abi_ulong target_addr,
+                                               struct itimerspec *host_its)
+{
+    struct target_itimerspec *target_itspec;
+
+    if (!lock_user_struct(VERIFY_WRITE, target_itspec, target_addr, 0)) {
+        return -TARGET_EFAULT;
+    }
+
+    target_itspec->it_interval.tv_sec = tswapal(host_its->it_interval.tv_sec);
+    target_itspec->it_interval.tv_nsec = tswapal(host_its->it_interval.tv_nsec);
+
+    target_itspec->it_value.tv_sec = tswapal(host_its->it_value.tv_sec);
+    target_itspec->it_value.tv_nsec = tswapal(host_its->it_value.tv_nsec);
+
+    unlock_user_struct(target_itspec, target_addr, 0);
+    return 0;
+}
+
 #if defined(TARGET_NR_stat64) || defined(TARGET_NR_newfstatat)
 static inline abi_long host_to_target_stat64(void *cpu_env,
                                              abi_ulong target_addr,
@@ -9195,6 +9233,124 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
         break;
     }
 #endif
+
+#ifdef TARGET_NR_timer_create
+    case TARGET_NR_timer_create:
+    {
+        /* args: clockid_t clockid, struct sigevent *sevp, timer_t *timerid */
+
+        struct sigevent host_sevp = { {0}, }, *phost_sevp = NULL;
+        struct target_sigevent *ptarget_sevp;
+        struct target_timer_t *ptarget_timer;
+
+        int clkid = arg1;
+        int timer_index = next_free_host_timer();
+
+        if (timer_index < 0) {
+            ret = -TARGET_EAGAIN;
+        } else {
+            timer_t *phtimer = g_posix_timers  + timer_index;
+
+            if (arg2) {
+                if (!lock_user_struct(VERIFY_READ, ptarget_sevp, arg2, 1)) {
+                    goto efault;
+                }
+
+                host_sevp.sigev_signo = tswap32(ptarget_sevp->sigev_signo);
+                host_sevp.sigev_notify = tswap32(ptarget_sevp->sigev_notify);
+
+                phost_sevp = &host_sevp;
+            }
+
+            ret = get_errno(timer_create(clkid, phost_sevp, phtimer));
+            if (ret) {
+                phtimer = NULL;
+            } else {
+                if (!lock_user_struct(VERIFY_WRITE, ptarget_timer, arg3, 1)) {
+                    goto efault;
+                }
+                ptarget_timer->ptr = tswap32(0xcafe0000 | timer_index);
+                unlock_user_struct(ptarget_timer, arg3, 1);
+            }
+        }
+        break;
+    }
+#endif
+
+#ifdef TARGET_NR_timer_settime
+    case TARGET_NR_timer_settime:
+    {
+        /* args: timer_t timerid, int flags, const struct itimerspec *new_value,
+         * struct itimerspec * old_value */
+        arg1 &= 0xffff;
+        if (arg3 == 0 || arg1 < 0 || arg1 >= ARRAY_SIZE(g_posix_timers)) {
+            ret = -TARGET_EINVAL;
+        } else {
+            timer_t htimer = g_posix_timers[arg1];
+            struct itimerspec hspec_new = {{0},}, hspec_old = {{0},};
+
+            target_to_host_itimerspec(&hspec_new, arg3);
+            ret = get_errno(
+                          timer_settime(htimer, arg2, &hspec_new, &hspec_old));
+            host_to_target_itimerspec(arg2, &hspec_old);
+        }
+        break;
+    }
+#endif
+
+#ifdef TARGET_NR_timer_gettime
+    case TARGET_NR_timer_gettime:
+    {
+        /* args: timer_t timerid, struct itimerspec *curr_value */
+        arg1 &= 0xffff;
+        if (!arg2) {
+            return -TARGET_EFAULT;
+        } else if (arg1 < 0 || arg1 >= ARRAY_SIZE(g_posix_timers)) {
+            ret = -TARGET_EINVAL;
+        } else {
+            timer_t htimer = g_posix_timers[arg1];
+            struct itimerspec hspec;
+            ret = get_errno(timer_gettime(htimer, &hspec));
+
+            if (host_to_target_itimerspec(arg2, &hspec)) {
+                ret = -TARGET_EFAULT;
+            }
+        }
+        break;
+    }
+#endif
+
+#ifdef TARGET_NR_timer_getoverrun
+    case TARGET_NR_timer_getoverrun:
+    {
+        /* args: timer_t timerid */
+        arg1 &= 0xffff;
+        if (arg1 < 0 || arg1 >= ARRAY_SIZE(g_posix_timers)) {
+            ret = -TARGET_EINVAL;
+        } else {
+            timer_t htimer = g_posix_timers[arg1];
+            ret = get_errno(timer_getoverrun(htimer));
+        }
+        break;
+    }
+#endif
+
+#ifdef TARGET_NR_timer_delete
+    case TARGET_NR_timer_delete:
+    {
+        /* args: timer_t timerid */
+        arg1 &= 0xffff;
+        if (arg1 < 0 || arg1 >= ARRAY_SIZE(g_posix_timers)) {
+            ret = -TARGET_EINVAL;
+        } else {
+            timer_t htimer = g_posix_timers[arg1];
+            ret = get_errno(timer_delete(htimer));
+            g_posix_timers[arg1] = 0;
+        }
+        break;
+    }
+#endif
+
     default:
     unimplemented:
         gemu_log("qemu: Unsupported syscall: %d\n", num);
index fe540f656306f04b97a2d0faaa8380c56e90566b..cf08db5a234c92b552625af57085729fa22fdb12 100644 (file)
@@ -168,6 +168,11 @@ struct target_itimerval {
     struct target_timeval it_value;
 };
 
+struct target_itimerspec {
+    struct target_timespec it_interval;
+    struct target_timespec it_value;
+};
+
 typedef abi_long target_clock_t;
 
 #define TARGET_HZ 100
@@ -2527,3 +2532,23 @@ struct target_ucred {
 };
 
 #endif
+
+
+struct target_timer_t {
+    abi_ulong ptr;
+};
+
+struct target_sigevent {
+    target_sigval_t sigev_value;
+    int32_t sigev_signo;
+    int32_t sigev_notify;
+    union {
+        int32_t _pad[ARRAY_SIZE(((struct sigevent *)0)->_sigev_un._pad)];
+        int32_t _tid;
+
+        struct {
+            void (*_function)(sigval_t);
+            void *_attribute;
+        } _sigev_thread;
+    } _sigev_un;
+};
diff --git a/linux-user/unicore32/target_structs.h b/linux-user/unicore32/target_structs.h
new file mode 100644 (file)
index 0000000..7893695
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * UniCore32 specific structures for linux-user
+ *
+ * Copyright (c) 2013 Fabrice Bellard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef TARGET_STRUCTS_H
+#define TARGET_STRUCTS_H
+
+struct target_ipc_perm {
+    abi_int __key;                      /* Key.  */
+    abi_uint uid;                       /* Owner's user ID.  */
+    abi_uint gid;                       /* Owner's group ID.  */
+    abi_uint cuid;                      /* Creator's user ID.  */
+    abi_uint cgid;                      /* Creator's group ID.  */
+    abi_ushort mode;                    /* Read/write permission.  */
+    abi_ushort __pad1;
+    abi_ushort __seq;                   /* Sequence number.  */
+    abi_ushort __pad2;
+    abi_ulong __unused1;
+    abi_ulong __unused2;
+};
+
+struct target_shmid_ds {
+    struct target_ipc_perm shm_perm;    /* operation permission struct */
+    abi_long shm_segsz;                 /* size of segment in bytes */
+    abi_ulong shm_atime;                /* time of last shmat() */
+#if TARGET_ABI_BITS == 32
+    abi_ulong __unused1;
+#endif
+    abi_ulong shm_dtime;                /* time of last shmdt() */
+#if TARGET_ABI_BITS == 32
+    abi_ulong __unused2;
+#endif
+    abi_ulong shm_ctime;                /* time of last change by shmctl() */
+#if TARGET_ABI_BITS == 32
+    abi_ulong __unused3;
+#endif
+    abi_int shm_cpid;                   /* pid of creator */
+    abi_int shm_lpid;                   /* pid of last shmop */
+    abi_ulong shm_nattch;               /* number of current attaches */
+    abi_ulong __unused4;
+    abi_ulong __unused5;
+};
+
+#endif
diff --git a/linux-user/x86_64/target_structs.h b/linux-user/x86_64/target_structs.h
new file mode 100644 (file)
index 0000000..d934056
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * X86-64 specific structures for linux-user
+ *
+ * Copyright (c) 2013 Fabrice Bellard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef TARGET_STRUCTS_H
+#define TARGET_STRUCTS_H
+
+struct target_ipc_perm {
+    abi_int __key;                      /* Key.  */
+    abi_uint uid;                       /* Owner's user ID.  */
+    abi_uint gid;                       /* Owner's group ID.  */
+    abi_uint cuid;                      /* Creator's user ID.  */
+    abi_uint cgid;                      /* Creator's group ID.  */
+    abi_ushort mode;                    /* Read/write permission.  */
+    abi_ushort __pad1;
+    abi_ushort __seq;                   /* Sequence number.  */
+    abi_ushort __pad2;
+    abi_ulong __unused1;
+    abi_ulong __unused2;
+};
+
+struct target_shmid_ds {
+    struct target_ipc_perm shm_perm;    /* operation permission struct */
+    abi_long shm_segsz;                 /* size of segment in bytes */
+    abi_ulong shm_atime;                /* time of last shmat() */
+#if TARGET_ABI_BITS == 32
+    abi_ulong __unused1;
+#endif
+    abi_ulong shm_dtime;                /* time of last shmdt() */
+#if TARGET_ABI_BITS == 32
+    abi_ulong __unused2;
+#endif
+    abi_ulong shm_ctime;                /* time of last change by shmctl() */
+#if TARGET_ABI_BITS == 32
+    abi_ulong __unused3;
+#endif
+    abi_int shm_cpid;                   /* pid of creator */
+    abi_int shm_lpid;                   /* pid of last shmop */
+    abi_ulong shm_nattch;               /* number of current attaches */
+    abi_ulong __unused4;
+    abi_ulong __unused5;
+};
+
+#endif
index 528372b41e0c500170e64e9b718e50f2d9e55212..cfd16d756ec79115174be176753f361585e3e051 100644 (file)
Binary files a/pc-bios/acpi-dsdt.aml and b/pc-bios/acpi-dsdt.aml differ
diff --git a/pc-bios/bios-256k.bin b/pc-bios/bios-256k.bin
new file mode 100644 (file)
index 0000000..68017e5
Binary files /dev/null and b/pc-bios/bios-256k.bin differ
index 697440c26c144ca6c4aa90d2f8a5014298137cfe..4f4383b06a95cd0f479c9d9e8e07234748a7279b 100644 (file)
Binary files a/pc-bios/bios.bin and b/pc-bios/bios.bin differ
index 4d23746ebf2f5d4da3bc7e3f139a17f0d887a6e6..d71b3a328ced5ce2cb16d153cfa7cda0aca966a4 100644 (file)
Binary files a/pc-bios/q35-acpi-dsdt.aml and b/pc-bios/q35-acpi-dsdt.aml differ
index 424dd0c70c4a52e1a98d8a64ebf4aa382b85d5cf..36b197d1907e75a309b7e832ea0bd78cb554b8fd 100644 (file)
Binary files a/pc-bios/vgabios-cirrus.bin and b/pc-bios/vgabios-cirrus.bin differ
index 3156c6e3f1a18f011014cd983bf57fe7c5a03e96..aaa3b10c7c7c4d939920c76d7f7ad9cbfce999b6 100644 (file)
Binary files a/pc-bios/vgabios-qxl.bin and b/pc-bios/vgabios-qxl.bin differ
index 5123c5fd070c14c1d11b432e5c522ec2d1026253..d329e240f91717d52e8550f9ec9c558c933e8ed8 100644 (file)
Binary files a/pc-bios/vgabios-stdvga.bin and b/pc-bios/vgabios-stdvga.bin differ
index 5e8c06b2286de62f27aa72c79defab686cdb07b5..31d56a94d0f4b8b277537bc50ffcdd08b5b98fd0 100644 (file)
Binary files a/pc-bios/vgabios-vmware.bin and b/pc-bios/vgabios-vmware.bin differ
index 892a2b537468cb8adcf85afb59588bfe35edec72..b87f74de7c0f1e079d79ab554d5fe1f38a798a1c 100644 (file)
Binary files a/pc-bios/vgabios.bin and b/pc-bios/vgabios.bin differ
index 8b9426484d1dbb2bde0d676b24f96cb7c746a6b4..eafc022ad0909b8da6c08592a39c83083355c2e2 100644 (file)
@@ -228,7 +228,6 @@ STEXI
 Allocate guest RAM from a temporarily created file in @var{path}.
 ETEXI
 
-#ifdef MAP_POPULATE
 DEF("mem-prealloc", 0, QEMU_OPTION_mem_prealloc,
     "-mem-prealloc   preallocate guest memory (use with -mem-path)\n",
     QEMU_ARCH_ALL)
@@ -237,7 +236,6 @@ STEXI
 @findex -mem-prealloc
 Preallocate memory when using -mem-path.
 ETEXI
-#endif
 
 DEF("k", HAS_ARG, QEMU_OPTION_k,
     "-k language     use keyboard layout (for example 'fr' for French)\n",
index 69cee443afaff5813c5533c7739de0bb7e6d274f..cf07869599e43544826d75dc86637720bb775e0e 100644 (file)
@@ -114,6 +114,7 @@ static const struct QemuSeccompSyscall seccomp_whitelist[] = {
     { SCMP_SYS(write), 244 },
     { SCMP_SYS(fcntl), 243 },
     { SCMP_SYS(tgkill), 242 },
+    { SCMP_SYS(kill), 242 },
     { SCMP_SYS(rt_sigaction), 242 },
     { SCMP_SYS(pipe2), 242 },
     { SCMP_SYS(munmap), 242 },
index 3aee1cf6a693965fdc63f38cc1d8da775f501dd9..fc8331aa67402c0924d38a2e51edfdd18364d6ff 100644 (file)
@@ -42,8 +42,8 @@ static QError *qerror_new(void)
  *
  * Return strong reference.
  */
-static QError *qerror_from_info(ErrorClass err_class, const char *fmt,
-                                va_list *va)
+static QError * GCC_FMT_ATTR(2, 0)
+qerror_from_info(ErrorClass err_class, const char *fmt, va_list *va)
 {
     QError *qerr;
 
index 10d5a65d61fa6c4ed850d985b361bc3a293a3586..1e04669af4d4b785f3aa1d5ae1cce1b8525ab35c 100644 (file)
@@ -56,9 +56,10 @@ default:
        @echo "                    the EfiRom utility from edk2 / tianocore)"
        @echo "  slof           -- update slof.bin"
 
-bios: build-seabios-config-seabios
-       cp seabios/builds/seabios/bios.bin ../pc-bios/bios.bin
-       cp seabios/builds/seabios/*dsdt.aml ../pc-bios/
+bios: build-seabios-config-seabios-128k build-seabios-config-seabios-256k
+       cp seabios/builds/seabios-128k/bios.bin ../pc-bios/bios.bin
+       cp seabios/builds/seabios-256k/bios.bin ../pc-bios/bios-256k.bin
+       cp seabios/builds/seabios-256k/src/fw/*dsdt.aml ../pc-bios/
 
 seavgabios: $(patsubst %,seavgabios-%,$(vgabios_variants))
 
@@ -72,9 +73,11 @@ build-seabios-config-%: config.%
        mkdir -p seabios/builds/$*
        cp $< seabios/builds/$*/.config
        $(MAKE) $(MAKEFLAGS) -C seabios \
+               CROSS_COMPILE=$(x86_64_cross_prefix) \
                KCONFIG_CONFIG=$(CURDIR)/seabios/builds/$*/.config \
                OUT=$(CURDIR)/seabios/builds/$*/ oldnoconfig
        $(MAKE) $(MAKEFLAGS) -C seabios \
+               CROSS_COMPILE=$(x86_64_cross_prefix) \
                KCONFIG_CONFIG=$(CURDIR)/seabios/builds/$*/.config \
                OUT=$(CURDIR)/seabios/builds/$*/ all
 
diff --git a/roms/config.seabios b/roms/config.seabios
deleted file mode 100644 (file)
index c373b87..0000000
+++ /dev/null
@@ -1 +0,0 @@
-# empty, default config works for us
diff --git a/roms/config.seabios-128k b/roms/config.seabios-128k
new file mode 100644 (file)
index 0000000..41f8381
--- /dev/null
@@ -0,0 +1,6 @@
+# for qemu machine types 1.7 + older
+# need to turn off features (xhci) to make it fit into 128k
+CONFIG_QEMU=y
+CONFIG_ROM_SIZE=128
+CONFIG_XEN=n
+CONFIG_USB_XHCI=n
diff --git a/roms/config.seabios-256k b/roms/config.seabios-256k
new file mode 100644 (file)
index 0000000..65e5015
--- /dev/null
@@ -0,0 +1,3 @@
+# for qemu machine types 2.0 + newer
+CONFIG_QEMU=y
+CONFIG_ROM_SIZE=256
index ece025f5980bae88fa677bc9c0d24d2e580e205d..31b8b4eea9d9ad58a73b22a6060d3ac1c419c26d 160000 (submodule)
@@ -1 +1 @@
-Subproject commit ece025f5980bae88fa677bc9c0d24d2e580e205d
+Subproject commit 31b8b4eea9d9ad58a73b22a6060d3ac1c419c26d
index 2ebc9bcacbf9c27604532e4c9d95ecd083797034..198f1b13a37b0081f66d2d10be92293e57fb2ded 100644 (file)
@@ -62,7 +62,7 @@ typedef struct AlphaCPU {
     CPUAlphaState env;
 
     /* This alarm doesn't exist in real hardware; we wish it did.  */
-    struct QEMUTimer *alarm_timer;
+    QEMUTimer *alarm_timer;
 } AlphaCPU;
 
 static inline AlphaCPU *alpha_env_get_cpu(CPUAlphaState *env)
index 47af9a8816334cbb6e1870f29f95fa2e7e6196db..bb98f6defc4a01d3ff2e9d7b8f075fab33afee85 100644 (file)
@@ -335,7 +335,7 @@ typedef struct ExtSaveArea {
 
 static const ExtSaveArea ext_save_areas[] = {
     [2] = { .feature = FEAT_1_ECX, .bits = CPUID_EXT_AVX,
-            .offset = 0x100, .size = 0x240 },
+            .offset = 0x240, .size = 0x100 },
 };
 
 const char *get_register_name_32(unsigned int reg)
@@ -2227,8 +2227,8 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
             const ExtSaveArea *esa = &ext_save_areas[count];
             if ((env->features[esa->feature] & esa->bits) == esa->bits &&
                 (kvm_mask & (1 << count)) != 0) {
-                *eax = esa->offset;
-                *ebx = esa->size;
+                *eax = esa->size;
+                *ebx = esa->offset;
             }
         }
         break;
index a29c82faf16b911053a12b4a5d4c6c708cb54574..9caf4474b9731114d47b3f9389e1f8a16eca0d42 100644 (file)
@@ -476,7 +476,7 @@ struct CPUMIPSState {
 
     const mips_def_t *cpu_model;
     void *irq[8];
-    struct QEMUTimer *timer; /* Internal timer */
+    QEMUTimer *timer; /* Internal timer */
 };
 
 #include "cpu-qom.h"
index 0f9efdf6def3e571e6992dc13be533cd0d4783d6..51d6afd1532b4d53d6f379de0516ae2d1c3798a9 100644 (file)
@@ -307,7 +307,7 @@ typedef struct CPUOpenRISCState {
 #ifndef CONFIG_USER_ONLY
     CPUOpenRISCTLBContext * tlb;
 
-    struct QEMUTimer *timer;
+    QEMUTimer *timer;
     uint32_t ttmr;          /* Timer tick mode register */
     uint32_t ttcr;          /* Timer tick count register */
 
index 41194ec06bbbc4100eb585b827fd4aff268182ff..c519063ba9b3b7e59b111778e470352439859ce4 100644 (file)
@@ -370,7 +370,7 @@ struct CPUTimer
     uint32_t    disabled;
     uint64_t    disabled_mask;
     int64_t     clock_offset;
-    struct QEMUTimer  *qtimer;
+    QEMUTimer  *qtimer;
 };
 
 typedef struct CPUTimer CPUTimer;
index e93a4a237b6bd66baa94c158d02e64c41af31458..82658a170c2cd7fc22a9a2658622c420799340e1 100644 (file)
@@ -22,6 +22,7 @@
  * THE SOFTWARE.
  */
 
+#include "elf.h"
 #include "tcg-be-ldst.h"
 
 /* The __ARM_ARCH define is provided by gcc 4.8.  Construct it otherwise.  */
@@ -58,9 +59,6 @@ static int arm_arch = __ARM_ARCH;
 #ifndef use_idiv_instructions
 bool use_idiv_instructions;
 #endif
-#ifdef CONFIG_GETAUXVAL
-# include <sys/auxv.h>
-#endif
 
 #ifndef NDEBUG
 static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
@@ -2036,22 +2034,20 @@ static const TCGTargetOpDef arm_op_defs[] = {
 
 static void tcg_target_init(TCGContext *s)
 {
-#if defined(CONFIG_GETAUXVAL)
     /* Only probe for the platform and capabilities if we havn't already
        determined maximum values at compile time.  */
-# if !defined(use_idiv_instructions)
+#ifndef use_idiv_instructions
     {
-        unsigned long hwcap = getauxval(AT_HWCAP);
+        unsigned long hwcap = qemu_getauxval(AT_HWCAP);
         use_idiv_instructions = (hwcap & HWCAP_ARM_IDIVA) != 0;
     }
-# endif
+#endif
     if (__ARM_ARCH < 7) {
-        const char *pl = (const char *)getauxval(AT_PLATFORM);
+        const char *pl = (const char *)qemu_getauxval(AT_PLATFORM);
         if (pl != NULL && pl[0] == 'v' && pl[1] >= '4' && pl[1] <= '9') {
             arm_arch = pl[1] - '0';
         }
     }
-#endif /* GETAUXVAL */
 
     tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I32], 0, 0xffff);
     tcg_regset_set32(tcg_target_call_clobber_regs, 0,
index 6109d862dbce3937d52a8ef2e5ce4207a8cb1c2e..06e440f9bc6b85f4574344f86060e709f969f9a0 100644 (file)
@@ -45,15 +45,10 @@ static uint8_t *tb_ret_addr;
 #define GUEST_BASE 0
 #endif
 
-#ifdef CONFIG_GETAUXVAL
-#include <sys/auxv.h>
+#include "elf.h"
 static bool have_isa_2_06;
 #define HAVE_ISA_2_06  have_isa_2_06
 #define HAVE_ISEL      have_isa_2_06
-#else
-#define HAVE_ISA_2_06  0
-#define HAVE_ISEL      0
-#endif
 
 #ifdef CONFIG_USE_GUEST_BASE
 #define TCG_GUEST_BASE_REG 30
@@ -2132,12 +2127,10 @@ static const TCGTargetOpDef ppc_op_defs[] = {
 
 static void tcg_target_init(TCGContext *s)
 {
-#ifdef CONFIG_GETAUXVAL
-    unsigned long hwcap = getauxval(AT_HWCAP);
+    unsigned long hwcap = qemu_getauxval(AT_HWCAP);
     if (hwcap & PPC_FEATURE_ARCH_2_06) {
         have_isa_2_06 = true;
     }
-#endif
 
     tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I32], 0, 0xffffffff);
     tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I64], 0, 0xffffffff);
index 0a4f3be0e9d41da3445de32674b5de4f256dc694..248726e82f7ca09887e4f1f0e6145923870c31eb 100644 (file)
@@ -31,6 +31,8 @@
 #error "unsupported code generation mode"
 #endif
 
+#include "elf.h"
+
 /* ??? The translation blocks produced by TCG are generally small enough to
    be entirely reachable with a 16-bit displacement.  Leaving the option for
    a 32-bit displacement here Just In Case.  */
@@ -2233,91 +2235,18 @@ static void sigill_handler(int sig)
 
 static void query_facilities(void)
 {
-    struct sigaction sa_old, sa_new;
-    register int r0 __asm__("0");
-    register void *r1 __asm__("1");
-    int fail;
-
-    memset(&sa_new, 0, sizeof(sa_new));
-    sa_new.sa_handler = sigill_handler;
-    sigaction(SIGILL, &sa_new, &sa_old);
-
-    /* First, try STORE FACILITY LIST EXTENDED.  If this is present, then
-       we need not do any more probing.  Unfortunately, this itself is an
-       extension and the original STORE FACILITY LIST instruction is
-       kernel-only, storing its results at absolute address 200.  */
-    /* stfle 0(%r1) */
-    r1 = &facilities;
-    asm volatile(".word 0xb2b0,0x1000"
-                 : "=r"(r0) : "0"(0), "r"(r1) : "memory", "cc");
-
-    if (got_sigill) {
-        /* STORE FACILITY EXTENDED is not available.  Probe for one of each
-           kind of instruction that we're interested in.  */
-        /* ??? Possibly some of these are in practice never present unless
-           the store-facility-extended facility is also present.  But since
-           that isn't documented it's just better to probe for each.  */
-
-        /* Test for z/Architecture.  Required even in 31-bit mode.  */
-        got_sigill = 0;
-        /* agr %r0,%r0 */
-        asm volatile(".word 0xb908,0x0000" : "=r"(r0) : : "cc");
-        if (!got_sigill) {
-            facilities |= FACILITY_ZARCH_ACTIVE;
-        }
-
-        /* Test for long displacement.  */
-        got_sigill = 0;
-        /* ly %r0,0(%r1) */
-        r1 = &facilities;
-        asm volatile(".word 0xe300,0x1000,0x0058"
-                     : "=r"(r0) : "r"(r1) : "cc");
-        if (!got_sigill) {
-            facilities |= FACILITY_LONG_DISP;
-        }
-
-        /* Test for extended immediates.  */
-        got_sigill = 0;
-        /* afi %r0,0 */
-        asm volatile(".word 0xc209,0x0000,0x0000" : : : "cc");
-        if (!got_sigill) {
-            facilities |= FACILITY_EXT_IMM;
-        }
-
-        /* Test for general-instructions-extension.  */
-        got_sigill = 0;
-        /* msfi %r0,1 */
-        asm volatile(".word 0xc201,0x0000,0x0001");
-        if (!got_sigill) {
-            facilities |= FACILITY_GEN_INST_EXT;
-        }
-    }
-
-    sigaction(SIGILL, &sa_old, NULL);
+    unsigned long hwcap = qemu_getauxval(AT_HWCAP);
 
-    /* The translator currently uses these extensions unconditionally.
-       Pruning this back to the base ESA/390 architecture doesn't seem
-       worthwhile, since even the KVM target requires z/Arch.  */
-    fail = 0;
-    if ((facilities & FACILITY_ZARCH_ACTIVE) == 0) {
-        fprintf(stderr, "TCG: z/Arch facility is required.\n");
-        fprintf(stderr, "TCG: Boot with a 64-bit enabled kernel.\n");
-        fail = 1;
-    }
-    if ((facilities & FACILITY_LONG_DISP) == 0) {
-        fprintf(stderr, "TCG: long-displacement facility is required.\n");
-        fail = 1;
-    }
+    /* Is STORE FACILITY LIST EXTENDED available?  Honestly, I believe this
+       is present on all 64-bit systems, but let's check for it anyway.  */
+    if (hwcap & HWCAP_S390_STFLE) {
+        register int r0 __asm__("0");
+        register void *r1 __asm__("1");
 
-    /* So far there's just enough support for 31-bit mode to let the
-       compile succeed.  This is good enough to run QEMU with KVM.  */
-    if (sizeof(void *) != 8) {
-        fprintf(stderr, "TCG: 31-bit mode is not supported.\n");
-        fail = 1;
-    }
-
-    if (fail) {
-        exit(-1);
+        /* stfle 0(%r1) */
+        r1 = &facilities;
+        asm volatile(".word 0xb2b0,0x1000"
+                     : "=r"(r0) : "0"(0), "r"(r1) : "memory", "cc");
     }
 }
 
index e32d00cefbd1abd5db665f0dda0a6433a0434f86..9f4456a82e290caf3ad8958d721493a5f57d2d23 100644 (file)
@@ -311,6 +311,9 @@ usb_ehci_sitd(uint32_t addr, uint32_t nxt, uint32_t active) "ITD @ %08x: next %0
 usb_ehci_port_attach(uint32_t port, const char *owner, const char *device) "attach port #%d, owner %s, device %s"
 usb_ehci_port_detach(uint32_t port, const char *owner) "detach port #%d, owner %s"
 usb_ehci_port_reset(uint32_t port, int enable) "reset port #%d - %d"
+usb_ehci_port_suspend(uint32_t port) "port #%d"
+usb_ehci_port_wakeup(uint32_t port) "port #%d"
+usb_ehci_port_resume(uint32_t port) "port #%d"
 usb_ehci_queue_action(void *q, const char *action) "q %p: %s"
 usb_ehci_packet_action(void *q, void *p, const char *action) "q %p p %p: %s"
 usb_ehci_irq(uint32_t level, uint32_t frindex, uint32_t sts, uint32_t mask) "level %d, frindex 0x%04x, sts 0x%x, mask 0x%x"
@@ -429,45 +432,32 @@ usb_uas_tmf_abort_task(int addr, uint16_t tag, uint16_t task_tag) "dev %d, tag 0
 usb_uas_tmf_logical_unit_reset(int addr, uint16_t tag, int lun) "dev %d, tag 0x%x, lun %d"
 usb_uas_tmf_unsupported(int addr, uint16_t tag, uint32_t function) "dev %d, tag 0x%x, function 0x%x"
 
-# hw/usb/host-linux.c
 # hw/usb/host-libusb.c
 usb_host_open_started(int bus, int addr) "dev %d:%d"
 usb_host_open_success(int bus, int addr) "dev %d:%d"
 usb_host_open_failure(int bus, int addr) "dev %d:%d"
-usb_host_disconnect(int bus, int addr) "dev %d:%d"
 usb_host_close(int bus, int addr) "dev %d:%d"
 usb_host_attach_kernel(int bus, int addr, int interface) "dev %d:%d, if %d"
 usb_host_detach_kernel(int bus, int addr, int interface) "dev %d:%d, if %d"
 usb_host_set_address(int bus, int addr, int config) "dev %d:%d, address %d"
 usb_host_set_config(int bus, int addr, int config) "dev %d:%d, config %d"
 usb_host_set_interface(int bus, int addr, int interface, int alt) "dev %d:%d, interface %d, alt %d"
-usb_host_claim_interfaces(int bus, int addr, int config, int nif) "dev %d:%d, config %d, nif %d"
 usb_host_claim_interface(int bus, int addr, int config, int interface) "dev %d:%d, config %d, if %d"
-usb_host_release_interfaces(int bus, int addr) "dev %d:%d"
 usb_host_release_interface(int bus, int addr, int interface) "dev %d:%d, if %d"
 usb_host_req_control(int bus, int addr, void *p, int req, int value, int index) "dev %d:%d, packet %p, req 0x%x, value %d, index %d"
 usb_host_req_data(int bus, int addr, void *p, int in, int ep, int size) "dev %d:%d, packet %p, in %d, ep %d, size %d"
 usb_host_req_complete(int bus, int addr, void *p, int status, int length) "dev %d:%d, packet %p, status %d, length %d"
 usb_host_req_emulated(int bus, int addr, void *p, int status) "dev %d:%d, packet %p, status %d"
 usb_host_req_canceled(int bus, int addr, void *p) "dev %d:%d, packet %p"
-usb_host_urb_submit(int bus, int addr, void *aurb, int length, int more) "dev %d:%d, aurb %p, length %d, more %d"
-usb_host_urb_complete(int bus, int addr, void *aurb, int status, int length, int more) "dev %d:%d, aurb %p, status %d, length %d, more %d"
-usb_host_urb_canceled(int bus, int addr, void *aurb) "dev %d:%d, aurb %p"
-usb_host_ep_set_halt(int bus, int addr, int ep) "dev %d:%d, ep %d"
-usb_host_ep_clear_halt(int bus, int addr, int ep) "dev %d:%d, ep %d"
 usb_host_iso_start(int bus, int addr, int ep) "dev %d:%d, ep %d"
 usb_host_iso_stop(int bus, int addr, int ep) "dev %d:%d, ep %d"
 usb_host_iso_out_of_bufs(int bus, int addr, int ep) "dev %d:%d, ep %d"
-usb_host_iso_many_urbs(int bus, int addr, int count) "dev %d:%d, count %d"
 usb_host_reset(int bus, int addr) "dev %d:%d"
 usb_host_auto_scan_enabled(void)
 usb_host_auto_scan_disabled(void)
-usb_host_claim_port(int bus, int hub, int port) "bus %d, hub addr %d, port %d"
-usb_host_parse_device(int bus, int addr, int vendor, int product) "dev %d:%d, id %04x:%04x"
 usb_host_parse_config(int bus, int addr, int value, int active) "dev %d:%d, value %d, active %d"
 usb_host_parse_interface(int bus, int addr, int num, int alt, int active) "dev %d:%d, num %d, alt %d, active %d"
 usb_host_parse_endpoint(int bus, int addr, int ep, const char *dir, const char *type, int active) "dev %d:%d, ep %d, %s, %s, active %d"
-usb_host_parse_unknown(int bus, int addr, int len, int type) "dev %d:%d, len %d, type %d"
 usb_host_parse_error(int bus, int addr, const char *errmsg) "dev %d:%d, msg %s"
 
 # hw/scsi/scsi-bus.c
@@ -1012,6 +1002,8 @@ dma_map_wait(void *dbs) "dbs=%p"
 
 # ui/console.c
 console_gfx_new(void) ""
+console_putchar_csi(int esc_param0, int esc_param1, int ch, int nb_esc_params) "escape sequence CSI%d;%d%c, %d parameters"
+console_putchar_unhandled(int ch) "unhandled escape character '%c'"
 console_txt_new(int w, int h) "%dx%d"
 console_select(int nr) "%d"
 console_refresh(int interval) "interval %d ms"
@@ -1022,6 +1014,11 @@ displaychangelistener_register(void *dcl, const char *name) "%p [ %s ]"
 displaychangelistener_unregister(void *dcl, const char *name) "%p [ %s ]"
 ppm_save(const char *filename, void *display_surface) "%s surface=%p"
 
+# ui/gtk.c
+gd_switch(int width, int height) "width=%d, height=%d"
+gd_update(int x, int y, int w, int h) "x=%d, y=%d, w=%d, h=%d"
+gd_key_event(int gdk_keycode, int qemu_keycode, const char *action) "translated GDK keycode %d to QEMU keycode %d (%s)"
+
 # hw/display/vmware_vga.c
 vmware_value_read(uint32_t index, uint32_t value) "index %d, value 0x%x"
 vmware_value_write(uint32_t index, uint32_t value) "index %d, value 0x%x"
index 199ba69101d532c4a6658b5c3007d9c4caff1a30..502e1600ab9d70b216be849ea7a9d353861385c1 100644 (file)
@@ -27,8 +27,8 @@
 #include "qemu/timer.h"
 #include "qmp-commands.h"
 #include "sysemu/char.h"
+#include "trace.h"
 
-//#define DEBUG_CONSOLE
 #define DEFAULT_BACKSCROLL 512
 #define MAX_CONSOLES 12
 #define CONSOLE_CURSOR_PERIOD 500
@@ -161,7 +161,7 @@ struct QemuConsole {
 };
 
 struct DisplayState {
-    struct QEMUTimer *gui_timer;
+    QEMUTimer *gui_timer;
     uint64_t last_update;
     uint64_t update_interval;
     bool refreshing;
@@ -866,10 +866,8 @@ static void console_putchar(QemuConsole *s, int ch)
                 s->nb_esc_params++;
             if (ch == ';')
                 break;
-#ifdef DEBUG_CONSOLE
-            fprintf(stderr, "escape sequence CSI%d;%d%c, %d parameters\n",
-                    s->esc_params[0], s->esc_params[1], ch, s->nb_esc_params);
-#endif
+            trace_console_putchar_csi(s->esc_params[0], s->esc_params[1],
+                                      ch, s->nb_esc_params);
             s->state = TTY_STATE_NORM;
             switch(ch) {
             case 'A':
@@ -983,9 +981,7 @@ static void console_putchar(QemuConsole *s, int ch)
                 s->y = s->y_saved;
                 break;
             default:
-#ifdef DEBUG_CONSOLE
-                fprintf(stderr, "unhandled escape character '%c'\n", ch);
-#endif
+                trace_console_putchar_unhandled(ch);
                 break;
             }
             break;
index b5f4f0bd407d26439f12c9dd6f1b6a2b4658a13b..6316f5ba00dfb1cb1806d91c938a9a5ccedae7a9 100644 (file)
--- a/ui/gtk.c
+++ b/ui/gtk.c
@@ -53,6 +53,7 @@
 #include <vte/vte.h>
 #include <math.h>
 
+#include "trace.h"
 #include "ui/console.h"
 #include "sysemu/sysemu.h"
 #include "qmp-commands.h"
 #include "keymaps.h"
 #include "sysemu/char.h"
 
-//#define DEBUG_GTK
-
-#ifdef DEBUG_GTK
-#define DPRINTF(fmt, ...) printf(fmt, ## __VA_ARGS__)
-#else
-#define DPRINTF(fmt, ...) do { } while (0)
-#endif
-
 #define MAX_VCS 10
 
 
@@ -302,7 +295,7 @@ static void gd_update(DisplayChangeListener *dcl,
     int fbw, fbh;
     int ww, wh;
 
-    DPRINTF("update(x=%d, y=%d, w=%d, h=%d)\n", x, y, w, h);
+    trace_gd_update(x, y, w, h);
 
     if (s->convert) {
         pixman_image_composite(PIXMAN_OP_SRC, s->ds->image, NULL, s->convert,
@@ -396,8 +389,7 @@ static void gd_switch(DisplayChangeListener *dcl,
     GtkDisplayState *s = container_of(dcl, GtkDisplayState, dcl);
     bool resized = true;
 
-    DPRINTF("resize(width=%d, height=%d)\n",
-            surface_width(surface), surface_height(surface));
+    trace_gd_switch(surface_width(surface), surface_height(surface));
 
     if (s->surface) {
         cairo_surface_destroy(s->surface);
@@ -732,9 +724,8 @@ static gboolean gd_key_event(GtkWidget *widget, GdkEventKey *key, void *opaque)
         qemu_keycode = 0;
     }
 
-    DPRINTF("translated GDK keycode %d to QEMU keycode %d (%s)\n",
-            gdk_keycode, qemu_keycode,
-            (key->type == GDK_KEY_PRESS) ? "down" : "up");
+    trace_gd_key_event(gdk_keycode, qemu_keycode,
+                       (key->type == GDK_KEY_PRESS) ? "down" : "up");
 
     for (i = 0; i < ARRAY_SIZE(modifier_keycode); i++) {
         if (qemu_keycode == modifier_keycode[i]) {
index 10d8c056f1d2769ccb7f4fb4bef3b66a53c1e3c4..1c70f60e0dd5dd98188a616f5210fc0146e8a655 100644 (file)
@@ -414,7 +414,7 @@ void kbd_put_keycode(int keycode)
     if (!runstate_is_running() && !runstate_check(RUN_STATE_SUSPENDED)) {
         return;
     }
-    if (entry) {
+    if (entry && entry->put_kbd) {
         entry->put_kbd(entry->opaque, keycode);
     }
 }
index 2bb13a2a59fbe1dafe231ab9d29adb422f089a06..af3e5cb15722fef2004745b70dcfdc5b1da61b44 100644 (file)
@@ -12,3 +12,4 @@ util-obj-y += qemu-option.o qemu-progress.o
 util-obj-y += hexdump.o
 util-obj-y += crc32c.o
 util-obj-y += throttle.o
+util-obj-y += getauxval.o
index b94013a8cb921cb4d90a5c007c74e243a42f8146..047003008bc3b7e08d964075fcb2095d6958a09e 100644 (file)
@@ -1,3 +1,4 @@
+#include "qemu-common.h"
 #include "qemu/cache-utils.h"
 
 #if defined(_ARCH_PPC)
@@ -9,31 +10,33 @@ struct qemu_cache_conf qemu_cache_conf = {
 #if defined _AIX
 #include <sys/systemcfg.h>
 
-static void ppc_init_cacheline_sizes(void)
+void qemu_cache_utils_init(void)
 {
     qemu_cache_conf.icache_bsize = _system_configuration.icache_line;
     qemu_cache_conf.dcache_bsize = _system_configuration.dcache_line;
 }
 
 #elif defined __linux__
+#include "qemu/osdep.h"
+#include "elf.h"
 
-#define QEMU_AT_NULL        0
-#define QEMU_AT_DCACHEBSIZE 19
-#define QEMU_AT_ICACHEBSIZE 20
-
-static void ppc_init_cacheline_sizes(char **envp)
+void qemu_cache_utils_init(void)
 {
-    unsigned long *auxv;
-
-    while (*envp++);
+    unsigned long dsize = qemu_getauxval(AT_DCACHEBSIZE);
+    unsigned long isize = qemu_getauxval(AT_ICACHEBSIZE);
 
-    for (auxv = (unsigned long *) envp; *auxv != QEMU_AT_NULL; auxv += 2) {
-        switch (*auxv) {
-        case QEMU_AT_DCACHEBSIZE: qemu_cache_conf.dcache_bsize = auxv[1]; break;
-        case QEMU_AT_ICACHEBSIZE: qemu_cache_conf.icache_bsize = auxv[1]; break;
-        default: break;
+    if (dsize == 0 || isize == 0) {
+        if (dsize == 0) {
+            fprintf(stderr, "getauxval AT_DCACHEBSIZE failed\n");
+        }
+        if (isize == 0) {
+            fprintf(stderr, "getauxval AT_ICACHEBSIZE failed\n");
         }
+        exit(1);
+
     }
+    qemu_cache_conf.dcache_bsize = dsize;
+    qemu_cache_conf.icache_bsize = isize;
 }
 
 #elif defined __APPLE__
@@ -41,7 +44,7 @@ static void ppc_init_cacheline_sizes(char **envp)
 #include <sys/types.h>
 #include <sys/sysctl.h>
 
-static void ppc_init_cacheline_sizes(void)
+void qemu_cache_utils_init(void)
 {
     size_t len;
     unsigned cacheline;
@@ -55,9 +58,8 @@ static void ppc_init_cacheline_sizes(void)
         qemu_cache_conf.icache_bsize = cacheline;
     }
 }
-#endif
 
-#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
+#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
 #include <errno.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -65,7 +67,7 @@ static void ppc_init_cacheline_sizes(void)
 #include <sys/types.h>
 #include <sys/sysctl.h>
 
-static void ppc_init_cacheline_sizes(void)
+void qemu_cache_utils_init(void)
 {
     size_t len = 4;
     unsigned cacheline;
@@ -81,17 +83,4 @@ static void ppc_init_cacheline_sizes(void)
 }
 #endif
 
-#ifdef __linux__
-void qemu_cache_utils_init(char **envp)
-{
-    ppc_init_cacheline_sizes(envp);
-}
-#else
-void qemu_cache_utils_init(char **envp)
-{
-    (void) envp;
-    ppc_init_cacheline_sizes();
-}
-#endif
-
 #endif /* _ARCH_PPC */
diff --git a/util/getauxval.c b/util/getauxval.c
new file mode 100644 (file)
index 0000000..476c883
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * QEMU access to the auxiliary vector
+ *
+ * Copyright (C) 2013 Red Hat, Inc
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "qemu-common.h"
+#include "qemu/osdep.h"
+
+#ifdef CONFIG_GETAUXVAL
+/* Don't inline this in qemu/osdep.h, because pulling in <sys/auxv.h> for
+   the system declaration of getauxval pulls in the system <elf.h>, which
+   conflicts with qemu's version.  */
+
+#include <sys/auxv.h>
+
+unsigned long qemu_getauxval(unsigned long key)
+{
+    return getauxval(key);
+}
+#elif defined(__linux__)
+#include "elf.h"
+
+/* Our elf.h doesn't contain Elf32_auxv_t and Elf64_auxv_t, which is ok because
+   that just makes it easier to define it properly for the host here.  */
+typedef struct {
+    unsigned long a_type;
+    unsigned long a_val;
+} ElfW_auxv_t;
+
+static const ElfW_auxv_t *auxv;
+
+void qemu_init_auxval(char **envp)
+{
+    /* The auxiliary vector is located just beyond the initial environment.  */
+    while (*envp++ != NULL) {
+        continue;
+    }
+    auxv = (const ElfW_auxv_t *)envp;
+}
+
+unsigned long qemu_getauxval(unsigned long type)
+{
+    /* If we were able to find the auxiliary vector, use it.  */
+    if (auxv) {
+        const ElfW_auxv_t *a;
+        for (a = auxv; a->a_type != 0; a++) {
+            if (a->a_type == type) {
+                return a->a_val;
+            }
+        }
+    }
+
+    return 0;
+}
+#endif
diff --git a/vl.c b/vl.c
index 8d5d874e6853746be878923d8b650b70df93e3d2..b0399de25f26b939820f7082f5c67f35885cdb46 100644 (file)
--- a/vl.c
+++ b/vl.c
@@ -188,9 +188,7 @@ static int display_remote;
 const char* keyboard_layout = NULL;
 ram_addr_t ram_size;
 const char *mem_path = NULL;
-#ifdef MAP_POPULATE
 int mem_prealloc = 0; /* force preallocation of physical target memory */
-#endif
 int nb_nics;
 NICInfo nd_table[MAX_NICS];
 int autostart;
@@ -428,6 +426,10 @@ static QemuOptsList qemu_machine_opts = {
             .name = "usb",
             .type = QEMU_OPT_BOOL,
             .help = "Set on/off to enable/disable usb",
+        },{
+            .name = "firmware",
+            .type = QEMU_OPT_STRING,
+            .help = "firmware image",
         },
         { /* End of list */ }
     },
@@ -2894,7 +2896,8 @@ int main(int argc, char **argv, char **envp)
     init_clocks();
     rtc_clock = QEMU_CLOCK_HOST;
 
-    qemu_cache_utils_init(envp);
+    qemu_init_auxval(envp);
+    qemu_cache_utils_init();
 
     QLIST_INIT (&vm_change_state_head);
     os_setup_early_signal_handling();
@@ -3206,11 +3209,9 @@ int main(int argc, char **argv, char **envp)
             case QEMU_OPTION_mempath:
                 mem_path = optarg;
                 break;
-#ifdef MAP_POPULATE
             case QEMU_OPTION_mem_prealloc:
                 mem_prealloc = 1;
                 break;
-#endif
             case QEMU_OPTION_d:
                 log_mask = optarg;
                 break;
@@ -3229,7 +3230,7 @@ int main(int argc, char **argv, char **envp)
                 }
                 break;
             case QEMU_OPTION_bios:
-                bios_name = optarg;
+                qemu_opts_set(qemu_find_opts("machine"), 0, "firmware", optarg);
                 break;
             case QEMU_OPTION_singlestep:
                 singlestep = 1;
@@ -4050,6 +4051,7 @@ int main(int argc, char **argv, char **envp)
     kernel_filename = qemu_opt_get(machine_opts, "kernel");
     initrd_filename = qemu_opt_get(machine_opts, "initrd");
     kernel_cmdline = qemu_opt_get(machine_opts, "append");
+    bios_name = qemu_opt_get(machine_opts, "firmware");
 
     boot_order = machine->default_boot_order;
     opts = qemu_opts_find(qemu_find_opts("boot-opts"), NULL);
index 9a27899ca1bff7b95fc4cdf66e32de62872ee8ad..4a594bdd9b5654bf8128200c7286bae36a6adce1 100644 (file)
--- a/xen-all.c
+++ b/xen-all.c
@@ -369,8 +369,8 @@ static int xen_remove_from_physmap(XenIOState *state,
     phys_offset = physmap->phys_offset;
     size = physmap->size;
 
-    DPRINTF("unmapping vram to %"HWADDR_PRIx" - %"HWADDR_PRIx", from ",
-            "%"HWADDR_PRIx"\n", phys_offset, phys_offset + size, start_addr);
+    DPRINTF("unmapping vram to %"HWADDR_PRIx" - %"HWADDR_PRIx", at "
+            "%"HWADDR_PRIx"\n", start_addr, start_addr + size, phys_offset);
 
     size >>= TARGET_PAGE_BITS;
     start_addr >>= TARGET_PAGE_BITS;