Merge remote branch 'mst/for_anthony' into staging
diff --git a/.gitignore b/.gitignore
index cdd6aad..d7d2146 100644
--- a/.gitignore
+++ b/.gitignore
@@ -46,6 +46,7 @@
 patches
 pc-bios/bios-pq/status
 pc-bios/vgabios-pq/status
+pc-bios/optionrom/linuxboot.bin
 pc-bios/optionrom/multiboot.bin
 pc-bios/optionrom/multiboot.raw
 .stgit-*
diff --git a/block.c b/block.c
index 3f3496e..30ae2b1 100644
--- a/block.c
+++ b/block.c
@@ -396,8 +396,8 @@
         if (is_protocol)
             snprintf(backing_filename, sizeof(backing_filename),
                      "%s", filename);
-        else
-            realpath(filename, backing_filename);
+        else if (!realpath(filename, backing_filename))
+            return -errno;
 
         bdrv_qcow2 = bdrv_find_format("qcow2");
         options = parse_option_parameters("", bdrv_qcow2->create_options, NULL);
diff --git a/block/bochs.c b/block/bochs.c
index bac81c4..3489258 100644
--- a/block/bochs.c
+++ b/block/bochs.c
@@ -146,7 +146,9 @@
       bs->total_sectors = le64_to_cpu(bochs.extra.redolog.disk) / 512;
     }
 
-    lseek(s->fd, le32_to_cpu(bochs.header), SEEK_SET);
+    if (lseek(s->fd, le32_to_cpu(bochs.header), SEEK_SET) == (off_t)-1) {
+        goto fail;
+    }
 
     s->catalog_size = le32_to_cpu(bochs.extra.redolog.catalog);
     s->catalog_bitmap = qemu_malloc(s->catalog_size * 4);
@@ -197,9 +199,13 @@
 //	bitmap_offset, block_offset);
 
     // read in bitmap for current extent
-    lseek(s->fd, bitmap_offset + (extent_offset / 8), SEEK_SET);
+    if (lseek(s->fd, bitmap_offset + (extent_offset / 8), SEEK_SET) ==
+        (off_t)-1) {
+        return -1;
+    }
 
-    read(s->fd, &bitmap_entry, 1);
+    if (read(s->fd, &bitmap_entry, 1) != 1)
+        return -1;
 
     if (!((bitmap_entry >> (extent_offset % 8)) & 1))
     {
@@ -208,7 +214,9 @@
 	return -1; // not allocated
     }
 
-    lseek(s->fd, block_offset, SEEK_SET);
+    if (lseek(s->fd, block_offset, SEEK_SET) == (off_t)-1) {
+        return -1;
+    }
 
     return 0;
 }
diff --git a/configure b/configure
index d815c7a..18aed43 100755
--- a/configure
+++ b/configure
@@ -2141,7 +2141,7 @@
 tools=
 if test `expr "$target_list" : ".*softmmu.*"` != 0 ; then
   tools="qemu-img\$(EXESUF) qemu-io\$(EXESUF) $tools"
-  if [ "$linux" = "yes" ] ; then
+  if [ "$linux" = "yes" -o "$bsd" = "yes" -o "$solaris" = "yes" ] ; then
       tools="qemu-nbd\$(EXESUF) $tools"
     if [ "$check_utests" = "yes" ]; then
       tools="check-qint check-qstring check-qdict check-qlist $tools"
diff --git a/hw/apb_pci.c b/hw/apb_pci.c
index fe8faa6..f05308b 100644
--- a/hw/apb_pci.c
+++ b/hw/apb_pci.c
@@ -225,6 +225,8 @@
     d->host_state.bus = pci_register_bus(&d->busdev.qdev, "pci",
                                          pci_apb_set_irq, pci_pbm_map_irq, pic,
                                          0, 32);
+    pci_bus_set_mem_base(d->host_state.bus, mem_base);
+
     pci_create_simple(d->host_state.bus, 0, "pbm");
     /* APB secondary busses */
     *bus2 = pci_bridge_init(d->host_state.bus, PCI_DEVFN(1, 0),
diff --git a/hw/boards.h b/hw/boards.h
index e1beda3..6f0f0d7 100644
--- a/hw/boards.h
+++ b/hw/boards.h
@@ -19,7 +19,7 @@
     QEMUMachineInitFunc *init;
     int use_scsi;
     int max_cpus;
-    int no_serial:1,
+    unsigned int no_serial:1,
         no_parallel:1,
         use_virtcon:1,
         no_vga:1,
diff --git a/hw/e1000.c b/hw/e1000.c
index 51c9d7d..fd3059a 100644
--- a/hw/e1000.c
+++ b/hw/e1000.c
@@ -1,6 +1,9 @@
 /*
  * QEMU e1000 emulation
  *
+ * Software developer's manual:
+ * http://download.intel.com/design/network/manuals/8254x_GBe_SDM.pdf
+ *
  * Nir Peleg, Tutis Systems Ltd. for Qumranet Inc.
  * Copyright (c) 2008 Qumranet
  * Based on work done by:
diff --git a/hw/elf_ops.h b/hw/elf_ops.h
index 6093dea..14b9ec0 100644
--- a/hw/elf_ops.h
+++ b/hw/elf_ops.h
@@ -149,9 +149,14 @@
         }
         i++;
     }
-    syms = qemu_realloc(syms, nsyms * sizeof(*syms));
+    if (nsyms) {
+        syms = qemu_realloc(syms, nsyms * sizeof(*syms));
 
-    qsort(syms, nsyms, sizeof(*syms), glue(symcmp, SZ));
+        qsort(syms, nsyms, sizeof(*syms), glue(symcmp, SZ));
+    } else {
+        qemu_free(syms);
+        syms = NULL;
+    }
 
     /* String table */
     if (symtab->sh_link >= ehdr->e_shnum)
diff --git a/hw/loader.c b/hw/loader.c
index 2ceb8eb..3aba47c 100644
--- a/hw/loader.c
+++ b/hw/loader.c
@@ -636,6 +636,9 @@
     Rom *rom;
 
     QTAILQ_FOREACH(rom, &roms, next) {
+        if (rom->fw_file) {
+            continue;
+        }
         if (rom->data == NULL)
             continue;
         cpu_physical_memory_write_rom(rom->addr, rom->data, rom->romsize);
@@ -654,6 +657,9 @@
     Rom *rom;
 
     QTAILQ_FOREACH(rom, &roms, next) {
+        if (rom->fw_file) {
+            continue;
+        }
         if (addr > rom->addr) {
             fprintf(stderr, "rom: requested regions overlap "
                     "(rom %s. free=0x" TARGET_FMT_plx
@@ -689,6 +695,9 @@
     Rom *rom;
 
     QTAILQ_FOREACH(rom, &roms, next) {
+        if (rom->fw_file) {
+            continue;
+        }
         if (rom->addr > addr)
             continue;
         if (rom->addr + rom->romsize < addr)
@@ -711,6 +720,9 @@
     Rom *rom;
 
     QTAILQ_FOREACH(rom, &roms, next) {
+        if (rom->fw_file) {
+            continue;
+        }
         if (rom->addr + rom->romsize < addr)
             continue;
         if (rom->addr > end)
@@ -752,7 +764,7 @@
     Rom *rom;
 
     QTAILQ_FOREACH(rom, &roms, next) {
-        if (rom->addr) {
+        if (!rom->fw_file) {
             monitor_printf(mon, "addr=" TARGET_FMT_plx
                            " size=0x%06zx mem=%s name=\"%s\" \n",
                            rom->addr, rom->romsize,
diff --git a/hw/lsi53c895a.c b/hw/lsi53c895a.c
index 463a889..f6660a3 100644
--- a/hw/lsi53c895a.c
+++ b/hw/lsi53c895a.c
@@ -607,7 +607,7 @@
     id = (tag >> 8) & 0xf;
     s->ssid = id | 0x80;
     /* LSI53C700 Family Compatibility, see LSI53C895A 4-73 */
-    if (!s->dcntl & LSI_DCNTL_COM) {
+    if (!(s->dcntl & LSI_DCNTL_COM)) {
         s->sfbr = 1 << (id & 0x7);
     }
     DPRINTF("Reselected target %d\n", id);
diff --git a/hw/mac_dbdma.c b/hw/mac_dbdma.c
index 98dccfd..8ec3d99 100644
--- a/hw/mac_dbdma.c
+++ b/hw/mac_dbdma.c
@@ -184,19 +184,19 @@
 static void dbdma_cmdptr_load(DBDMA_channel *ch)
 {
     DBDMA_DPRINTF("dbdma_cmdptr_load 0x%08x\n",
-                  be32_to_cpu(ch->regs[DBDMA_CMDPTR_LO]));
-    cpu_physical_memory_read(be32_to_cpu(ch->regs[DBDMA_CMDPTR_LO]),
+                  ch->regs[DBDMA_CMDPTR_LO]);
+    cpu_physical_memory_read(ch->regs[DBDMA_CMDPTR_LO],
                              (uint8_t*)&ch->current, sizeof(dbdma_cmd));
 }
 
 static void dbdma_cmdptr_save(DBDMA_channel *ch)
 {
     DBDMA_DPRINTF("dbdma_cmdptr_save 0x%08x\n",
-                  be32_to_cpu(ch->regs[DBDMA_CMDPTR_LO]));
+                  ch->regs[DBDMA_CMDPTR_LO]);
     DBDMA_DPRINTF("xfer_status 0x%08x res_count 0x%04x\n",
                   le16_to_cpu(ch->current.xfer_status),
                   le16_to_cpu(ch->current.res_count));
-    cpu_physical_memory_write(be32_to_cpu(ch->regs[DBDMA_CMDPTR_LO]),
+    cpu_physical_memory_write(ch->regs[DBDMA_CMDPTR_LO],
                               (uint8_t*)&ch->current, sizeof(dbdma_cmd));
 }
 
@@ -204,8 +204,8 @@
 {
     DBDMA_DPRINTF("kill_channel\n");
 
-    ch->regs[DBDMA_STATUS] |= cpu_to_be32(DEAD);
-    ch->regs[DBDMA_STATUS] &= cpu_to_be32(~ACTIVE);
+    ch->regs[DBDMA_STATUS] |= DEAD;
+    ch->regs[DBDMA_STATUS] &= ~ACTIVE;
 
     qemu_irq_raise(ch->irq);
 }
@@ -230,10 +230,10 @@
         return;
     }
 
-    status = be32_to_cpu(ch->regs[DBDMA_STATUS]) & DEVSTAT;
+    status = ch->regs[DBDMA_STATUS] & DEVSTAT;
 
-    sel_mask = (be32_to_cpu(ch->regs[DBDMA_INTR_SEL]) >> 16) & 0x0f;
-    sel_value = be32_to_cpu(ch->regs[DBDMA_INTR_SEL]) & 0x0f;
+    sel_mask = (ch->regs[DBDMA_INTR_SEL] >> 16) & 0x0f;
+    sel_value = ch->regs[DBDMA_INTR_SEL] & 0x0f;
 
     cond = (status & sel_mask) == (sel_value & sel_mask);
 
@@ -268,10 +268,10 @@
         return 1;
     }
 
-    status = be32_to_cpu(ch->regs[DBDMA_STATUS]) & DEVSTAT;
+    status = ch->regs[DBDMA_STATUS] & DEVSTAT;
 
-    sel_mask = (be32_to_cpu(ch->regs[DBDMA_WAIT_SEL]) >> 16) & 0x0f;
-    sel_value = be32_to_cpu(ch->regs[DBDMA_WAIT_SEL]) & 0x0f;
+    sel_mask = (ch->regs[DBDMA_WAIT_SEL] >> 16) & 0x0f;
+    sel_value = ch->regs[DBDMA_WAIT_SEL] & 0x0f;
 
     cond = (status & sel_mask) == (sel_value & sel_mask);
 
@@ -292,10 +292,10 @@
 {
     uint32_t cp;
 
-    ch->regs[DBDMA_STATUS] &= cpu_to_be32(~BT);
+    ch->regs[DBDMA_STATUS] &= ~BT;
 
-    cp = be32_to_cpu(ch->regs[DBDMA_CMDPTR_LO]);
-    ch->regs[DBDMA_CMDPTR_LO] = cpu_to_be32(cp + sizeof(dbdma_cmd));
+    cp = ch->regs[DBDMA_CMDPTR_LO];
+    ch->regs[DBDMA_CMDPTR_LO] = cp + sizeof(dbdma_cmd);
     dbdma_cmdptr_load(ch);
 }
 
@@ -304,7 +304,7 @@
     dbdma_cmd *current = &ch->current;
 
     ch->regs[DBDMA_CMDPTR_LO] = current->cmd_dep;
-    ch->regs[DBDMA_STATUS] |= cpu_to_be32(BT);
+    ch->regs[DBDMA_STATUS] |= BT;
     dbdma_cmdptr_load(ch);
 }
 
@@ -331,10 +331,10 @@
         return;
     }
 
-    status = be32_to_cpu(ch->regs[DBDMA_STATUS]) & DEVSTAT;
+    status = ch->regs[DBDMA_STATUS] & DEVSTAT;
 
-    sel_mask = (be32_to_cpu(ch->regs[DBDMA_BRANCH_SEL]) >> 16) & 0x0f;
-    sel_value = be32_to_cpu(ch->regs[DBDMA_BRANCH_SEL]) & 0x0f;
+    sel_mask = (ch->regs[DBDMA_BRANCH_SEL] >> 16) & 0x0f;
+    sel_value = ch->regs[DBDMA_BRANCH_SEL] & 0x0f;
 
     cond = (status & sel_mask) == (sel_value & sel_mask);
 
@@ -365,19 +365,19 @@
     if (conditional_wait(ch))
         goto wait;
 
-    current->xfer_status = cpu_to_le16(be32_to_cpu(ch->regs[DBDMA_STATUS]));
-    current->res_count = cpu_to_le16(be32_to_cpu(io->len));
+    current->xfer_status = cpu_to_le16(ch->regs[DBDMA_STATUS]);
+    current->res_count = cpu_to_le16(io->len);
     dbdma_cmdptr_save(ch);
     if (io->is_last)
-        ch->regs[DBDMA_STATUS] &= cpu_to_be32(~FLUSH);
+        ch->regs[DBDMA_STATUS] &= ~FLUSH;
 
     conditional_interrupt(ch);
     conditional_branch(ch);
 
 wait:
     ch->processing = 0;
-    if ((ch->regs[DBDMA_STATUS] & cpu_to_be32(RUN)) &&
-        (ch->regs[DBDMA_STATUS] & cpu_to_be32(ACTIVE)))
+    if ((ch->regs[DBDMA_STATUS] & RUN) &&
+        (ch->regs[DBDMA_STATUS] & ACTIVE))
         channel_run(ch);
 }
 
@@ -456,9 +456,9 @@
     if (conditional_wait(ch))
         goto wait;
 
-    current->xfer_status = cpu_to_le16(be32_to_cpu(ch->regs[DBDMA_STATUS]));
+    current->xfer_status = cpu_to_le16(ch->regs[DBDMA_STATUS]);
     dbdma_cmdptr_save(ch);
-    ch->regs[DBDMA_STATUS] &= cpu_to_be32(~FLUSH);
+    ch->regs[DBDMA_STATUS] &= ~FLUSH;
 
     conditional_interrupt(ch);
     next(ch);
@@ -494,9 +494,9 @@
     if (conditional_wait(ch))
         goto wait;
 
-    current->xfer_status = cpu_to_le16(be32_to_cpu(ch->regs[DBDMA_STATUS]));
+    current->xfer_status = cpu_to_le16(ch->regs[DBDMA_STATUS]);
     dbdma_cmdptr_save(ch);
-    ch->regs[DBDMA_STATUS] &= cpu_to_be32(~FLUSH);
+    ch->regs[DBDMA_STATUS] &= ~FLUSH;
 
     conditional_interrupt(ch);
     next(ch);
@@ -512,7 +512,7 @@
     if (conditional_wait(ch))
         goto wait;
 
-    current->xfer_status = cpu_to_le16(be32_to_cpu(ch->regs[DBDMA_STATUS]));
+    current->xfer_status = cpu_to_le16(ch->regs[DBDMA_STATUS]);
     dbdma_cmdptr_save(ch);
 
     conditional_interrupt(ch);
@@ -524,7 +524,7 @@
 
 static void stop(DBDMA_channel *ch)
 {
-    ch->regs[DBDMA_STATUS] &= cpu_to_be32(~(ACTIVE|DEAD|FLUSH));
+    ch->regs[DBDMA_STATUS] &= ~(ACTIVE|DEAD|FLUSH);
 
     /* the stop command does not increment command pointer */
 }
@@ -541,7 +541,7 @@
 
     /* clear WAKE flag at command fetch */
 
-    ch->regs[DBDMA_STATUS] &= cpu_to_be32(~WAKE);
+    ch->regs[DBDMA_STATUS] &= ~WAKE;
 
     cmd = le16_to_cpu(current->command) & COMMAND_MASK;
 
@@ -618,7 +618,7 @@
     int channel;
 
     for (channel = 0; channel < DBDMA_CHANNELS; channel++, ch++) {
-            uint32_t status = be32_to_cpu(ch->regs[DBDMA_STATUS]);
+            uint32_t status = ch->regs[DBDMA_STATUS];
             if (!ch->processing && (status & RUN) && (status & ACTIVE))
                 channel_run(ch);
     }
@@ -660,12 +660,12 @@
     uint16_t mask, value;
     uint32_t status;
 
-    mask = (be32_to_cpu(ch->regs[DBDMA_CONTROL]) >> 16) & 0xffff;
-    value = be32_to_cpu(ch->regs[DBDMA_CONTROL]) & 0xffff;
+    mask = (ch->regs[DBDMA_CONTROL] >> 16) & 0xffff;
+    value = ch->regs[DBDMA_CONTROL] & 0xffff;
 
     value &= (RUN | PAUSE | FLUSH | WAKE | DEVSTAT);
 
-    status = be32_to_cpu(ch->regs[DBDMA_STATUS]);
+    status = ch->regs[DBDMA_STATUS];
 
     status = (value & mask) | (status & ~mask);
 
@@ -677,14 +677,14 @@
     }
     if (status & PAUSE)
         status &= ~ACTIVE;
-    if ((be32_to_cpu(ch->regs[DBDMA_STATUS]) & RUN) && !(status & RUN)) {
+    if ((ch->regs[DBDMA_STATUS] & RUN) && !(status & RUN)) {
         /* RUN is cleared */
         status &= ~(ACTIVE|DEAD);
     }
 
     DBDMA_DPRINTF("    status 0x%08x\n", status);
 
-    ch->regs[DBDMA_STATUS] = cpu_to_be32(status);
+    ch->regs[DBDMA_STATUS] = status;
 
     if (status & ACTIVE)
         qemu_bh_schedule(dbdma_bh);
@@ -703,10 +703,14 @@
     DBDMA_DPRINTF("channel 0x%x reg 0x%x\n",
                   (uint32_t)addr >> DBDMA_CHANNEL_SHIFT, reg);
 
+#ifdef TARGET_WORDS_BIGENDIAN
+    value = bswap32(value);
+#endif
+
     /* cmdptr cannot be modified if channel is RUN or ACTIVE */
 
     if (reg == DBDMA_CMDPTR_LO &&
-        (ch->regs[DBDMA_STATUS] & cpu_to_be32(RUN | ACTIVE)))
+        (ch->regs[DBDMA_STATUS] & (RUN | ACTIVE)))
 	return;
 
     ch->regs[reg] = value;
@@ -717,7 +721,7 @@
         break;
     case DBDMA_CMDPTR_LO:
         /* 16-byte aligned */
-        ch->regs[DBDMA_CMDPTR_LO] &= cpu_to_be32(~0xf);
+        ch->regs[DBDMA_CMDPTR_LO] &= ~0xf;
         dbdma_cmdptr_load(ch);
         break;
     case DBDMA_STATUS:
@@ -782,6 +786,9 @@
         break;
     }
 
+#ifdef TARGET_WORDS_BIGENDIAN
+    value = bswap32(value);
+#endif
     return value;
 }
 
diff --git a/hw/pc.c b/hw/pc.c
index db7d58e..83f8dd0 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -613,7 +613,10 @@
 
         mb_kernel_data = qemu_malloc(mb_kernel_size);
         fseek(f, mb_kernel_text_offset, SEEK_SET);
-        fread(mb_kernel_data, 1, mb_kernel_size, f);
+        if (fread(mb_kernel_data, 1, mb_kernel_size, f) != mb_kernel_size) {
+            fprintf(stderr, "fread() failed\n");
+            exit(1);
+        }
         fclose(f);
     }
 
@@ -887,8 +890,14 @@
     setup  = qemu_malloc(setup_size);
     kernel = qemu_malloc(kernel_size);
     fseek(f, 0, SEEK_SET);
-    fread(setup, 1, setup_size, f);
-    fread(kernel, 1, kernel_size, f);
+    if (fread(setup, 1, setup_size, f) != setup_size) {
+        fprintf(stderr, "fread() failed\n");
+        exit(1);
+    }
+    if (fread(kernel, 1, kernel_size, f) != kernel_size) {
+        fprintf(stderr, "fread() failed\n");
+        exit(1);
+    }
     fclose(f);
     memcpy(setup, header, MIN(sizeof(header), setup_size));
 
diff --git a/hw/pci.c b/hw/pci.c
index bf6ceb9..08e51f8 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -44,6 +44,7 @@
     void *irq_opaque;
     PCIDevice *devices[256];
     PCIDevice *parent_dev;
+    target_phys_addr_t mem_base;
 
     QLIST_HEAD(, PCIBus) child; /* this will be replaced by qdev later */
     QLIST_ENTRY(PCIBus) sibling;/* this will be replaced by qdev later */
@@ -71,7 +72,6 @@
 static void pci_set_irq(void *opaque, int irq_num, int level);
 static int pci_add_option_rom(PCIDevice *pdev);
 
-target_phys_addr_t pci_mem_base;
 static uint16_t pci_default_sub_vendor_id = PCI_SUBVENDOR_ID_REDHAT_QUMRANET;
 static uint16_t pci_default_sub_device_id = PCI_SUBDEVICE_ID_QEMU;
 
@@ -237,6 +237,11 @@
     bus->hotplug = hotplug;
 }
 
+void pci_bus_set_mem_base(PCIBus *bus, target_phys_addr_t base)
+{
+    bus->mem_base = base;
+}
+
 PCIBus *pci_register_bus(DeviceState *parent, const char *name,
                          pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
                          void *irq_opaque, int devfn_min, int nirq)
@@ -634,9 +639,11 @@
     }
     return pci_dev;
 }
-static target_phys_addr_t pci_to_cpu_addr(target_phys_addr_t addr)
+
+static target_phys_addr_t pci_to_cpu_addr(PCIBus *bus,
+                                          target_phys_addr_t addr)
 {
-    return addr + pci_mem_base;
+    return addr + bus->mem_base;
 }
 
 static void pci_unregister_io_regions(PCIDevice *pci_dev)
@@ -651,9 +658,10 @@
         if (r->type == PCI_BASE_ADDRESS_SPACE_IO) {
             isa_unassign_ioport(r->addr, r->filtered_size);
         } else {
-            cpu_register_physical_memory(pci_to_cpu_addr(r->addr),
-                                                     r->filtered_size,
-                                                     IO_MEM_UNASSIGNED);
+            cpu_register_physical_memory(pci_to_cpu_addr(pci_dev->bus,
+                                                         r->addr),
+                                         r->filtered_size,
+                                         IO_MEM_UNASSIGNED);
         }
     }
 }
@@ -925,7 +933,7 @@
                     isa_unassign_ioport(r->addr, r->filtered_size);
                 }
             } else {
-                cpu_register_physical_memory(pci_to_cpu_addr(r->addr),
+                cpu_register_physical_memory(pci_to_cpu_addr(d->bus, r->addr),
                                              r->filtered_size,
                                              IO_MEM_UNASSIGNED);
                 qemu_unregister_coalesced_mmio(r->addr, r->filtered_size);
@@ -941,7 +949,12 @@
              * Teach them such cases, such that filtered_size < size and
              * addr & (size - 1) != 0.
              */
-            r->map_func(d, i, r->addr, r->filtered_size, r->type);
+            if (r->type & PCI_BASE_ADDRESS_SPACE_IO) {
+                r->map_func(d, i, r->addr, r->filtered_size, r->type);
+            } else {
+                r->map_func(d, i, pci_to_cpu_addr(d->bus, r->addr),
+                            r->filtered_size, r->type);
+            }
         }
     }
 }
diff --git a/hw/pci.h b/hw/pci.h
index 5687bcb..9b5ae97 100644
--- a/hw/pci.h
+++ b/hw/pci.h
@@ -10,8 +10,6 @@
 
 /* PCI bus */
 
-extern target_phys_addr_t pci_mem_base;
-
 #define PCI_DEVFN(slot, func)   ((((slot) & 0x1f) << 3) | ((func) & 0x07))
 #define PCI_SLOT(devfn)         (((devfn) >> 3) & 0x1f)
 #define PCI_FUNC(devfn)         ((devfn) & 0x07)
@@ -219,6 +217,8 @@
                          pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
                          void *irq_opaque, int devfn_min, int nirq);
 
+void pci_bus_set_mem_base(PCIBus *bus, target_phys_addr_t base);
+
 PCIDevice *pci_nic_init(NICInfo *nd, const char *default_model,
                         const char *default_devaddr);
 PCIDevice *pci_nic_init_nofail(NICInfo *nd, const char *default_model,
diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c
index 736e91e..a2f9cc1 100644
--- a/hw/scsi-bus.c
+++ b/hw/scsi-bus.c
@@ -374,6 +374,7 @@
     static const char *names[] = {
         [ TEST_UNIT_READY          ] = "TEST_UNIT_READY",
         [ REZERO_UNIT              ] = "REZERO_UNIT",
+        /* REWIND and REZERO_UNIT use the same operation code */
         [ REQUEST_SENSE            ] = "REQUEST_SENSE",
         [ FORMAT_UNIT              ] = "FORMAT_UNIT",
         [ READ_BLOCK_LIMITS        ] = "READ_BLOCK_LIMITS",
@@ -409,7 +410,7 @@
         [ SEARCH_LOW               ] = "SEARCH_LOW",
         [ SET_LIMITS               ] = "SET_LIMITS",
         [ PRE_FETCH                ] = "PRE_FETCH",
-        [ READ_POSITION            ] = "READ_POSITION",
+        /* READ_POSITION and PRE_FETCH use the same operation code */
         [ SYNCHRONIZE_CACHE        ] = "SYNCHRONIZE_CACHE",
         [ LOCK_UNLOCK_CACHE        ] = "LOCK_UNLOCK_CACHE",
         [ READ_DEFECT_DATA         ] = "READ_DEFECT_DATA",
@@ -443,7 +444,6 @@
         [ SEND_VOLUME_TAG          ] = "SEND_VOLUME_TAG",
         [ WRITE_LONG_2             ] = "WRITE_LONG_2",
 
-        [ REWIND                   ] = "REWIND",
         [ REPORT_DENSITY_SUPPORT   ] = "REPORT_DENSITY_SUPPORT",
         [ GET_CONFIGURATION        ] = "GET_CONFIGURATION",
         [ READ_16                  ] = "READ_16",
diff --git a/hw/sun4m.c b/hw/sun4m.c
index 7db00b8..ad1efb1 100644
--- a/hw/sun4m.c
+++ b/hw/sun4m.c
@@ -917,6 +917,9 @@
     if (kernel_cmdline) {
         fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, CMDLINE_ADDR);
         pstrcpy_targphys("cmdline", CMDLINE_ADDR, TARGET_PAGE_SIZE, kernel_cmdline);
+        fw_cfg_add_bytes(fw_cfg, FW_CFG_CMDLINE_DATA,
+                         (uint8_t*)strdup(kernel_cmdline),
+                         strlen(kernel_cmdline) + 1);
     } else {
         fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, 0);
     }
@@ -1500,6 +1503,9 @@
     if (kernel_cmdline) {
         fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, CMDLINE_ADDR);
         pstrcpy_targphys("cmdline", CMDLINE_ADDR, TARGET_PAGE_SIZE, kernel_cmdline);
+        fw_cfg_add_bytes(fw_cfg, FW_CFG_CMDLINE_DATA,
+                         (uint8_t*)strdup(kernel_cmdline),
+                         strlen(kernel_cmdline) + 1);
     } else {
         fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, 0);
     }
@@ -1688,6 +1694,9 @@
     if (kernel_cmdline) {
         fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, CMDLINE_ADDR);
         pstrcpy_targphys("cmdline", CMDLINE_ADDR, TARGET_PAGE_SIZE, kernel_cmdline);
+        fw_cfg_add_bytes(fw_cfg, FW_CFG_CMDLINE_DATA,
+                         (uint8_t*)strdup(kernel_cmdline),
+                         strlen(kernel_cmdline) + 1);
     } else {
         fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, 0);
     }
diff --git a/hw/sun4u.c b/hw/sun4u.c
index a7a227b..9d46f08 100644
--- a/hw/sun4u.c
+++ b/hw/sun4u.c
@@ -39,12 +39,20 @@
 #include "elf.h"
 
 //#define DEBUG_IRQ
+//#define DEBUG_EBUS
 
 #ifdef DEBUG_IRQ
-#define DPRINTF(fmt, ...)                                       \
+#define CPUIRQ_DPRINTF(fmt, ...)                                \
     do { printf("CPUIRQ: " fmt , ## __VA_ARGS__); } while (0)
 #else
-#define DPRINTF(fmt, ...)
+#define CPUIRQ_DPRINTF(fmt, ...)
+#endif
+
+#ifdef DEBUG_EBUS
+#define EBUS_DPRINTF(fmt, ...)                                  \
+    do { printf("EBUS: " fmt , ## __VA_ARGS__); } while (0)
+#else
+#define EBUS_DPRINTF(fmt, ...)
 #endif
 
 #define KERNEL_LOAD_ADDR     0x00404000
@@ -238,14 +246,14 @@
 
                 env->interrupt_index = TT_EXTINT | i;
                 if (old_interrupt != env->interrupt_index) {
-                    DPRINTF("Set CPU IRQ %d\n", i);
+                    CPUIRQ_DPRINTF("Set CPU IRQ %d\n", i);
                     cpu_interrupt(env, CPU_INTERRUPT_HARD);
                 }
                 break;
             }
         }
     } else if (!pil && (env->interrupt_index & ~15) == TT_EXTINT) {
-        DPRINTF("Reset CPU IRQ %d\n", env->interrupt_index & 15);
+        CPUIRQ_DPRINTF("Reset CPU IRQ %d\n", env->interrupt_index & 15);
         env->interrupt_index = 0;
         cpu_reset_interrupt(env, CPU_INTERRUPT_HARD);
     }
@@ -256,12 +264,12 @@
     CPUState *env = opaque;
 
     if (level) {
-        DPRINTF("Raise CPU IRQ %d\n", irq);
+        CPUIRQ_DPRINTF("Raise CPU IRQ %d\n", irq);
         env->halted = 0;
         env->pil_in |= 1 << irq;
         cpu_check_irqs(env);
     } else {
-        DPRINTF("Lower CPU IRQ %d\n", irq);
+        CPUIRQ_DPRINTF("Lower CPU IRQ %d\n", irq);
         env->pil_in &= ~(1 << irq);
         cpu_check_irqs(env);
     }
@@ -347,7 +355,8 @@
 static void ebus_mmio_mapfunc(PCIDevice *pci_dev, int region_num,
                               pcibus_t addr, pcibus_t size, int type)
 {
-    DPRINTF("Mapping region %d registers at %08x\n", region_num, addr);
+    EBUS_DPRINTF("Mapping region %d registers at %" FMT_PCIBUS "\n",
+                 region_num, addr);
     switch (region_num) {
     case 0:
         isa_mmio_init(addr, 0x1000000);
@@ -652,6 +661,9 @@
     if (kernel_cmdline) {
         fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, CMDLINE_ADDR);
         pstrcpy_targphys("cmdline", CMDLINE_ADDR, TARGET_PAGE_SIZE, kernel_cmdline);
+        fw_cfg_add_bytes(fw_cfg, FW_CFG_CMDLINE_DATA,
+                         (uint8_t*)strdup(kernel_cmdline),
+                         strlen(kernel_cmdline) + 1);
     } else {
         fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, 0);
     }
diff --git a/linux-user/main.c b/linux-user/main.c
index d8bb830..a0d8ce7 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -548,6 +548,8 @@
     case 3:
         segv = get_user_u32(val, addr);
         break;
+    default:
+        abort();
     }
     if (segv) {
         env->cp15.c6_data = addr;
diff --git a/path.c b/path.c
index cc9e007..0d2bf14 100644
--- a/path.c
+++ b/path.c
@@ -46,7 +46,10 @@
 {
     struct pathelem *new = malloc(sizeof(*new));
     new->name = strdup(name);
-    asprintf(&new->pathname, "%s/%s", root, name);
+    if (asprintf(&new->pathname, "%s/%s", root, name) == -1) {
+        printf("Cannot allocate memory\n");
+        exit(1);
+    }
     new->num_entries = 0;
     return new;
 }
diff --git a/pc-bios/README b/pc-bios/README
index 3f2c978..1b7a666 100644
--- a/pc-bios/README
+++ b/pc-bios/README
@@ -13,8 +13,9 @@
 - OpenBIOS (http://www.openbios.org/) is a free (GPL v2) portable
   firmware implementation. The goal is to implement a 100% IEEE
   1275-1994 (referred to as Open Firmware) compliant firmware.
-  The included images for Sparc32, Sparc64 and PowerPC (for 32 and 64 bit
-  PPC CPUs) are built from OpenBIOS SVN revision 640.
+  The included images for Sparc32 and PowerPC (for 32 and 64 bit
+  PPC CPUs) are built from OpenBIOS SVN revision 640, Sparc64 image
+  from r649.
 
 - The PXE roms come from Rom-o-Matic gPXE 0.9.9 with BANNER_TIMEOUT=0
 
diff --git a/pc-bios/openbios-sparc64 b/pc-bios/openbios-sparc64
index 6b86637..0e91cab 100644
--- a/pc-bios/openbios-sparc64
+++ b/pc-bios/openbios-sparc64
Binary files differ
diff --git a/qemu-io.c b/qemu-io.c
index aa26e36..1c19b92 100644
--- a/qemu-io.c
+++ b/qemu-io.c
@@ -492,7 +492,8 @@
 	int c, cnt;
 	char *buf;
 	int64_t offset;
-	int total;
+        /* Some compilers get confused and warn if this is not initialized.  */
+        int total = 0;
 	int nr_iov;
 	QEMUIOVector qiov;
 	int pattern = 0;
@@ -747,7 +748,8 @@
 	int c, cnt;
 	char *buf;
 	int64_t offset;
-	int total;
+        /* Some compilers get confused and warn if this is not initialized.  */
+        int total = 0;
 	int nr_iov;
 	int pattern = 0xcd;
 	QEMUIOVector qiov;
diff --git a/qemu-nbd.c b/qemu-nbd.c
index 6cdb834..6707ea5 100644
--- a/qemu-nbd.c
+++ b/qemu-nbd.c
@@ -30,6 +30,7 @@
 #include <netinet/tcp.h>
 #include <arpa/inet.h>
 #include <signal.h>
+#include <libgen.h>
 
 #define SOCKET_PATH    "/var/lock/qemu-nbd-%s"
 
@@ -352,7 +353,8 @@
         }
 
         if (socket == NULL) {
-            sprintf(sockpath, SOCKET_PATH, basename(device));
+            snprintf(sockpath, sizeof(sockpath), SOCKET_PATH,
+                     basename(device));
             socket = sockpath;
         }
 
diff --git a/qemu-options.hx b/qemu-options.hx
index b8cc375..ecd50eb 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -1936,4 +1936,4 @@
     "-readconfig <file>\n")
 DEF("writeconfig", HAS_ARG, QEMU_OPTION_writeconfig,
     "-writeconfig <file>\n"
-    "                read/write config file")
+    "                read/write config file\n")
diff --git a/savevm.c b/savevm.c
index aefe052..829f735 100644
--- a/savevm.c
+++ b/savevm.c
@@ -339,8 +339,7 @@
 {
     QEMUFileStdio *s = opaque;
     fseek(s->stdio_file, pos, SEEK_SET);
-    fwrite(buf, 1, size, s->stdio_file);
-    return size;
+    return fwrite(buf, 1, size, s->stdio_file);
 }
 
 static int file_get_buffer(void *opaque, uint8_t *buf, int64_t pos, int size)
diff --git a/sdl.c b/sdl.c
index 034440f..3317310 100644
--- a/sdl.c
+++ b/sdl.c
@@ -849,7 +849,8 @@
 
     flags = SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE;
     if (SDL_Init (flags)) {
-        fprintf(stderr, "Could not initialize SDL - exiting\n");
+        fprintf(stderr, "Could not initialize SDL(%s) - exiting\n",
+                SDL_GetError());
         exit(1);
     }
     vi = SDL_GetVideoInfo();
diff --git a/slirp/misc.c b/slirp/misc.c
index c76ad8f..05f4fb3 100644
--- a/slirp/misc.c
+++ b/slirp/misc.c
@@ -200,14 +200,8 @@
 		execvp(argv[0], (char **)argv);
 
 		/* Ooops, failed, let's tell the user why */
-		  {
-			  char buff[256];
-
-			  snprintf(buff, sizeof(buff),
-                                   "Error: execvp of %s failed: %s\n",
-                                   argv[0], strerror(errno));
-			  write(2, buff, strlen(buff)+1);
-		  }
+        fprintf(stderr, "Error: execvp of %s failed: %s\n",
+                argv[0], strerror(errno));
 		close(0); close(1); close(2); /* XXX */
 		exit(1);
 
diff --git a/target-arm/translate.c b/target-arm/translate.c
index 45bf772..5cf3e06 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -6622,7 +6622,7 @@
                                 gen_store_exclusive(s, rd, rm, 15, addr, 2);
                                 break;
                             case 1: /*  strexd */
-                                gen_store_exclusive(s, rd, rm, rm + 1, addr, 2);
+                                gen_store_exclusive(s, rd, rm, rm + 1, addr, 3);
                                 break;
                             case 2: /*  strexb */
                                 gen_store_exclusive(s, rd, rm, 15, addr, 0);
diff --git a/target-i386/helper.c b/target-i386/helper.c
index 730e396..c39a993 100644
--- a/target-i386/helper.c
+++ b/target-i386/helper.c
@@ -106,7 +106,7 @@
 
 #define I486_FEATURES (CPUID_FP87 | CPUID_VME | CPUID_PSE)
 #define PENTIUM_FEATURES (I486_FEATURES | CPUID_DE | CPUID_TSC | \
-          CPUID_MSR | CPUID_MCE | CPUID_CX8 | CPUID_MMX)
+          CPUID_MSR | CPUID_MCE | CPUID_CX8 | CPUID_MMX | CPUID_APIC)
 #define PENTIUM2_FEATURES (PENTIUM_FEATURES | CPUID_PAE | CPUID_SEP | \
           CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_CMOV | CPUID_PAT | \
           CPUID_PSE36 | CPUID_FXSR)
diff --git a/target-i386/translate.c b/target-i386/translate.c
index 64bc0a3..511a4ea 100644
--- a/target-i386/translate.c
+++ b/target-i386/translate.c
@@ -6259,6 +6259,8 @@
             tval += next_eip;
             if (s->dflag == 0)
                 tval &= 0xffff;
+            else if(!CODE64(s))
+                tval &= 0xffffffff;
             gen_movtl_T0_im(next_eip);
             gen_push_T0(s);
             gen_jmp(s, tval);
diff --git a/target-sparc/op_helper.c b/target-sparc/op_helper.c
index c3cc0a4..dab2c25 100644
--- a/target-sparc/op_helper.c
+++ b/target-sparc/op_helper.c
@@ -3447,10 +3447,10 @@
         change_pstate(PS_PEF | PS_PRIV | PS_IG);
         break;
     case TT_TFAULT:
-    case TT_TMISS:
     case TT_DFAULT:
-    case TT_DMISS:
-    case TT_DPROT:
+    case TT_TMISS ... TT_TMISS + 3:
+    case TT_DMISS ... TT_DMISS + 3:
+    case TT_DPROT ... TT_DPROT + 3:
         change_pstate(PS_PEF | PS_PRIV | PS_MG);
         break;
     default:
@@ -3686,21 +3686,24 @@
 void do_unassigned_access(target_phys_addr_t addr, int is_write, int is_exec,
                           int is_asi, int size)
 {
-#ifdef DEBUG_UNASSIGNED
     CPUState *saved_env;
 
     /* XXX: hack to restore env in all cases, even if not called from
        generated code */
     saved_env = env;
     env = cpu_single_env;
+
+#ifdef DEBUG_UNASSIGNED
     printf("Unassigned mem access to " TARGET_FMT_plx " from " TARGET_FMT_lx
            "\n", addr, env->pc);
-    env = saved_env;
 #endif
+
     if (is_exec)
         raise_exception(TT_CODE_ACCESS);
     else
         raise_exception(TT_DATA_ACCESS);
+
+    env = saved_env;
 }
 #endif
 
diff --git a/tcg/tcg.h b/tcg/tcg.h
index 9824493..121b17c 100644
--- a/tcg/tcg.h
+++ b/tcg/tcg.h
@@ -205,6 +205,11 @@
     TCG_COND_GTU,
 } TCGCond;
 
+static inline TCGCond tcg_unsigned_cond(TCGCond c)
+{
+    return (c >= TCG_COND_LT && c <= TCG_COND_GT ? c + 4 : c);
+}
+
 #define TEMP_VAL_DEAD  0
 #define TEMP_VAL_REG   1
 #define TEMP_VAL_MEM   2