r2356 - in trunk/src/host/qemu-neo1973: . hw linux-user linux-user/i386 pc-bios target-arm target-i386 target-mips target-ppc target-sh4 target-sparc

andrew at sita.openmoko.org andrew at sita.openmoko.org
Mon Jul 2 22:44:21 CEST 2007


Author: andrew
Date: 2007-07-02 22:43:42 +0200 (Mon, 02 Jul 2007)
New Revision: 2356

Modified:
   trunk/src/host/qemu-neo1973/Changelog
   trunk/src/host/qemu-neo1973/Makefile
   trunk/src/host/qemu-neo1973/Makefile.target
   trunk/src/host/qemu-neo1973/block-vmdk.c
   trunk/src/host/qemu-neo1973/configure
   trunk/src/host/qemu-neo1973/cpu-defs.h
   trunk/src/host/qemu-neo1973/dyngen.h
   trunk/src/host/qemu-neo1973/exec-all.h
   trunk/src/host/qemu-neo1973/exec.c
   trunk/src/host/qemu-neo1973/hw/ads7846.c
   trunk/src/host/qemu-neo1973/hw/eepro100.c
   trunk/src/host/qemu-neo1973/hw/integratorcp.c
   trunk/src/host/qemu-neo1973/hw/mips_malta.c
   trunk/src/host/qemu-neo1973/hw/mips_pica61.c
   trunk/src/host/qemu-neo1973/hw/ne2000.c
   trunk/src/host/qemu-neo1973/hw/parallel.c
   trunk/src/host/qemu-neo1973/hw/pcnet.c
   trunk/src/host/qemu-neo1973/hw/pl110.c
   trunk/src/host/qemu-neo1973/hw/realview.c
   trunk/src/host/qemu-neo1973/hw/slavio_serial.c
   trunk/src/host/qemu-neo1973/hw/spitz.c
   trunk/src/host/qemu-neo1973/hw/sun4m.c
   trunk/src/host/qemu-neo1973/hw/tcx.c
   trunk/src/host/qemu-neo1973/hw/versatilepb.c
   trunk/src/host/qemu-neo1973/linux-user/elfload.c
   trunk/src/host/qemu-neo1973/linux-user/i386/syscall_nr.h
   trunk/src/host/qemu-neo1973/linux-user/main.c
   trunk/src/host/qemu-neo1973/linux-user/syscall.c
   trunk/src/host/qemu-neo1973/linux-user/syscall_defs.h
   trunk/src/host/qemu-neo1973/monitor.c
   trunk/src/host/qemu-neo1973/pc-bios/README
   trunk/src/host/qemu-neo1973/pc-bios/openbios-sparc32
   trunk/src/host/qemu-neo1973/pc-bios/openbios-sparc64
   trunk/src/host/qemu-neo1973/qemu-doc.texi
   trunk/src/host/qemu-neo1973/qemu-img.c
   trunk/src/host/qemu-neo1973/readline.c
   trunk/src/host/qemu-neo1973/sdl.c
   trunk/src/host/qemu-neo1973/target-arm/cpu.h
   trunk/src/host/qemu-neo1973/target-arm/helper.c
   trunk/src/host/qemu-neo1973/target-i386/exec.h
   trunk/src/host/qemu-neo1973/target-i386/helper.c
   trunk/src/host/qemu-neo1973/target-i386/op.c
   trunk/src/host/qemu-neo1973/target-i386/translate.c
   trunk/src/host/qemu-neo1973/target-mips/cpu.h
   trunk/src/host/qemu-neo1973/target-mips/helper.c
   trunk/src/host/qemu-neo1973/target-mips/op.c
   trunk/src/host/qemu-neo1973/target-mips/op_helper.c
   trunk/src/host/qemu-neo1973/target-mips/translate.c
   trunk/src/host/qemu-neo1973/target-mips/translate_init.c
   trunk/src/host/qemu-neo1973/target-ppc/cpu.h
   trunk/src/host/qemu-neo1973/target-ppc/op.c
   trunk/src/host/qemu-neo1973/target-sh4/cpu.h
   trunk/src/host/qemu-neo1973/target-sh4/exec.h
   trunk/src/host/qemu-neo1973/target-sh4/op.c
   trunk/src/host/qemu-neo1973/target-sh4/translate.c
   trunk/src/host/qemu-neo1973/target-sparc/translate.c
   trunk/src/host/qemu-neo1973/vl.c
   trunk/src/host/qemu-neo1973/vl.h
Log:
Merge changes from cvs.savannah.nongnu.org:/sources/qemu.


Modified: trunk/src/host/qemu-neo1973/Changelog
===================================================================
--- trunk/src/host/qemu-neo1973/Changelog	2007-07-01 11:01:12 UTC (rev 2355)
+++ trunk/src/host/qemu-neo1973/Changelog	2007-07-02 20:43:42 UTC (rev 2356)
@@ -7,6 +7,9 @@
   - MIPS 64-bit FPU support (Thiemo Seufer)
   - Xscale PDA emulation (Andrzei Zaborowski)
   - ColdFire system emulation (Paul Brook)
+  - Improved SH4 support (Magnus Damm)
+  - MIPS64 support (Aurelien Jarno, Thiemo Seufer)
+  - Preliminary Alpha guest support (J. Mayer)
 
 version 0.9.0:
 

Modified: trunk/src/host/qemu-neo1973/Makefile
===================================================================
--- trunk/src/host/qemu-neo1973/Makefile	2007-07-01 11:01:12 UTC (rev 2355)
+++ trunk/src/host/qemu-neo1973/Makefile	2007-07-02 20:43:42 UTC (rev 2356)
@@ -49,7 +49,7 @@
 clean:
 # avoid old build problems by removing potentially incorrect old files
 	rm -f config.mak config.h op-i386.h opc-i386.h gen-op-i386.h op-arm.h opc-arm.h gen-op-arm.h 
-	rm -f *.o *.a $(TOOLS) dyngen$(EXESUF) TAGS *.pod *~ */*~
+	rm -f *.o *.a $(TOOLS) dyngen$(EXESUF) TAGS cscope.* *.pod *~ */*~
 	$(MAKE) -C tests clean
 	for d in $(TARGET_DIRS); do \
 	$(MAKE) -C $$d $@ || exit 1 ; \

Modified: trunk/src/host/qemu-neo1973/Makefile.target
===================================================================
--- trunk/src/host/qemu-neo1973/Makefile.target	2007-07-01 11:01:12 UTC (rev 2355)
+++ trunk/src/host/qemu-neo1973/Makefile.target	2007-07-02 20:43:42 UTC (rev 2356)
@@ -446,6 +446,7 @@
 ifeq ($(TARGET_BASE_ARCH), mips)
 VL_OBJS+= mips_r4k.o mips_malta.o mips_pica61.o
 VL_OBJS+= mips_timer.o mips_int.o dma.o vga.o serial.o i8254.o i8259.o
+VL_OBJS+= jazz_led.o
 VL_OBJS+= ide.o gt64xxx.o pckbd.o ps2.o fdc.o mc146818rtc.o usb-uhci.o acpi.o ds1225y.o
 VL_OBJS+= piix_pci.o smbus_eeprom.o parallel.o mixeng.o cirrus_vga.o $(SOUND_HW) $(AUDIODRV)
 CPPFLAGS += -DHAS_AUDIO
@@ -463,7 +464,7 @@
 endif
 ifeq ($(TARGET_BASE_ARCH), arm)
 VL_OBJS+= integratorcp.o versatilepb.o ps2.o smc91c111.o arm_pic.o arm_timer.o
-VL_OBJS+= arm_boot.o pl011.o pl050.o pl080.o pl110.o pl181.o pl190.o
+VL_OBJS+= arm_boot.o pl011.o pl031.o pl050.o pl080.o pl110.o pl181.o pl190.o
 VL_OBJS+= versatile_pci.o sd.o ptimer.o
 VL_OBJS+= arm_gic.o realview.o arm_sysctl.o
 VL_OBJS+= arm-semi.o

Modified: trunk/src/host/qemu-neo1973/block-vmdk.c
===================================================================
--- trunk/src/host/qemu-neo1973/block-vmdk.c	2007-07-01 11:01:12 UTC (rev 2355)
+++ trunk/src/host/qemu-neo1973/block-vmdk.c	2007-07-02 20:43:42 UTC (rev 2356)
@@ -75,8 +75,25 @@
 
     unsigned int cluster_sectors;
     uint32_t parent_cid;
+    int is_parent;
 } BDRVVmdkState;
 
+typedef struct VmdkMetaData {
+    uint32_t offset;
+    unsigned int l1_index;
+    unsigned int l2_index;
+    unsigned int l2_offset;
+    int valid;
+} VmdkMetaData;
+
+typedef struct ActiveBDRVState{
+    BlockDriverState *hd;            // active image handler
+    uint64_t cluster_offset;         // current write offset
+}ActiveBDRVState;
+
+static ActiveBDRVState activeBDRV;
+
+
 static int vmdk_probe(const uint8_t *buf, int buf_size, const char *filename)
 {
     uint32_t magic;
@@ -305,7 +322,7 @@
         bdrv_close(bs->backing_hd);
 }
 
-
+int parent_open = 0;
 static int vmdk_parent_open(BlockDriverState *bs, const char * filename)
 {
     BDRVVmdkState *s = bs->opaque;
@@ -339,8 +356,10 @@
             bdrv_close(s->hd);
             return -1;
         }
-        if (bdrv_open(s->hd->backing_hd, parent_img_name, 0) < 0)
+        parent_open = 1;
+        if (bdrv_open(s->hd->backing_hd, parent_img_name, BDRV_O_RDONLY) < 0)
             goto failure;
+        parent_open = 0;
     }
 
     return 0;
@@ -352,6 +371,11 @@
     uint32_t magic;
     int l1_size, i, ret;
 
+    if (parent_open)
+        // Parent must be opened as RO.
+        flags = BDRV_O_RDONLY;
+    fprintf(stderr, "(VMDK) image open: flags=0x%x filename=%s\n", flags, bs->filename);
+
     ret = bdrv_file_open(&s->hd, filename, flags);
     if (ret < 0)
         return ret;
@@ -387,6 +411,11 @@
         s->l1_table_offset = le64_to_cpu(header.rgd_offset) << 9;
         s->l1_backup_table_offset = le64_to_cpu(header.gd_offset) << 9;
 
+        if (parent_open)
+            s->is_parent = 1;
+        else
+            s->is_parent = 0;
+
         // try to open parent images, if exist
         if (vmdk_parent_open(bs, filename) != 0)
             goto fail;
@@ -430,7 +459,8 @@
     return -1;
 }
 
-static uint64_t get_cluster_offset(BlockDriverState *bs, uint64_t offset, int allocate);
+static uint64_t get_cluster_offset(BlockDriverState *bs, VmdkMetaData *m_data,
+                                   uint64_t offset, int allocate);
 
 static int get_whole_cluster(BlockDriverState *bs, uint64_t cluster_offset,
                              uint64_t offset, int allocate)
@@ -446,27 +476,55 @@
 
         if (!vmdk_is_cid_valid(bs))
             return -1;
-        parent_cluster_offset = get_cluster_offset(s->hd->backing_hd, offset, allocate);
-        if (bdrv_pread(ps->hd, parent_cluster_offset, whole_grain, ps->cluster_sectors*512) != 
-                                                                            ps->cluster_sectors*512)
-            return -1;
 
-        if (bdrv_pwrite(s->hd, cluster_offset << 9, whole_grain, sizeof(whole_grain)) != 
-                                                                            sizeof(whole_grain))
+        parent_cluster_offset = get_cluster_offset(s->hd->backing_hd, NULL, offset, allocate);
+
+        if (parent_cluster_offset) {
+            BDRVVmdkState *act_s = activeBDRV.hd->opaque;
+
+            if (bdrv_pread(ps->hd, parent_cluster_offset, whole_grain, ps->cluster_sectors*512) != ps->cluster_sectors*512)
+                return -1;
+
+            //Write grain only into the active image
+            if (bdrv_pwrite(act_s->hd, activeBDRV.cluster_offset << 9, whole_grain, sizeof(whole_grain)) != sizeof(whole_grain))
+                return -1;
+        }
+    }
+    return 0;
+}
+
+static int vmdk_L2update(BlockDriverState *bs, VmdkMetaData *m_data)
+{
+    BDRVVmdkState *s = bs->opaque;
+
+    /* update L2 table */
+    if (bdrv_pwrite(s->hd, ((int64_t)m_data->l2_offset * 512) + (m_data->l2_index * sizeof(m_data->offset)),
+                    &(m_data->offset), sizeof(m_data->offset)) != sizeof(m_data->offset))
+        return -1;
+    /* update backup L2 table */
+    if (s->l1_backup_table_offset != 0) {
+        m_data->l2_offset = s->l1_backup_table[m_data->l1_index];
+        if (bdrv_pwrite(s->hd, ((int64_t)m_data->l2_offset * 512) + (m_data->l2_index * sizeof(m_data->offset)),
+                        &(m_data->offset), sizeof(m_data->offset)) != sizeof(m_data->offset))
             return -1;
     }
+
     return 0;
 }
 
-static uint64_t get_cluster_offset(BlockDriverState *bs,
+static uint64_t get_cluster_offset(BlockDriverState *bs, VmdkMetaData *m_data,
                                    uint64_t offset, int allocate)
 {
     BDRVVmdkState *s = bs->opaque;
     unsigned int l1_index, l2_offset, l2_index;
     int min_index, i, j;
-    uint32_t min_count, *l2_table, tmp;
+    uint32_t min_count, *l2_table, tmp = 0;
     uint64_t cluster_offset;
-    
+    int status;
+
+    if (m_data)
+        m_data->valid = 0;
+
     l1_index = (offset >> 9) / s->l1_entry_sectors;
     if (l1_index >= s->l1_size)
         return 0;
@@ -504,32 +562,45 @@
  found:
     l2_index = ((offset >> 9) / s->cluster_sectors) % s->l2_size;
     cluster_offset = le32_to_cpu(l2_table[l2_index]);
+
     if (!cluster_offset) {
         struct stat file_buf;
 
         if (!allocate)
             return 0;
-        stat(s->hd->filename, &file_buf);
-        cluster_offset = file_buf.st_size;
-        bdrv_truncate(s->hd, cluster_offset + (s->cluster_sectors << 9));
+        // Avoid the L2 tables update for the images that have snapshots.
+        if (!s->is_parent) {
+            status = stat(s->hd->filename, &file_buf);
+            if (status == -1) {
+                fprintf(stderr, "(VMDK) Fail file stat: filename =%s size=0x%lx errno=%s\n",
+                                s->hd->filename, (uint64_t)file_buf.st_size, strerror(errno));
+                return 0;
+            }
+            cluster_offset = file_buf.st_size;
+            bdrv_truncate(s->hd, cluster_offset + (s->cluster_sectors << 9));
 
-        cluster_offset >>= 9;
-        /* update L2 table */
-        tmp = cpu_to_le32(cluster_offset);
-        l2_table[l2_index] = tmp;
-        if (bdrv_pwrite(s->hd, ((int64_t)l2_offset * 512) + (l2_index * sizeof(tmp)), 
-                        &tmp, sizeof(tmp)) != sizeof(tmp))
-            return 0;
-        /* update backup L2 table */
-        if (s->l1_backup_table_offset != 0) {
-            l2_offset = s->l1_backup_table[l1_index];
-            if (bdrv_pwrite(s->hd, ((int64_t)l2_offset * 512) + (l2_index * sizeof(tmp)), 
-                            &tmp, sizeof(tmp)) != sizeof(tmp))
-                return 0;
+            cluster_offset >>= 9;
+            tmp = cpu_to_le32(cluster_offset);
+            l2_table[l2_index] = tmp;
+            // Save the active image state
+            activeBDRV.cluster_offset = cluster_offset;
+            activeBDRV.hd = bs;
         }
-
+        /* First of all we write grain itself, to avoid race condition
+         * that may to corrupt the image.
+         * This problem may occur because of insufficient space on host disk
+         * or inappropriate VM shutdown.
+         */
         if (get_whole_cluster(bs, cluster_offset, offset, allocate) == -1)
             return 0;
+
+        if (m_data) {
+            m_data->offset = tmp;
+            m_data->l1_index = l1_index;
+            m_data->l2_index = l2_index;
+            m_data->l2_offset = l2_offset;
+            m_data->valid = 1;
+        }
     }
     cluster_offset <<= 9;
     return cluster_offset;
@@ -542,7 +613,7 @@
     int index_in_cluster, n;
     uint64_t cluster_offset;
 
-    cluster_offset = get_cluster_offset(bs, sector_num << 9, 0);
+    cluster_offset = get_cluster_offset(bs, NULL, sector_num << 9, 0);
     index_in_cluster = sector_num % s->cluster_sectors;
     n = s->cluster_sectors - index_in_cluster;
     if (n > nb_sectors)
@@ -559,7 +630,7 @@
     uint64_t cluster_offset;
 
     while (nb_sectors > 0) {
-        cluster_offset = get_cluster_offset(bs, sector_num << 9, 0);
+        cluster_offset = get_cluster_offset(bs, NULL, sector_num << 9, 0);
         index_in_cluster = sector_num % s->cluster_sectors;
         n = s->cluster_sectors - index_in_cluster;
         if (n > nb_sectors)
@@ -590,20 +661,34 @@
                      const uint8_t *buf, int nb_sectors)
 {
     BDRVVmdkState *s = bs->opaque;
+    VmdkMetaData m_data;
     int index_in_cluster, n;
     uint64_t cluster_offset;
     static int cid_update = 0;
 
+    if (sector_num > bs->total_sectors) {
+        fprintf(stderr,
+                "(VMDK) Wrong offset: sector_num=0x%lx total_sectors=0x%lx\n",
+                sector_num, bs->total_sectors);
+        return -1;
+    }
+
     while (nb_sectors > 0) {
         index_in_cluster = sector_num & (s->cluster_sectors - 1);
         n = s->cluster_sectors - index_in_cluster;
         if (n > nb_sectors)
             n = nb_sectors;
-        cluster_offset = get_cluster_offset(bs, sector_num << 9, 1);
+        cluster_offset = get_cluster_offset(bs, &m_data, sector_num << 9, 1);
         if (!cluster_offset)
             return -1;
+
         if (bdrv_pwrite(s->hd, cluster_offset + index_in_cluster * 512, buf, n * 512) != n * 512)
             return -1;
+        if (m_data.valid) {
+            /* update L2 tables */
+            if (vmdk_L2update(bs, &m_data) == -1)
+                return -1;
+        }
         nb_sectors -= n;
         sector_num += n;
         buf += n * 512;

Modified: trunk/src/host/qemu-neo1973/configure
===================================================================
--- trunk/src/host/qemu-neo1973/configure	2007-07-01 11:01:12 UTC (rev 2355)
+++ trunk/src/host/qemu-neo1973/configure	2007-07-02 20:43:42 UTC (rev 2356)
@@ -113,6 +113,12 @@
 MINGW32*)
 mingw32="yes"
 ;;
+GNU/kFreeBSD)
+oss="yes"
+if [ "$cpu" = "i386" -o "$cpu" = "x86_64" ] ; then
+    kqemu="yes"
+fi
+;;
 FreeBSD)
 bsd="yes"
 oss="yes"

Modified: trunk/src/host/qemu-neo1973/cpu-defs.h
===================================================================
--- trunk/src/host/qemu-neo1973/cpu-defs.h	2007-07-01 11:01:12 UTC (rev 2355)
+++ trunk/src/host/qemu-neo1973/cpu-defs.h	2007-07-02 20:43:42 UTC (rev 2356)
@@ -141,7 +141,7 @@
                                                                         \
     struct {                                                            \
         target_ulong vaddr;                                             \
-        int is_ram;                                                     \
+        target_phys_addr_t addend;                                      \
     } watchpoint[MAX_WATCHPOINTS];                                      \
     int nb_watchpoints;                                                 \
     int watchpoint_hit;                                                 \

Modified: trunk/src/host/qemu-neo1973/dyngen.h
===================================================================
--- trunk/src/host/qemu-neo1973/dyngen.h	2007-07-01 11:01:12 UTC (rev 2355)
+++ trunk/src/host/qemu-neo1973/dyngen.h	2007-07-02 20:43:42 UTC (rev 2356)
@@ -392,7 +392,8 @@
 	0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,	/* nop 0; brl IP */
 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0
     };
-    uint8_t *gen_code_ptr = *gen_code_pp, *plt_start, *got_start, *vp;
+    uint8_t *gen_code_ptr = *gen_code_pp, *plt_start, *got_start;
+    uint64_t *vp;
     struct ia64_fixup *fixup;
     unsigned int offset = 0;
     struct fdesc {
@@ -429,12 +430,12 @@
     /* First, create the GOT: */
     for (fixup = ltoff_fixes; fixup; fixup = fixup->next) {
 	/* first check if we already have this value in the GOT: */
-	for (vp = got_start; vp < gen_code_ptr; ++vp)
-	    if (*(uint64_t *) vp == fixup->value)
+	for (vp = (uint64_t *) got_start; vp < (uint64_t *) gen_code_ptr; ++vp)
+	    if (*vp == fixup->value)
 		break;
-	if (vp == gen_code_ptr) {
+	if (vp == (uint64_t *) gen_code_ptr) {
 	    /* Nope, we need to put the value in the GOT: */
-	    *(uint64_t *) vp = fixup->value;
+	    *vp = fixup->value;
 	    gen_code_ptr += 8;
 	}
 	ia64_imm22(fixup->addr, (long) vp - gp);

Modified: trunk/src/host/qemu-neo1973/exec-all.h
===================================================================
--- trunk/src/host/qemu-neo1973/exec-all.h	2007-07-01 11:01:12 UTC (rev 2355)
+++ trunk/src/host/qemu-neo1973/exec-all.h	2007-07-02 20:43:42 UTC (rev 2356)
@@ -346,8 +346,8 @@
    cache flushing, but slower because of indirect jump) */
 #define GOTO_TB(opname, tbparam, n)\
 do {\
-    static void __attribute__((unused)) *dummy ## n = &&dummy_label ## n;\
-    static void __attribute__((unused)) *__op_label ## n \
+    static void __attribute__((used)) *dummy ## n = &&dummy_label ## n;\
+    static void __attribute__((used)) *__op_label ## n \
         __asm__(ASM_OP_LABEL_NAME(n, opname)) = &&label ## n;\
     goto *(void *)(((TranslationBlock *)tbparam)->tb_next[n]);\
 label ## n: ;\

Modified: trunk/src/host/qemu-neo1973/exec.c
===================================================================
--- trunk/src/host/qemu-neo1973/exec.c	2007-07-01 11:01:12 UTC (rev 2355)
+++ trunk/src/host/qemu-neo1973/exec.c	2007-07-02 20:43:42 UTC (rev 2356)
@@ -152,6 +152,7 @@
 char *logfilename = "/tmp/qemu.log";
 FILE *logfile;
 int loglevel;
+static int log_append = 0;
 
 /* statistics */
 static int tlb_flush_count;
@@ -1160,7 +1161,7 @@
 {
     loglevel = log_flags;
     if (loglevel && !logfile) {
-        logfile = fopen(logfilename, "w");
+        logfile = fopen(logfilename, log_append ? "a" : "w");
         if (!logfile) {
             perror(logfilename);
             _exit(1);
@@ -1174,12 +1175,22 @@
 #else
         setvbuf(logfile, NULL, _IOLBF, 0);
 #endif
+        log_append = 1;
     }
+    if (!loglevel && logfile) {
+        fclose(logfile);
+        logfile = NULL;
+    }
 }
 
 void cpu_set_log_filename(const char *filename)
 {
     logfilename = strdup(filename);
+    if (logfile) {
+        fclose(logfile);
+        logfile = NULL;
+    }
+    cpu_set_log(loglevel);
 }
 
 /* mask must never be zero, except for A20 change call */
@@ -1626,17 +1637,18 @@
         for (i = 0; i < env->nb_watchpoints; i++) {
             if (vaddr == (env->watchpoint[i].vaddr & TARGET_PAGE_MASK)) {
                 if (address & ~TARGET_PAGE_MASK) {
-                    env->watchpoint[i].is_ram = 0;
+                    env->watchpoint[i].addend = 0;
                     address = vaddr | io_mem_watch;
                 } else {
-                    env->watchpoint[i].is_ram = 1;
+                    env->watchpoint[i].addend = pd - paddr +
+                        (unsigned long) phys_ram_base;
                     /* TODO: Figure out how to make read watchpoints coexist
                        with code.  */
                     pd = (pd & TARGET_PAGE_MASK) | io_mem_watch | IO_MEM_ROMD;
                 }
             }
         }
-        
+
         index = (vaddr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
         addend -= vaddr;
         te = &env->tlb_table[is_user][index];
@@ -2178,7 +2190,7 @@
 
 /* Generate a debug exception if a watchpoint has been hit.
    Returns the real physical address of the access.  addr will be a host
-   address in the is_ram case.  */
+   address in case of a RAM location.  */
 static target_ulong check_watchpoint(target_phys_addr_t addr)
 {
     CPUState *env = cpu_single_env;
@@ -2190,8 +2202,7 @@
     for (i = 0; i < env->nb_watchpoints; i++) {
         watch = env->watchpoint[i].vaddr;
         if (((env->mem_write_vaddr ^ watch) & TARGET_PAGE_MASK) == 0) {
-            if (env->watchpoint[i].is_ram)
-                retaddr = addr - (unsigned long)phys_ram_base;
+            retaddr = addr - env->watchpoint[i].addend;
             if (((addr ^ watch) & ~TARGET_PAGE_MASK) == 0) {
                 cpu_single_env->watchpoint_hit = i + 1;
                 cpu_interrupt(cpu_single_env, CPU_INTERRUPT_DEBUG);

Modified: trunk/src/host/qemu-neo1973/hw/ads7846.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/ads7846.c	2007-07-01 11:01:12 UTC (rev 2355)
+++ trunk/src/host/qemu-neo1973/hw/ads7846.c	2007-07-02 20:43:42 UTC (rev 2356)
@@ -30,10 +30,10 @@
 #define CB_A2		(1 << 6)
 #define CB_START	(1 << 7)
 
-#define X_AXIS_DMAX	3680
-#define X_AXIS_MIN	150
-#define Y_AXIS_DMAX	3640
-#define Y_AXIS_MIN	190
+#define X_AXIS_DMAX	3470
+#define X_AXIS_MIN	290
+#define Y_AXIS_DMAX	3450
+#define Y_AXIS_MIN	200
 
 #define ADS_VBAT	2000
 #define ADS_VAUX	2000
@@ -95,10 +95,11 @@
     struct ads7846_state_s *s = opaque;
 
     if (buttons_state) {
-        s->input[1] = ADS_YPOS(x, y);
+        x = 0x7fff - x;
+        s->input[1] = ADS_XPOS(x, y);
         s->input[3] = ADS_Z1POS(x, y);
         s->input[4] = ADS_Z2POS(x, y);
-        s->input[5] = ADS_XPOS(x, y);
+        s->input[5] = ADS_YPOS(x, y);
     }
 
     if (s->pressure == !buttons_state) {

Modified: trunk/src/host/qemu-neo1973/hw/eepro100.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/eepro100.c	2007-07-01 11:01:12 UTC (rev 2355)
+++ trunk/src/host/qemu-neo1973/hw/eepro100.c	2007-07-02 20:43:42 UTC (rev 2356)
@@ -1571,10 +1571,9 @@
 static int nic_load(QEMUFile * f, void *opaque, int version_id)
 {
     EEPRO100State *s = (EEPRO100State *) opaque;
+    int i;
     int ret;
 
-    missing("NIC load");
-
     if (version_id > 3)
         return -EINVAL;
 
@@ -1608,15 +1607,62 @@
     qemu_get_buffer(f, s->mult, 8);
     qemu_get_buffer(f, s->mem, sizeof(s->mem));
 
+    /* Restore all members of struct between scv_stat and mem */
+    qemu_get_8s(f, &s->scb_stat);
+    qemu_get_8s(f, &s->int_stat);
+    for (i = 0; i < 3; i++)
+        qemu_get_be32s(f, &s->region[i]);
+    qemu_get_buffer(f, s->macaddr, 6);
+    for (i = 0; i < 19; i++) 
+        qemu_get_be32s(f, &s->statcounter[i]);
+    for (i = 0; i < 32; i++)
+        qemu_get_be16s(f, &s->mdimem[i]);
+    /* The eeprom should be saved and restored by its own routines */
+    qemu_get_be32s(f, &s->device);
+    qemu_get_be32s(f, &s->pointer);
+    qemu_get_be32s(f, &s->cu_base);
+    qemu_get_be32s(f, &s->cu_offset);
+    qemu_get_be32s(f, &s->ru_base);
+    qemu_get_be32s(f, &s->ru_offset);
+    qemu_get_be32s(f, &s->statsaddr);
+    /* Restore epro100_stats_t statistics */
+    qemu_get_be32s(f, &s->statistics.tx_good_frames);
+    qemu_get_be32s(f, &s->statistics.tx_max_collisions);
+    qemu_get_be32s(f, &s->statistics.tx_late_collisions);
+    qemu_get_be32s(f, &s->statistics.tx_underruns);
+    qemu_get_be32s(f, &s->statistics.tx_lost_crs);
+    qemu_get_be32s(f, &s->statistics.tx_deferred);
+    qemu_get_be32s(f, &s->statistics.tx_single_collisions);
+    qemu_get_be32s(f, &s->statistics.tx_multiple_collisions);
+    qemu_get_be32s(f, &s->statistics.tx_total_collisions);
+    qemu_get_be32s(f, &s->statistics.rx_good_frames);
+    qemu_get_be32s(f, &s->statistics.rx_crc_errors);
+    qemu_get_be32s(f, &s->statistics.rx_alignment_errors);
+    qemu_get_be32s(f, &s->statistics.rx_resource_errors);
+    qemu_get_be32s(f, &s->statistics.rx_overrun_errors);
+    qemu_get_be32s(f, &s->statistics.rx_cdt_errors);
+    qemu_get_be32s(f, &s->statistics.rx_short_frame_errors);
+    qemu_get_be32s(f, &s->statistics.fc_xmt_pause);
+    qemu_get_be32s(f, &s->statistics.fc_rcv_pause);
+    qemu_get_be32s(f, &s->statistics.fc_rcv_unsupported);
+    qemu_get_be16s(f, &s->statistics.xmt_tco_frames);
+    qemu_get_be16s(f, &s->statistics.rcv_tco_frames);
+    qemu_get_be32s(f, &s->statistics.complete);
+#if 0
+    qemu_get_be16s(f, &s->status);
+#endif
+
+    /* Configuration bytes. */
+    qemu_get_buffer(f, s->configuration, sizeof(s->configuration));
+
     return 0;
 }
 
 static void nic_save(QEMUFile * f, void *opaque)
 {
     EEPRO100State *s = (EEPRO100State *) opaque;
+    int i;
 
-    missing("NIC save");
-
     if (s->pci_dev)
         pci_device_save(s->pci_dev, f);
 
@@ -1639,6 +1685,54 @@
     qemu_put_8s(f, &s->curpag);
     qemu_put_buffer(f, s->mult, 8);
     qemu_put_buffer(f, s->mem, sizeof(s->mem));
+
+    /* Save all members of struct between scv_stat and mem */
+    qemu_put_8s(f, &s->scb_stat);
+    qemu_put_8s(f, &s->int_stat);
+    for (i = 0; i < 3; i++)
+        qemu_put_be32s(f, &s->region[i]);
+    qemu_put_buffer(f, s->macaddr, 6);
+    for (i = 0; i < 19; i++) 
+        qemu_put_be32s(f, &s->statcounter[i]);
+    for (i = 0; i < 32; i++)
+        qemu_put_be16s(f, &s->mdimem[i]);
+    /* The eeprom should be saved and restored by its own routines */
+    qemu_put_be32s(f, &s->device);
+    qemu_put_be32s(f, &s->pointer);
+    qemu_put_be32s(f, &s->cu_base);
+    qemu_put_be32s(f, &s->cu_offset);
+    qemu_put_be32s(f, &s->ru_base);
+    qemu_put_be32s(f, &s->ru_offset);
+    qemu_put_be32s(f, &s->statsaddr);
+    /* Save epro100_stats_t statistics */
+    qemu_put_be32s(f, &s->statistics.tx_good_frames);
+    qemu_put_be32s(f, &s->statistics.tx_max_collisions);
+    qemu_put_be32s(f, &s->statistics.tx_late_collisions);
+    qemu_put_be32s(f, &s->statistics.tx_underruns);
+    qemu_put_be32s(f, &s->statistics.tx_lost_crs);
+    qemu_put_be32s(f, &s->statistics.tx_deferred);
+    qemu_put_be32s(f, &s->statistics.tx_single_collisions);
+    qemu_put_be32s(f, &s->statistics.tx_multiple_collisions);
+    qemu_put_be32s(f, &s->statistics.tx_total_collisions);
+    qemu_put_be32s(f, &s->statistics.rx_good_frames);
+    qemu_put_be32s(f, &s->statistics.rx_crc_errors);
+    qemu_put_be32s(f, &s->statistics.rx_alignment_errors);
+    qemu_put_be32s(f, &s->statistics.rx_resource_errors);
+    qemu_put_be32s(f, &s->statistics.rx_overrun_errors);
+    qemu_put_be32s(f, &s->statistics.rx_cdt_errors);
+    qemu_put_be32s(f, &s->statistics.rx_short_frame_errors);
+    qemu_put_be32s(f, &s->statistics.fc_xmt_pause);
+    qemu_put_be32s(f, &s->statistics.fc_rcv_pause);
+    qemu_put_be32s(f, &s->statistics.fc_rcv_unsupported);
+    qemu_put_be16s(f, &s->statistics.xmt_tco_frames);
+    qemu_put_be16s(f, &s->statistics.rcv_tco_frames);
+    qemu_put_be32s(f, &s->statistics.complete);
+#if 0
+    qemu_put_be16s(f, &s->status);
+#endif
+
+    /* Configuration bytes. */
+    qemu_put_buffer(f, s->configuration, sizeof(s->configuration));
 }
 
 static void nic_init(PCIBus * bus, NICInfo * nd,

Modified: trunk/src/host/qemu-neo1973/hw/integratorcp.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/integratorcp.c	2007-07-01 11:01:12 UTC (rev 2355)
+++ trunk/src/host/qemu-neo1973/hw/integratorcp.c	2007-07-02 20:43:42 UTC (rev 2356)
@@ -490,6 +490,7 @@
                        cpu_pic[ARM_PIC_CPU_FIQ]);
     icp_pic_init(0xca000000, pic[26], NULL);
     icp_pit_init(0x13000000, pic, 5);
+    pl031_init(0x15000000, pic[8]);
     pl011_init(0x16000000, pic[1], serial_hds[0]);
     pl011_init(0x17000000, pic[2], serial_hds[1]);
     icp_control_init(0xcb000000);

Modified: trunk/src/host/qemu-neo1973/hw/mips_malta.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/mips_malta.c	2007-07-01 11:01:12 UTC (rev 2355)
+++ trunk/src/host/qemu-neo1973/hw/mips_malta.c	2007-07-02 20:43:42 UTC (rev 2356)
@@ -42,7 +42,6 @@
 #define ENVP_NB_ENTRIES	 	16
 #define ENVP_ENTRY_SIZE	 	256
 
-extern int nographic;
 extern FILE *logfile;
 
 typedef struct {
@@ -67,18 +66,16 @@
     int i;
     MaltaFPGAState *s = opaque;
 
-    if (!nographic) {
-        for (i = 7 ; i >= 0 ; i--) {
-            if (s->leds & (1 << i))
-                leds_text[i] = '#';
-            else
-                leds_text[i] = ' ';
-        }
-        leds_text[8] = '\0';
-
-        qemu_chr_printf(s->display, "\e[H\n\n|\e[32m%-8.8s\e[00m|\r\n", leds_text);
-        qemu_chr_printf(s->display, "\n\n\n\n|\e[31m%-8.8s\e[00m|", s->display_text);
+    for (i = 7 ; i >= 0 ; i--) {
+        if (s->leds & (1 << i))
+            leds_text[i] = '#';
+        else
+            leds_text[i] = ' ';
     }
+    leds_text[8] = '\0';
+
+    qemu_chr_printf(s->display, "\e[H\n\n|\e[32m%-8.8s\e[00m|\r\n", leds_text);
+    qemu_chr_printf(s->display, "\n\n\n\n|\e[31m%-8.8s\e[00m|", s->display_text);
 }
 
 /*
@@ -415,22 +412,20 @@
     cpu_register_physical_memory(base, 0x900, malta);
     cpu_register_physical_memory(base + 0xa00, 0x100000 - 0xa00, malta);
 
-    if (!nographic) {
-        s->display = qemu_chr_open("vc");
-        qemu_chr_printf(s->display, "\e[HMalta LEDBAR\r\n");
-        qemu_chr_printf(s->display, "+--------+\r\n");
-        qemu_chr_printf(s->display, "+        +\r\n");
-        qemu_chr_printf(s->display, "+--------+\r\n");
-        qemu_chr_printf(s->display, "\n");
-        qemu_chr_printf(s->display, "Malta ASCII\r\n");
-        qemu_chr_printf(s->display, "+--------+\r\n");
-        qemu_chr_printf(s->display, "+        +\r\n");
-        qemu_chr_printf(s->display, "+--------+\r\n");
+    s->display = qemu_chr_open("vc");
+    qemu_chr_printf(s->display, "\e[HMalta LEDBAR\r\n");
+    qemu_chr_printf(s->display, "+--------+\r\n");
+    qemu_chr_printf(s->display, "+        +\r\n");
+    qemu_chr_printf(s->display, "+--------+\r\n");
+    qemu_chr_printf(s->display, "\n");
+    qemu_chr_printf(s->display, "Malta ASCII\r\n");
+    qemu_chr_printf(s->display, "+--------+\r\n");
+    qemu_chr_printf(s->display, "+        +\r\n");
+    qemu_chr_printf(s->display, "+--------+\r\n");
 
-        uart_chr = qemu_chr_open("vc");
-        qemu_chr_printf(uart_chr, "CBUS UART\r\n");
-        s->uart = serial_mm_init(base + 0x900, 3, env->irq[2], uart_chr, 1);
-    }
+    uart_chr = qemu_chr_open("vc");
+    qemu_chr_printf(uart_chr, "CBUS UART\r\n");
+    s->uart = serial_mm_init(base + 0x900, 3, env->irq[2], uart_chr, 1);
 
     malta_fpga_reset(s);
     qemu_register_reset(malta_fpga_reset, s);

Modified: trunk/src/host/qemu-neo1973/hw/mips_pica61.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/mips_pica61.c	2007-07-01 11:01:12 UTC (rev 2355)
+++ trunk/src/host/qemu-neo1973/hw/mips_pica61.c	2007-07-02 20:43:42 UTC (rev 2356)
@@ -151,11 +151,8 @@
             serial_mm_init(serial_base[i], 0, i8259[serial_irq[i]], serial_hds[i], 1);
         }
     }
-    for (i = 0; i < MAX_PARALLEL_PORTS; i++) {
-        if (parallel_hds[i]) {
-            /* FIXME: memory mapped! parallel_init(0x80008000, i8259[17], parallel_hds[i]); */
-        }
-    }
+    /* Parallel port */
+    if (parallel_hds[0]) parallel_mm_init(0x80008000, 0, i8259[1], parallel_hds[0]);
 
     /* Sound card */
     /* FIXME: missing Jazz sound, IRQ 18 */
@@ -171,6 +168,9 @@
      * but let's do with what Qemu currenly emulates... */
     isa_vga_mm_init(ds, phys_ram_base + ram_size, ram_size, vga_ram_size,
                     0x40000000, 0x60000000, 0);
+
+    /* LED indicator */
+    jazz_led_init(ds, 0x8000f000);
 }
 
 QEMUMachine mips_pica61_machine = {

Modified: trunk/src/host/qemu-neo1973/hw/ne2000.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/ne2000.c	2007-07-01 11:01:12 UTC (rev 2355)
+++ trunk/src/host/qemu-neo1973/hw/ne2000.c	2007-07-02 20:43:42 UTC (rev 2356)
@@ -224,7 +224,7 @@
 {
     NE2000State *s = opaque;
     uint8_t *p;
-    int total_len, next, avail, len, index, mcast_idx;
+    unsigned int total_len, next, avail, len, index, mcast_idx;
     uint8_t buf1[60];
     static const uint8_t broadcast_macaddr[6] = 
         { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
@@ -293,7 +293,10 @@
 
     /* write packet data */
     while (size > 0) {
-        avail = s->stop - index;
+        if (index <= s->stop)
+            avail = s->stop - index;
+        else
+            avail = 0;
         len = size;
         if (len > avail)
             len = avail;

Modified: trunk/src/host/qemu-neo1973/hw/parallel.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/parallel.c	2007-07-01 11:01:12 UTC (rev 2355)
+++ trunk/src/host/qemu-neo1973/hw/parallel.c	2007-07-02 20:43:42 UTC (rev 2356)
@@ -71,6 +71,9 @@
     int hw_driver;
     int epp_timeout;
     uint32_t last_read_offset; /* For debugging */
+    /* Memory-mapped interface */
+    target_phys_addr_t base;
+    int it_shift;
 };
 
 static void parallel_update_irq(ParallelState *s)
@@ -400,15 +403,8 @@
     return ret;
 }
 
-/* If fd is zero, it means that the parallel device uses the console */
-ParallelState *parallel_init(int base, qemu_irq irq, CharDriverState *chr)
+static void parallel_reset(ParallelState *s, qemu_irq irq, CharDriverState *chr)
 {
-    ParallelState *s;
-    uint8_t dummy;
-
-    s = qemu_mallocz(sizeof(ParallelState));
-    if (!s)
-        return NULL;
     s->datar = ~0;
     s->dataw = ~0;
     s->status = PARA_STS_BUSY;
@@ -423,7 +419,19 @@
     s->hw_driver = 0;
     s->epp_timeout = 0;
     s->last_read_offset = ~0U;
+}
 
+/* If fd is zero, it means that the parallel device uses the console */
+ParallelState *parallel_init(int base, qemu_irq irq, CharDriverState *chr)
+{
+    ParallelState *s;
+    uint8_t dummy;
+
+    s = qemu_mallocz(sizeof(ParallelState));
+    if (!s)
+        return NULL;
+    parallel_reset(s, irq, chr);
+
     if (qemu_chr_ioctl(chr, CHR_IOCTL_PP_READ_STATUS, &dummy) == 0) {
         s->hw_driver = 1;
         s->status = dummy;
@@ -445,3 +453,79 @@
     }
     return s;
 }
+
+/* Memory mapped interface */
+uint32_t parallel_mm_readb (void *opaque, target_phys_addr_t addr)
+{
+    ParallelState *s = opaque;
+
+    return parallel_ioport_read_sw(s, (addr - s->base) >> s->it_shift) & 0xFF;
+}
+
+void parallel_mm_writeb (void *opaque,
+                       target_phys_addr_t addr, uint32_t value)
+{
+    ParallelState *s = opaque;
+
+    parallel_ioport_write_sw(s, (addr - s->base) >> s->it_shift, value & 0xFF);
+}
+
+uint32_t parallel_mm_readw (void *opaque, target_phys_addr_t addr)
+{
+    ParallelState *s = opaque;
+
+    return parallel_ioport_read_sw(s, (addr - s->base) >> s->it_shift) & 0xFFFF;
+}
+
+void parallel_mm_writew (void *opaque,
+                       target_phys_addr_t addr, uint32_t value)
+{
+    ParallelState *s = opaque;
+
+    parallel_ioport_write_sw(s, (addr - s->base) >> s->it_shift, value & 0xFFFF);
+}
+
+uint32_t parallel_mm_readl (void *opaque, target_phys_addr_t addr)
+{
+    ParallelState *s = opaque;
+
+    return parallel_ioport_read_sw(s, (addr - s->base) >> s->it_shift);
+}
+
+void parallel_mm_writel (void *opaque,
+                       target_phys_addr_t addr, uint32_t value)
+{
+    ParallelState *s = opaque;
+
+    parallel_ioport_write_sw(s, (addr - s->base) >> s->it_shift, value);
+}
+
+static CPUReadMemoryFunc *parallel_mm_read_sw[] = {
+    &parallel_mm_readb,
+    &parallel_mm_readw,
+    &parallel_mm_readl,
+};
+
+static CPUWriteMemoryFunc *parallel_mm_write_sw[] = {
+    &parallel_mm_writeb,
+    &parallel_mm_writew,
+    &parallel_mm_writel,
+};
+
+/* If fd is zero, it means that the parallel device uses the console */
+ParallelState *parallel_mm_init(target_phys_addr_t base, int it_shift, qemu_irq irq, CharDriverState *chr)
+{
+    ParallelState *s;
+    int io_sw;
+
+    s = qemu_mallocz(sizeof(ParallelState));
+    if (!s)
+        return NULL;
+    parallel_reset(s, irq, chr);
+    s->base = base;
+    s->it_shift = it_shift;
+
+    io_sw = cpu_register_io_memory(0, parallel_mm_read_sw, parallel_mm_write_sw, s);
+    cpu_register_physical_memory(base, 8 << it_shift, io_sw);
+    return s;
+}

Modified: trunk/src/host/qemu-neo1973/hw/pcnet.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/pcnet.c	2007-07-01 11:01:12 UTC (rev 2355)
+++ trunk/src/host/qemu-neo1973/hw/pcnet.c	2007-07-02 20:43:42 UTC (rev 2356)
@@ -2011,16 +2011,39 @@
 
 #if defined (TARGET_SPARC) && !defined(TARGET_SPARC64) // Avoid compile failure
 
+static void lance_mem_writew(void *opaque, target_phys_addr_t addr,
+                             uint32_t val)
+{
+#ifdef PCNET_DEBUG_IO
+    printf("lance_mem_writew addr=" TARGET_FMT_plx " val=0x%04x\n", addr,
+           val & 0xffff);
+#endif
+    pcnet_ioport_writew(opaque, addr & 7, val & 0xffff);
+}
+
+static uint32_t lance_mem_readw(void *opaque, target_phys_addr_t addr)
+{
+    uint32_t val;
+
+    val = pcnet_ioport_readw(opaque, addr & 7);
+#ifdef PCNET_DEBUG_IO
+    printf("pcnet_mmio_readw addr=" TARGET_FMT_plx " val = 0x%04x\n", addr,
+           val & 0xffff);
+#endif
+
+    return val & 0xffff;
+}
+
 static CPUReadMemoryFunc *lance_mem_read[3] = {
-    (CPUReadMemoryFunc *)&pcnet_ioport_readw,
-    (CPUReadMemoryFunc *)&pcnet_ioport_readw,
-    (CPUReadMemoryFunc *)&pcnet_ioport_readw,
+    lance_mem_readw,
+    lance_mem_readw,
+    lance_mem_readw,
 };
 
 static CPUWriteMemoryFunc *lance_mem_write[3] = {
-    (CPUWriteMemoryFunc *)&pcnet_ioport_writew,
-    (CPUWriteMemoryFunc *)&pcnet_ioport_writew,
-    (CPUWriteMemoryFunc *)&pcnet_ioport_writew,
+    lance_mem_writew,
+    lance_mem_writew,
+    lance_mem_writew,
 };
 
 void lance_init(NICInfo *nd, target_phys_addr_t leaddr, void *dma_opaque,

Modified: trunk/src/host/qemu-neo1973/hw/pl110.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/pl110.c	2007-07-01 11:01:12 UTC (rev 2355)
+++ trunk/src/host/qemu-neo1973/hw/pl110.c	2007-07-02 20:43:42 UTC (rev 2356)
@@ -302,8 +302,12 @@
     case 5: /* LCDLPBASE */
         return s->lpbase;
     case 6: /* LCDIMSC */
+	if (s->versatile)
+	  return s->cr;
         return s->int_mask;
     case 7: /* LCDControl */
+	if (s->versatile)
+	  return s->int_mask;
         return s->cr;
     case 8: /* LCDRIS */
         return s->int_status;

Modified: trunk/src/host/qemu-neo1973/hw/realview.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/realview.c	2007-07-01 11:01:12 UTC (rev 2355)
+++ trunk/src/host/qemu-neo1973/hw/realview.c	2007-07-02 20:43:42 UTC (rev 2356)
@@ -57,6 +57,8 @@
 
     pl181_init(0x10005000, sd_bdrv, pic[17], pic[18]);
 
+    pl031_init(0x10017000, pic[10]);
+
     pci_bus = pci_vpb_init(pic, 48, 1);
     if (usb_enabled) {
         usb_ohci_init_pci(pci_bus, 3, -1);
@@ -102,7 +104,7 @@
     /*  0x10014000 GPIO 1.  */
     /*  0x10015000 GPIO 2.  */
     /* 0x10016000 Reserved.  */
-    /*  0x10017000 RTC.  */
+    /* 0x10017000 RTC.  */
     /*  0x10018000 DMC.  */
     /*  0x10019000 PCI controller config.  */
     /*  0x10020000 CLCD.  */

Modified: trunk/src/host/qemu-neo1973/hw/slavio_serial.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/slavio_serial.c	2007-07-01 11:01:12 UTC (rev 2355)
+++ trunk/src/host/qemu-neo1973/hw/slavio_serial.c	2007-07-02 20:43:42 UTC (rev 2356)
@@ -354,7 +354,7 @@
 
 static void slavio_serial_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
 {
-    SerialState *ser = opaque;
+    SerialState *serial = opaque;
     ChannelState *s;
     uint32_t saddr;
     int newreg, channel;
@@ -362,7 +362,7 @@
     val &= 0xff;
     saddr = (addr & 3) >> 1;
     channel = (addr & SERIAL_MAXADDR) >> 2;
-    s = &ser->chn[channel];
+    s = &serial->chn[channel];
     switch (saddr) {
     case 0:
 	SER_DPRINTF("Write channel %c, reg[%d] = %2.2x\n", CHN_C(s), s->reg, val & 0xff);
@@ -407,13 +407,13 @@
 	    default:
 		break;
 	    case 0x40:
-		slavio_serial_reset_chn(&ser->chn[1]);
+		slavio_serial_reset_chn(&serial->chn[1]);
 		return;
 	    case 0x80:
-		slavio_serial_reset_chn(&ser->chn[0]);
+		slavio_serial_reset_chn(&serial->chn[0]);
 		return;
 	    case 0xc0:
-		slavio_serial_reset(ser);
+		slavio_serial_reset(serial);
 		return;
 	    }
 	    break;
@@ -446,7 +446,7 @@
 
 static uint32_t slavio_serial_mem_readb(void *opaque, target_phys_addr_t addr)
 {
-    SerialState *ser = opaque;
+    SerialState *serial = opaque;
     ChannelState *s;
     uint32_t saddr;
     uint32_t ret;
@@ -454,7 +454,7 @@
 
     saddr = (addr & 3) >> 1;
     channel = (addr & SERIAL_MAXADDR) >> 2;
-    s = &ser->chn[channel];
+    s = &serial->chn[channel];
     switch (saddr) {
     case 0:
 	SER_DPRINTF("Read channel %c, reg[%d] = %2.2x\n", CHN_C(s), s->reg, s->rregs[s->reg]);

Modified: trunk/src/host/qemu-neo1973/hw/spitz.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/spitz.c	2007-07-01 11:01:12 UTC (rev 2355)
+++ trunk/src/host/qemu-neo1973/hw/spitz.c	2007-07-02 20:43:42 UTC (rev 2356)
@@ -919,8 +919,8 @@
 /* Wm8750 and Max7310 on I2C */
 
 #define AKITA_MAX_ADDR	0x18
-#define SPITZ_WM_ADDRL	0x1a
-#define SPITZ_WM_ADDRH	0x1b
+#define SPITZ_WM_ADDRL	0x1b
+#define SPITZ_WM_ADDRH	0x1a
 
 #define SPITZ_GPIO_WM	5
 

Modified: trunk/src/host/qemu-neo1973/hw/sun4m.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/sun4m.c	2007-07-01 11:01:12 UTC (rev 2355)
+++ trunk/src/host/qemu-neo1973/hw/sun4m.c	2007-07-02 20:43:42 UTC (rev 2356)
@@ -154,8 +154,6 @@
     m48t59_write(nvram, start + 1, sum & 0xff);
 }
 
-static m48t59_t *nvram;
-
 extern int nographic;
 
 static void nvram_init(m48t59_t *nvram, uint8_t *macaddr, const char *cmdline,
@@ -292,13 +290,13 @@
     env->halted = 1;
 }
 
-static void sun4m_hw_init(const struct hwdef *hwdef, int ram_size,
-                          DisplayState *ds, const char *cpu_model)
+static void *sun4m_hw_init(const struct hwdef *hwdef, int RAM_size,
+                           DisplayState *ds, const char *cpu_model)
 
 {
     CPUState *env, *envs[MAX_CPUS];
     unsigned int i;
-    void *iommu, *espdma, *ledma, *main_esp;
+    void *iommu, *espdma, *ledma, *main_esp, *nvram;
     const sparc_def_t *def;
     qemu_irq *cpu_irqs[MAX_CPUS], *slavio_irq, *slavio_cpu_irq,
         *espdma_irq, *ledma_irq;
@@ -328,7 +326,7 @@
         cpu_irqs[i] = qemu_allocate_irqs(dummy_cpu_set_irq, NULL, MAX_PILS);
 
     /* allocate RAM */
-    cpu_register_physical_memory(0, ram_size, 0);
+    cpu_register_physical_memory(0, RAM_size, 0);
 
     iommu = iommu_init(hwdef->iommu_base);
     slavio_intctl = slavio_intctl_init(hwdef->intctl_base,
@@ -347,7 +345,7 @@
         fprintf(stderr, "qemu: Unsupported depth: %d\n", graphic_depth);
         exit (1);
     }
-    tcx_init(ds, hwdef->tcx_base, phys_ram_base + ram_size, ram_size,
+    tcx_init(ds, hwdef->tcx_base, phys_ram_base + RAM_size, RAM_size,
              hwdef->vram_size, graphic_width, graphic_height, graphic_depth);
 
     if (nd_table[0].model == NULL
@@ -388,13 +386,16 @@
                                    slavio_irq[hwdef->me_irq]);
     if (hwdef->cs_base != (target_phys_addr_t)-1)
         cs_init(hwdef->cs_base, hwdef->cs_irq, slavio_intctl);
+
+    return nvram;
 }
 
-static void sun4m_load_kernel(long vram_size, int ram_size, int boot_device,
+static void sun4m_load_kernel(long vram_size, int RAM_size, int boot_device,
                               const char *kernel_filename,
                               const char *kernel_cmdline,
                               const char *initrd_filename,
-                              int machine_id)
+                              int machine_id,
+                              void *nvram)
 {
     int ret, linux_boot;
     char buf[1024];
@@ -403,7 +404,7 @@
 
     linux_boot = (kernel_filename != NULL);
 
-    prom_offset = ram_size + vram_size;
+    prom_offset = RAM_size + vram_size;
     cpu_register_physical_memory(PROM_ADDR, 
                                  (PROM_SIZE_MAX + TARGET_PAGE_SIZE - 1) & TARGET_PAGE_MASK, 
                                  prom_offset | IO_MEM_ROM);
@@ -451,7 +452,7 @@
         }
     }
     nvram_init(nvram, (uint8_t *)&nd_table[0].macaddr, kernel_cmdline,
-               boot_device, ram_size, kernel_size, graphic_width,
+               boot_device, RAM_size, kernel_size, graphic_width,
                graphic_height, graphic_depth, machine_id);
 }
 
@@ -524,46 +525,48 @@
     },
 };
 
-static void sun4m_common_init(int ram_size, int boot_device, DisplayState *ds,
+static void sun4m_common_init(int RAM_size, int boot_device, DisplayState *ds,
                               const char *kernel_filename, const char *kernel_cmdline,
                               const char *initrd_filename, const char *cpu_model,
                               unsigned int machine, int max_ram)
 {
-    if ((unsigned int)ram_size > (unsigned int)max_ram) {
+    void *nvram;
+
+    if ((unsigned int)RAM_size > (unsigned int)max_ram) {
         fprintf(stderr, "qemu: Too much memory for this machine: %d, maximum %d\n",
-                (unsigned int)ram_size / (1024 * 1024),
+                (unsigned int)RAM_size / (1024 * 1024),
                 (unsigned int)max_ram / (1024 * 1024));
         exit(1);
     }
-    sun4m_hw_init(&hwdefs[machine], ram_size, ds, cpu_model);
+    nvram = sun4m_hw_init(&hwdefs[machine], RAM_size, ds, cpu_model);
 
-    sun4m_load_kernel(hwdefs[machine].vram_size, ram_size, boot_device,
+    sun4m_load_kernel(hwdefs[machine].vram_size, RAM_size, boot_device,
                       kernel_filename, kernel_cmdline, initrd_filename,
-                      hwdefs[machine].machine_id);
+                      hwdefs[machine].machine_id, nvram);
 }
 
 /* SPARCstation 5 hardware initialisation */
-static void ss5_init(int ram_size, int vga_ram_size, int boot_device,
+static void ss5_init(int RAM_size, int vga_ram_size, int boot_device,
                        DisplayState *ds, const char **fd_filename, int snapshot,
                        const char *kernel_filename, const char *kernel_cmdline,
                        const char *initrd_filename, const char *cpu_model)
 {
     if (cpu_model == NULL)
         cpu_model = "Fujitsu MB86904";
-    sun4m_common_init(ram_size, boot_device, ds, kernel_filename,
+    sun4m_common_init(RAM_size, boot_device, ds, kernel_filename,
                       kernel_cmdline, initrd_filename, cpu_model,
                       0, 0x10000000);
 }
 
 /* SPARCstation 10 hardware initialisation */
-static void ss10_init(int ram_size, int vga_ram_size, int boot_device,
+static void ss10_init(int RAM_size, int vga_ram_size, int boot_device,
                             DisplayState *ds, const char **fd_filename, int snapshot,
                             const char *kernel_filename, const char *kernel_cmdline,
                             const char *initrd_filename, const char *cpu_model)
 {
     if (cpu_model == NULL)
         cpu_model = "TI SuperSparc II";
-    sun4m_common_init(ram_size, boot_device, ds, kernel_filename,
+    sun4m_common_init(RAM_size, boot_device, ds, kernel_filename,
                       kernel_cmdline, initrd_filename, cpu_model,
                       1, PROM_ADDR); // XXX prom overlap, actually first 4GB ok
 }

Modified: trunk/src/host/qemu-neo1973/hw/tcx.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/tcx.c	2007-07-01 11:01:12 UTC (rev 2355)
+++ trunk/src/host/qemu-neo1973/hw/tcx.c	2007-07-02 20:43:42 UTC (rev 2356)
@@ -180,7 +180,7 @@
     ram_addr_t page, page_min, page_max;
     int y, y_start, dd, ds;
     uint8_t *d, *s;
-    void (*f)(TCXState *s1, uint8_t *d, const uint8_t *s, int width);
+    void (*f)(TCXState *s1, uint8_t *dst, const uint8_t *src, int width);
 
     if (ts->ds->depth == 0)
 	return;

Modified: trunk/src/host/qemu-neo1973/hw/versatilepb.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/versatilepb.c	2007-07-01 11:01:12 UTC (rev 2355)
+++ trunk/src/host/qemu-neo1973/hw/versatilepb.c	2007-07-02 20:43:42 UTC (rev 2356)
@@ -223,6 +223,9 @@
     pl181_init(0x1000b000, NULL, sic, 23, 2);
 #endif
 
+    /* Add PL031 Real Time Clock. */
+    pl031_init(0x101e8000,pic[10]);
+
     /* Memory map for Versatile/PB:  */
     /* 0x10000000 System registers.  */
     /* 0x10001000 PCI controller config registers.  */

Modified: trunk/src/host/qemu-neo1973/linux-user/elfload.c
===================================================================
--- trunk/src/host/qemu-neo1973/linux-user/elfload.c	2007-07-01 11:01:12 UTC (rev 2355)
+++ trunk/src/host/qemu-neo1973/linux-user/elfload.c	2007-07-02 20:43:42 UTC (rev 2356)
@@ -325,7 +325,7 @@
 {
   /* Check other registers XXXXX */
   regs->pc = infop->entry;
-  regs->regs[15] = infop->start_stack - 16 * 4;
+  regs->regs[15] = infop->start_stack;
 }
 
 #define USE_ELF_CORE_DUMP

Modified: trunk/src/host/qemu-neo1973/linux-user/i386/syscall_nr.h
===================================================================
--- trunk/src/host/qemu-neo1973/linux-user/i386/syscall_nr.h	2007-07-01 11:01:12 UTC (rev 2355)
+++ trunk/src/host/qemu-neo1973/linux-user/i386/syscall_nr.h	2007-07-02 20:43:42 UTC (rev 2356)
@@ -271,4 +271,7 @@
 #define TARGET_NR_clock_getres	(TARGET_NR_timer_create+7)
 #define TARGET_NR_clock_nanosleep	(TARGET_NR_timer_create+8)
 
+#define TARGET_NR_tgkill		270
 #define TARGET_NR_utimes		271
+
+#define TARGET_NR_set_robust_list	311

Modified: trunk/src/host/qemu-neo1973/linux-user/main.c
===================================================================
--- trunk/src/host/qemu-neo1973/linux-user/main.c	2007-07-01 11:01:12 UTC (rev 2355)
+++ trunk/src/host/qemu-neo1973/linux-user/main.c	2007-07-02 20:43:42 UTC (rev 2356)
@@ -1666,11 +1666,12 @@
            "usage: qemu-" TARGET_ARCH " [-h] [-g] [-d opts] [-L path] [-s size] [-cpu model] program [arguments...]\n"
            "Linux CPU emulator (compiled for %s emulation)\n"
            "\n"
-           "-h           print this help\n"
-           "-g port      wait gdb connection to port\n"
-           "-L path      set the elf interpreter prefix (default=%s)\n"
-           "-s size      set the stack size in bytes (default=%ld)\n"
-           "-cpu model   select CPU (-cpu ? for list)\n"
+           "-h                print this help\n"
+           "-g port           wait gdb connection to port\n"
+           "-L path           set the elf interpreter prefix (default=%s)\n"
+           "-s size           set the stack size in bytes (default=%ld)\n"
+           "-cpu model        select CPU (-cpu ? for list)\n"
+           "-drop-ld-preload  drop LD_PRELOAD for target process\n"
            "\n"
            "debug options:\n"
 #ifdef USE_CODE_COPY
@@ -1702,7 +1703,9 @@
     int optind;
     const char *r;
     int gdbstub_port = 0;
-    
+    int drop_ld_preload = 0, environ_count = 0;
+    char **target_environ, **wrk, **dst;
+
     if (argc <= 1)
         usage();
 
@@ -1774,6 +1777,8 @@
 #endif
                 _exit(1);
             }
+        } else if (!strcmp(r, "drop-ld-preload")) {
+            drop_ld_preload = 1;
         } else 
 #ifdef USE_CODE_COPY
         if (!strcmp(r, "no-code-copy")) {
@@ -1802,11 +1807,31 @@
     env = cpu_init();
     global_env = env;
     
-    if (loader_exec(filename, argv+optind, environ, regs, info) != 0) {
-	printf("Error loading %s\n", filename);
-	_exit(1);
+    wrk = environ;
+    while (*(wrk++))
+        environ_count++;
+
+    target_environ = malloc((environ_count + 1) * sizeof(char *));
+    if (!target_environ)
+        abort();
+    for (wrk = environ, dst = target_environ; *wrk; wrk++) {
+        if (drop_ld_preload && !strncmp(*wrk, "LD_PRELOAD=", 11))
+            continue;
+        *(dst++) = strdup(*wrk);
     }
+    *dst = NULL; /* NULL terminate target_environ */
+
+    if (loader_exec(filename, argv+optind, target_environ, regs, info) != 0) {
+        printf("Error loading %s\n", filename);
+        _exit(1);
+    }
+
+    for (wrk = target_environ; *wrk; wrk++) {
+        free(*wrk);
+    }
     
+    free(target_environ);
+
     if (loglevel) {
         page_dump(logfile);
     
@@ -1908,6 +1933,8 @@
     cpu_x86_load_seg(env, R_FS, __USER_DS);
     cpu_x86_load_seg(env, R_GS, __USER_DS);
 
+    /* This hack makes Wine work... */
+    env->segs[R_FS].selector = 0;
 #elif defined(TARGET_ARM)
     {
         int i;

Modified: trunk/src/host/qemu-neo1973/linux-user/syscall.c
===================================================================
--- trunk/src/host/qemu-neo1973/linux-user/syscall.c	2007-07-01 11:01:12 UTC (rev 2355)
+++ trunk/src/host/qemu-neo1973/linux-user/syscall.c	2007-07-02 20:43:42 UTC (rev 2356)
@@ -144,6 +144,7 @@
 #define __NR_sys_getdents64 __NR_getdents64
 #define __NR_sys_rt_sigqueueinfo __NR_rt_sigqueueinfo
 #define __NR_sys_syslog __NR_syslog
+#define __NR_sys_tgkill __NR_tgkill
 
 #if defined(__alpha__) || defined (__ia64__) || defined(__x86_64__)
 #define __NR__llseek __NR_lseek
@@ -164,6 +165,7 @@
           loff_t *, res, uint, wh);
 _syscall3(int,sys_rt_sigqueueinfo,int,pid,int,sig,siginfo_t *,uinfo)
 _syscall3(int,sys_syslog,int,type,char*,bufp,int,len)
+_syscall3(int,sys_tgkill,int,tgid,int,pid,int,sig)
 #ifdef __NR_exit_group
 _syscall1(int,exit_group,int,error_code)
 #endif
@@ -4604,10 +4606,21 @@
       break;
 #endif
 
+#ifdef TARGET_NR_tgkill
+    case TARGET_NR_tgkill:
+	ret = get_errno(sys_tgkill((int)arg1, (int)arg2, (int)arg3));
+	break;
+#endif
+
+#ifdef TARGET_NR_set_robust_list
+    case TARGET_NR_set_robust_list:
+	goto unimplemented_nowarn;
+#endif
+
     default:
     unimplemented:
         gemu_log("qemu: Unsupported syscall: %d\n", num);
-#if defined(TARGET_NR_setxattr) || defined(TARGET_NR_get_thread_area) || defined(TARGET_NR_getdomainname)
+#if defined(TARGET_NR_setxattr) || defined(TARGET_NR_get_thread_area) || defined(TARGET_NR_getdomainname) || defined(TARGET_NR_set_robust_list)
     unimplemented_nowarn:
 #endif
         ret = -ENOSYS;

Modified: trunk/src/host/qemu-neo1973/linux-user/syscall_defs.h
===================================================================
--- trunk/src/host/qemu-neo1973/linux-user/syscall_defs.h	2007-07-01 11:01:12 UTC (rev 2355)
+++ trunk/src/host/qemu-neo1973/linux-user/syscall_defs.h	2007-07-02 20:43:42 UTC (rev 2356)
@@ -869,7 +869,7 @@
 #define TARGET_MAP_NORESERVE	0x4000		/* don't check for reservations */
 #endif
 
-#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SH4)
+#if defined(TARGET_I386) || defined(TARGET_ARM)
 struct target_stat {
 	unsigned short st_dev;
 	unsigned short __pad1;
@@ -1242,6 +1242,65 @@
        target_long     __unused[3];
 };
 
+#elif defined(TARGET_SH4)
+
+struct target_stat {
+	target_ulong  st_dev;
+	target_ulong  st_ino;
+	unsigned short st_mode;
+	unsigned short st_nlink;
+	unsigned short st_uid;
+	unsigned short st_gid;
+	target_ulong  st_rdev;
+	target_ulong  st_size;
+	target_ulong  st_blksize;
+	target_ulong  st_blocks;
+	target_ulong  target_st_atime;
+	target_ulong  target_st_atime_nsec;
+	target_ulong  target_st_mtime;
+	target_ulong  target_st_mtime_nsec;
+	target_ulong  target_st_ctime;
+	target_ulong  target_st_ctime_nsec;
+	target_ulong  __unused4;
+	target_ulong  __unused5;
+};
+
+/* This matches struct stat64 in glibc2.1, hence the absolutely
+ * insane amounts of padding around dev_t's.
+ */
+struct target_stat64 {
+	unsigned long long	st_dev;
+	unsigned char	__pad0[4];
+
+#define TARGET_STAT64_HAS_BROKEN_ST_INO	1
+	target_ulong	__st_ino;
+
+	unsigned int	st_mode;
+	unsigned int	st_nlink;
+
+	target_ulong	st_uid;
+	target_ulong	st_gid;
+
+	unsigned long long	st_rdev;
+	unsigned char	__pad3[4];
+
+	long long	st_size;
+	target_ulong	st_blksize;
+
+	unsigned long long	st_blocks;	/* Number 512-byte blocks allocated. */
+
+	target_ulong	target_st_atime;
+	target_ulong	target_st_atime_nsec;
+
+	target_ulong	target_st_mtime;
+	target_ulong	target_st_mtime_nsec;
+
+	target_ulong	target_st_ctime;
+	target_ulong	target_st_ctime_nsec; 
+
+	unsigned long long	st_ino;
+};
+
 #else
 #error unsupported CPU
 #endif

Modified: trunk/src/host/qemu-neo1973/monitor.c
===================================================================
--- trunk/src/host/qemu-neo1973/monitor.c	2007-07-01 11:01:12 UTC (rev 2355)
+++ trunk/src/host/qemu-neo1973/monitor.c	2007-07-02 20:43:42 UTC (rev 2356)
@@ -409,6 +409,11 @@
     vga_hw_screen_dump(filename);
 }
 
+static void do_logfile(const char *filename)
+{
+    cpu_set_log_filename(filename);
+}
+
 static void do_log(const char *items)
 {
     int mask;
@@ -787,7 +792,7 @@
 
     { 0xb5, "kp_divide" },
     { 0x37, "kp_multiply" },
-    { 0x4a, "kp_substract" },
+    { 0x4a, "kp_subtract" },
     { 0x4e, "kp_add" },
     { 0x9c, "kp_enter" },
     { 0x53, "kp_decimal" },
@@ -1239,6 +1244,8 @@
       "device filename", "change a removable medium" },
     { "screendump", "F", do_screen_dump, 
       "filename", "save screen into PPM image 'filename'" },
+    { "logfile", "s", do_logfile,
+      "filename", "output logs to 'filename'" },
     { "log", "s", do_log,
       "item1[,...]", "activate logging of the specified items to '/tmp/qemu.log'" }, 
     { "savevm", "s?", do_savevm,

Modified: trunk/src/host/qemu-neo1973/pc-bios/README
===================================================================
--- trunk/src/host/qemu-neo1973/pc-bios/README	2007-07-01 11:01:12 UTC (rev 2355)
+++ trunk/src/host/qemu-neo1973/pc-bios/README	2007-07-02 20:43:42 UTC (rev 2356)
@@ -14,8 +14,7 @@
 - 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 Sparc32 image is built from SVN version 149 and Sparc64
-  image from version 125.
+  The included Sparc32 and Sparc64 images are built from SVN version 157.
 
 - The PXE roms come from Rom-o-Matic etherboot 5.4.2.
   pcnet32:pcnet32 -- [0x1022,0x2000]

Modified: trunk/src/host/qemu-neo1973/pc-bios/openbios-sparc32
===================================================================
(Binary files differ)

Modified: trunk/src/host/qemu-neo1973/pc-bios/openbios-sparc64
===================================================================
(Binary files differ)

Modified: trunk/src/host/qemu-neo1973/qemu-doc.texi
===================================================================
--- trunk/src/host/qemu-neo1973/qemu-doc.texi	2007-07-01 11:01:12 UTC (rev 2355)
+++ trunk/src/host/qemu-neo1973/qemu-doc.texi	2007-07-02 20:43:42 UTC (rev 2356)
@@ -1363,8 +1363,7 @@
 above but it can be used with the tslib library because in addition to touch
 coordinates it reports touch pressure.
 @item @code{keyboard}
-Standard USB keyboard.  Will override the PS/2 keyboard emulation (if
-present).
+Standard USB keyboard.  Will override the PS/2 keyboard (if present).
 @end table
 
 @node host_usb_devices

Modified: trunk/src/host/qemu-neo1973/qemu-img.c
===================================================================
--- trunk/src/host/qemu-neo1973/qemu-img.c	2007-07-01 11:01:12 UTC (rev 2355)
+++ trunk/src/host/qemu-neo1973/qemu-img.c	2007-07-02 20:43:42 UTC (rev 2356)
@@ -297,7 +297,7 @@
     drv = bdrv_find_format(fmt);
     if (!drv)
         error("Unknown file format '%s'", fmt);
-    printf("Formating '%s', fmt=%s",
+    printf("Formatting '%s', fmt=%s",
            filename, fmt);
     if (encrypted)
         printf(", encrypted");

Modified: trunk/src/host/qemu-neo1973/readline.c
===================================================================
--- trunk/src/host/qemu-neo1973/readline.c	2007-07-01 11:01:12 UTC (rev 2355)
+++ trunk/src/host/qemu-neo1973/readline.c	2007-07-02 20:43:42 UTC (rev 2356)
@@ -156,6 +156,45 @@
     }
 }
 
+static void term_backword(void)
+{
+    int start;
+
+    if (term_cmd_buf_index == 0 || term_cmd_buf_index > term_cmd_buf_size) {
+        return;
+    }
+
+    start = term_cmd_buf_index - 1;
+
+    /* find first word (backwards) */
+    while (start > 0) {
+        if (!isspace(term_cmd_buf[start])) {
+            break;
+        }
+
+        --start;
+    }
+
+    /* find first space (backwards) */
+    while (start > 0) {
+        if (isspace(term_cmd_buf[start])) {
+            ++start;
+            break;
+        }
+
+        --start;
+    }
+
+    /* remove word */
+    if (start < term_cmd_buf_index) {
+        memmove(term_cmd_buf + start,
+                term_cmd_buf + term_cmd_buf_index,
+                term_cmd_buf_size - term_cmd_buf_index);
+        term_cmd_buf_size -= term_cmd_buf_index - start;
+        term_cmd_buf_index = start;
+    }
+}
+
 static void term_bol(void)
 {
     term_cmd_buf_index = 0;
@@ -338,6 +377,10 @@
             /* NOTE: readline_start can be called here */
             term_readline_func(term_readline_opaque, term_cmd_buf);
             break;
+        case 23:
+            /* ^W */
+            term_backword();
+            break;
         case 27:
             term_esc_state = IS_ESC;
             break;

Modified: trunk/src/host/qemu-neo1973/sdl.c
===================================================================
--- trunk/src/host/qemu-neo1973/sdl.c	2007-07-01 11:01:12 UTC (rev 2355)
+++ trunk/src/host/qemu-neo1973/sdl.c	2007-07-02 20:43:42 UTC (rev 2356)
@@ -223,8 +223,12 @@
 
     if (!vm_running)
         status = " [Stopped]";
-    else if (gui_grab)
-        status = " - Press Ctrl-Alt to exit grab";
+    else if (gui_grab) {
+        if (!alt_grab)
+            status = " - Press Ctrl-Alt to exit grab";
+        else
+            status = " - Press Ctrl-Alt-Shift to exit grab";
+    }
 
     if (qemu_name)
         snprintf(buf, sizeof(buf), "QEMU (%s)%s", qemu_name, status);
@@ -357,8 +361,13 @@
         case SDL_KEYDOWN:
         case SDL_KEYUP:
             if (ev->type == SDL_KEYDOWN) {
-                mod_state = (SDL_GetModState() & gui_grab_code) ==
-                    gui_grab_code;
+                if (!alt_grab) {
+                    mod_state = (SDL_GetModState() & gui_grab_code) ==
+                                gui_grab_code;
+                } else {
+                    mod_state = (SDL_GetModState() & (gui_grab_code | KMOD_LSHIFT)) ==
+                                (gui_grab_code | KMOD_LSHIFT);
+                }
                 gui_key_modifier_pressed = mod_state;
                 if (gui_key_modifier_pressed) {
                     int keycode;
@@ -419,7 +428,12 @@
                     }
                 }
             } else if (ev->type == SDL_KEYUP) {
-                mod_state = (ev->key.keysym.mod & gui_grab_code);
+                if (!alt_grab) {
+                    mod_state = (ev->key.keysym.mod & gui_grab_code);
+                } else {
+                    mod_state = (ev->key.keysym.mod &
+                                 (gui_grab_code | KMOD_LSHIFT));
+                }
                 if (!mod_state) {
                     if (gui_key_modifier_pressed) {
                         gui_key_modifier_pressed = 0;
@@ -452,6 +466,7 @@
         case SDL_QUIT:
             if (!no_quit) {
                 qemu_system_shutdown_request();
+                vm_start();	/* In case we're paused */
             }
             break;
         case SDL_MOUSEMOTION:

Modified: trunk/src/host/qemu-neo1973/target-arm/cpu.h
===================================================================
--- trunk/src/host/qemu-neo1973/target-arm/cpu.h	2007-07-01 11:01:12 UTC (rev 2355)
+++ trunk/src/host/qemu-neo1973/target-arm/cpu.h	2007-07-02 20:43:42 UTC (rev 2356)
@@ -83,6 +83,7 @@
         uint32_t c0_cachetype;
         uint32_t c1_sys; /* System control register.  */
         uint32_t c1_coproc; /* Coprocessor access register.  */
+        uint32_t c1_xscaleauxcr; /* XScale auxiliary control register.  */
         uint32_t c2_base; /* MMU translation table base.  */
         uint32_t c2_data; /* MPU data cachable bits.  */
         uint32_t c2_insn; /* MPU instruction cachable bits.  */

Modified: trunk/src/host/qemu-neo1973/target-arm/helper.c
===================================================================
--- trunk/src/host/qemu-neo1973/target-arm/helper.c	2007-07-01 11:01:12 UTC (rev 2355)
+++ trunk/src/host/qemu-neo1973/target-arm/helper.c	2007-07-02 20:43:42 UTC (rev 2356)
@@ -22,16 +22,19 @@
         set_feature(env, ARM_FEATURE_VFP);
         env->vfp.xregs[ARM_VFP_FPSID] = 0x41011090;
         env->cp15.c0_cachetype = 0x1dd20d2;
+        env->cp15.c1_sys = 0x00090078;
         break;
     case ARM_CPUID_ARM946:
         set_feature(env, ARM_FEATURE_MPU);
         env->cp15.c0_cachetype = 0x0f004006;
+        env->cp15.c1_sys = 0x00000078;
         break;
     case ARM_CPUID_ARM1026:
         set_feature(env, ARM_FEATURE_VFP);
         set_feature(env, ARM_FEATURE_AUXCR);
         env->vfp.xregs[ARM_VFP_FPSID] = 0x410110a0;
         env->cp15.c0_cachetype = 0x1dd20d2;
+        env->cp15.c1_sys = 0x00090078;
         break;
     case ARM_CPUID_PXA250:
     case ARM_CPUID_PXA255:
@@ -41,6 +44,7 @@
         set_feature(env, ARM_FEATURE_XSCALE);
         /* JTAG_ID is ((id << 28) | 0x09265013) */
         env->cp15.c0_cachetype = 0xd172172;
+        env->cp15.c1_sys = 0x00000078;
         break;
     case ARM_CPUID_PXA270_A0:
     case ARM_CPUID_PXA270_A1:
@@ -53,6 +57,7 @@
         set_feature(env, ARM_FEATURE_IWMMXT);
         env->iwmmxt.cregs[ARM_IWMMXT_wCID] = 0x69051000 | 'Q';
         env->cp15.c0_cachetype = 0xd172172;
+        env->cp15.c1_sys = 0x00000078;
         break;
     default:
         cpu_abort(env, "Bad CPU ID: %x\n", id);
@@ -642,6 +647,8 @@
     crm = insn & 0xf;
     switch ((insn >> 16) & 0xf) {
     case 0: /* ID codes.  */
+        if (arm_feature(env, ARM_FEATURE_XSCALE))
+            break;
         goto bad_reg;
     case 1: /* System configuration.  */
         switch (op2) {
@@ -653,12 +660,14 @@
             tlb_flush(env, 1);
             break;
         case 1:
-            /* XScale doesn't implement AUX CR (P-Bit) but allows
-             * writing with zero and reading.  */
-            if (arm_feature(env, ARM_FEATURE_XSCALE))
+            if (arm_feature(env, ARM_FEATURE_XSCALE)) {
+                env->cp15.c1_xscaleauxcr = val;
                 break;
+            }
             goto bad_reg;
         case 2:
+            if (arm_feature(env, ARM_FEATURE_XSCALE))
+                goto bad_reg;
             env->cp15.c1_coproc = val;
             /* ??? Is this safe when called from within a TB?  */
             tb_flush(env);
@@ -844,6 +853,9 @@
         case 2: /* TCM status.  */
             if (arm_feature(env, ARM_FEATURE_S3C))
                 return env->cp15.c0_cpuid;
+            if (arm_feature(env, ARM_FEATURE_XSCALE))
+                goto bad_reg;
+            return 0;
         }
     case 1: /* System configuration.  */
         switch (op2) {
@@ -853,9 +865,11 @@
             if (arm_feature(env, ARM_FEATURE_AUXCR))
                 return 1;
             if (arm_feature(env, ARM_FEATURE_XSCALE))
-                return 0;
+                return env->cp15.c1_xscaleauxcr;
             goto bad_reg;
         case 2: /* Coprocessor access register.  */
+            if (arm_feature(env, ARM_FEATURE_XSCALE))
+                goto bad_reg;
             return env->cp15.c1_coproc;
         default:
             goto bad_reg;

Modified: trunk/src/host/qemu-neo1973/target-i386/exec.h
===================================================================
--- trunk/src/host/qemu-neo1973/target-i386/exec.h	2007-07-01 11:01:12 UTC (rev 2355)
+++ trunk/src/host/qemu-neo1973/target-i386/exec.h	2007-07-02 20:43:42 UTC (rev 2356)
@@ -190,6 +190,7 @@
 void helper_idivq_EAX_T0(void);
 void helper_bswapq_T0(void);
 void helper_cmpxchg8b(void);
+void helper_single_step(void);
 void helper_cpuid(void);
 void helper_enter_level(int level, int data32);
 void helper_enter64_level(int level, int data64);

Modified: trunk/src/host/qemu-neo1973/target-i386/helper.c
===================================================================
--- trunk/src/host/qemu-neo1973/target-i386/helper.c	2007-07-01 11:01:12 UTC (rev 2355)
+++ trunk/src/host/qemu-neo1973/target-i386/helper.c	2007-07-02 20:43:42 UTC (rev 2356)
@@ -1622,6 +1622,12 @@
     CC_SRC = eflags;
 }
 
+void helper_single_step()
+{
+    env->dr[6] |= 0x4000;
+    raise_exception(EXCP01_SSTP);
+}
+
 void helper_cpuid(void)
 {
     uint32_t index;

Modified: trunk/src/host/qemu-neo1973/target-i386/op.c
===================================================================
--- trunk/src/host/qemu-neo1973/target-i386/op.c	2007-07-01 11:01:12 UTC (rev 2355)
+++ trunk/src/host/qemu-neo1973/target-i386/op.c	2007-07-02 20:43:42 UTC (rev 2356)
@@ -730,6 +730,11 @@
     helper_cmpxchg8b();
 }
 
+void OPPROTO op_single_step(void)
+{
+    helper_single_step();
+}
+
 void OPPROTO op_movl_T0_0(void)
 {
     T0 = 0;

Modified: trunk/src/host/qemu-neo1973/target-i386/translate.c
===================================================================
--- trunk/src/host/qemu-neo1973/target-i386/translate.c	2007-07-01 11:01:12 UTC (rev 2355)
+++ trunk/src/host/qemu-neo1973/target-i386/translate.c	2007-07-02 20:43:42 UTC (rev 2356)
@@ -2277,7 +2277,7 @@
     if (s->singlestep_enabled) {
         gen_op_debug();
     } else if (s->tf) {
-        gen_op_raise_exception(EXCP01_SSTP);
+	gen_op_single_step();
     } else {
         gen_op_movl_T0_0();
         gen_op_exit_tb();
@@ -5327,8 +5327,12 @@
         if (CODE64(s))
             goto illegal_op;
         val = ldub_code(s->pc++);
-        gen_op_aam(val);
-        s->cc_op = CC_OP_LOGICB;
+        if (val == 0) {
+            gen_exception(s, EXCP00_DIVZ, pc_start - s->cs_base);
+        } else {
+            gen_op_aam(val);
+            s->cc_op = CC_OP_LOGICB;
+        }
         break;
     case 0xd5: /* aad */
         if (CODE64(s))

Modified: trunk/src/host/qemu-neo1973/target-mips/cpu.h
===================================================================
--- trunk/src/host/qemu-neo1973/target-mips/cpu.h	2007-07-01 11:01:12 UTC (rev 2355)
+++ trunk/src/host/qemu-neo1973/target-mips/cpu.h	2007-07-02 20:43:42 UTC (rev 2356)
@@ -102,6 +102,8 @@
 
     uint32_t nb_tlb;
     uint32_t tlb_in_use;
+    uint32_t SEGBITS;
+    target_ulong SEGMask;
     int (*map_address) (CPUMIPSState *env, target_ulong *physical, int *prot, target_ulong address, int rw, int access_type);
     void (*do_tlbwi) (void);
     void (*do_tlbwr) (void);

Modified: trunk/src/host/qemu-neo1973/target-mips/helper.c
===================================================================
--- trunk/src/host/qemu-neo1973/target-mips/helper.c	2007-07-01 11:01:12 UTC (rev 2355)
+++ trunk/src/host/qemu-neo1973/target-mips/helper.c	2007-07-02 20:43:42 UTC (rev 2356)
@@ -77,7 +77,7 @@
         target_ulong tag = address & ~mask;
         target_ulong VPN = tlb->VPN & ~mask;
 #ifdef TARGET_MIPS64
-        tag &= 0xC00000FFFFFFFFFFULL;
+        tag &= env->SEGMask;
 #endif
 
         /* Check ASID, virtual page number & size */
@@ -130,28 +130,27 @@
 
     if (address <= (int32_t)0x7FFFFFFFUL) {
         /* useg */
-        if (!(env->CP0_Status & (1 << CP0St_ERL) && user_mode)) {
-            ret = env->map_address(env, physical, prot, address, rw, access_type);
-        } else {
+        if (env->CP0_Status & (1 << CP0St_ERL)) {
             *physical = address & 0xFFFFFFFF;
             *prot = PAGE_READ | PAGE_WRITE;
+        } else {
+            ret = env->map_address(env, physical, prot, address, rw, access_type);
         }
 #ifdef TARGET_MIPS64
 /*
    XXX: Assuming :
    - PABITS = 36 (correct for MIPS64R1)
-   - SEGBITS = 40
 */
     } else if (address < 0x3FFFFFFFFFFFFFFFULL) {
         /* xuseg */
-	if (UX && address < 0x000000FFFFFFFFFFULL) {
+	if (UX && address < (0x3FFFFFFFFFFFFFFFULL & env->SEGMask)) {
             ret = env->map_address(env, physical, prot, address, rw, access_type);
 	} else {
 	    ret = TLBRET_BADADDR;
         }
     } else if (address < 0x7FFFFFFFFFFFFFFFULL) {
         /* xsseg */
-	if (SX && address < 0x400000FFFFFFFFFFULL) {
+	if (SX && address < (0x7FFFFFFFFFFFFFFFULL & env->SEGMask)) {
             ret = env->map_address(env, physical, prot, address, rw, access_type);
 	} else {
 	    ret = TLBRET_BADADDR;
@@ -159,9 +158,9 @@
     } else if (address < 0xBFFFFFFFFFFFFFFFULL) {
         /* xkphys */
         /* XXX: check supervisor mode */
-        if (KX && (address & 0x03FFFFFFFFFFFFFFULL) < 0X0000000FFFFFFFFFULL)
+        if (KX && (address & 0x07FFFFFFFFFFFFFFULL) < 0X0000000FFFFFFFFFULL)
 	{
-            *physical = address & 0X000000FFFFFFFFFFULL;
+            *physical = address & 0X0000000FFFFFFFFFULL;
             *prot = PAGE_READ | PAGE_WRITE;
 	} else {
 	    ret = TLBRET_BADADDR;
@@ -169,7 +168,7 @@
     } else if (address < 0xFFFFFFFF7FFFFFFFULL) {
         /* xkseg */
         /* XXX: check supervisor mode */
-	if (KX && address < 0xC00000FF7FFFFFFFULL) {
+	if (KX && address < (0xFFFFFFFF7FFFFFFFULL & env->SEGMask)) {
             ret = env->map_address(env, physical, prot, address, rw, access_type);
 	} else {
 	    ret = TLBRET_BADADDR;
@@ -303,10 +302,10 @@
         env->CP0_EntryHi =
             (env->CP0_EntryHi & 0xFF) | (address & (TARGET_PAGE_MASK << 1));
 #ifdef TARGET_MIPS64
-        env->CP0_EntryHi &= 0xc00000ffffffffffULL;
-        env->CP0_XContext = (env->CP0_XContext & 0xfffffffe00000000ULL) |
-                            ((address >> 31) & 0x0000000180000000ULL) |
-                            ((address >> 9) & 0x000000007ffffff0ULL);
+        env->CP0_EntryHi &= env->SEGMask;
+        env->CP0_XContext = (env->CP0_XContext & ((~0ULL) << (env->SEGBITS - 7))) |
+                            ((address & 0xC00000000000ULL) >> (env->SEGBITS - 9)) |
+                            ((address & ((1ULL << env->SEGBITS) - 1) & 0xFFFFFFFFFFFFE000ULL) >> 9);
 #endif
         env->exception_index = exception;
         env->error_code = error_code;
@@ -555,7 +554,7 @@
     if (tlb->V0) {
         addr = tlb->VPN & ~mask;
 #ifdef TARGET_MIPS64
-        if (addr >= 0xC00000FF80000000ULL) {
+        if (addr >= (0xFFFFFFFF80000000ULL & env->SEGMask)) {
             addr |= 0x3FFFFF0000000000ULL;
         }
 #endif
@@ -568,7 +567,7 @@
     if (tlb->V1) {
         addr = (tlb->VPN & ~mask) | ((mask >> 1) + 1);
 #ifdef TARGET_MIPS64
-        if (addr >= 0xC00000FF80000000ULL) {
+        if (addr >= (0xFFFFFFFF80000000ULL & env->SEGMask)) {
             addr |= 0x3FFFFF0000000000ULL;
         }
 #endif

Modified: trunk/src/host/qemu-neo1973/target-mips/op.c
===================================================================
--- trunk/src/host/qemu-neo1973/target-mips/op.c	2007-07-01 11:01:12 UTC (rev 2355)
+++ trunk/src/host/qemu-neo1973/target-mips/op.c	2007-07-02 20:43:42 UTC (rev 2356)
@@ -297,7 +297,7 @@
    with Status_UX = 0 should be casted to 32-bit and sign extended.
    See the MIPS64 PRA manual, section 4.10. */
 #ifdef TARGET_MIPS64
-    if ((env->CP0_Status & (1 << CP0St_UM)) &&
+    if ((env->hflags & MIPS_HFLAG_UM) &&
         !(env->CP0_Status & (1 << CP0St_UX)))
         T0 = (int64_t)(int32_t)(T0 + T1);
     else
@@ -1328,7 +1328,7 @@
     /* 1k pages not implemented */
     val = T0 & ((TARGET_PAGE_MASK << 1) | 0xFF);
 #ifdef TARGET_MIPS64
-    val = T0 & 0xC00000FFFFFFFFFFULL;
+    val &= env->SEGMask;
 #endif
     old = env->CP0_EntryHi;
     env->CP0_EntryHi = val;
@@ -1433,7 +1433,7 @@
 
 void op_mtc0_config0 (void)
 {
-    env->CP0_Config0 = (env->CP0_Config0 & 0x81FFFFF8) | (T0 & 0x00000001);
+    env->CP0_Config0 = (env->CP0_Config0 & 0x81FFFFF8) | (T0 & 0x00000007);
     RETURN();
 }
 
@@ -1526,7 +1526,8 @@
 #ifdef TARGET_MIPS64
 void op_mtc0_xcontext (void)
 {
-    env->CP0_XContext = (env->CP0_XContext & 0x1ffffffffULL) | (T0 & ~0x1ffffffffULL);
+    target_ulong mask = (1ULL << (env->SEGBITS - 7)) - 1;
+    env->CP0_XContext = (env->CP0_XContext & mask) | (T0 & ~mask);
     RETURN();
 }
 
@@ -1607,7 +1608,7 @@
 void op_cp0_enabled(void)
 {
     if (!(env->CP0_Status & (1 << CP0St_CU0)) &&
-	(env->hflags & MIPS_HFLAG_UM)) {
+        (env->hflags & MIPS_HFLAG_UM)) {
         CALL_FROM_TB2(do_raise_exception_err, EXCP_CpU, 0);
     }
     RETURN();

Modified: trunk/src/host/qemu-neo1973/target-mips/op_helper.c
===================================================================
--- trunk/src/host/qemu-neo1973/target-mips/op_helper.c	2007-07-01 11:01:12 UTC (rev 2355)
+++ trunk/src/host/qemu-neo1973/target-mips/op_helper.c	2007-07-02 20:43:42 UTC (rev 2356)
@@ -374,7 +374,7 @@
     tlb = &env->mmu.r4k.tlb[idx];
     tlb->VPN = env->CP0_EntryHi & (TARGET_PAGE_MASK << 1);
 #ifdef TARGET_MIPS64
-    tlb->VPN &= 0xC00000FFFFFFFFFFULL;
+    tlb->VPN &= env->SEGMask;
 #endif
     tlb->ASID = env->CP0_EntryHi & 0xFF;
     tlb->PageMask = env->CP0_PageMask;
@@ -597,6 +597,13 @@
 
 /* Complex FPU operations which may need stack space. */
 
+#define FLOAT_SIGN32 (1 << 31)
+#define FLOAT_SIGN64 (1ULL << 63)
+#define FLOAT_ONE32 (0x3f8 << 20)
+#define FLOAT_ONE64 (0x3ffULL << 52)
+#define FLOAT_TWO32 (1 << 30)
+#define FLOAT_TWO64 (1ULL << 62)
+
 /* convert MIPS rounding mode in FCR31 to IEEE library */
 unsigned int ieee_rm[] = {
     float_round_nearest_even,
@@ -775,7 +782,7 @@
 FLOAT_OP(roundl, d)
 {
     set_float_rounding_mode(float_round_nearest_even, &env->fp_status);
-    DT2 = float64_round_to_int(FDT0, &env->fp_status);
+    DT2 = float64_to_int64(FDT0, &env->fp_status);
     RESTORE_ROUNDING_MODE;
     update_fcr31();
     if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
@@ -784,7 +791,7 @@
 FLOAT_OP(roundl, s)
 {
     set_float_rounding_mode(float_round_nearest_even, &env->fp_status);
-    DT2 = float32_round_to_int(FST0, &env->fp_status);
+    DT2 = float32_to_int64(FST0, &env->fp_status);
     RESTORE_ROUNDING_MODE;
     update_fcr31();
     if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
@@ -793,7 +800,7 @@
 FLOAT_OP(roundw, d)
 {
     set_float_rounding_mode(float_round_nearest_even, &env->fp_status);
-    WT2 = float64_round_to_int(FDT0, &env->fp_status);
+    WT2 = float64_to_int32(FDT0, &env->fp_status);
     RESTORE_ROUNDING_MODE;
     update_fcr31();
     if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
@@ -802,7 +809,7 @@
 FLOAT_OP(roundw, s)
 {
     set_float_rounding_mode(float_round_nearest_even, &env->fp_status);
-    WT2 = float32_round_to_int(FST0, &env->fp_status);
+    WT2 = float32_to_int32(FST0, &env->fp_status);
     RESTORE_ROUNDING_MODE;
     update_fcr31();
     if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
@@ -841,7 +848,7 @@
 FLOAT_OP(ceill, d)
 {
     set_float_rounding_mode(float_round_up, &env->fp_status);
-    DT2 = float64_round_to_int(FDT0, &env->fp_status);
+    DT2 = float64_to_int64(FDT0, &env->fp_status);
     RESTORE_ROUNDING_MODE;
     update_fcr31();
     if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
@@ -850,7 +857,7 @@
 FLOAT_OP(ceill, s)
 {
     set_float_rounding_mode(float_round_up, &env->fp_status);
-    DT2 = float32_round_to_int(FST0, &env->fp_status);
+    DT2 = float32_to_int64(FST0, &env->fp_status);
     RESTORE_ROUNDING_MODE;
     update_fcr31();
     if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
@@ -859,7 +866,7 @@
 FLOAT_OP(ceilw, d)
 {
     set_float_rounding_mode(float_round_up, &env->fp_status);
-    WT2 = float64_round_to_int(FDT0, &env->fp_status);
+    WT2 = float64_to_int32(FDT0, &env->fp_status);
     RESTORE_ROUNDING_MODE;
     update_fcr31();
     if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
@@ -868,7 +875,7 @@
 FLOAT_OP(ceilw, s)
 {
     set_float_rounding_mode(float_round_up, &env->fp_status);
-    WT2 = float32_round_to_int(FST0, &env->fp_status);
+    WT2 = float32_to_int32(FST0, &env->fp_status);
     RESTORE_ROUNDING_MODE;
     update_fcr31();
     if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
@@ -878,7 +885,7 @@
 FLOAT_OP(floorl, d)
 {
     set_float_rounding_mode(float_round_down, &env->fp_status);
-    DT2 = float64_round_to_int(FDT0, &env->fp_status);
+    DT2 = float64_to_int64(FDT0, &env->fp_status);
     RESTORE_ROUNDING_MODE;
     update_fcr31();
     if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
@@ -887,7 +894,7 @@
 FLOAT_OP(floorl, s)
 {
     set_float_rounding_mode(float_round_down, &env->fp_status);
-    DT2 = float32_round_to_int(FST0, &env->fp_status);
+    DT2 = float32_to_int64(FST0, &env->fp_status);
     RESTORE_ROUNDING_MODE;
     update_fcr31();
     if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
@@ -896,7 +903,7 @@
 FLOAT_OP(floorw, d)
 {
     set_float_rounding_mode(float_round_down, &env->fp_status);
-    WT2 = float64_round_to_int(FDT0, &env->fp_status);
+    WT2 = float64_to_int32(FDT0, &env->fp_status);
     RESTORE_ROUNDING_MODE;
     update_fcr31();
     if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
@@ -905,66 +912,86 @@
 FLOAT_OP(floorw, s)
 {
     set_float_rounding_mode(float_round_down, &env->fp_status);
-    WT2 = float32_round_to_int(FST0, &env->fp_status);
+    WT2 = float32_to_int32(FST0, &env->fp_status);
     RESTORE_ROUNDING_MODE;
     update_fcr31();
     if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
         WT2 = 0x7fffffff;
 }
 
-/* unary operations, MIPS specific, s and d */
-#define FLOAT_UNOP(name)  \
-FLOAT_OP(name, d)         \
-{                         \
-    set_float_exception_flags(0, &env->fp_status);            \
-/* XXX: not implemented */ \
-/*    FDT2 = float64_ ## name (FDT0, &env->fp_status);*/          \
-do_raise_exception(EXCP_RI); \
-    update_fcr31();       \
-}                         \
-FLOAT_OP(name, s)         \
-{                         \
-    set_float_exception_flags(0, &env->fp_status);            \
-/* XXX: not implemented */ \
-/*    FST2 = float32_ ## name (FST0, &env->fp_status);*/          \
-do_raise_exception(EXCP_RI); \
-    update_fcr31();       \
+/* MIPS specific unary operations */
+FLOAT_OP(recip, d)
+{
+    set_float_exception_flags(0, &env->fp_status);
+    FDT2 = float64_div(FLOAT_ONE64, FDT0, &env->fp_status);
+    update_fcr31();
 }
-FLOAT_UNOP(rsqrt)
-FLOAT_UNOP(recip)
-#undef FLOAT_UNOP
+FLOAT_OP(recip, s)
+{
+    set_float_exception_flags(0, &env->fp_status);
+    FST2 = float32_div(FLOAT_ONE32, FST0, &env->fp_status);
+    update_fcr31();
+}
 
-/* unary operations, MIPS specific, s, d and ps */
-#define FLOAT_UNOP(name)  \
-FLOAT_OP(name, d)         \
-{                         \
-    set_float_exception_flags(0, &env->fp_status);            \
-/* XXX: not implemented */ \
-/*    FDT2 = float64_ ## name (FDT0, &env->fp_status);*/          \
-do_raise_exception(EXCP_RI); \
-    update_fcr31();       \
-}                         \
-FLOAT_OP(name, s)         \
-{                         \
-    set_float_exception_flags(0, &env->fp_status);            \
-/* XXX: not implemented */ \
-/*    FST2 = float32_ ## name (FST0, &env->fp_status);*/          \
-do_raise_exception(EXCP_RI); \
-    update_fcr31();       \
-}                         \
-FLOAT_OP(name, ps)        \
-{                         \
-    set_float_exception_flags(0, &env->fp_status);            \
-/* XXX: not implemented */ \
-/*    FST2 = float32_ ## name (FST0, &env->fp_status);*/          \
-/*    FSTH2 = float32_ ## name (FSTH0, &env->fp_status);*/        \
-do_raise_exception(EXCP_RI); \
-    update_fcr31();       \
+FLOAT_OP(rsqrt, d)
+{
+    set_float_exception_flags(0, &env->fp_status);
+    FDT2 = float64_sqrt(FDT0, &env->fp_status);
+    FDT2 = float64_div(FLOAT_ONE64, FDT2, &env->fp_status);
+    update_fcr31();
 }
-FLOAT_UNOP(rsqrt1)
-FLOAT_UNOP(recip1)
-#undef FLOAT_UNOP
+FLOAT_OP(rsqrt, s)
+{
+    set_float_exception_flags(0, &env->fp_status);
+    FST2 = float32_sqrt(FST0, &env->fp_status);
+    FST2 = float32_div(FLOAT_ONE32, FST2, &env->fp_status);
+    update_fcr31();
+}
 
+FLOAT_OP(recip1, d)
+{
+    set_float_exception_flags(0, &env->fp_status);
+    FDT2 = float64_div(FLOAT_ONE64, FDT0, &env->fp_status);
+    update_fcr31();
+}
+FLOAT_OP(recip1, s)
+{
+    set_float_exception_flags(0, &env->fp_status);
+    FST2 = float32_div(FLOAT_ONE32, FST0, &env->fp_status);
+    update_fcr31();
+}
+FLOAT_OP(recip1, ps)
+{
+    set_float_exception_flags(0, &env->fp_status);
+    FST2 = float32_div(FLOAT_ONE32, FST0, &env->fp_status);
+    FSTH2 = float32_div(FLOAT_ONE32, FSTH0, &env->fp_status);
+    update_fcr31();
+}
+
+FLOAT_OP(rsqrt1, d)
+{
+    set_float_exception_flags(0, &env->fp_status);
+    FDT2 = float64_sqrt(FDT0, &env->fp_status);
+    FDT2 = float64_div(FLOAT_ONE64, FDT2, &env->fp_status);
+    update_fcr31();
+}
+FLOAT_OP(rsqrt1, s)
+{
+    set_float_exception_flags(0, &env->fp_status);
+    FST2 = float32_sqrt(FST0, &env->fp_status);
+    FST2 = float32_div(FLOAT_ONE32, FST2, &env->fp_status);
+    update_fcr31();
+}
+FLOAT_OP(rsqrt1, ps)
+{
+    set_float_exception_flags(0, &env->fp_status);
+    FST2 = float32_sqrt(FST0, &env->fp_status);
+    FSTH2 = float32_sqrt(FSTH0, &env->fp_status);
+    FST2 = float32_div(FLOAT_ONE32, FST2, &env->fp_status);
+    FSTH2 = float32_div(FLOAT_ONE32, FSTH2, &env->fp_status);
+    update_fcr31();
+}
+
 /* binary operations */
 #define FLOAT_BINOP(name) \
 FLOAT_OP(name, d)         \
@@ -976,7 +1003,7 @@
         FDT2 = 0x7ff7ffffffffffffULL;                         \
     else if (GET_FP_CAUSE(env->fcr31) & FP_UNDERFLOW) {       \
         if ((env->fcr31 & 0x3) == 0)                          \
-            FDT2 &= 0x8000000000000000ULL;                    \
+            FDT2 &= FLOAT_SIGN64;                             \
     }                     \
 }                         \
 FLOAT_OP(name, s)         \
@@ -988,7 +1015,7 @@
         FST2 = 0x7fbfffff;                                    \
     else if (GET_FP_CAUSE(env->fcr31) & FP_UNDERFLOW) {       \
         if ((env->fcr31 & 0x3) == 0)                          \
-            FST2 &= 0x80000000ULL;                            \
+            FST2 &= FLOAT_SIGN32;                             \
     }                     \
 }                         \
 FLOAT_OP(name, ps)        \
@@ -1002,8 +1029,8 @@
         FSTH2 = 0x7fbfffff;                                   \
     } else if (GET_FP_CAUSE(env->fcr31) & FP_UNDERFLOW) {     \
         if ((env->fcr31 & 0x3) == 0) {                        \
-            FST2 &= 0x80000000ULL;                            \
-            FSTH2 &= 0x80000000ULL;                           \
+            FST2 &= FLOAT_SIGN32;                             \
+            FSTH2 &= FLOAT_SIGN32;                            \
         }                 \
     }                     \
 }
@@ -1013,37 +1040,59 @@
 FLOAT_BINOP(div)
 #undef FLOAT_BINOP
 
-/* binary operations, MIPS specific */
-#define FLOAT_BINOP(name) \
-FLOAT_OP(name, d)         \
-{                         \
-    set_float_exception_flags(0, &env->fp_status);            \
-/* XXX: not implemented */ \
-/*    FDT2 = float64_ ## name (FDT0, FDT1, &env->fp_status);*/    \
-do_raise_exception(EXCP_RI); \
-    update_fcr31();       \
-}                         \
-FLOAT_OP(name, s)         \
-{                         \
-    set_float_exception_flags(0, &env->fp_status);            \
-/* XXX: not implemented */ \
-/*    FST2 = float32_ ## name (FST0, FST1, &env->fp_status);*/    \
-do_raise_exception(EXCP_RI); \
-    update_fcr31();       \
-}                         \
-FLOAT_OP(name, ps)        \
-{                         \
-    set_float_exception_flags(0, &env->fp_status);            \
-/* XXX: not implemented */ \
-/*    FST2 = float32_ ## name (FST0, FST1, &env->fp_status);*/    \
-/*    FSTH2 = float32_ ## name (FSTH0, FSTH1, &env->fp_status);*/ \
-do_raise_exception(EXCP_RI); \
-    update_fcr31();       \
+/* MIPS specific binary operations */
+FLOAT_OP(recip2, d)
+{
+    set_float_exception_flags(0, &env->fp_status);
+    FDT2 = float64_mul(FDT0, FDT2, &env->fp_status);
+    FDT2 = float64_sub(FDT2, FLOAT_ONE64, &env->fp_status) ^ FLOAT_SIGN64;
+    update_fcr31();
 }
-FLOAT_BINOP(rsqrt2)
-FLOAT_BINOP(recip2)
-#undef FLOAT_BINOP
+FLOAT_OP(recip2, s)
+{
+    set_float_exception_flags(0, &env->fp_status);
+    FST2 = float32_mul(FST0, FST2, &env->fp_status);
+    FST2 = float32_sub(FST2, FLOAT_ONE32, &env->fp_status) ^ FLOAT_SIGN32;
+    update_fcr31();
+}
+FLOAT_OP(recip2, ps)
+{
+    set_float_exception_flags(0, &env->fp_status);
+    FST2 = float32_mul(FST0, FST2, &env->fp_status);
+    FSTH2 = float32_mul(FSTH0, FSTH2, &env->fp_status);
+    FST2 = float32_sub(FST2, FLOAT_ONE32, &env->fp_status) ^ FLOAT_SIGN32;
+    FSTH2 = float32_sub(FSTH2, FLOAT_ONE32, &env->fp_status) ^ FLOAT_SIGN32;
+    update_fcr31();
+}
 
+FLOAT_OP(rsqrt2, d)
+{
+    set_float_exception_flags(0, &env->fp_status);
+    FDT2 = float64_mul(FDT0, FDT2, &env->fp_status);
+    FDT2 = float64_sub(FDT2, FLOAT_ONE64, &env->fp_status);
+    FDT2 = float64_div(FDT2, FLOAT_TWO64, &env->fp_status) ^ FLOAT_SIGN64;
+    update_fcr31();
+}
+FLOAT_OP(rsqrt2, s)
+{
+    set_float_exception_flags(0, &env->fp_status);
+    FST2 = float32_mul(FST0, FST2, &env->fp_status);
+    FST2 = float32_sub(FST2, FLOAT_ONE32, &env->fp_status);
+    FST2 = float32_div(FST2, FLOAT_TWO32, &env->fp_status) ^ FLOAT_SIGN32;
+    update_fcr31();
+}
+FLOAT_OP(rsqrt2, ps)
+{
+    set_float_exception_flags(0, &env->fp_status);
+    FST2 = float32_mul(FST0, FST2, &env->fp_status);
+    FSTH2 = float32_mul(FSTH0, FSTH2, &env->fp_status);
+    FST2 = float32_sub(FST2, FLOAT_ONE32, &env->fp_status);
+    FSTH2 = float32_sub(FSTH2, FLOAT_ONE32, &env->fp_status);
+    FST2 = float32_div(FST2, FLOAT_TWO32, &env->fp_status) ^ FLOAT_SIGN32;
+    FSTH2 = float32_div(FSTH2, FLOAT_TWO32, &env->fp_status) ^ FLOAT_SIGN32;
+    update_fcr31();
+}
+
 FLOAT_OP(addr, ps)
 {
     set_float_exception_flags(0, &env->fp_status);
@@ -1060,6 +1109,7 @@
     update_fcr31();
 }
 
+/* compare operations */
 #define FOP_COND_D(op, cond)                   \
 void do_cmp_d_ ## op (long cc)                 \
 {                                              \
@@ -1073,8 +1123,8 @@
 void do_cmpabs_d_ ## op (long cc)              \
 {                                              \
     int c;                                     \
-    FDT0 &= ~(1ULL << 63);                     \
-    FDT1 &= ~(1ULL << 63);                     \
+    FDT0 &= ~FLOAT_SIGN64;                     \
+    FDT1 &= ~FLOAT_SIGN64;                     \
     c = cond;                                  \
     update_fcr31();                            \
     if (c)                                     \
@@ -1131,8 +1181,8 @@
 void do_cmpabs_s_ ## op (long cc)              \
 {                                              \
     int c;                                     \
-    FST0 &= ~(1 << 31);                        \
-    FST1 &= ~(1 << 31);                        \
+    FST0 &= ~FLOAT_SIGN32;                     \
+    FST1 &= ~FLOAT_SIGN32;                     \
     c = cond;                                  \
     update_fcr31();                            \
     if (c)                                     \
@@ -1194,10 +1244,10 @@
 void do_cmpabs_ps_ ## op (long cc)             \
 {                                              \
     int cl, ch;                                \
-    FST0 &= ~(1 << 31);                        \
-    FSTH0 &= ~(1 << 31);                       \
-    FST1 &= ~(1 << 31);                        \
-    FSTH1 &= ~(1 << 31);                       \
+    FST0 &= ~FLOAT_SIGN32;                     \
+    FSTH0 &= ~FLOAT_SIGN32;                    \
+    FST1 &= ~FLOAT_SIGN32;                     \
+    FSTH1 &= ~FLOAT_SIGN32;                    \
     cl = condl;                                \
     ch = condh;                                \
     update_fcr31();                            \

Modified: trunk/src/host/qemu-neo1973/target-mips/translate.c
===================================================================
--- trunk/src/host/qemu-neo1973/target-mips/translate.c	2007-07-01 11:01:12 UTC (rev 2355)
+++ trunk/src/host/qemu-neo1973/target-mips/translate.c	2007-07-02 20:43:42 UTC (rev 2356)
@@ -4551,7 +4551,7 @@
     case FOP(31, 16):
         check_cp1_64bitmode(ctx);
         GEN_LOAD_FREG_FTN(WT0, fs);
-        GEN_LOAD_FREG_FTN(WT2, fd);
+        GEN_LOAD_FREG_FTN(WT2, ft);
         gen_op_float_rsqrt2_s();
         GEN_STORE_FTN_FREG(fd, WT2);
         opn = "rsqrt2.s";
@@ -5036,8 +5036,8 @@
         check_cp1_64bitmode(ctx);
         GEN_LOAD_FREG_FTN(WT0, fs);
         GEN_LOAD_FREG_FTN(WTH0, fs);
-        GEN_LOAD_FREG_FTN(WT2, fd);
-        GEN_LOAD_FREG_FTN(WTH2, fd);
+        GEN_LOAD_FREG_FTN(WT2, ft);
+        GEN_LOAD_FREG_FTN(WTH2, ft);
         gen_op_float_rsqrt2_ps();
         GEN_STORE_FTN_FREG(fd, WT2);
         GEN_STORE_FTN_FREG(fd, WTH2);

Modified: trunk/src/host/qemu-neo1973/target-mips/translate_init.c
===================================================================
--- trunk/src/host/qemu-neo1973/target-mips/translate_init.c	2007-07-01 11:01:12 UTC (rev 2355)
+++ trunk/src/host/qemu-neo1973/target-mips/translate_init.c	2007-07-02 20:43:42 UTC (rev 2356)
@@ -71,13 +71,13 @@
     int32_t CCRes;
     int32_t Status_rw_bitmask;
     int32_t CP1_fcr0;
+    int32_t SEGBITS;
 };
 
 /*****************************************************************************/
 /* MIPS CPU definitions */
 static mips_def_t mips_defs[] =
 {
-#ifndef TARGET_MIPS64
     {
         .name = "4Kc",
         .CP0_PRid = 0x00018000,
@@ -88,6 +88,7 @@
         .SYNCI_Step = 32,
         .CCRes = 2,
         .Status_rw_bitmask = 0x3278FF17,
+        .SEGBITS = 32,
     },
     {
         .name = "4KEcR1",
@@ -99,6 +100,7 @@
         .SYNCI_Step = 32,
         .CCRes = 2,
         .Status_rw_bitmask = 0x3278FF17,
+        .SEGBITS = 32,
     },
     {
         .name = "4KEc",
@@ -110,6 +112,7 @@
         .SYNCI_Step = 32,
         .CCRes = 2,
         .Status_rw_bitmask = 0x3278FF17,
+        .SEGBITS = 32,
     },
     {
         .name = "24Kc",
@@ -121,6 +124,7 @@
         .SYNCI_Step = 32,
         .CCRes = 2,
         .Status_rw_bitmask = 0x3278FF17,
+        .SEGBITS = 32,
     },
     {
         .name = "24Kf",
@@ -134,8 +138,9 @@
         .Status_rw_bitmask = 0x3678FF17,
         .CP1_fcr0 = (1 << FCR0_F64) | (1 << FCR0_L) | (1 << FCR0_W) |
                     (1 << FCR0_D) | (1 << FCR0_S) | (0x93 << FCR0_PRID),
+        .SEGBITS = 32,
     },
-#else
+#ifdef TARGET_MIPS64
     {
         .name = "R4000",
         .CP0_PRid = 0x00000400,
@@ -148,6 +153,7 @@
         .Status_rw_bitmask = 0x3678FFFF,
 	/* The R4000 has a full 64bit FPU doesn't use the fcr0 bits. */
         .CP1_fcr0 = (0x5 << FCR0_PRID) | (0x0 << FCR0_REV),
+        .SEGBITS = 40,
     },
     {
         .name = "5Kc",
@@ -162,6 +168,7 @@
         .SYNCI_Step = 32,
         .CCRes = 2,
         .Status_rw_bitmask = 0x32F8FFFF,
+        .SEGBITS = 42,
     },
     {
         .name = "5Kf",
@@ -179,6 +186,7 @@
 	/* The 5Kf has F64 / L / W but doesn't use the fcr0 bits. */
         .CP1_fcr0 = (1 << FCR0_D) | (1 << FCR0_S) |
                     (0x81 << FCR0_PRID) | (0x0 << FCR0_REV),
+        .SEGBITS = 42,
     },
     {
         .name = "20Kc",
@@ -199,6 +207,7 @@
         .CP1_fcr0 = (1 << FCR0_3D) | (1 << FCR0_PS) |
                     (1 << FCR0_D) | (1 << FCR0_S) |
                     (0x82 << FCR0_PRID) | (0x0 << FCR0_REV),
+        .SEGBITS = 40,
     },
 #endif
 };
@@ -275,6 +284,10 @@
     env->CCRes = def->CCRes;
     env->Status_rw_bitmask = def->Status_rw_bitmask;
     env->fcr0 = def->CP1_fcr0;
+#ifdef TARGET_MIPS64
+    env->SEGBITS = def->SEGBITS;
+    env->SEGMask = (3ULL << 62) | ((1ULL << def->SEGBITS) - 1);
+#endif
 #ifdef CONFIG_USER_ONLY
     if (env->CP0_Config1 & (1 << CP0C1_FP))
         env->hflags |= MIPS_HFLAG_FPU;

Modified: trunk/src/host/qemu-neo1973/target-ppc/cpu.h
===================================================================
--- trunk/src/host/qemu-neo1973/target-ppc/cpu.h	2007-07-01 11:01:12 UTC (rev 2355)
+++ trunk/src/host/qemu-neo1973/target-ppc/cpu.h	2007-07-02 20:43:42 UTC (rev 2356)
@@ -1326,7 +1326,7 @@
     EXCP_FP_ZX         = 0x03,  /* FP divide by zero                */
     EXCP_FP_XX         = 0x04,  /* FP inexact                       */
     EXCP_FP_VXNAN      = 0x05,  /* FP invalid SNaN op               */
-    EXCP_FP_VXISI      = 0x06,  /* FP invalid infinite substraction */
+    EXCP_FP_VXISI      = 0x06,  /* FP invalid infinite subtraction */
     EXCP_FP_VXIDI      = 0x07,  /* FP invalid infinite divide       */
     EXCP_FP_VXZDZ      = 0x08,  /* FP invalid zero divide           */
     EXCP_FP_VXIMZ      = 0x09,  /* FP invalid infinite * zero       */

Modified: trunk/src/host/qemu-neo1973/target-ppc/op.c
===================================================================
--- trunk/src/host/qemu-neo1973/target-ppc/op.c	2007-07-01 11:01:12 UTC (rev 2355)
+++ trunk/src/host/qemu-neo1973/target-ppc/op.c	2007-07-02 20:43:42 UTC (rev 2356)
@@ -1025,7 +1025,7 @@
 }
 #endif
 
-/* substract from */
+/* subtract from */
 PPC_OP(subf)
 {
     T0 = T1 - T0;
@@ -1058,7 +1058,7 @@
 }
 #endif
 
-/* substract from carrying */
+/* subtract from carrying */
 void OPPROTO op_check_subfc (void)
 {
     if (likely((uint32_t)T0 > (uint32_t)T1)) {
@@ -1081,7 +1081,7 @@
 }
 #endif
 
-/* substract from extended */
+/* subtract from extended */
 void OPPROTO op_subfe (void)
 {
     do_subfe();
@@ -1096,7 +1096,7 @@
 }
 #endif
 
-/* substract from immediate carrying */
+/* subtract from immediate carrying */
 void OPPROTO op_subfic (void)
 {
     T0 = (int32_t)PARAM1 + ~T0 + 1;
@@ -1121,7 +1121,7 @@
 }
 #endif
 
-/* substract from minus one extended */
+/* subtract from minus one extended */
 void OPPROTO op_subfme (void)
 {
     T0 = ~T0 + xer_ca - 1;
@@ -1154,7 +1154,7 @@
 }
 #endif
 
-/* substract from zero extended */
+/* subtract from zero extended */
 void OPPROTO op_subfze (void)
 {
     T1 = ~T0;

Modified: trunk/src/host/qemu-neo1973/target-sh4/cpu.h
===================================================================
--- trunk/src/host/qemu-neo1973/target-sh4/cpu.h	2007-07-01 11:01:12 UTC (rev 2355)
+++ trunk/src/host/qemu-neo1973/target-sh4/cpu.h	2007-07-02 20:43:42 UTC (rev 2356)
@@ -80,7 +80,7 @@
 typedef struct CPUSH4State {
     uint32_t flags;		/* general execution flags */
     uint32_t gregs[24];		/* general registers */
-    uint32_t fregs[32];		/* floating point registers */
+    float32 fregs[32];		/* floating point registers */
     uint32_t sr;		/* status register */
     uint32_t ssr;		/* saved status register */
     uint32_t spc;		/* saved program counter */
@@ -99,6 +99,7 @@
     /* temporary float registers */
     float32 ft0, ft1;
     float64 dt0, dt1;
+    float_status fp_status;
 
     /* Those belong to the specific unit (SH7750) but are handled here */
     uint32_t mmucr;		/* MMU control register */
@@ -114,6 +115,7 @@
     jmp_buf jmp_env;
     int user_mode_only;
     int interrupt_request;
+    int halted;
     int exception_index;
      CPU_COMMON tlb_t utlb[UTLB_SIZE];	/* unified translation table */
     tlb_t itlb[ITLB_SIZE];	/* instruction translation table */

Modified: trunk/src/host/qemu-neo1973/target-sh4/exec.h
===================================================================
--- trunk/src/host/qemu-neo1973/target-sh4/exec.h	2007-07-01 11:01:12 UTC (rev 2355)
+++ trunk/src/host/qemu-neo1973/target-sh4/exec.h	2007-07-02 20:43:42 UTC (rev 2356)
@@ -36,6 +36,16 @@
 #include "cpu.h"
 #include "exec-all.h"
 
+static inline int cpu_halted(CPUState *env) {
+    if (!env->halted)
+        return 0;
+    if (env->interrupt_request & CPU_INTERRUPT_HARD) {
+        env->halted = 0;
+        return 0;
+    }
+    return EXCP_HALTED;
+}
+
 #ifndef CONFIG_USER_ONLY
 #include "softmmu_exec.h"
 #endif

Modified: trunk/src/host/qemu-neo1973/target-sh4/op.c
===================================================================
--- trunk/src/host/qemu-neo1973/target-sh4/op.c	2007-07-01 11:01:12 UTC (rev 2355)
+++ trunk/src/host/qemu-neo1973/target-sh4/op.c	2007-07-02 20:43:42 UTC (rev 2356)
@@ -509,6 +509,9 @@
 void OPPROTO op_lds_T0_fpscr(void)
 {
     env->fpscr = T0 & 0x003fffff;
+    env->fp_status.float_rounding_mode = T0 & 0x01 ?
+      float_round_to_zero : float_round_nearest_even;
+
     RETURN();
 }
 
@@ -695,28 +698,130 @@
 
 void OPPROTO op_fmov_frN_FT0(void)
 {
-    FT0 = *(float32 *)&env->fregs[PARAM1];
+    FT0 = env->fregs[PARAM1];
     RETURN();
 }
 
 void OPPROTO op_fmov_drN_DT0(void)
 {
-    DT0 = *(float64 *)&env->fregs[PARAM1];
+    CPU_DoubleU d;
+
+    d.l.upper = *(uint32_t *)&env->fregs[PARAM1];
+    d.l.lower = *(uint32_t *)&env->fregs[PARAM1 + 1];
+    DT0 = d.d;
     RETURN();
 }
 
+void OPPROTO op_fmov_frN_FT1(void)
+{
+    FT1 = env->fregs[PARAM1];
+    RETURN();
+}
+
+void OPPROTO op_fmov_drN_DT1(void)
+{
+    CPU_DoubleU d;
+
+    d.l.upper = *(uint32_t *)&env->fregs[PARAM1];
+    d.l.lower = *(uint32_t *)&env->fregs[PARAM1 + 1];
+    DT1 = d.d;
+    RETURN();
+}
+
 void OPPROTO op_fmov_FT0_frN(void)
 {
-    *(float32 *)&env->fregs[PARAM1] = FT0;
+    env->fregs[PARAM1] = FT0;
     RETURN();
 }
 
 void OPPROTO op_fmov_DT0_drN(void)
 {
-    *(float64 *)&env->fregs[PARAM1] = DT0;
+    CPU_DoubleU d;
+
+    d.d = DT0;
+    *(uint32_t *)&env->fregs[PARAM1] = d.l.upper;
+    *(uint32_t *)&env->fregs[PARAM1 + 1] = d.l.lower;
     RETURN();
 }
 
+void OPPROTO op_fadd_FT(void)
+{
+    FT0 = float32_add(FT0, FT1, &env->fp_status);
+    RETURN();
+}
+
+void OPPROTO op_fadd_DT(void)
+{
+    DT0 = float64_add(DT0, DT1, &env->fp_status);
+    RETURN();
+}
+
+void OPPROTO op_fsub_FT(void)
+{
+    FT0 = float32_sub(FT0, FT1, &env->fp_status);
+    RETURN();
+}
+
+void OPPROTO op_fsub_DT(void)
+{
+    DT0 = float64_sub(DT0, DT1, &env->fp_status);
+    RETURN();
+}
+
+void OPPROTO op_fmul_FT(void)
+{
+    FT0 = float32_mul(FT0, FT1, &env->fp_status);
+    RETURN();
+}
+
+void OPPROTO op_fmul_DT(void)
+{
+    DT0 = float64_mul(DT0, DT1, &env->fp_status);
+    RETURN();
+}
+
+void OPPROTO op_fdiv_FT(void)
+{
+    FT0 = float32_div(FT0, FT1, &env->fp_status);
+    RETURN();
+}
+
+void OPPROTO op_fdiv_DT(void)
+{
+    DT0 = float64_div(DT0, DT1, &env->fp_status);
+    RETURN();
+}
+
+void OPPROTO op_float_FT(void)
+{
+    FT0 = int32_to_float32(env->fpul, &env->fp_status);
+    RETURN();
+}
+
+void OPPROTO op_float_DT(void)
+{
+    DT0 = int32_to_float64(env->fpul, &env->fp_status);
+    RETURN();
+}
+
+void OPPROTO op_ftrc_FT(void)
+{
+    env->fpul = float32_to_int32_round_to_zero(FT0, &env->fp_status);
+    RETURN();
+}
+
+void OPPROTO op_ftrc_DT(void)
+{
+    env->fpul = float64_to_int32_round_to_zero(DT0, &env->fp_status);
+    RETURN();
+}
+
+void OPPROTO op_fmov_T0_frN(void)
+{
+    *(unsigned int *)&env->fregs[PARAM1] = T0;
+    RETURN();
+}
+
 void OPPROTO op_dec1_rN(void)
 {
     env->gregs[PARAM1] -= 1;

Modified: trunk/src/host/qemu-neo1973/target-sh4/translate.c
===================================================================
--- trunk/src/host/qemu-neo1973/target-sh4/translate.c	2007-07-01 11:01:12 UTC (rev 2355)
+++ trunk/src/host/qemu-neo1973/target-sh4/translate.c	2007-07-02 20:43:42 UTC (rev 2356)
@@ -125,13 +125,19 @@
 void cpu_sh4_reset(CPUSH4State * env)
 {
 #if defined(CONFIG_USER_ONLY)
-    env->sr = 0x00000000;
+    env->sr = SR_FD;            /* FD - kernel does lazy fpu context switch */
 #else
     env->sr = 0x700000F0;	/* MD, RB, BL, I3-I0 */
 #endif
     env->vbr = 0;
     env->pc = 0xA0000000;
-    env->fpscr = 0x00040001;
+#if defined(CONFIG_USER_ONLY)
+    env->fpscr = FPSCR_PR; /* value for userspace according to the kernel */
+    env->fp_status.float_rounding_mode = float_round_nearest_even; /* ?! */
+#else
+    env->fpscr = 0x00040001; /* CPU reset value according to SH4 manual */
+    env->fp_status.float_rounding_mode = float_round_to_zero;
+#endif
     env->mmucr = 0;
 }
 
@@ -238,6 +244,7 @@
 #define FREG(x) (ctx->fpscr & FPSCR_FR ? (x) ^ 0x10 : (x))
 #define XHACK(x) ((((x) & 1 ) << 4) | ((x) & 0xe))
 #define XREG(x) (ctx->fpscr & FPSCR_FR ? XHACK(x) ^ 0x10 : XHACK(x))
+#define DREG(x) FREG(x) /* Assumes lsb of (x) is always 0 */
 
 #define CHECK_NOT_DELAY_SLOT \
   if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) \
@@ -640,29 +647,22 @@
 	gen_op_movl_rN_T0(REG(B7_4));
 	gen_op_xor_T0_rN(REG(B11_8));
 	return;
-    case 0xf00c:		/* fmov {F,D,X}Rm,{F,D,X}Rn */
-	if (ctx->fpscr & FPSCR_PR) {
-	    gen_op_fmov_drN_DT0(XREG(B7_4));
-	    gen_op_fmov_DT0_drN(XREG(B11_8));
-	} else if (ctx->fpscr & FPSCR_SZ) {
+    case 0xf00c: /* fmov {F,D,X}Rm,{F,D,X}Rn - FPSCR: Nothing */
+	if (ctx->fpscr & FPSCR_SZ) {
 	    if (ctx->opcode & 0x0110)
 		break; /* illegal instruction */
-	    gen_op_fmov_drN_DT0(XREG(B7_4));
-	    gen_op_fmov_DT0_drN(XREG(B11_8));
+	    gen_op_fmov_drN_DT0(DREG(B7_4));
+	    gen_op_fmov_DT0_drN(DREG(B11_8));
 	} else {
 	    gen_op_fmov_frN_FT0(FREG(B7_4));
 	    gen_op_fmov_FT0_frN(FREG(B11_8));
 	}
 	return;
-    case 0xf00a:		/* fmov {F,D,X}Rm, at Rn */
-	if (ctx->fpscr & FPSCR_PR) {
-	    gen_op_fmov_drN_DT0(XREG(B7_4));
-	    gen_op_movl_rN_T1(REG(B11_8));
-	    gen_op_stfq_DT0_T1(ctx);
-	} else if (ctx->fpscr & FPSCR_SZ) {
+    case 0xf00a: /* fmov {F,D,X}Rm, at Rn - FPSCR: Nothing */
+	if (ctx->fpscr & FPSCR_SZ) {
 	    if (ctx->opcode & 0x0010)
 		break; /* illegal instruction */
-	    gen_op_fmov_drN_DT0(XREG(B7_4));
+	    gen_op_fmov_drN_DT0(DREG(B7_4));
 	    gen_op_movl_rN_T1(REG(B11_8));
 	    gen_op_stfq_DT0_T1(ctx);
 	} else {
@@ -671,35 +671,26 @@
 	    gen_op_stfl_FT0_T1(ctx);
 	}
 	return;
-    case 0xf008:		/* fmov @Rm,{F,D,X}Rn */
-	if (ctx->fpscr & FPSCR_PR) {
-	    gen_op_movl_rN_T0(REG(B7_4));
-	    gen_op_ldfq_T0_DT0(ctx);
-	    gen_op_fmov_DT0_drN(XREG(B11_8));
-	} else if (ctx->fpscr & FPSCR_SZ) {
+    case 0xf008: /* fmov @Rm,{F,D,X}Rn - FPSCR: Nothing */
+	if (ctx->fpscr & FPSCR_SZ) {
 	    if (ctx->opcode & 0x0100)
 		break; /* illegal instruction */
 	    gen_op_movl_rN_T0(REG(B7_4));
 	    gen_op_ldfq_T0_DT0(ctx);
-	    gen_op_fmov_DT0_drN(XREG(B11_8));
+	    gen_op_fmov_DT0_drN(DREG(B11_8));
 	} else {
 	    gen_op_movl_rN_T0(REG(B7_4));
 	    gen_op_ldfl_T0_FT0(ctx);
 	    gen_op_fmov_FT0_frN(FREG(B11_8));
 	}
 	return;
-    case 0xf009:		/* fmov @Rm+,{F,D,X}Rn */
-	if (ctx->fpscr & FPSCR_PR) {
-	    gen_op_movl_rN_T0(REG(B7_4));
-	    gen_op_ldfq_T0_DT0(ctx);
-	    gen_op_fmov_DT0_drN(XREG(B11_8));
-	    gen_op_inc8_rN(REG(B7_4));
-	} else if (ctx->fpscr & FPSCR_SZ) {
+    case 0xf009: /* fmov @Rm+,{F,D,X}Rn - FPSCR: Nothing */
+	if (ctx->fpscr & FPSCR_SZ) {
 	    if (ctx->opcode & 0x0100)
 		break; /* illegal instruction */
 	    gen_op_movl_rN_T0(REG(B7_4));
 	    gen_op_ldfq_T0_DT0(ctx);
-	    gen_op_fmov_DT0_drN(XREG(B11_8));
+	    gen_op_fmov_DT0_drN(DREG(B11_8));
 	    gen_op_inc8_rN(REG(B7_4));
 	} else {
 	    gen_op_movl_rN_T0(REG(B7_4));
@@ -708,17 +699,12 @@
 	    gen_op_inc4_rN(REG(B7_4));
 	}
 	return;
-    case 0xf00b:		/* fmov {F,D,X}Rm, at -Rn */
-	if (ctx->fpscr & FPSCR_PR) {
-	    gen_op_dec8_rN(REG(B11_8));
-	    gen_op_fmov_drN_DT0(XREG(B7_4));
-	    gen_op_movl_rN_T1(REG(B11_8));
-	    gen_op_stfq_DT0_T1(ctx);
-	} else if (ctx->fpscr & FPSCR_SZ) {
+    case 0xf00b: /* fmov {F,D,X}Rm, at -Rn - FPSCR: Nothing */
+	if (ctx->fpscr & FPSCR_SZ) {
 	    if (ctx->opcode & 0x0100)
 		break; /* illegal instruction */
 	    gen_op_dec8_rN(REG(B11_8));
-	    gen_op_fmov_drN_DT0(XREG(B7_4));
+	    gen_op_fmov_drN_DT0(DREG(B7_4));
 	    gen_op_movl_rN_T1(REG(B11_8));
 	    gen_op_stfq_DT0_T1(ctx);
 	} else {
@@ -728,19 +714,14 @@
 	    gen_op_stfl_FT0_T1(ctx);
 	}
 	return;
-    case 0xf006:		/* fmov @(R0,Rm),{F,D,X}Rm */
-	if (ctx->fpscr & FPSCR_PR) {
-	    gen_op_movl_rN_T0(REG(B7_4));
-	    gen_op_add_rN_T0(REG(0));
-	    gen_op_ldfq_T0_DT0(ctx);
-	    gen_op_fmov_DT0_drN(XREG(B11_8));
-	} else if (ctx->fpscr & FPSCR_SZ) {
+    case 0xf006: /* fmov @(R0,Rm),{F,D,X}Rm - FPSCR: Nothing */
+	if (ctx->fpscr & FPSCR_SZ) {
 	    if (ctx->opcode & 0x0100)
 		break; /* illegal instruction */
 	    gen_op_movl_rN_T0(REG(B7_4));
 	    gen_op_add_rN_T0(REG(0));
 	    gen_op_ldfq_T0_DT0(ctx);
-	    gen_op_fmov_DT0_drN(XREG(B11_8));
+	    gen_op_fmov_DT0_drN(DREG(B11_8));
 	} else {
 	    gen_op_movl_rN_T0(REG(B7_4));
 	    gen_op_add_rN_T0(REG(0));
@@ -748,16 +729,11 @@
 	    gen_op_fmov_FT0_frN(FREG(B11_8));
 	}
 	return;
-    case 0xf007:		/* fmov {F,D,X}Rn,@(R0,Rn) */
-	if (ctx->fpscr & FPSCR_PR) {
-	    gen_op_fmov_drN_DT0(XREG(B7_4));
-	    gen_op_movl_rN_T1(REG(B11_8));
-	    gen_op_add_rN_T1(REG(0));
-	    gen_op_stfq_DT0_T1(ctx);
-	} else if (ctx->fpscr & FPSCR_SZ) {
+    case 0xf007: /* fmov {F,D,X}Rn,@(R0,Rn) - FPSCR: Nothing */
+	if (ctx->fpscr & FPSCR_SZ) {
 	    if (ctx->opcode & 0x0010)
 		break; /* illegal instruction */
-	    gen_op_fmov_drN_DT0(XREG(B7_4));
+	    gen_op_fmov_drN_DT0(DREG(B7_4));
 	    gen_op_movl_rN_T1(REG(B11_8));
 	    gen_op_add_rN_T1(REG(0));
 	    gen_op_stfq_DT0_T1(ctx);
@@ -768,6 +744,49 @@
 	    gen_op_stfl_FT0_T1(ctx);
 	}
 	return;
+    case 0xf000: /* fadd Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
+    case 0xf001: /* fsub Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
+    case 0xf002: /* fmul Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
+    case 0xf003: /* fdiv Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
+    case 0xf004: /* fcmp/eq Rm,Rn - FPSCR: R[PR,Enable.V]/W[Cause,Flag] */
+    case 0xf005: /* fcmp/gt Rm,Rn - FPSCR: R[PR,Enable.V]/W[Cause,Flag] */
+	if (ctx->fpscr & FPSCR_PR) {
+	    if (ctx->opcode & 0x0110)
+		break; /* illegal instruction */
+	    gen_op_fmov_drN_DT1(DREG(B7_4));
+	    gen_op_fmov_drN_DT0(DREG(B11_8));
+	}
+	else {
+	    gen_op_fmov_frN_FT1(FREG(B7_4));
+	    gen_op_fmov_frN_FT0(FREG(B11_8));
+	}
+
+	switch (ctx->opcode & 0xf00f) {
+	case 0xf000:		/* fadd Rm,Rn */
+	    ctx->fpscr & FPSCR_PR ? gen_op_fadd_DT() : gen_op_fadd_FT();
+	    break;
+	case 0xf001:		/* fsub Rm,Rn */
+	    ctx->fpscr & FPSCR_PR ? gen_op_fsub_DT() : gen_op_fsub_FT();
+	    break;
+	case 0xf002:		/* fmul Rm,Rn */
+	    ctx->fpscr & FPSCR_PR ? gen_op_fmul_DT() : gen_op_fmul_FT();
+	    break;
+	case 0xf003:		/* fdiv Rm,Rn */
+	    ctx->fpscr & FPSCR_PR ? gen_op_fdiv_DT() : gen_op_fdiv_FT();
+	    break;
+	case 0xf004:		/* fcmp/eq Rm,Rn */
+	    return;
+	case 0xf005:		/* fcmp/gt Rm,Rn */
+	    return;
+	}
+
+	if (ctx->fpscr & FPSCR_PR) {
+	    gen_op_fmov_DT0_drN(DREG(B11_8));
+	}
+	else {
+	    gen_op_fmov_FT0_frN(FREG(B11_8));
+	}
+	return;
     }
 
     switch (ctx->opcode & 0xff00) {
@@ -1071,14 +1090,52 @@
     case 0x401b:		/* tas.b @Rn */
 	gen_op_tasb_rN(REG(B11_8));
 	return;
-    case 0xf00d:		/* fsts FPUL,FRn */
+    case 0xf00d: /* fsts FPUL,FRn - FPSCR: Nothing */
 	gen_op_movl_fpul_FT0();
 	gen_op_fmov_FT0_frN(FREG(B11_8));
 	return;
-    case 0xf01d:		/* flds FRm.FPUL */
+    case 0xf01d: /* flds FRm,FPUL - FPSCR: Nothing */
 	gen_op_fmov_frN_FT0(FREG(B11_8));
 	gen_op_movl_FT0_fpul();
 	return;
+    case 0xf02d: /* float FPUL,FRn/DRn - FPSCR: R[PR,Enable.I]/W[Cause,Flag] */
+	if (ctx->fpscr & FPSCR_PR) {
+	    if (ctx->opcode & 0x0100)
+		break; /* illegal instruction */
+	    gen_op_float_DT();
+	    gen_op_fmov_DT0_drN(DREG(B11_8));
+	}
+	else {
+	    gen_op_float_FT();
+	    gen_op_fmov_FT0_frN(FREG(B11_8));
+	}
+	return;
+    case 0xf03d: /* ftrc FRm/DRm,FPUL - FPSCR: R[PR,Enable.V]/W[Cause,Flag] */
+	if (ctx->fpscr & FPSCR_PR) {
+	    if (ctx->opcode & 0x0100)
+		break; /* illegal instruction */
+	    gen_op_fmov_drN_DT0(DREG(B11_8));
+	    gen_op_ftrc_DT();
+	}
+	else {
+	    gen_op_fmov_frN_FT0(FREG(B11_8));
+	    gen_op_ftrc_FT();
+	}
+	return;
+    case 0xf08d: /* fldi0 FRn - FPSCR: R[PR] */
+	if (!(ctx->fpscr & FPSCR_PR)) {
+	    gen_op_movl_imm_T0(0);
+	    gen_op_fmov_T0_frN(FREG(B11_8));
+	    return;
+	}
+	break;
+    case 0xf09d: /* fldi1 FRn - FPSCR: R[PR] */
+	if (!(ctx->fpscr & FPSCR_PR)) {
+	    gen_op_movl_imm_T0(0x3f800000);
+	    gen_op_fmov_T0_frN(FREG(B11_8));
+	    return;
+	}
+	break;
     }
 
     fprintf(stderr, "unknown instruction 0x%04x at pc 0x%08x\n",

Modified: trunk/src/host/qemu-neo1973/target-sparc/translate.c
===================================================================
--- trunk/src/host/qemu-neo1973/target-sparc/translate.c	2007-07-01 11:01:12 UTC (rev 2355)
+++ trunk/src/host/qemu-neo1973/target-sparc/translate.c	2007-07-02 20:43:42 UTC (rev 2356)
@@ -598,7 +598,8 @@
     }
 }
 
-static inline void gen_branch2(DisasContext *dc, long tb, target_ulong pc1, target_ulong pc2)
+static inline void gen_branch2(DisasContext *dc, target_ulong pc1,
+                               target_ulong pc2)
 {
     int l1;
 
@@ -612,7 +613,8 @@
     gen_goto_tb(dc, 1, pc2, pc2 + 4);
 }
 
-static inline void gen_branch_a(DisasContext *dc, long tb, target_ulong pc1, target_ulong pc2)
+static inline void gen_branch_a(DisasContext *dc, target_ulong pc1,
+                                target_ulong pc2)
 {
     int l1;
 
@@ -626,12 +628,13 @@
     gen_goto_tb(dc, 1, pc2 + 4, pc2 + 8);
 }
 
-static inline void gen_branch(DisasContext *dc, long tb, target_ulong pc, target_ulong npc)
+static inline void gen_branch(DisasContext *dc, target_ulong pc,
+                              target_ulong npc)
 {
     gen_goto_tb(dc, 0, pc, npc);
 }
 
-static inline void gen_generic_branch(DisasContext *dc, target_ulong npc1, target_ulong npc2)
+static inline void gen_generic_branch(target_ulong npc1, target_ulong npc2)
 {
     int l1, l2;
 
@@ -651,7 +654,7 @@
 static inline void flush_T2(DisasContext * dc)
 {
     if (dc->npc == JUMP_PC) {
-        gen_generic_branch(dc, dc->jump_pc[0], dc->jump_pc[1]);
+        gen_generic_branch(dc->jump_pc[0], dc->jump_pc[1]);
         dc->npc = DYNAMIC_PC;
     }
 }
@@ -659,7 +662,7 @@
 static inline void save_npc(DisasContext * dc)
 {
     if (dc->npc == JUMP_PC) {
-        gen_generic_branch(dc, dc->jump_pc[0], dc->jump_pc[1]);
+        gen_generic_branch(dc->jump_pc[0], dc->jump_pc[1]);
         dc->npc = DYNAMIC_PC;
     } else if (dc->npc != DYNAMIC_PC) {
         gen_movl_npc_im(dc->npc);
@@ -675,7 +678,7 @@
 static inline void gen_mov_pc_npc(DisasContext * dc)
 {
     if (dc->npc == JUMP_PC) {
-        gen_generic_branch(dc, dc->jump_pc[0], dc->jump_pc[1]);
+        gen_generic_branch(dc->jump_pc[0], dc->jump_pc[1]);
         gen_op_mov_pc_npc();
         dc->pc = DYNAMIC_PC;
     } else if (dc->npc == DYNAMIC_PC) {
@@ -861,7 +864,7 @@
         flush_T2(dc);
         gen_cond[cc][cond]();
 	if (a) {
-	    gen_branch_a(dc, (long)dc->tb, target, dc->npc);
+	    gen_branch_a(dc, target, dc->npc);
             dc->is_br = 1;
 	} else {
             dc->pc = dc->npc;
@@ -900,7 +903,7 @@
         flush_T2(dc);
         gen_fcond[cc][cond]();
 	if (a) {
-	    gen_branch_a(dc, (long)dc->tb, target, dc->npc);
+	    gen_branch_a(dc, target, dc->npc);
             dc->is_br = 1;
 	} else {
             dc->pc = dc->npc;
@@ -921,7 +924,7 @@
     flush_T2(dc);
     gen_cond_reg(cond);
     if (a) {
-	gen_branch_a(dc, (long)dc->tb, target, dc->npc);
+	gen_branch_a(dc, target, dc->npc);
 	dc->is_br = 1;
     } else {
 	dc->pc = dc->npc;
@@ -3123,7 +3126,7 @@
 	gen_op_next_insn();
     } else if (dc->npc == JUMP_PC) {
         /* we can do a static jump */
-        gen_branch2(dc, (long)dc->tb, dc->jump_pc[0], dc->jump_pc[1]);
+        gen_branch2(dc, dc->jump_pc[0], dc->jump_pc[1]);
         dc->is_br = 1;
     } else {
 	dc->pc = dc->npc;
@@ -3249,7 +3252,7 @@
         if (dc->pc != DYNAMIC_PC && 
             (dc->npc != DYNAMIC_PC && dc->npc != JUMP_PC)) {
             /* static PC and NPC: we can use direct chaining */
-            gen_branch(dc, (long)tb, dc->pc, dc->npc);
+            gen_branch(dc, dc->pc, dc->npc);
         } else {
             if (dc->pc != DYNAMIC_PC)
                 gen_jmp_im(dc->pc);

Modified: trunk/src/host/qemu-neo1973/vl.c
===================================================================
--- trunk/src/host/qemu-neo1973/vl.c	2007-07-01 11:01:12 UTC (rev 2355)
+++ trunk/src/host/qemu-neo1973/vl.c	2007-07-02 20:43:42 UTC (rev 2356)
@@ -47,6 +47,8 @@
 #ifndef __APPLE__
 #include <libutil.h>
 #endif
+#elif defined (__GLIBC__) && defined (__FreeBSD_kernel__)
+#include <freebsd/stdlib.h>
 #else
 #ifndef __sun__
 #include <linux/if.h>
@@ -196,6 +198,7 @@
 int semihosting_enabled = 0;
 int autostart = 1;
 const char *qemu_name;
+int alt_grab = 0;
 #ifdef TARGET_SPARC
 unsigned int nb_prom_envs = 0;
 const char *prom_envs[MAX_PROM_ENVS];
@@ -203,6 +206,8 @@
 struct bt_piconet_s *local_piconet;
 struct modem_ops_s modem_ops;
 
+#define TFR(expr) do { if ((expr) != -1) break; } while (errno == EINTR)
+
 /***********************************************************/
 /* x86 ISA bus support */
 
@@ -1028,7 +1033,7 @@
 
 static int start_rtc_timer(void)
 {
-    rtc_fd = open("/dev/rtc", O_RDONLY);
+    TFR(rtc_fd = open("/dev/rtc", O_RDONLY));
     if (rtc_fd < 0)
         return -1;
     if (ioctl(rtc_fd, RTC_IRQP_SET, RTC_FREQ) < 0) {
@@ -1639,7 +1644,7 @@
 {
     int fd_out;
 
-    fd_out = open(file_out, O_WRONLY | O_TRUNC | O_CREAT | O_BINARY, 0666);
+    TFR(fd_out = open(file_out, O_WRONLY | O_TRUNC | O_CREAT | O_BINARY, 0666));
     if (fd_out < 0)
         return NULL;
     return qemu_chr_open_fd(-1, fd_out);
@@ -1652,14 +1657,14 @@
 
     snprintf(filename_in, 256, "%s.in", filename);
     snprintf(filename_out, 256, "%s.out", filename);
-    fd_in = open(filename_in, O_RDWR | O_BINARY);
-    fd_out = open(filename_out, O_RDWR | O_BINARY);
+    TFR(fd_in = open(filename_in, O_RDWR | O_BINARY));
+    TFR(fd_out = open(filename_out, O_RDWR | O_BINARY));
     if (fd_in < 0 || fd_out < 0) {
 	if (fd_in >= 0)
 	    close(fd_in);
 	if (fd_out >= 0)
 	    close(fd_out);
-        fd_in = fd_out = open(filename, O_RDWR | O_BINARY);
+        TFR(fd_in = fd_out = open(filename, O_RDWR | O_BINARY));
         if (fd_in < 0)
             return NULL;
     }
@@ -1763,17 +1768,19 @@
     return chr;
 }
 
-#if defined(__linux__)
+#if defined(__linux__) || defined(__sun__)
 static CharDriverState *qemu_chr_open_pty(void)
 {
     struct termios tty;
     char slave_name[1024];
     int master_fd, slave_fd;
     
+#if defined(__linux__)
     /* Not satisfying */
     if (openpty(&master_fd, &slave_fd, slave_name, NULL, NULL) < 0) {
         return NULL;
     }
+#endif
     
     /* Disabling local echo and line-buffered output */
     tcgetattr (master_fd, &tty);
@@ -1908,19 +1915,26 @@
     CharDriverState *chr;
     int fd;
 
-    fd = open(filename, O_RDWR | O_NONBLOCK);
-    if (fd < 0)
-        return NULL;
+    TFR(fd = open(filename, O_RDWR | O_NONBLOCK));
     fcntl(fd, F_SETFL, O_NONBLOCK);
     tty_serial_init(fd, 115200, 'N', 8, 1);
     chr = qemu_chr_open_fd(fd, fd);
-    if (!chr)
+    if (!chr) {
+        close(fd);
         return NULL;
+    }
     chr->chr_ioctl = tty_serial_ioctl;
     qemu_chr_reset(chr);
     return chr;
 }
+#else  /* ! __linux__ && ! __sun__ */
+static CharDriverState *qemu_chr_open_pty(void)
+{
+    return NULL;
+}
+#endif /* __linux__ || __sun__ */
 
+#if defined(__linux__)
 typedef struct {
     int fd;
     int mode;
@@ -2031,7 +2045,7 @@
     ParallelCharDriver *drv;
     int fd;
 
-    fd = open(filename, O_RDWR);
+    TFR(fd = open(filename, O_RDWR));
     if (fd < 0)
         return NULL;
 
@@ -2063,17 +2077,10 @@
 
     return chr;
 }
+#endif /* __linux__ */
 
-#else
-static CharDriverState *qemu_chr_open_pty(void)
-{
-    return NULL;
-}
-#endif
+#else /* _WIN32 */
 
-#endif /* !defined(_WIN32) */
-
-#ifdef _WIN32
 typedef struct {
     int max_size;
     HANDLE hcom, hrecv, hsend;
@@ -2439,7 +2446,7 @@
 
     return qemu_chr_open_win_file(fd_out);
 }
-#endif
+#endif /* !_WIN32 */
 
 /***********************************************************/
 /* UDP Net console */
@@ -2953,16 +2960,17 @@
     } else if (!strcmp(filename, "stdio")) {
         return qemu_chr_open_stdio();
     } else 
-#endif
 #if defined(__linux__)
     if (strstart(filename, "/dev/parport", NULL)) {
         return qemu_chr_open_pp(filename);
     } else 
+#endif
+#if defined(__linux__) || defined(__sun__)
     if (strstart(filename, "/dev/", NULL)) {
         return qemu_chr_open_tty(filename);
-    } else 
+    } else
 #endif
-#ifdef _WIN32
+#else /* !_WIN32 */
     if (strstart(filename, "COM", NULL)) {
         return qemu_chr_open_win(filename);
     } else
@@ -3191,11 +3199,11 @@
 
     for(vc = vlan->first_client; vc != NULL; vc = vc->next) {
         if (vc != vc1) {
-            if (vc->fd_can_read && !vc->fd_can_read(vc->opaque))
-                return 0;
+            if (vc->fd_can_read && vc->fd_can_read(vc->opaque))
+                return 1;
         }
     }
-    return 1;
+    return 0;
 }
 
 void qemu_send_packet(VLANClientState *vc1, const uint8_t *buf, int size)
@@ -3452,14 +3460,14 @@
     return s;
 }
 
-#ifdef _BSD
+#if defined (_BSD) || defined (__FreeBSD_kernel__)
 static int tap_open(char *ifname, int ifname_size)
 {
     int fd;
     char *dev;
     struct stat s;
 
-    fd = open("/dev/tap", O_RDWR);
+    TFR(fd = open("/dev/tap", O_RDWR));
     if (fd < 0) {
         fprintf(stderr, "warning: could not open /dev/tap: no virtual network emulation\n");
         return -1;
@@ -3503,12 +3511,14 @@
     if( ip_fd )
        close(ip_fd);
 
-    if( (ip_fd = open("/dev/udp", O_RDWR, 0)) < 0){
+    TFR(ip_fd = open("/dev/udp", O_RDWR, 0));
+    if (ip_fd < 0) {
        syslog(LOG_ERR, "Can't open /dev/ip (actually /dev/udp)");
        return -1;
     }
 
-    if( (tap_fd = open("/dev/tap", O_RDWR, 0)) < 0){
+    TFR(tap_fd = open("/dev/tap", O_RDWR, 0));
+    if (tap_fd < 0) {
        syslog(LOG_ERR, "Can't open /dev/tap");
        return -1;
     }
@@ -3521,7 +3531,8 @@
     if ((ppa = ioctl (tap_fd, I_STR, &strioc_ppa)) < 0)
        syslog (LOG_ERR, "Can't assign new interface");
 
-    if( (if_fd = open("/dev/tap", O_RDWR, 0)) < 0){
+    TFR(if_fd = open("/dev/tap", O_RDWR, 0));
+    if (if_fd < 0) {
        syslog(LOG_ERR, "Can't open /dev/tap (2)");
        return -1;
     }
@@ -3553,7 +3564,8 @@
     if (ioctl (ip_fd, I_PUSH, "arp") < 0)
         syslog (LOG_ERR, "Can't push ARP module (3)\n");
     /* Open arp_fd */
-    if ((arp_fd = open ("/dev/tap", O_RDWR, 0)) < 0)
+    TFR(arp_fd = open ("/dev/tap", O_RDWR, 0));
+    if (arp_fd < 0)
        syslog (LOG_ERR, "Can't open %s\n", "/dev/tap");
 
     /* Set ifname to arp */
@@ -3609,7 +3621,7 @@
     struct ifreq ifr;
     int fd, ret;
     
-    fd = open("/dev/net/tun", O_RDWR);
+    TFR(fd = open("/dev/net/tun", O_RDWR));
     if (fd < 0) {
         fprintf(stderr, "warning: could not open /dev/net/tun: no virtual network emulation\n");
         return -1;
@@ -3645,7 +3657,7 @@
         pstrcpy(ifname, sizeof(ifname), ifname1);
     else
         ifname[0] = '\0';
-    fd = tap_open(ifname, sizeof(ifname));
+    TFR(fd = tap_open(ifname, sizeof(ifname)));
     if (fd < 0)
         return -1;
 
@@ -4712,6 +4724,34 @@
 }
 
 /***********************************************************/
+/* dumb display */
+
+static void dumb_update(DisplayState *ds, int x, int y, int w, int h)
+{
+}
+
+static void dumb_resize(DisplayState *ds, int w, int h)
+{
+}
+
+static void dumb_refresh(DisplayState *ds)
+{
+#if defined(CONFIG_SDL)
+    vga_hw_update();
+#endif
+}
+
+static void dumb_display_init(DisplayState *ds)
+{
+    ds->data = NULL;
+    ds->linesize = 0;
+    ds->depth = 0;
+    ds->dpy_update = dumb_update;
+    ds->dpy_resize = dumb_resize;
+    ds->dpy_refresh = dumb_refresh;
+}
+
+/***********************************************************/
 /* I/O handling */
 
 #define MAX_IO_HANDLERS 64
@@ -5900,6 +5940,7 @@
     qemu_put_be32(f, env->cp15.c0_cachetype);
     qemu_put_be32(f, env->cp15.c1_sys);
     qemu_put_be32(f, env->cp15.c1_coproc);
+    qemu_put_be32(f, env->cp15.c1_xscaleauxcr);
     qemu_put_be32(f, env->cp15.c2_base);
     qemu_put_be32(f, env->cp15.c2_data);
     qemu_put_be32(f, env->cp15.c2_insn);
@@ -5971,6 +6012,7 @@
     env->cp15.c0_cachetype = qemu_get_be32(f);
     env->cp15.c1_sys = qemu_get_be32(f);
     env->cp15.c1_coproc = qemu_get_be32(f);
+    env->cp15.c1_xscaleauxcr = qemu_get_be32(f);
     env->cp15.c2_base = qemu_get_be32(f);
     env->cp15.c2_data = qemu_get_be32(f);
     env->cp15.c2_insn = qemu_get_be32(f);
@@ -6524,8 +6566,6 @@
     shutdown_requested = 1;
     if (cpu_single_env)
         cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT);
-    /* In case the emulation is stopped */
-    vm_start();
 }
 
 void qemu_system_powerdown_request(void)
@@ -6750,7 +6790,7 @@
     return ret;
 }
 
-void help(void)
+static void help(int exitcode)
 {
     printf("QEMU PC emulator version " QEMU_VERSION ", Copyright (c) 2003-2007 Fabrice Bellard\n"
            "usage: %s [options] [disk_image]\n"
@@ -6771,6 +6811,7 @@
            "-snapshot       write to temporary files instead of disk image files\n"
 #ifdef CONFIG_SDL
            "-no-frame       open SDL window without a frame and window decorations\n"
+           "-alt-grab       use Ctrl-Alt-Shift to grab mouse (instead of Ctrl-Alt)\n"
            "-no-quit        disable SDL window close capability\n"
 #endif
 #ifdef TARGET_I386
@@ -6892,7 +6933,7 @@
 #endif
            DEFAULT_GDBSTUB_PORT,
            "/tmp/qemu.log");
-    exit(1);
+    exit(exitcode);
 }
 
 #define HAS_ARG 0x0001
@@ -6955,6 +6996,7 @@
     QEMU_OPTION_loadvm,
     QEMU_OPTION_full_screen,
     QEMU_OPTION_no_frame,
+    QEMU_OPTION_alt_grab,
     QEMU_OPTION_no_quit,
     QEMU_OPTION_pidfile,
     QEMU_OPTION_no_kqemu,
@@ -7041,14 +7083,15 @@
 #endif
     { "localtime", 0, QEMU_OPTION_localtime },
     { "std-vga", 0, QEMU_OPTION_std_vga },
-    { "echr", 1, QEMU_OPTION_echr },
-    { "monitor", 1, QEMU_OPTION_monitor },
-    { "serial", 1, QEMU_OPTION_serial },
-    { "parallel", 1, QEMU_OPTION_parallel },
+    { "echr", HAS_ARG, QEMU_OPTION_echr },
+    { "monitor", HAS_ARG, QEMU_OPTION_monitor },
+    { "serial", HAS_ARG, QEMU_OPTION_serial },
+    { "parallel", HAS_ARG, QEMU_OPTION_parallel },
     { "loadvm", HAS_ARG, QEMU_OPTION_loadvm },
     { "full-screen", 0, QEMU_OPTION_full_screen },
 #ifdef CONFIG_SDL
     { "no-frame", 0, QEMU_OPTION_no_frame },
+    { "alt-grab", 0, QEMU_OPTION_alt_grab },
     { "no-quit", 0, QEMU_OPTION_no_quit },
 #endif
     { "pidfile", HAS_ARG, QEMU_OPTION_pidfile },
@@ -7465,12 +7508,12 @@
                                m->name, m->desc, 
                                m == first_machine ? " (default)" : "");
                     }
-                    exit(1);
+                    exit(*optarg != '?');
                 }
                 break;
             case QEMU_OPTION_cpu:
                 /* hw initialization will check this */
-                if (optarg[0] == '?') {
+                if (*optarg == '?') {
 #if defined(TARGET_PPC)
                     ppc_cpu_list(stdout, &fprintf);
 #elif defined(TARGET_ARM)
@@ -7480,7 +7523,7 @@
 #elif defined(TARGET_SPARC)
                     sparc_cpu_list(stdout, &fprintf);
 #endif
-                    exit(1);
+                    exit(0);
                 } else {
                     cpu_model = optarg;
                 }
@@ -7634,12 +7677,12 @@
                 break;
 #endif
             case QEMU_OPTION_h:
-                help();
+                help(0);
                 break;
             case QEMU_OPTION_m:
                 ram_size = atoi(optarg) * 1024 * 1024;
                 if (ram_size <= 0)
-                    help();
+                    help(1);
                 if (ram_size > PHYS_RAM_MAX_SIZE) {
                     fprintf(stderr, "qemu: at most %d MB RAM can be simulated\n",
                             PHYS_RAM_MAX_SIZE / (1024 * 1024));
@@ -7767,6 +7810,9 @@
             case QEMU_OPTION_no_frame:
                 no_frame = 1;
                 break;
+            case QEMU_OPTION_alt_grab:
+                alt_grab = 1;
+                break;
             case QEMU_OPTION_no_quit:
                 no_quit = 1;
                 break;
@@ -7925,7 +7971,7 @@
         hd_filename[0] == '\0' && 
         (cdrom_index >= 0 && hd_filename[cdrom_index] == '\0') &&
         fd_filename[0] == '\0')
-        help();
+        help(1);
 
     /* boot to floppy or the default cd if no hard disk defined yet */
     if (hd_filename[0] == '\0' && boot_device == 'c') {
@@ -8103,7 +8149,8 @@
     /* terminal init */
     memset(&display_state, 0, sizeof(display_state));
     if (nographic) {
-        /* nothing to do */
+        /* nearly nothing to do */
+        dumb_display_init(ds);
     } else if (vnc_display != NULL) {
         vnc_display_init(ds, vnc_display);
     } else {
@@ -8200,8 +8247,9 @@
                     gdbstub_port);
             exit(1);
         }
-    } else 
+    }
 #endif
+
     if (loadvm)
         do_loadvm(loadvm);
 
@@ -8226,7 +8274,7 @@
 	if (len != 1)
 	    exit(1);
 
-	fd = open("/dev/null", O_RDWR);
+	TFR(fd = open("/dev/null", O_RDWR));
 	if (fd == -1)
 	    exit(1);
 

Modified: trunk/src/host/qemu-neo1973/vl.h
===================================================================
--- trunk/src/host/qemu-neo1973/vl.h	2007-07-01 11:01:12 UTC (rev 2355)
+++ trunk/src/host/qemu-neo1973/vl.h	2007-07-02 20:43:42 UTC (rev 2356)
@@ -156,6 +156,7 @@
 extern const char *keyboard_layout;
 extern int kqemu_allowed;
 extern int win2k_install_hack;
+extern int alt_grab;
 extern int usb_enabled;
 extern int smp_cpus;
 extern int cursor_hide;
@@ -1091,6 +1092,7 @@
 
 typedef struct ParallelState ParallelState;
 ParallelState *parallel_init(int base, qemu_irq irq, CharDriverState *chr);
+ParallelState *parallel_mm_init(target_phys_addr_t base, int it_shift, qemu_irq irq, CharDriverState *chr);
 
 /* i8259.c */
 
@@ -1128,6 +1130,9 @@
 int pit_get_mode(PITState *pit, int channel);
 int pit_get_out(PITState *pit, int channel, int64_t current_time);
 
+/* jazz_led.c */
+extern void jazz_led_init(DisplayState *ds, target_phys_addr_t base);
+
 /* pcspk.c */
 void pcspk_init(PITState *);
 int pcspk_audio_init(AudioState *, qemu_irq *pic);
@@ -1440,6 +1445,9 @@
 /* smc91c111.c */
 void smc91c111_init(NICInfo *, uint32_t, qemu_irq);
 
+/* pl031.c */
+void pl031_init(uint32_t base, qemu_irq irq);
+
 /* pl110.c */
 void *pl110_init(DisplayState *ds, uint32_t base, qemu_irq irq, int);
 





More information about the commitlog mailing list