r3387 - in trunk/src/host/qemu-neo1973: . audio darwin-user hw linux-user slirp target-alpha target-i386 target-mips target-ppc target-sparc tests

andrew at sita.openmoko.org andrew at sita.openmoko.org
Fri Nov 9 18:12:53 CET 2007


Author: andrew
Date: 2007-11-09 18:12:19 +0100 (Fri, 09 Nov 2007)
New Revision: 3387

Added:
   trunk/src/host/qemu-neo1973/audio/.cvsignore
   trunk/src/host/qemu-neo1973/slirp/.cvsignore
Removed:
   trunk/src/host/qemu-neo1973/target-i386/translate-copy.c
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/audio/audio.h
   trunk/src/host/qemu-neo1973/configure
   trunk/src/host/qemu-neo1973/cpu-all.h
   trunk/src/host/qemu-neo1973/cpu-exec.c
   trunk/src/host/qemu-neo1973/darwin-user/main.c
   trunk/src/host/qemu-neo1973/darwin-user/signal.c
   trunk/src/host/qemu-neo1973/dyngen.c
   trunk/src/host/qemu-neo1973/exec-all.h
   trunk/src/host/qemu-neo1973/exec.c
   trunk/src/host/qemu-neo1973/host-utils.c
   trunk/src/host/qemu-neo1973/host-utils.h
   trunk/src/host/qemu-neo1973/hw/fdc.c
   trunk/src/host/qemu-neo1973/hw/grackle_pci.c
   trunk/src/host/qemu-neo1973/hw/i2c.c
   trunk/src/host/qemu-neo1973/hw/ide.c
   trunk/src/host/qemu-neo1973/hw/mac_nvram.c
   trunk/src/host/qemu-neo1973/hw/macio.c
   trunk/src/host/qemu-neo1973/hw/mc146818rtc.c
   trunk/src/host/qemu-neo1973/hw/omap.c
   trunk/src/host/qemu-neo1973/hw/omap.h
   trunk/src/host/qemu-neo1973/hw/omap1_clk.c
   trunk/src/host/qemu-neo1973/hw/omap_mmc.c
   trunk/src/host/qemu-neo1973/hw/palm.c
   trunk/src/host/qemu-neo1973/hw/pc.c
   trunk/src/host/qemu-neo1973/hw/ppc_chrp.c
   trunk/src/host/qemu-neo1973/hw/ppc_mac.h
   trunk/src/host/qemu-neo1973/hw/ppc_oldworld.c
   trunk/src/host/qemu-neo1973/hw/slavio_misc.c
   trunk/src/host/qemu-neo1973/hw/sun4m.c
   trunk/src/host/qemu-neo1973/hw/tsc210x.c
   trunk/src/host/qemu-neo1973/linux-user/main.c
   trunk/src/host/qemu-neo1973/linux-user/mmap.c
   trunk/src/host/qemu-neo1973/linux-user/qemu.h
   trunk/src/host/qemu-neo1973/linux-user/signal.c
   trunk/src/host/qemu-neo1973/linux-user/strace.c
   trunk/src/host/qemu-neo1973/linux-user/syscall_defs.h
   trunk/src/host/qemu-neo1973/qemu-doc.texi
   trunk/src/host/qemu-neo1973/slirp/misc.h
   trunk/src/host/qemu-neo1973/slirp/slirp.h
   trunk/src/host/qemu-neo1973/slirp/tcp_subr.c
   trunk/src/host/qemu-neo1973/target-alpha/op.c
   trunk/src/host/qemu-neo1973/target-i386/cpu.h
   trunk/src/host/qemu-neo1973/target-i386/helper.c
   trunk/src/host/qemu-neo1973/target-i386/helper2.c
   trunk/src/host/qemu-neo1973/target-i386/translate.c
   trunk/src/host/qemu-neo1973/target-mips/exec.h
   trunk/src/host/qemu-neo1973/target-mips/helper.c
   trunk/src/host/qemu-neo1973/target-mips/mips-defs.h
   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/op_mem.c
   trunk/src/host/qemu-neo1973/target-mips/op_template.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/exec.h
   trunk/src/host/qemu-neo1973/target-ppc/helper.c
   trunk/src/host/qemu-neo1973/target-ppc/helper_regs.h
   trunk/src/host/qemu-neo1973/target-ppc/op.c
   trunk/src/host/qemu-neo1973/target-ppc/op_helper.c
   trunk/src/host/qemu-neo1973/target-ppc/op_helper.h
   trunk/src/host/qemu-neo1973/target-ppc/translate.c
   trunk/src/host/qemu-neo1973/target-ppc/translate_init.c
   trunk/src/host/qemu-neo1973/target-sparc/cpu.h
   trunk/src/host/qemu-neo1973/target-sparc/helper.c
   trunk/src/host/qemu-neo1973/target-sparc/op_helper.c
   trunk/src/host/qemu-neo1973/target-sparc/translate.c
   trunk/src/host/qemu-neo1973/tests/qruncom.c
   trunk/src/host/qemu-neo1973/translate-all.c
   trunk/src/host/qemu-neo1973/vl.c
   trunk/src/host/qemu-neo1973/vl.h
Log:
Sync with cvs.savannah.nongnu.org:/sources/qemu.


Modified: trunk/src/host/qemu-neo1973/Changelog
===================================================================
--- trunk/src/host/qemu-neo1973/Changelog	2007-11-09 16:32:22 UTC (rev 3386)
+++ trunk/src/host/qemu-neo1973/Changelog	2007-11-09 17:12:19 UTC (rev 3387)
@@ -5,7 +5,7 @@
   - CPU model selection support (J. Mayer, Paul Brook, Herve Poussineau)
   - Several Sparc fixes (Aurelien Jarno, Blue Swirl, Robert Reif)
   - MIPS 64-bit FPU support (Thiemo Seufer)
-  - Xscale PDA emulation (Andrzei Zaborowski)
+  - Xscale PDA emulation (Andrzej Zaborowski)
   - ColdFire system emulation (Paul Brook)
   - Improved SH4 support (Magnus Damm)
   - MIPS64 support (Aurelien Jarno, Thiemo Seufer)
@@ -16,6 +16,7 @@
   - SPARC32PLUS execution support (Blue Swirl)
   - MIPS mipssim pequdo machine (Thiemo Seufer)
   - Strace for Linux userland emulation (Stuart Anderson, Thayne Harbaugh)
+  - OMAP310 MPU emulation plus Palm T|E machine (Andrzej Zaborowski)
 
 version 0.9.0:
 

Modified: trunk/src/host/qemu-neo1973/Makefile
===================================================================
--- trunk/src/host/qemu-neo1973/Makefile	2007-11-09 16:32:22 UTC (rev 3386)
+++ trunk/src/host/qemu-neo1973/Makefile	2007-11-09 17:12:19 UTC (rev 3387)
@@ -11,7 +11,9 @@
 BASE_CFLAGS += $(OS_CFLAGS) $(ARCH_CFLAGS)
 BASE_LDFLAGS += $(OS_LDFLAGS) $(ARCH_LDFLAGS)
 
-CPPFLAGS += -I. -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE
+CPPFLAGS += -I. -I$(SRC_PATH) -MMD -MP
+CPPFLAGS += -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE
+CPPFLAGS += -DQEMU_TOOL
 LIBS=
 ifdef CONFIG_STATIC
 BASE_LDFLAGS += -static
@@ -25,23 +27,99 @@
 
 LIBS+=$(AIOLIBS)
 
-all: $(TOOLS) $(DOCS) recurse-all $(MODEM)
+all: libqemu_common.a $(TOOLS) $(DOCS) recurse-all $(MODEM)
 
 subdir-%: dyngen$(EXESUF)
 	$(MAKE) -C $(subst subdir-,,$@) all
 
 recurse-all: $(patsubst %,subdir-%, $(TARGET_DIRS))
 
-qemu-img$(EXESUF): qemu-img.c cutils.c block.c block-raw.c block-cow.c block-qcow.c aes.c block-vmdk.c block-cloop.c block-dmg.c block-bochs.c block-vpc.c block-vvfat.c block-qcow2.c block-parallels.c
-	$(CC) -DQEMU_TOOL $(CFLAGS) $(CPPFLAGS) $(BASE_CFLAGS) $(LDFLAGS) $(BASE_LDFLAGS) -o $@ $^ -lz $(LIBS)
+######################################################################
+# libqemu_common.a: target indepedent part of system emulation. The
+# long term path is to suppress *all* target specific code in case of
+# system emulation, i.e. a single QEMU executable should support all
+# CPUs and machines.
 
+OBJS+=cutils.o readline.o console.o 
+#OBJS+=block.o block-raw.o
+OBJS+=block-cow.o block-qcow.o aes.o block-vmdk.o block-cloop.o block-dmg.o block-bochs.o block-vpc.o block-vvfat.o block-qcow2.o block-parallels.o
+
+ifdef CONFIG_WIN32
+OBJS+=tap-win32.o
+endif
+
+AUDIO_OBJS = audio.o noaudio.o wavaudio.o mixeng.o
+ifdef CONFIG_SDL
+AUDIO_OBJS += sdlaudio.o
+endif
+ifdef CONFIG_OSS
+AUDIO_OBJS += ossaudio.o
+endif
+ifdef CONFIG_COREAUDIO
+AUDIO_OBJS += coreaudio.o
+endif
+ifdef CONFIG_ALSA
+AUDIO_OBJS += alsaaudio.o
+endif
+ifdef CONFIG_DSOUND
+AUDIO_OBJS += dsoundaudio.o
+endif
+ifdef CONFIG_FMOD
+AUDIO_OBJS += fmodaudio.o
+audio/audio.o audio/fmodaudio.o: CPPFLAGS := -I$(CONFIG_FMOD_INC) $(CPPFLAGS)
+endif
+AUDIO_OBJS+= wavcapture.o
+OBJS+=$(addprefix audio/, $(AUDIO_OBJS))
+
+ifdef CONFIG_SDL
+OBJS+=sdl.o x_keymap.o
+endif
+OBJS+=vnc.o d3des.o
+
+ifdef CONFIG_COCOA
+OBJS+=cocoa.o
+endif
+
+ifdef CONFIG_SLIRP
+CPPFLAGS+=-I$(SRC_PATH)/slirp
+SLIRP_OBJS=cksum.o if.o ip_icmp.o ip_input.o ip_output.o \
+slirp.o mbuf.o misc.o sbuf.o socket.o tcp_input.o tcp_output.o \
+tcp_subr.o tcp_timer.o udp.o bootp.o debug.o tftp.o
+OBJS+=$(addprefix slirp/, $(SLIRP_OBJS))
+endif
+
+cocoa.o: cocoa.m
+	$(CC) $(CFLAGS) $(CPPFLAGS) $(BASE_CFLAGS) -c -o $@ $<
+
+sdl.o: sdl.c keymaps.c sdl_keysym.h
+	$(CC) $(CFLAGS) $(CPPFLAGS) $(SDL_CFLAGS) $(BASE_CFLAGS) -c -o $@ $<
+
+vnc.o: vnc.c keymaps.c sdl_keysym.h vnchextile.h d3des.c d3des.h
+	$(CC) $(CFLAGS) $(CPPFLAGS) $(BASE_CFLAGS) -c -o $@ $<
+
+audio/sdlaudio.o: audio/sdlaudio.c
+	$(CC) $(CFLAGS) $(CPPFLAGS) $(SDL_CFLAGS) $(BASE_CFLAGS) -c -o $@ $<
+
+libqemu_common.a: $(OBJS)
+	rm -f $@ 
+	$(AR) rcs $@ $(OBJS)
+
+######################################################################
+
+qemu-img$(EXESUF): qemu-img.o block.o block-raw.o libqemu_common.a
+	$(CC) $(LDFLAGS) $(BASE_LDFLAGS) -o $@ $^ -lz $(LIBS)
+
+%.o: %.c
+	$(CC) $(CFLAGS) $(CPPFLAGS) $(BASE_CFLAGS) -c -o $@ $<
+
+# dyngen host tool
+dyngen$(EXESUF): dyngen.c
+	$(HOST_CC) $(CFLAGS) $(CPPFLAGS) $(BASE_CFLAGS) -o $@ $^
+
 phonesim: phonesim/phonesim
 phonesim/phonesim:
 	$(MAKE) -C phonesim
 
-dyngen$(EXESUF): dyngen.c
-	$(HOST_CC) $(CFLAGS) $(CPPFLAGS) $(BASE_CFLAGS) -o $@ $^
-
 raw2flash$(EXESUF) flash2raw$(EXESUF): raw2flash.c
 	$(CC) -D$@ $(CFLAGS) $(LDFLAGS) $(DEFINES) -o $@ $^
 	for m in $(MODELS); do \
@@ -52,7 +130,8 @@
 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 cscope.* *.pod *~ */*~
+	rm -f *.o *.d *.a $(TOOLS) dyngen$(EXESUF) TAGS cscope.* *.pod *~ */*~
+	rm -f slirp/*.o slirp/*.d audio/*.o audio/*.d
 	$(MAKE) -C tests clean
 	for d in $(TARGET_DIRS); do \
 	$(MAKE) -C $$d $@ || exit 1 ; \
@@ -197,3 +276,6 @@
 ifneq ($(wildcard .depend),)
 include .depend
 endif
+
+# Include automatically generated dependency files
+-include $(wildcard *.d audio/*.d slirp/*.d)

Modified: trunk/src/host/qemu-neo1973/Makefile.target
===================================================================
--- trunk/src/host/qemu-neo1973/Makefile.target	2007-11-09 16:32:22 UTC (rev 3386)
+++ trunk/src/host/qemu-neo1973/Makefile.target	2007-11-09 17:12:19 UTC (rev 3387)
@@ -23,7 +23,7 @@
 TARGET_BASE_ARCH:=sparc
 endif
 TARGET_PATH=$(SRC_PATH)/target-$(TARGET_BASE_ARCH)
-VPATH=$(SRC_PATH):$(TARGET_PATH):$(SRC_PATH)/hw:$(SRC_PATH)/audio
+VPATH=$(SRC_PATH):$(TARGET_PATH):$(SRC_PATH)/hw
 CPPFLAGS=-I. -I.. -I$(TARGET_PATH) -I$(SRC_PATH) -MMD -MP
 ifdef CONFIG_DARWIN_USER
 VPATH+=:$(SRC_PATH)/darwin-user
@@ -302,10 +302,7 @@
 
 ifeq ($(TARGET_ARCH), i386)
 LIBOBJS+=helper.o helper2.o
-ifeq ($(ARCH), i386)
-LIBOBJS+=translate-copy.o
 endif
-endif
 
 ifeq ($(TARGET_ARCH), x86_64)
 LIBOBJS+=helper.o helper2.o
@@ -399,43 +396,25 @@
 endif
 
 # must use static linking to avoid leaving stuff in virtual address space
-VL_OBJS=vl.o osdep.o readline.o monitor.o pci.o console.o loader.o isa_mmio.o
-VL_OBJS+=cutils.o
+VL_OBJS=vl.o osdep.o monitor.o pci.o loader.o isa_mmio.o
+# XXX: suppress QEMU_TOOL tests
 VL_OBJS+=block.o block-raw.o
-VL_OBJS+=block-cow.o block-qcow.o aes.o block-vmdk.o block-cloop.o block-dmg.o block-bochs.o block-vpc.o block-vvfat.o block-qcow2.o block-parallels.o
 VL_OBJS+=irq.o
-ifdef CONFIG_WIN32
-VL_OBJS+=tap-win32.o
-endif
 
-SOUND_HW = sb16.o es1370.o
-AUDIODRV = audio.o noaudio.o wavaudio.o mixeng.o
-ifdef CONFIG_SDL
-AUDIODRV += sdlaudio.o
-endif
-ifdef CONFIG_OSS
-AUDIODRV += ossaudio.o
-endif
-ifdef CONFIG_COREAUDIO
-AUDIODRV += coreaudio.o
-endif
 ifdef CONFIG_ALSA
-AUDIODRV += alsaaudio.o
 LIBS += -lasound
 endif
 ifdef CONFIG_DSOUND
-AUDIODRV += dsoundaudio.o
 LIBS += -lole32 -ldxguid
 endif
 ifdef CONFIG_FMOD
-AUDIODRV += fmodaudio.o
-audio.o fmodaudio.o: CPPFLAGS := -I$(CONFIG_FMOD_INC) $(CPPFLAGS)
 LIBS += $(CONFIG_FMOD_LIB)
 endif
+
+SOUND_HW = sb16.o es1370.o
 ifdef CONFIG_ADLIB
 SOUND_HW += fmopl.o adlib.o
 endif
-AUDIODRV+= wavcapture.o
 
 ifdef CONFIG_VNC_TLS
 CPPFLAGS += $(CONFIG_VNC_TLS_CFLAGS)
@@ -470,7 +449,7 @@
 
 ifeq ($(TARGET_BASE_ARCH), i386)
 # Hardware support
-VL_OBJS+= ide.o pckbd.o ps2.o vga.o $(SOUND_HW) dma.o $(AUDIODRV)
+VL_OBJS+= ide.o pckbd.o ps2.o vga.o $(SOUND_HW) dma.o
 VL_OBJS+= fdc.o mc146818rtc.o serial.o i8259.o i8254.o pcspk.o pc.o
 VL_OBJS+= cirrus_vga.o apic.o parallel.o acpi.o piix_pci.o
 VL_OBJS+= usb-uhci.o smbus_eeprom.o vmmouse.o vmport.o vmware_vga.o
@@ -479,7 +458,7 @@
 ifeq ($(TARGET_BASE_ARCH), ppc)
 CPPFLAGS += -DHAS_AUDIO -DHAS_AUDIO_CHOICE
 # shared objects
-VL_OBJS+= ppc.o ide.o vga.o $(SOUND_HW) dma.o openpic.o $(AUDIODRV)
+VL_OBJS+= ppc.o ide.o vga.o $(SOUND_HW) dma.o openpic.o
 # PREP target
 VL_OBJS+= pckbd.o ps2.o serial.o i8259.o i8254.o fdc.o m48t59.o mc146818rtc.o
 VL_OBJS+= prep_pci.o ppc_prep.o
@@ -497,7 +476,7 @@
 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)
+VL_OBJS+= piix_pci.o smbus_eeprom.o parallel.o cirrus_vga.o $(SOUND_HW)
 VL_OBJS+= mipsnet.o
 CPPFLAGS += -DHAS_AUDIO
 endif
@@ -526,12 +505,12 @@
 VL_OBJS+= arm-semi.o
 VL_OBJS+= pxa2xx.o pxa2xx_pic.o pxa2xx_gpio.o pxa2xx_timer.o pxa2xx_dma.o
 VL_OBJS+= pxa2xx_lcd.o pxa2xx_mmci.o pxa2xx_pcmcia.o max111x.o max7310.o
-VL_OBJS+= spitz.o ads7846.o ide.o serial.o nand.o ecc.o
-VL_OBJS+= $(AUDIODRV) wm8750.o wm8753.o
+VL_OBJS+= spitz.o ads7846.o ide.o serial.o nand.o ecc.o wm8750.o wm8753.o
 VL_OBJS+= s3c2410.o s3c24xx_gpio.o s3c24xx_lcd.o s3c24xx_mmci.o s3c24xx_rtc.o
 VL_OBJS+= s3c24xx_udc.o neo1973.o pcf5060x.o jbt6k74.o gps.o
 VL_OBJS+= $(GSM_OBJS) modem.o
-VL_OBJS+= omap.o omap_lcdc.o omap1_clk.o omap_mmc.o palm.o tsc210x.o
+VL_OBJS+= omap.o omap_lcdc.o omap1_clk.o omap_mmc.o omap_i2c.o
+VL_OBJS+= palm.o tsc210x.o
 CPPFLAGS+= -DHAS_AUDIO $(GSM_CPPFLAGS)
 endif
 ifeq ($(TARGET_BASE_ARCH), sh4)
@@ -545,12 +524,7 @@
 ifdef CONFIG_GDBSTUB
 VL_OBJS+=gdbstub.o
 endif
-ifdef CONFIG_SDL
-VL_OBJS+=sdl.o x_keymap.o
-endif
-VL_OBJS+=vnc.o d3des.o
 ifdef CONFIG_COCOA
-VL_OBJS+=cocoa.o
 COCOA_LIBS=-F/System/Library/Frameworks -framework Cocoa -framework IOKit
 ifdef CONFIG_COREAUDIO
 COCOA_LIBS+=-framework CoreAudio
@@ -558,10 +532,6 @@
 endif
 ifdef CONFIG_SLIRP
 CPPFLAGS+=-I$(SRC_PATH)/slirp
-SLIRP_OBJS=cksum.o if.o ip_icmp.o ip_input.o ip_output.o \
-slirp.o mbuf.o misc.o sbuf.o socket.o tcp_input.o tcp_output.o \
-tcp_subr.o tcp_timer.o udp.o bootp.o debug.o tftp.o
-VL_OBJS+=$(addprefix slirp/, $(SLIRP_OBJS))
 endif
 
 VL_LDFLAGS=$(VL_OS_LDFLAGS)
@@ -600,21 +570,9 @@
 SDL_LIBS := $(filter-out -mwindows, $(SDL_LIBS)) -mconsole
 endif
 
-$(QEMU_SYSTEM): $(VL_OBJS) libqemu.a
+$(QEMU_SYSTEM): $(VL_OBJS) ../libqemu_common.a libqemu.a
 	$(CC) $(VL_LDFLAGS) $(LDFLAGS) -o $@ $^ $(LIBS) $(SDL_LIBS) $(COCOA_LIBS) $(VL_LIBS)
 
-cocoa.o: cocoa.m
-	$(CC) $(CFLAGS) $(CPPFLAGS) $(BASE_CFLAGS) -c -o $@ $<
-
-sdl.o: sdl.c keymaps.c sdl_keysym.h
-	$(CC) $(CFLAGS) $(CPPFLAGS) $(SDL_CFLAGS) $(BASE_CFLAGS) -c -o $@ $<
-
-vnc.o: vnc.c keymaps.c sdl_keysym.h vnchextile.h d3des.c d3des.h
-	$(CC) $(CFLAGS) $(CPPFLAGS) $(BASE_CFLAGS) -c -o $@ $<
-
-sdlaudio.o: sdlaudio.c
-	$(CC) $(CFLAGS) $(CPPFLAGS) $(SDL_CFLAGS) $(BASE_CFLAGS) -c -o $@ $<
-
 depend: $(SRCS)
 	$(CC) -MM $(CFLAGS) $(CPPFLAGS) $(BASE_CFLAGS) $^ 1>.depend
 
@@ -671,7 +629,7 @@
 	$(CC) $(CPPFLAGS) -c -o $@ $<
 
 clean:
-	rm -f *.o *.a *~ $(PROGS) gen-op.h opc.h op.h nwfpe/*.o slirp/*.o fpu/*.o
+	rm -f *.o *.a *~ $(PROGS) gen-op.h opc.h op.h nwfpe/*.o fpu/*.o
 	rm -f *.d */*.d
 
 install: all

Added: trunk/src/host/qemu-neo1973/audio/.cvsignore
===================================================================
--- trunk/src/host/qemu-neo1973/audio/.cvsignore	2007-11-09 16:32:22 UTC (rev 3386)
+++ trunk/src/host/qemu-neo1973/audio/.cvsignore	2007-11-09 17:12:19 UTC (rev 3387)
@@ -0,0 +1 @@
+*.d

Modified: trunk/src/host/qemu-neo1973/audio/audio.h
===================================================================
--- trunk/src/host/qemu-neo1973/audio/audio.h	2007-11-09 16:32:22 UTC (rev 3386)
+++ trunk/src/host/qemu-neo1973/audio/audio.h	2007-11-09 17:12:19 UTC (rev 3387)
@@ -24,7 +24,7 @@
 #ifndef QEMU_AUDIO_H
 #define QEMU_AUDIO_H
 
-#include "config.h"
+#include "config-host.h"
 #include "sys-queue.h"
 
 typedef void (*audio_callback_fn_t) (void *opaque, int avail);

Modified: trunk/src/host/qemu-neo1973/configure
===================================================================
--- trunk/src/host/qemu-neo1973/configure	2007-11-09 16:32:22 UTC (rev 3386)
+++ trunk/src/host/qemu-neo1973/configure	2007-11-09 17:12:19 UTC (rev 3387)
@@ -316,7 +316,8 @@
 if [ "$bsd" = "yes" -o "$darwin" = "yes" -o "$mingw32" = "yes" ] ; then
     AIOLIBS=
 else
-    AIOLIBS="-lrt"
+    # Some Linux architectures (e.g. s390) don't imply -lpthread automatically.
+    AIOLIBS="-lrt -lpthread"
 fi
 
 # default flags for all hosts
@@ -951,6 +952,29 @@
 if [ "$build_docs" = "yes" ] ; then
   echo "BUILD_DOCS=yes" >> $config_mak
 fi
+if test "$static" = "yes"; then
+  sdl1=$sdl_static
+else
+  sdl1=$sdl
+fi
+if test "$sdl1" = "yes" ; then
+  echo "#define CONFIG_SDL 1" >> $config_h
+  echo "CONFIG_SDL=yes" >> $config_mak
+  if test "$target_softmmu" = "no" -o "$static" = "yes"; then
+    echo "SDL_LIBS=$sdl_static_libs" >> $config_mak
+  else
+    echo "SDL_LIBS=`$sdl_config --libs`" >> $config_mak
+  fi
+  if [ "${aa}" = "yes" ] ; then
+    echo "SDL_CFLAGS=`$sdl_config --cflags` `aalib-config --cflags`" >> $config_mak
+  else
+    echo "SDL_CFLAGS=`$sdl_config --cflags`" >> $config_mak
+  fi
+fi
+if test "$cocoa" = "yes" ; then
+    echo "#define CONFIG_COCOA 1" >> $config_h
+    echo "CONFIG_COCOA=yes" >> $config_mak
+fi
 
 # XXX: suppress that
 if [ "$bsd" = "yes" ] ; then
@@ -1041,9 +1065,6 @@
 if test "$target" = "arm-linux-user" -o "$target" = "armeb-linux-user" ; then
   mkdir -p $target_dir/nwfpe
 fi
-if test "$target_user_only" = "no" ; then
-  mkdir -p $target_dir/slirp
-fi
 if test "$target" = "arm-softmmu" ; then
   mkdir -p $target_dir/gnokiigsm
 fi
@@ -1138,16 +1159,18 @@
   echo "TARGET_ARCH=mips" >> $config_mak
   echo "#define TARGET_ARCH \"mips\"" >> $config_h
   echo "#define TARGET_MIPS 1" >> $config_h
+  echo "#define TARGET_ABI_MIPSO32 1" >> $config_h
 elif test "$target_cpu" = "mipsn32" -o "$target_cpu" = "mipsn32el" ; then
   echo "TARGET_ARCH=mipsn32" >> $config_mak
   echo "#define TARGET_ARCH \"mipsn32\"" >> $config_h
   echo "#define TARGET_MIPS 1" >> $config_h
-  echo "#define TARGET_MIPSN32 1" >> $config_h
+  echo "#define TARGET_ABI_MIPSN32 1" >> $config_h
 elif test "$target_cpu" = "mips64" -o "$target_cpu" = "mips64el" ; then
   echo "TARGET_ARCH=mips64" >> $config_mak
   echo "#define TARGET_ARCH \"mips64\"" >> $config_h
   echo "#define TARGET_MIPS 1" >> $config_h
   echo "#define TARGET_MIPS64 1" >> $config_h
+  echo "#define TARGET_ABI_MIPSN64 1" >> $config_h
 elif test "$target_cpu" = "cris" ; then
   echo "TARGET_ARCH=cris" >> $config_mak
   echo "#define TARGET_ARCH \"cris\"" >> $config_h
@@ -1206,42 +1229,14 @@
   echo "TARGET_HAS_ELFLOAD32=yes" >> $config_mak
   echo "#define TARGET_HAS_ELFLOAD32 1" >> $config_h
 fi
-# sdl defines
 
-if test "$target_user_only" = "no"; then
-    if test "$target_softmmu" = "no" -o "$static" = "yes"; then
-        sdl1=$sdl_static
-    else
-        sdl1=$sdl
-    fi
-    if test "$sdl1" = "yes" ; then
-        echo "#define CONFIG_SDL 1" >> $config_h
-        echo "CONFIG_SDL=yes" >> $config_mak
-        if test "$target_softmmu" = "no" -o "$static" = "yes"; then
-            echo "SDL_LIBS=$sdl_static_libs" >> $config_mak
-        else
-            echo "SDL_LIBS=`$sdl_config --libs`" >> $config_mak
-        fi
-        if [ "${aa}" = "yes" ] ; then
-            echo "SDL_CFLAGS=`$sdl_config --cflags` `aalib-config --cflags`" >> $config_mak
-        else
-            echo "SDL_CFLAGS=`$sdl_config --cflags`" >> $config_mak
-        fi
-    fi
-fi
-
-if test "$cocoa" = "yes" ; then
-    echo "#define CONFIG_COCOA 1" >> $config_h
-    echo "CONFIG_COCOA=yes" >> $config_mak
-fi
-
 test -f ${config_h}~ && cmp -s $config_h ${config_h}~ && mv ${config_h}~ $config_h
 
 done # for target in $targets
 
 # build tree in object directory if source path is different from current one
 if test "$source_path_used" = "yes" ; then
-    DIRS="tests tests/cris"
+    DIRS="tests tests/cris slirp audio"
     FILES="Makefile tests/Makefile"
     FILES="$FILES tests/cris/Makefile tests/cris/.gdbinit"
     for dir in $DIRS ; do

Modified: trunk/src/host/qemu-neo1973/cpu-all.h
===================================================================
--- trunk/src/host/qemu-neo1973/cpu-all.h	2007-11-09 16:32:22 UTC (rev 3386)
+++ trunk/src/host/qemu-neo1973/cpu-all.h	2007-11-09 17:12:19 UTC (rev 3387)
@@ -691,6 +691,7 @@
 int page_get_flags(target_ulong address);
 void page_set_flags(target_ulong start, target_ulong end, int flags);
 void page_unprotect_range(target_ulong data, target_ulong data_size);
+int page_check_range(target_ulong start, target_ulong len, int flags);
 
 CPUState *cpu_copy(CPUState *env);
 

Modified: trunk/src/host/qemu-neo1973/cpu-exec.c
===================================================================
--- trunk/src/host/qemu-neo1973/cpu-exec.c	2007-11-09 16:32:22 UTC (rev 3386)
+++ trunk/src/host/qemu-neo1973/cpu-exec.c	2007-11-09 17:12:19 UTC (rev 3387)
@@ -181,10 +181,8 @@
     flags = (((env->pstate & PS_PEF) >> 1) | ((env->fprs & FPRS_FEF) << 2))
         | (env->pstate & PS_PRIV) | ((env->lsu & (DMMU_E | IMMU_E)) >> 2);
 #else
-    // FPU enable . MMU Boot . MMU enabled . MMU no-fault . Supervisor
-    flags = (env->psref << 4) | (((env->mmuregs[0] & MMU_BM) >> 14) << 3)
-        | ((env->mmuregs[0] & (MMU_E | MMU_NF)) << 1)
-        | env->psrs;
+    // FPU enable . Supervisor
+    flags = (env->psref << 4) | env->psrs;
 #endif
     cs_base = env->npc;
     pc = env->pc;
@@ -614,19 +612,9 @@
 #if USE_KQEMU
                         (env->kqemu_enabled != 2) &&
 #endif
-                        tb->page_addr[1] == -1
-#if defined(TARGET_I386) && defined(USE_CODE_COPY)
-                    && (tb->cflags & CF_CODE_COPY) ==
-                    (((TranslationBlock *)(T0 & ~3))->cflags & CF_CODE_COPY)
-#endif
-                    ) {
+                        tb->page_addr[1] == -1) {
                     spin_lock(&tb_lock);
                     tb_add_jump((TranslationBlock *)(long)(T0 & ~3), T0 & 3, tb);
-#if defined(USE_CODE_COPY)
-                    /* propagates the FP use info */
-                    ((TranslationBlock *)(T0 & ~3))->cflags |=
-                        (tb->cflags & CF_FP_USED);
-#endif
                     spin_unlock(&tb_lock);
                 }
                 }
@@ -650,80 +638,6 @@
                               : /* no outputs */
                               : "r" (gen_func)
                               : "r1", "r2", "r3", "r8", "r9", "r10", "r12", "r14");
-#elif defined(TARGET_I386) && defined(USE_CODE_COPY)
-{
-    if (!(tb->cflags & CF_CODE_COPY)) {
-        if ((tb->cflags & CF_FP_USED) && env->native_fp_regs) {
-            save_native_fp_state(env);
-        }
-        gen_func();
-    } else {
-        if ((tb->cflags & CF_FP_USED) && !env->native_fp_regs) {
-            restore_native_fp_state(env);
-        }
-        /* we work with native eflags */
-        CC_SRC = cc_table[CC_OP].compute_all();
-        CC_OP = CC_OP_EFLAGS;
-        asm(".globl exec_loop\n"
-            "\n"
-            "debug1:\n"
-            "    pushl %%ebp\n"
-            "    fs movl %10, %9\n"
-            "    fs movl %11, %%eax\n"
-            "    andl $0x400, %%eax\n"
-            "    fs orl %8, %%eax\n"
-            "    pushl %%eax\n"
-            "    popf\n"
-            "    fs movl %%esp, %12\n"
-            "    fs movl %0, %%eax\n"
-            "    fs movl %1, %%ecx\n"
-            "    fs movl %2, %%edx\n"
-            "    fs movl %3, %%ebx\n"
-            "    fs movl %4, %%esp\n"
-            "    fs movl %5, %%ebp\n"
-            "    fs movl %6, %%esi\n"
-            "    fs movl %7, %%edi\n"
-            "    fs jmp *%9\n"
-            "exec_loop:\n"
-            "    fs movl %%esp, %4\n"
-            "    fs movl %12, %%esp\n"
-            "    fs movl %%eax, %0\n"
-            "    fs movl %%ecx, %1\n"
-            "    fs movl %%edx, %2\n"
-            "    fs movl %%ebx, %3\n"
-            "    fs movl %%ebp, %5\n"
-            "    fs movl %%esi, %6\n"
-            "    fs movl %%edi, %7\n"
-            "    pushf\n"
-            "    popl %%eax\n"
-            "    movl %%eax, %%ecx\n"
-            "    andl $0x400, %%ecx\n"
-            "    shrl $9, %%ecx\n"
-            "    andl $0x8d5, %%eax\n"
-            "    fs movl %%eax, %8\n"
-            "    movl $1, %%eax\n"
-            "    subl %%ecx, %%eax\n"
-            "    fs movl %%eax, %11\n"
-            "    fs movl %9, %%ebx\n" /* get T0 value */
-            "    popl %%ebp\n"
-            :
-            : "m" (*(uint8_t *)offsetof(CPUState, regs[0])),
-            "m" (*(uint8_t *)offsetof(CPUState, regs[1])),
-            "m" (*(uint8_t *)offsetof(CPUState, regs[2])),
-            "m" (*(uint8_t *)offsetof(CPUState, regs[3])),
-            "m" (*(uint8_t *)offsetof(CPUState, regs[4])),
-            "m" (*(uint8_t *)offsetof(CPUState, regs[5])),
-            "m" (*(uint8_t *)offsetof(CPUState, regs[6])),
-            "m" (*(uint8_t *)offsetof(CPUState, regs[7])),
-            "m" (*(uint8_t *)offsetof(CPUState, cc_src)),
-            "m" (*(uint8_t *)offsetof(CPUState, tmp0)),
-            "a" (gen_func),
-            "m" (*(uint8_t *)offsetof(CPUState, df)),
-            "m" (*(uint8_t *)offsetof(CPUState, saved_esp))
-            : "%ecx", "%edx"
-            );
-    }
-}
 #elif defined(__ia64)
 		struct fptr {
 			void *ip;
@@ -761,11 +675,6 @@
 
 
 #if defined(TARGET_I386)
-#if defined(USE_CODE_COPY)
-    if (env->native_fp_regs) {
-        save_native_fp_state(env);
-    }
-#endif
     /* restore flags in standard format */
     env->eflags = env->eflags | cc_table[CC_OP].compute_all() | (DF & DF_MASK);
 #elif defined(TARGET_ARM)
@@ -1277,26 +1186,6 @@
 # define ERROR_sig(context)   ((context)->uc_mcontext.gregs[REG_ERR])
 #endif
 
-#if defined(USE_CODE_COPY)
-static void cpu_send_trap(unsigned long pc, int trap,
-                          struct ucontext *uc)
-{
-    TranslationBlock *tb;
-
-    if (cpu_single_env)
-        env = cpu_single_env; /* XXX: find a correct solution for multithread */
-    /* now we have a real cpu fault */
-    tb = tb_find_pc(pc);
-    if (tb) {
-        /* the PC is inside the translated code. It means that we have
-           a virtual CPU fault */
-        cpu_restore_state(tb, env, pc, uc);
-    }
-    sigprocmask(SIG_SETMASK, &uc->uc_sigmask, NULL);
-    raise_exception_err(trap, env->error_code);
-}
-#endif
-
 int cpu_signal_handler(int host_signum, void *pinfo,
                        void *puc)
 {
@@ -1313,17 +1202,10 @@
 #endif
     pc = EIP_sig(uc);
     trapno = TRAP_sig(uc);
-#if defined(TARGET_I386) && defined(USE_CODE_COPY)
-    if (trapno == 0x00 || trapno == 0x05) {
-        /* send division by zero or bound exception */
-        cpu_send_trap(pc, trapno, uc);
-        return 1;
-    } else
-#endif
-        return handle_cpu_signal(pc, (unsigned long)info->si_addr,
-                                 trapno == 0xe ?
-                                 (ERROR_sig(uc) >> 1) & 1 : 0,
-                                 &uc->uc_sigmask, puc);
+    return handle_cpu_signal(pc, (unsigned long)info->si_addr,
+                             trapno == 0xe ?
+                             (ERROR_sig(uc) >> 1) & 1 : 0,
+                             &uc->uc_sigmask, puc);
 }
 
 #elif defined(__x86_64__)

Modified: trunk/src/host/qemu-neo1973/darwin-user/main.c
===================================================================
--- trunk/src/host/qemu-neo1973/darwin-user/main.c	2007-11-09 16:32:22 UTC (rev 3386)
+++ trunk/src/host/qemu-neo1973/darwin-user/main.c	2007-11-09 17:12:19 UTC (rev 3387)
@@ -757,9 +757,6 @@
            "-s size      set the stack size in bytes (default=%ld)\n"
            "\n"
            "debug options:\n"
-#ifdef USE_CODE_COPY
-           "-no-code-copy   disable code copy acceleration\n"
-#endif
            "-d options   activate log (logfile='%s')\n"
            "-g wait for gdb on port 1234\n"
            "-p pagesize  set the host page size to 'pagesize'\n",
@@ -845,11 +842,6 @@
         if (!strcmp(r, "g")) {
             use_gdbstub = 1;
         } else
-#ifdef USE_CODE_COPY
-        if (!strcmp(r, "no-code-copy")) {
-            code_copy_enabled = 0;
-        } else
-#endif
         {
             usage();
         }

Modified: trunk/src/host/qemu-neo1973/darwin-user/signal.c
===================================================================
--- trunk/src/host/qemu-neo1973/darwin-user/signal.c	2007-11-09 16:32:22 UTC (rev 3386)
+++ trunk/src/host/qemu-neo1973/darwin-user/signal.c	2007-11-09 17:12:19 UTC (rev 3387)
@@ -198,11 +198,7 @@
 
     /* the CPU emulator uses some host signals to detect exceptions,
        we we forward to it some signals */
-    if (host_signum == SIGSEGV || host_signum == SIGBUS
-#if defined(TARGET_I386) && defined(USE_CODE_COPY)
-        || host_signum == SIGFPE
-#endif
-        ) {
+    if (host_signum == SIGSEGV || host_signum == SIGBUS) {
         if (cpu_signal_handler(host_signum, (void*)info, puc))
             return;
     }

Modified: trunk/src/host/qemu-neo1973/dyngen.c
===================================================================
--- trunk/src/host/qemu-neo1973/dyngen.c	2007-11-09 16:32:22 UTC (rev 3386)
+++ trunk/src/host/qemu-neo1973/dyngen.c	2007-11-09 17:12:19 UTC (rev 3387)
@@ -701,6 +701,8 @@
     uint32_t *n_strtab;
     EXE_SYM *sym;
     EXE_RELOC *rel;
+    const char *p;
+    int aux_size, j;
 
     fd = open(filename, O_RDONLY
 #ifdef _WIN32
@@ -727,7 +729,6 @@
     sdata = malloc(sizeof(void *) * fhdr.f_nscns);
     memset(sdata, 0, sizeof(void *) * fhdr.f_nscns);
 
-    const char *p;
     for(i = 0;i < fhdr.f_nscns; i++) {
         sec = &shdr[i];
         if (!strstart(sec->s_name,  ".bss", &p))
@@ -771,7 +772,6 @@
 	/* set coff symbol */
 	symtab = malloc(sizeof(struct coff_sym) * nb_syms);
 
-	int aux_size, j;
 	for (i = 0, ext_sym = coff_symtab, sym = symtab; i < nb_syms; i++, ext_sym++, sym++) {
 		memset(sym, 0, sizeof(*sym));
 		sym->st_syment = ext_sym;

Modified: trunk/src/host/qemu-neo1973/exec-all.h
===================================================================
--- trunk/src/host/qemu-neo1973/exec-all.h	2007-11-09 16:32:22 UTC (rev 3386)
+++ trunk/src/host/qemu-neo1973/exec-all.h	2007-11-09 17:12:19 UTC (rev 3387)
@@ -91,9 +91,6 @@
 extern FILE *logfile;
 extern int loglevel;
 
-void muls64(int64_t *phigh, int64_t *plow, int64_t a, int64_t b);
-void mulu64(uint64_t *phigh, uint64_t *plow, uint64_t a, uint64_t b);
-
 int gen_intermediate_code(CPUState *env, struct TranslationBlock *tb);
 int gen_intermediate_code_pc(CPUState *env, struct TranslationBlock *tb);
 void dump_ops(const uint16_t *opc_buf, const uint32_t *opparam_buf);

Modified: trunk/src/host/qemu-neo1973/exec.c
===================================================================
--- trunk/src/host/qemu-neo1973/exec.c	2007-11-09 16:32:22 UTC (rev 3386)
+++ trunk/src/host/qemu-neo1973/exec.c	2007-11-09 17:12:19 UTC (rev 3387)
@@ -339,10 +339,10 @@
 {
     CPUState *env;
 #if defined(DEBUG_FLUSH)
-    printf("qemu: flush code_size=%d nb_tbs=%d avg_tb_size=%d\n",
-           code_gen_ptr - code_gen_buffer,
-           nb_tbs,
-           nb_tbs > 0 ? (code_gen_ptr - code_gen_buffer) / nb_tbs : 0);
+    printf("qemu: flush code_size=%ld nb_tbs=%d avg_tb_size=%ld\n",
+           (unsigned long)(code_gen_ptr - code_gen_buffer),
+           nb_tbs, nb_tbs > 0 ?
+           ((unsigned long)(code_gen_ptr - code_gen_buffer)) / nb_tbs : 0);
 #endif
     nb_tbs = 0;
 
@@ -889,7 +889,7 @@
         mprotect(g2h(page_addr), qemu_host_page_size,
                  (prot & PAGE_BITS) & ~PAGE_WRITE);
 #ifdef DEBUG_TB_INVALIDATE
-        printf("protecting code page: 0x%08lx\n",
+        printf("protecting code page: 0x" TARGET_FMT_lx "\n",
                page_addr);
 #endif
     }
@@ -944,11 +944,6 @@
     tb->jmp_first = (TranslationBlock *)((long)tb | 2);
     tb->jmp_next[0] = NULL;
     tb->jmp_next[1] = NULL;
-#ifdef USE_CODE_COPY
-    tb->cflags &= ~CF_FP_USED;
-    if (tb->cflags & CF_TB_FP_USED)
-        tb->cflags |= CF_FP_USED;
-#endif
 
     /* init original jump addresses */
     if (tb->tb_next_offset[0] != 0xffff)
@@ -1875,6 +1870,33 @@
     spin_unlock(&tb_lock);
 }
 
+int page_check_range(target_ulong start, target_ulong len, int flags)
+{
+    PageDesc *p;
+    target_ulong end;
+    target_ulong addr;
+
+    end = TARGET_PAGE_ALIGN(start+len); /* must do before we loose bits in the next step */
+    start = start & TARGET_PAGE_MASK;
+
+    if( end < start )
+        /* we've wrapped around */
+        return -1;
+    for(addr = start; addr < end; addr += TARGET_PAGE_SIZE) {
+        p = page_find(addr >> TARGET_PAGE_BITS);
+        if( !p )
+            return -1;
+        if( !(p->flags & PAGE_VALID) )
+            return -1;
+
+        if (!(p->flags & PAGE_READ) && (flags & PAGE_READ) )
+            return -1;
+        if (!(p->flags & PAGE_WRITE) && (flags & PAGE_WRITE) )
+            return -1;
+    }
+    return 0;
+}
+
 /* called from signal handler: invalidate the code and unprotect the
    page. Return TRUE if the fault was succesfully handled. */
 int page_unprotect(target_ulong address, unsigned long pc, void *puc)
@@ -2062,7 +2084,7 @@
 static uint32_t unassigned_mem_readb(void *opaque, target_phys_addr_t addr)
 {
 #ifdef DEBUG_UNASSIGNED
-    printf("Unassigned mem read " TARGET_FMT_lx "\n", addr);
+    printf("Unassigned mem read " TARGET_FMT_plx "\n", addr);
 #endif
 #ifdef TARGET_SPARC
     do_unassigned_access(addr, 0, 0, 0);
@@ -2075,7 +2097,7 @@
 static void unassigned_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
 {
 #ifdef DEBUG_UNASSIGNED
-    printf("Unassigned mem write " TARGET_FMT_lx " = 0x%x\n", addr, val);
+    printf("Unassigned mem write " TARGET_FMT_plx " = 0x%x\n", addr, val);
 #endif
 #ifdef TARGET_SPARC
     do_unassigned_access(addr, 1, 0, 0);

Modified: trunk/src/host/qemu-neo1973/host-utils.c
===================================================================
--- trunk/src/host/qemu-neo1973/host-utils.c	2007-11-09 16:32:22 UTC (rev 3386)
+++ trunk/src/host/qemu-neo1973/host-utils.c	2007-11-09 17:12:19 UTC (rev 3387)
@@ -23,11 +23,13 @@
  * THE SOFTWARE.
  */
 
-#include "vl.h"
+#include "exec.h"
+#include "host-utils.h"
 
 //#define DEBUG_MULDIV
 
 /* Long integer helpers */
+#if !defined(__x86_64__)
 static void add128 (uint64_t *plow, uint64_t *phigh, uint64_t a, uint64_t b)
 {
     *plow += a;
@@ -69,17 +71,10 @@
     *phigh += v;
 }
 
-
 /* Unsigned 64x64 -> 128 multiplication */
 void mulu64 (uint64_t *plow, uint64_t *phigh, uint64_t a, uint64_t b)
 {
-#if defined(__x86_64__)
-    __asm__ ("mul %0\n\t"
-             : "=d" (*phigh), "=a" (*plow)
-             : "a" (a), "0" (b));
-#else
     mul64(plow, phigh, a, b);
-#endif
 #if defined(DEBUG_MULDIV)
     printf("mulu64: 0x%016llx * 0x%016llx = 0x%016llx%016llx\n",
            a, b, *phigh, *plow);
@@ -89,11 +84,6 @@
 /* Signed 64x64 -> 128 multiplication */
 void muls64 (uint64_t *plow, uint64_t *phigh, int64_t a, int64_t b)
 {
-#if defined(__x86_64__)
-    __asm__ ("imul %0\n\t"
-             : "=d" (*phigh), "=a" (*plow)
-             : "a" (a), "0" (b));
-#else
     int sa, sb;
 
     sa = (a < 0);
@@ -106,9 +96,9 @@
     if (sa ^ sb) {
         neg128(plow, phigh);
     }
-#endif
 #if defined(DEBUG_MULDIV)
     printf("muls64: 0x%016llx * 0x%016llx = 0x%016llx%016llx\n",
            a, b, *phigh, *plow);
 #endif
 }
+#endif /* !defined(__x86_64__) */

Modified: trunk/src/host/qemu-neo1973/host-utils.h
===================================================================
--- trunk/src/host/qemu-neo1973/host-utils.h	2007-11-09 16:32:22 UTC (rev 3386)
+++ trunk/src/host/qemu-neo1973/host-utils.h	2007-11-09 17:12:19 UTC (rev 3387)
@@ -23,6 +23,28 @@
  * THE SOFTWARE.
  */
 
+#if defined(__x86_64__)
+#define __HAVE_FAST_MULU64__
+static always_inline void mulu64 (uint64_t *plow, uint64_t *phigh,
+                                  uint64_t a, uint64_t b)
+{
+    __asm__ ("mul %0\n\t"
+             : "=d" (*phigh), "=a" (*plow)
+             : "a" (a), "0" (b));
+}
+#define __HAVE_FAST_MULS64__
+static always_inline void muls64 (uint64_t *plow, uint64_t *phigh,
+                                  int64_t a, int64_t b)
+{
+    __asm__ ("imul %0\n\t"
+             : "=d" (*phigh), "=a" (*plow)
+             : "a" (a), "0" (b));
+}
+#else
+void muls64(uint64_t *phigh, uint64_t *plow, int64_t a, int64_t b);
+void mulu64(uint64_t *phigh, uint64_t *plow, uint64_t a, uint64_t b);
+#endif
+
 /* Note that some of those functions may end up calling libgcc functions,
    depending on the host machine. It is up to the target emulation to
    cope with that. */
@@ -68,34 +90,13 @@
 {
     int cnt = 0;
 
-    if (!(val & 0xFFFFFFFF00000000ULL)) {
+    if (!(val >> 32)) {
         cnt += 32;
-        val <<= 32;
+    } else {
+        val >>= 32;
     }
-    if (!(val & 0xFFFF000000000000ULL)) {
-        cnt += 16;
-        val <<= 16;
-    }
-    if (!(val & 0xFF00000000000000ULL)) {
-        cnt += 8;
-        val <<= 8;
-    }
-    if (!(val & 0xF000000000000000ULL)) {
-        cnt += 4;
-        val <<= 4;
-    }
-    if (!(val & 0xC000000000000000ULL)) {
-        cnt += 2;
-        val <<= 2;
-    }
-    if (!(val & 0x8000000000000000ULL)) {
-        cnt++;
-        val <<= 1;
-    }
-    if (!(val & 0x8000000000000000ULL)) {
-        cnt++;
-    }
-    return cnt;
+
+    return cnt + clz32(val);
 }
 
 static always_inline int clo64(uint64_t val)

Modified: trunk/src/host/qemu-neo1973/hw/fdc.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/fdc.c	2007-11-09 16:32:22 UTC (rev 3386)
+++ trunk/src/host/qemu-neo1973/hw/fdc.c	2007-11-09 17:12:19 UTC (rev 3387)
@@ -106,7 +106,7 @@
 }
 
 static int _fd_sector (uint8_t head, uint8_t track,
-                        uint8_t sect, uint8_t last_sect)
+                       uint8_t sect, uint8_t last_sect)
 {
     return (((track * 2) + head) * last_sect) + sect - 1;
 }
@@ -124,7 +124,7 @@
     int ret;
 
     if (track > drv->max_track ||
-	(head != 0 && (drv->flags & FDISK_DBL_SIDES) == 0)) {
+        (head != 0 && (drv->flags & FDISK_DBL_SIDES) == 0)) {
         FLOPPY_DPRINTF("try to read %d %02x %02x (max=%d %d %02x %02x)\n",
                        head, track, sect, 1,
                        (drv->flags & FDISK_DBL_SIDES) == 0 ? 0 : 1,
@@ -149,8 +149,8 @@
         }
 #endif
         drv->head = head;
-	if (drv->track != track)
-	    ret = 1;
+        if (drv->track != track)
+            ret = 1;
         drv->track = track;
         drv->sect = sect;
     }
@@ -179,7 +179,7 @@
     const unsigned char *str;
 } fd_format_t;
 
-static fd_format_t fd_formats[] = {
+static const fd_format_t fd_formats[] = {
     /* First entry is default format */
     /* 1.44 MB 3"1/2 floppy disks */
     { FDRIVE_DRV_144, FDRIVE_DISK_144, 18, 80, 1, "1.44 MB 3\"1/2", },
@@ -229,65 +229,65 @@
 /* Revalidate a disk drive after a disk change */
 static void fd_revalidate (fdrive_t *drv)
 {
-    fd_format_t *parse;
+    const fd_format_t *parse;
     int64_t nb_sectors, size;
     int i, first_match, match;
     int nb_heads, max_track, last_sect, ro;
 
     FLOPPY_DPRINTF("revalidate\n");
     if (drv->bs != NULL && bdrv_is_inserted(drv->bs)) {
-	ro = bdrv_is_read_only(drv->bs);
-	bdrv_get_geometry_hint(drv->bs, &nb_heads, &max_track, &last_sect);
-	if (nb_heads != 0 && max_track != 0 && last_sect != 0) {
-	    FLOPPY_DPRINTF("User defined disk (%d %d %d)",
+        ro = bdrv_is_read_only(drv->bs);
+        bdrv_get_geometry_hint(drv->bs, &nb_heads, &max_track, &last_sect);
+        if (nb_heads != 0 && max_track != 0 && last_sect != 0) {
+            FLOPPY_DPRINTF("User defined disk (%d %d %d)",
                            nb_heads - 1, max_track, last_sect);
-	} else {
-	    bdrv_get_geometry(drv->bs, &nb_sectors);
-	    match = -1;
-	    first_match = -1;
-	    for (i = 0;; i++) {
-		parse = &fd_formats[i];
-		if (parse->drive == FDRIVE_DRV_NONE)
-		    break;
-		if (drv->drive == parse->drive ||
-		    drv->drive == FDRIVE_DRV_NONE) {
-		    size = (parse->max_head + 1) * parse->max_track *
-			parse->last_sect;
-		    if (nb_sectors == size) {
-			match = i;
-			break;
-		    }
-		    if (first_match == -1)
-			first_match = i;
-		}
-	    }
-	    if (match == -1) {
-		if (first_match == -1)
-		    match = 1;
-		else
-		    match = first_match;
-		parse = &fd_formats[match];
-	    }
-	    nb_heads = parse->max_head + 1;
-	    max_track = parse->max_track;
-	    last_sect = parse->last_sect;
-	    drv->drive = parse->drive;
-	    FLOPPY_DPRINTF("%s floppy disk (%d h %d t %d s) %s\n", parse->str,
+        } else {
+            bdrv_get_geometry(drv->bs, &nb_sectors);
+            match = -1;
+            first_match = -1;
+            for (i = 0;; i++) {
+                parse = &fd_formats[i];
+                if (parse->drive == FDRIVE_DRV_NONE)
+                    break;
+                if (drv->drive == parse->drive ||
+                    drv->drive == FDRIVE_DRV_NONE) {
+                    size = (parse->max_head + 1) * parse->max_track *
+                        parse->last_sect;
+                    if (nb_sectors == size) {
+                        match = i;
+                        break;
+                    }
+                    if (first_match == -1)
+                        first_match = i;
+                }
+            }
+            if (match == -1) {
+                if (first_match == -1)
+                    match = 1;
+                else
+                    match = first_match;
+                parse = &fd_formats[match];
+            }
+            nb_heads = parse->max_head + 1;
+            max_track = parse->max_track;
+            last_sect = parse->last_sect;
+            drv->drive = parse->drive;
+            FLOPPY_DPRINTF("%s floppy disk (%d h %d t %d s) %s\n", parse->str,
                            nb_heads, max_track, last_sect, ro ? "ro" : "rw");
-	}
-	    if (nb_heads == 1) {
-		drv->flags &= ~FDISK_DBL_SIDES;
-	    } else {
-		drv->flags |= FDISK_DBL_SIDES;
-	    }
-	    drv->max_track = max_track;
-	    drv->last_sect = last_sect;
-	drv->ro = ro;
+        }
+        if (nb_heads == 1) {
+            drv->flags &= ~FDISK_DBL_SIDES;
+        } else {
+            drv->flags |= FDISK_DBL_SIDES;
+        }
+        drv->max_track = max_track;
+        drv->last_sect = last_sect;
+        drv->ro = ro;
     } else {
-	FLOPPY_DPRINTF("No disk in drive\n");
+        FLOPPY_DPRINTF("No disk in drive\n");
         drv->last_sect = 0;
-	drv->max_track = 0;
-	drv->flags &= ~FDISK_DBL_SIDES;
+        drv->max_track = 0;
+        drv->flags &= ~FDISK_DBL_SIDES;
     }
 }
 
@@ -395,6 +395,8 @@
     uint8_t lock;
     /* Power down config (also with status regB access mode */
     uint8_t pwrd;
+    /* Sun4m quirks? */
+    int sun4m;
     /* Floppy drives */
     fdrive_t drives[2];
 };
@@ -405,33 +407,35 @@
     uint32_t retval;
 
     switch (reg & 0x07) {
-#ifdef TARGET_SPARC
     case 0x00:
-	// Identify to Linux as S82078B
-	retval = fdctrl_read_statusB(fdctrl);
-	break;
-#endif
+        if (fdctrl->sun4m) {
+            // Identify to Linux as S82078B
+            retval = fdctrl_read_statusB(fdctrl);
+        } else {
+            retval = (uint32_t)(-1);
+        }
+        break;
     case 0x01:
-	retval = fdctrl_read_statusB(fdctrl);
-	break;
+        retval = fdctrl_read_statusB(fdctrl);
+        break;
     case 0x02:
-	retval = fdctrl_read_dor(fdctrl);
-	break;
+        retval = fdctrl_read_dor(fdctrl);
+        break;
     case 0x03:
         retval = fdctrl_read_tape(fdctrl);
-	break;
+        break;
     case 0x04:
         retval = fdctrl_read_main_status(fdctrl);
-	break;
+        break;
     case 0x05:
         retval = fdctrl_read_data(fdctrl);
-	break;
+        break;
     case 0x07:
         retval = fdctrl_read_dir(fdctrl);
-	break;
+        break;
     default:
-	retval = (uint32_t)(-1);
-	break;
+        retval = (uint32_t)(-1);
+        break;
     }
     FLOPPY_DPRINTF("read reg%d: 0x%02x\n", reg & 7, retval);
 
@@ -446,19 +450,19 @@
 
     switch (reg & 0x07) {
     case 0x02:
-	fdctrl_write_dor(fdctrl, value);
-	break;
+        fdctrl_write_dor(fdctrl, value);
+        break;
     case 0x03:
         fdctrl_write_tape(fdctrl, value);
-	break;
+        break;
     case 0x04:
         fdctrl_write_rate(fdctrl, value);
-	break;
+        break;
     case 0x05:
         fdctrl_write_data(fdctrl, value);
-	break;
+        break;
     default:
-	break;
+        break;
     }
 }
 
@@ -598,6 +602,7 @@
     fdctrl->dma_chann = dma_chann;
     fdctrl->io_base = io_base;
     fdctrl->config = 0x60; /* Implicit seek, polling & FIFO enabled */
+    fdctrl->sun4m = 0;
     if (fdctrl->dma_chann != -1) {
         fdctrl->dma_en = 1;
         DMA_register_channel(dma_chann, &fdctrl_transfer_handler, fdctrl);
@@ -610,7 +615,8 @@
     fdctrl_reset(fdctrl, 0);
     fdctrl->state = FD_CTRL_ACTIVE;
     if (mem_mapped) {
-        io_mem = cpu_register_io_memory(0, fdctrl_mem_read, fdctrl_mem_write, fdctrl);
+        io_mem = cpu_register_io_memory(0, fdctrl_mem_read, fdctrl_mem_write,
+                                        fdctrl);
         cpu_register_physical_memory(io_base, 0x08, io_mem);
     } else {
         register_ioport_read((uint32_t)io_base + 0x01, 5, 1, &fdctrl_read,
@@ -631,6 +637,17 @@
     return fdctrl;
 }
 
+fdctrl_t *sun4m_fdctrl_init (qemu_irq irq, target_phys_addr_t io_base,
+                             BlockDriverState **fds)
+{
+    fdctrl_t *fdctrl;
+
+    fdctrl = fdctrl_init(irq, 0, 1, io_base, fds);
+    fdctrl->sun4m = 1;
+
+    return fdctrl;
+}
+
 /* XXX: may change if moved to bdrv */
 int fdctrl_get_drive_type(fdctrl_t *fdctrl, int drive_num)
 {
@@ -647,14 +664,12 @@
 
 static void fdctrl_raise_irq (fdctrl_t *fdctrl, uint8_t status)
 {
-#ifdef TARGET_SPARC
     // Sparc mutation
-    if (!fdctrl->dma_en) {
-	fdctrl->state &= ~FD_CTRL_BUSY;
-	fdctrl->int_status = status;
-	return;
+    if (fdctrl->sun4m && !fdctrl->dma_en) {
+        fdctrl->state &= ~FD_CTRL_BUSY;
+        fdctrl->int_status = status;
+        return;
     }
-#endif
     if (~(fdctrl->state & FD_CTRL_INTR)) {
         qemu_set_irq(fdctrl->irq, 1);
         fdctrl->state |= FD_CTRL_INTR;
@@ -713,9 +728,9 @@
 
     /* Drive motors state indicators */
     if (drv0(fdctrl)->drflags & FDRIVE_MOTOR_ON)
-	retval |= 1 << 5;
+        retval |= 1 << 5;
     if (drv1(fdctrl)->drflags & FDRIVE_MOTOR_ON)
-	retval |= 1 << 4;
+        retval |= 1 << 4;
     /* DMA enable */
     retval |= fdctrl->dma_en << 3;
     /* Reset indicator */
@@ -822,9 +837,9 @@
 {
     /* Reset mode */
     if (fdctrl->state & FD_CTRL_RESET) {
-            FLOPPY_DPRINTF("Floppy controller in RESET state !\n");
-            return;
-        }
+        FLOPPY_DPRINTF("Floppy controller in RESET state !\n");
+        return;
+    }
     FLOPPY_DPRINTF("select rate register set to 0x%02x\n", value);
     /* Reset: autoclear */
     if (value & 0x80) {
@@ -842,6 +857,7 @@
 static int fdctrl_media_changed(fdrive_t *drv)
 {
     int ret;
+
     if (!drv->bs)
         return 0;
     ret = bdrv_media_changed(drv->bs);
@@ -857,7 +873,7 @@
     uint32_t retval = 0;
 
     if (fdctrl_media_changed(drv0(fdctrl)) ||
-	fdctrl_media_changed(drv1(fdctrl)))
+        fdctrl_media_changed(drv1(fdctrl)))
         retval |= 0x80;
     if (retval != 0)
         FLOPPY_DPRINTF("Floppy digital input register: 0x%02x\n", retval);
@@ -904,7 +920,7 @@
 
 /* Callback for transfer end (stop or abort) */
 static void fdctrl_stop_transfer (fdctrl_t *fdctrl, uint8_t status0,
-				  uint8_t status1, uint8_t status2)
+                                  uint8_t status1, uint8_t status2)
 {
     fdrive_t *cur_drv;
 
@@ -986,12 +1002,12 @@
     if (fdctrl->fifo[5] == 00) {
         fdctrl->data_len = fdctrl->fifo[8];
     } else {
-	int tmp;
+        int tmp;
         fdctrl->data_len = 128 << (fdctrl->fifo[5] > 7 ? 7 : fdctrl->fifo[5]);
         tmp = (cur_drv->last_sect - ks + 1);
         if (fdctrl->fifo[0] & 0x80)
             tmp += cur_drv->last_sect;
-	fdctrl->data_len *= tmp;
+        fdctrl->data_len *= tmp;
     }
     fdctrl->eot = fdctrl->fifo[6];
     if (fdctrl->dma_en) {
@@ -1000,9 +1016,9 @@
         dma_mode = DMA_get_channel_mode(fdctrl->dma_chann);
         dma_mode = (dma_mode >> 2) & 3;
         FLOPPY_DPRINTF("dma_mode=%d direction=%d (%d - %d)\n",
-		       dma_mode, direction,
+                       dma_mode, direction,
                        (128 << fdctrl->fifo[5]) *
-		       (cur_drv->last_sect - ks + 1), fdctrl->data_len);
+                       (cur_drv->last_sect - ks + 1), fdctrl->data_len);
         if (((direction == FD_DIR_SCANE || direction == FD_DIR_SCANL ||
               direction == FD_DIR_SCANH) && dma_mode == 0) ||
             (direction == FD_DIR_WRITE && dma_mode == 2) ||
@@ -1016,7 +1032,7 @@
             DMA_schedule(fdctrl->dma_chann);
             return;
         } else {
-	    FLOPPY_ERROR("dma_mode=%d direction=%d\n", dma_mode, direction);
+            FLOPPY_ERROR("dma_mode=%d direction=%d\n", dma_mode, direction);
         }
     }
     FLOPPY_DPRINTF("start non-DMA transfer\n");
@@ -1056,11 +1072,11 @@
     if (dma_len > fdctrl->data_len)
         dma_len = fdctrl->data_len;
     if (cur_drv->bs == NULL) {
-	if (fdctrl->data_dir == FD_DIR_WRITE)
-	    fdctrl_stop_transfer(fdctrl, 0x60, 0x00, 0x00);
-	else
-	    fdctrl_stop_transfer(fdctrl, 0x40, 0x00, 0x00);
-	len = 0;
+        if (fdctrl->data_dir == FD_DIR_WRITE)
+            fdctrl_stop_transfer(fdctrl, 0x60, 0x00, 0x00);
+        else
+            fdctrl_stop_transfer(fdctrl, 0x40, 0x00, 0x00);
+        len = 0;
         goto transfer_error;
     }
     rel_pos = fdctrl->data_pos % FD_SECTOR_LEN;
@@ -1074,45 +1090,39 @@
                        cur_drv->track, cur_drv->sect, fd_sector(cur_drv),
                        fd_sector(cur_drv) * 512);
         if (fdctrl->data_dir != FD_DIR_WRITE ||
-	    len < FD_SECTOR_LEN || rel_pos != 0) {
+            len < FD_SECTOR_LEN || rel_pos != 0) {
             /* READ & SCAN commands and realign to a sector for WRITE */
             if (bdrv_read(cur_drv->bs, fd_sector(cur_drv),
-			  fdctrl->fifo, 1) < 0) {
+                          fdctrl->fifo, 1) < 0) {
                 FLOPPY_DPRINTF("Floppy: error getting sector %d\n",
                                fd_sector(cur_drv));
                 /* Sure, image size is too small... */
                 memset(fdctrl->fifo, 0, FD_SECTOR_LEN);
             }
         }
-	switch (fdctrl->data_dir) {
-	case FD_DIR_READ:
-	    /* READ commands */
+        switch (fdctrl->data_dir) {
+        case FD_DIR_READ:
+            /* READ commands */
             DMA_write_memory (nchan, fdctrl->fifo + rel_pos,
                               fdctrl->data_pos, len);
-/* 	    cpu_physical_memory_write(addr + fdctrl->data_pos, */
-/* 				      fdctrl->fifo + rel_pos, len); */
-	    break;
-	case FD_DIR_WRITE:
+            break;
+        case FD_DIR_WRITE:
             /* WRITE commands */
             DMA_read_memory (nchan, fdctrl->fifo + rel_pos,
                              fdctrl->data_pos, len);
-/*             cpu_physical_memory_read(addr + fdctrl->data_pos, */
-/* 				     fdctrl->fifo + rel_pos, len); */
             if (bdrv_write(cur_drv->bs, fd_sector(cur_drv),
-			   fdctrl->fifo, 1) < 0) {
+                           fdctrl->fifo, 1) < 0) {
                 FLOPPY_ERROR("writting sector %d\n", fd_sector(cur_drv));
                 fdctrl_stop_transfer(fdctrl, 0x60, 0x00, 0x00);
                 goto transfer_error;
             }
-	    break;
-	default:
-	    /* SCAN commands */
+            break;
+        default:
+            /* SCAN commands */
             {
-		uint8_t tmpbuf[FD_SECTOR_LEN];
+                uint8_t tmpbuf[FD_SECTOR_LEN];
                 int ret;
                 DMA_read_memory (nchan, tmpbuf, fdctrl->data_pos, len);
-/*                 cpu_physical_memory_read(addr + fdctrl->data_pos, */
-/*                                          tmpbuf, len); */
                 ret = memcmp(tmpbuf, fdctrl->fifo + rel_pos, len);
                 if (ret == 0) {
                     status2 = 0x08;
@@ -1124,47 +1134,47 @@
                     goto end_transfer;
                 }
             }
-	    break;
+            break;
         }
-	fdctrl->data_pos += len;
-	rel_pos = fdctrl->data_pos % FD_SECTOR_LEN;
+        fdctrl->data_pos += len;
+        rel_pos = fdctrl->data_pos % FD_SECTOR_LEN;
         if (rel_pos == 0) {
             /* Seek to next sector */
-	    FLOPPY_DPRINTF("seek to next sector (%d %02x %02x => %d) (%d)\n",
-			   cur_drv->head, cur_drv->track, cur_drv->sect,
-			   fd_sector(cur_drv),
-			   fdctrl->data_pos - len);
+            FLOPPY_DPRINTF("seek to next sector (%d %02x %02x => %d) (%d)\n",
+                           cur_drv->head, cur_drv->track, cur_drv->sect,
+                           fd_sector(cur_drv),
+                           fdctrl->data_pos - len);
             /* XXX: cur_drv->sect >= cur_drv->last_sect should be an
                error in fact */
             if (cur_drv->sect >= cur_drv->last_sect ||
                 cur_drv->sect == fdctrl->eot) {
-		cur_drv->sect = 1;
-		if (FD_MULTI_TRACK(fdctrl->data_state)) {
-		    if (cur_drv->head == 0 &&
-			(cur_drv->flags & FDISK_DBL_SIDES) != 0) {
+                cur_drv->sect = 1;
+                if (FD_MULTI_TRACK(fdctrl->data_state)) {
+                    if (cur_drv->head == 0 &&
+                        (cur_drv->flags & FDISK_DBL_SIDES) != 0) {
                         cur_drv->head = 1;
                     } else {
                         cur_drv->head = 0;
-			cur_drv->track++;
-			if ((cur_drv->flags & FDISK_DBL_SIDES) == 0)
-			    break;
+                        cur_drv->track++;
+                        if ((cur_drv->flags & FDISK_DBL_SIDES) == 0)
+                            break;
                     }
                 } else {
                     cur_drv->track++;
                     break;
                 }
-		FLOPPY_DPRINTF("seek to next track (%d %02x %02x => %d)\n",
-			       cur_drv->head, cur_drv->track,
-			       cur_drv->sect, fd_sector(cur_drv));
+                FLOPPY_DPRINTF("seek to next track (%d %02x %02x => %d)\n",
+                               cur_drv->head, cur_drv->track,
+                               cur_drv->sect, fd_sector(cur_drv));
             } else {
                 cur_drv->sect++;
             }
         }
     }
-end_transfer:
+ end_transfer:
     len = fdctrl->data_pos - start_pos;
     FLOPPY_DPRINTF("end transfer %d %d %d\n",
-		   fdctrl->data_pos, len, fdctrl->data_len);
+                   fdctrl->data_pos, len, fdctrl->data_len);
     if (fdctrl->data_dir == FD_DIR_SCANE ||
         fdctrl->data_dir == FD_DIR_SCANL ||
         fdctrl->data_dir == FD_DIR_SCANH)
@@ -1174,7 +1184,7 @@
     fdctrl->data_len -= len;
     //    if (fdctrl->data_len == 0)
     fdctrl_stop_transfer(fdctrl, status0, status1, status2);
-transfer_error:
+ transfer_error:
 
     return len;
 }
@@ -1199,8 +1209,7 @@
             len = fdctrl->data_len - fdctrl->data_pos;
             if (len > FD_SECTOR_LEN)
                 len = FD_SECTOR_LEN;
-            bdrv_read(cur_drv->bs, fd_sector(cur_drv),
-                      fdctrl->fifo, len);
+            bdrv_read(cur_drv->bs, fd_sector(cur_drv), fdctrl->fifo, 1);
         }
     }
     retval = fdctrl->fifo[pos];
@@ -1271,18 +1280,18 @@
         FLOPPY_ERROR("formatting sector %d\n", fd_sector(cur_drv));
         fdctrl_stop_transfer(fdctrl, 0x60, 0x00, 0x00);
     } else {
-	if (cur_drv->sect == cur_drv->last_sect) {
-	    fdctrl->data_state &= ~FD_STATE_FORMAT;
-	    /* Last sector done */
-	    if (FD_DID_SEEK(fdctrl->data_state))
-		fdctrl_stop_transfer(fdctrl, 0x20, 0x00, 0x00);
-	    else
-		fdctrl_stop_transfer(fdctrl, 0x00, 0x00, 0x00);
-	} else {
-	    /* More to do */
-	    fdctrl->data_pos = 0;
-	    fdctrl->data_len = 4;
-	}
+        if (cur_drv->sect == cur_drv->last_sect) {
+            fdctrl->data_state &= ~FD_STATE_FORMAT;
+            /* Last sector done */
+            if (FD_DID_SEEK(fdctrl->data_state))
+                fdctrl_stop_transfer(fdctrl, 0x20, 0x00, 0x00);
+            else
+                fdctrl_stop_transfer(fdctrl, 0x00, 0x00, 0x00);
+        } else {
+            /* More to do */
+            fdctrl->data_pos = 0;
+            fdctrl->data_len = 4;
+        }
     }
 }
 
@@ -1307,8 +1316,7 @@
         fdctrl->fifo[fdctrl->data_pos++] = value;
         if (fdctrl->data_pos % FD_SECTOR_LEN == (FD_SECTOR_LEN - 1) ||
             fdctrl->data_pos == fdctrl->data_len) {
-            bdrv_write(cur_drv->bs, fd_sector(cur_drv),
-                       fdctrl->fifo, FD_SECTOR_LEN);
+            bdrv_write(cur_drv->bs, fd_sector(cur_drv), fdctrl->fifo, 1);
         }
         /* Switch from transfer mode to status mode
          * then from status mode to command mode
@@ -1411,8 +1419,8 @@
 #endif
             fdctrl->fifo[1] = cur_drv->track;
             fdctrl_set_fifo(fdctrl, 2, 0);
-	    fdctrl_reset_irq(fdctrl);
-	    fdctrl->int_status = 0xC0;
+            fdctrl_reset_irq(fdctrl);
+            fdctrl->int_status = 0xC0;
             return;
         case 0x0E:
             /* DUMPREG */
@@ -1427,7 +1435,7 @@
             fdctrl->fifo[5] = (fdctrl->timer1 << 1) | fdctrl->dma_en;
             fdctrl->fifo[6] = cur_drv->last_sect;
             fdctrl->fifo[7] = (fdctrl->lock << 7) |
-                    (cur_drv->perpendicular << 2);
+                (cur_drv->perpendicular << 2);
             fdctrl->fifo[8] = fdctrl->config;
             fdctrl->fifo[9] = fdctrl->precomp_trk;
             fdctrl_set_fifo(fdctrl, 10, 0);
@@ -1495,7 +1503,7 @@
             fdctrl->fifo[7] = fdctrl->timer1;
             fdctrl->fifo[8] = cur_drv->last_sect;
             fdctrl->fifo[9] = (fdctrl->lock << 7) |
-                    (cur_drv->perpendicular << 2);
+                (cur_drv->perpendicular << 2);
             fdctrl->fifo[10] = fdctrl->config;
             fdctrl->fifo[11] = fdctrl->precomp_trk;
             fdctrl->fifo[12] = fdctrl->pwrd;
@@ -1572,25 +1580,25 @@
             return;
         }
     }
-enqueue:
+ enqueue:
     FLOPPY_DPRINTF("%s: %02x\n", __func__, value);
     fdctrl->fifo[fdctrl->data_pos] = value;
     if (++fdctrl->data_pos == fdctrl->data_len) {
         /* We now have all parameters
          * and will be able to treat the command
          */
-	if (fdctrl->data_state & FD_STATE_FORMAT) {
-	    fdctrl_format_sector(fdctrl);
-	    return;
-	}
+        if (fdctrl->data_state & FD_STATE_FORMAT) {
+            fdctrl_format_sector(fdctrl);
+            return;
+        }
         switch (fdctrl->fifo[0] & 0x1F) {
         case 0x06:
-        {
-            /* READ variants */
-            FLOPPY_DPRINTF("treat READ command\n");
-            fdctrl_start_transfer(fdctrl, FD_DIR_READ);
-            return;
-        }
+            {
+                /* READ variants */
+                FLOPPY_DPRINTF("treat READ command\n");
+                fdctrl_start_transfer(fdctrl, FD_DIR_READ);
+                return;
+            }
         case 0x0C:
             /* READ_DELETED variants */
 //            FLOPPY_DPRINTF("treat READ_DELETED command\n");
@@ -1645,7 +1653,7 @@
             FLOPPY_DPRINTF("treat SPECIFY command\n");
             fdctrl->timer0 = (fdctrl->fifo[1] >> 4) & 0xF;
             fdctrl->timer1 = fdctrl->fifo[2] >> 1;
-	    fdctrl->dma_en = 1 - (fdctrl->fifo[2] & 1) ;
+            fdctrl->dma_en = 1 - (fdctrl->fifo[2] & 1) ;
             /* No result back */
             fdctrl_reset_fifo(fdctrl);
             break;
@@ -1653,7 +1661,7 @@
             /* SENSE_DRIVE_STATUS */
             FLOPPY_DPRINTF("treat SENSE_DRIVE_STATUS command\n");
             fdctrl->cur_drv = fdctrl->fifo[1] & 1;
-	    cur_drv = get_cur_drv(fdctrl);
+            cur_drv = get_cur_drv(fdctrl);
             cur_drv->head = (fdctrl->fifo[1] >> 2) & 1;
             /* 1 Byte status back */
             fdctrl->fifo[0] = (cur_drv->ro << 6) |
@@ -1667,23 +1675,23 @@
             /* RECALIBRATE */
             FLOPPY_DPRINTF("treat RECALIBRATE command\n");
             fdctrl->cur_drv = fdctrl->fifo[1] & 1;
-	    cur_drv = get_cur_drv(fdctrl);
+            cur_drv = get_cur_drv(fdctrl);
             fd_recalibrate(cur_drv);
-	    fdctrl_reset_fifo(fdctrl);
+            fdctrl_reset_fifo(fdctrl);
             /* Raise Interrupt */
-	    fdctrl_raise_irq(fdctrl, 0x20);
+            fdctrl_raise_irq(fdctrl, 0x20);
             break;
         case 0x0F:
             /* SEEK */
             FLOPPY_DPRINTF("treat SEEK command\n");
             fdctrl->cur_drv = fdctrl->fifo[1] & 1;
-	    cur_drv = get_cur_drv(fdctrl);
-	    fd_start(cur_drv);
+            cur_drv = get_cur_drv(fdctrl);
+            fd_start(cur_drv);
             if (fdctrl->fifo[2] <= cur_drv->track)
                 cur_drv->dir = 1;
             else
                 cur_drv->dir = 0;
-	    fdctrl_reset_fifo(fdctrl);
+            fdctrl_reset_fifo(fdctrl);
             if (fdctrl->fifo[2] > cur_drv->max_track) {
                 fdctrl_raise_irq(fdctrl, 0x60);
             } else {
@@ -1728,7 +1736,7 @@
             fdctrl_start_transfer(fdctrl, FD_DIR_READ);
             break;
         case 0x4A:
-                /* READ_ID */
+            /* READ_ID */
             FLOPPY_DPRINTF("treat READ_ID command\n");
             /* XXX: should set main status register to busy */
             cur_drv->head = (fdctrl->fifo[1] >> 2) & 1;
@@ -1754,30 +1762,30 @@
             break;
         case 0x4D:
             /* FORMAT_TRACK */
-	    FLOPPY_DPRINTF("treat FORMAT_TRACK command\n");
-	    fdctrl->cur_drv = fdctrl->fifo[1] & 1;
-	    cur_drv = get_cur_drv(fdctrl);
-	    fdctrl->data_state |= FD_STATE_FORMAT;
-	    if (fdctrl->fifo[0] & 0x80)
-		fdctrl->data_state |= FD_STATE_MULTI;
-	    else
-		fdctrl->data_state &= ~FD_STATE_MULTI;
-	    fdctrl->data_state &= ~FD_STATE_SEEK;
-	    cur_drv->bps =
-		fdctrl->fifo[2] > 7 ? 16384 : 128 << fdctrl->fifo[2];
+            FLOPPY_DPRINTF("treat FORMAT_TRACK command\n");
+            fdctrl->cur_drv = fdctrl->fifo[1] & 1;
+            cur_drv = get_cur_drv(fdctrl);
+            fdctrl->data_state |= FD_STATE_FORMAT;
+            if (fdctrl->fifo[0] & 0x80)
+                fdctrl->data_state |= FD_STATE_MULTI;
+            else
+                fdctrl->data_state &= ~FD_STATE_MULTI;
+            fdctrl->data_state &= ~FD_STATE_SEEK;
+            cur_drv->bps =
+                fdctrl->fifo[2] > 7 ? 16384 : 128 << fdctrl->fifo[2];
 #if 0
-	    cur_drv->last_sect =
-		cur_drv->flags & FDISK_DBL_SIDES ? fdctrl->fifo[3] :
-		fdctrl->fifo[3] / 2;
+            cur_drv->last_sect =
+                cur_drv->flags & FDISK_DBL_SIDES ? fdctrl->fifo[3] :
+                fdctrl->fifo[3] / 2;
 #else
-	    cur_drv->last_sect = fdctrl->fifo[3];
+            cur_drv->last_sect = fdctrl->fifo[3];
 #endif
-	    /* TODO: implement format using DMA expected by the Bochs BIOS
-	     * and Linux fdformat (read 3 bytes per sector via DMA and fill
-	     * the sector with the specified fill byte
-	     */
-	    fdctrl->data_state &= ~FD_STATE_FORMAT;
-	    fdctrl_stop_transfer(fdctrl, 0x00, 0x00, 0x00);
+            /* TODO: implement format using DMA expected by the Bochs BIOS
+             * and Linux fdformat (read 3 bytes per sector via DMA and fill
+             * the sector with the specified fill byte
+             */
+            fdctrl->data_state &= ~FD_STATE_FORMAT;
+            fdctrl_stop_transfer(fdctrl, 0x00, 0x00, 0x00);
             break;
         case 0x8E:
             /* DRIVE_SPECIFICATION_COMMAND */
@@ -1803,16 +1811,16 @@
             /* RELATIVE_SEEK_OUT */
             FLOPPY_DPRINTF("treat RELATIVE_SEEK_OUT command\n");
             fdctrl->cur_drv = fdctrl->fifo[1] & 1;
-	    cur_drv = get_cur_drv(fdctrl);
-	    fd_start(cur_drv);
-                cur_drv->dir = 0;
+            cur_drv = get_cur_drv(fdctrl);
+            fd_start(cur_drv);
+            cur_drv->dir = 0;
             if (fdctrl->fifo[2] + cur_drv->track >= cur_drv->max_track) {
-		cur_drv->track = cur_drv->max_track - 1;
+                cur_drv->track = cur_drv->max_track - 1;
             } else {
                 cur_drv->track += fdctrl->fifo[2];
             }
-	    fdctrl_reset_fifo(fdctrl);
-	    fdctrl_raise_irq(fdctrl, 0x20);
+            fdctrl_reset_fifo(fdctrl);
+            fdctrl_raise_irq(fdctrl, 0x20);
             break;
         case 0xCD:
             /* FORMAT_AND_WRITE */
@@ -1821,20 +1829,20 @@
             fdctrl_unimplemented(fdctrl);
             break;
         case 0xCF:
-                /* RELATIVE_SEEK_IN */
+            /* RELATIVE_SEEK_IN */
             FLOPPY_DPRINTF("treat RELATIVE_SEEK_IN command\n");
             fdctrl->cur_drv = fdctrl->fifo[1] & 1;
-	    cur_drv = get_cur_drv(fdctrl);
-	    fd_start(cur_drv);
-                cur_drv->dir = 1;
+            cur_drv = get_cur_drv(fdctrl);
+            fd_start(cur_drv);
+            cur_drv->dir = 1;
             if (fdctrl->fifo[2] > cur_drv->track) {
-		cur_drv->track = 0;
+                cur_drv->track = 0;
             } else {
                 cur_drv->track -= fdctrl->fifo[2];
             }
-	    fdctrl_reset_fifo(fdctrl);
-	    /* Raise Interrupt */
-	    fdctrl_raise_irq(fdctrl, 0x20);
+            fdctrl_reset_fifo(fdctrl);
+            /* Raise Interrupt */
+            fdctrl_raise_irq(fdctrl, 0x20);
             break;
         }
     }
@@ -1844,6 +1852,7 @@
 {
     fdctrl_t *fdctrl = opaque;
     fdrive_t *cur_drv = get_cur_drv(fdctrl);
+
     /* Pretend we are spinning.
      * This is needed for Coherent, which uses READ ID to check for
      * sector interleaving.

Modified: trunk/src/host/qemu-neo1973/hw/grackle_pci.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/grackle_pci.c	2007-11-09 16:32:22 UTC (rev 3386)
+++ trunk/src/host/qemu-neo1973/hw/grackle_pci.c	2007-11-09 17:12:19 UTC (rev 3387)
@@ -115,22 +115,6 @@
     d->config[0x0b] = 0x06; // class_base = PCI_bridge
     d->config[0x0e] = 0x00; // header_type
 
-    d->config[0x18] = 0x00;  // primary_bus
-    d->config[0x19] = 0x01;  // secondary_bus
-    d->config[0x1a] = 0x00;  // subordinate_bus
-    d->config[0x1c] = 0x00;
-    d->config[0x1d] = 0x00;
-
-    d->config[0x20] = 0x00; // memory_base
-    d->config[0x21] = 0x00;
-    d->config[0x22] = 0x01; // memory_limit
-    d->config[0x23] = 0x00;
-
-    d->config[0x24] = 0x00; // prefetchable_memory_base
-    d->config[0x25] = 0x00;
-    d->config[0x26] = 0x00; // prefetchable_memory_limit
-    d->config[0x27] = 0x00;
-
 #if 0
     /* PCI2PCI bridge same values as PearPC - check this */
     d->config[0x00] = 0x11; // vendor_id

Modified: trunk/src/host/qemu-neo1973/hw/i2c.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/i2c.c	2007-11-09 16:32:22 UTC (rev 3386)
+++ trunk/src/host/qemu-neo1973/hw/i2c.c	2007-11-09 17:12:19 UTC (rev 3387)
@@ -51,8 +51,7 @@
     return bus->current_dev != NULL;
 }
 
-/* Returns nonzero if the bus is already busy, or is the address is not
-   valid.  */
+/* Returns non-zero if the address is not valid.  */
 /* TODO: Make this handle multiple masters.  */
 int i2c_start_transfer(i2c_bus *bus, int address, int recv)
 {

Modified: trunk/src/host/qemu-neo1973/hw/ide.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/ide.c	2007-11-09 16:32:22 UTC (rev 3386)
+++ trunk/src/host/qemu-neo1973/hw/ide.c	2007-11-09 17:12:19 UTC (rev 3387)
@@ -358,7 +358,7 @@
     uint8_t *data_ptr;
     uint8_t *data_end;
     uint8_t io_buffer[MAX_MULT_SECTORS*512 + 4];
-    QEMUTimer *sector_write_timer; /* only used for win2k instal hack */
+    QEMUTimer *sector_write_timer; /* only used for win2k install hack */
     uint32_t irq_count; /* counts IRQs when using win2k install hack */
     /* CF-ATA extended error */
     uint8_t ext_error;
@@ -865,45 +865,11 @@
     ide_set_irq(s);
 }
 
-static void ide_sector_write_aio_cb(void *opaque, int ret)
-{
-    BMDMAState *bm = opaque;
-    IDEState *s = bm->ide_if;
-
-#ifdef TARGET_I386
-    if (win2k_install_hack && ((++s->irq_count % 16) == 0)) {
-	/* It seems there is a bug in the Windows 2000 installer HDD
-	   IDE driver which fills the disk with empty logs when the
-	   IDE write IRQ comes too early. This hack tries to correct
-	   that at the expense of slower write performances. Use this
-	   option _only_ to install Windows 2000. You must disable it
-	   for normal use. */
-	qemu_mod_timer(s->sector_write_timer,
-		       qemu_get_clock(vm_clock) + (ticks_per_sec / 1000));
-    } else
-#endif
-    {
-	ide_set_irq(s);
-    }
-    bm->aiocb = NULL;
-}
-
 static void ide_sector_write(IDEState *s)
 {
-    BMDMAState *bm;
     int64_t sector_num;
-    int n, n1;
+    int ret, n, n1;
 
-    s->io_buffer_index = 0;
-    s->io_buffer_size = 0;
-    bm = s->bmdma;
-    if(bm == NULL) {
-	bm = qemu_mallocz(sizeof(BMDMAState));
-	s->bmdma = bm;
-    }
-    bm->ide_if = s;
-    bm->dma_cb = ide_sector_write_aio_cb;
-
     s->status = READY_STAT | SEEK_STAT;
     sector_num = ide_get_sector(s);
 #if defined(DEBUG_IDE)
@@ -912,6 +878,7 @@
     n = s->nsector;
     if (n > s->req_nb_sectors)
         n = s->req_nb_sectors;
+    ret = bdrv_write(s->bs, sector_num, s->io_buffer, n);
     s->nsector -= n;
     if (s->nsector == 0) {
         /* no more sectors to write */
@@ -924,8 +891,21 @@
     }
     ide_set_sector(s, sector_num + n);
 
-    bm->aiocb = bdrv_aio_write(s->bs, sector_num, s->io_buffer, n,
-			       ide_sector_write_aio_cb, bm);
+#ifdef TARGET_I386
+    if (win2k_install_hack && ((++s->irq_count % 16) == 0)) {
+        /* It seems there is a bug in the Windows 2000 installer HDD
+           IDE driver which fills the disk with empty logs when the
+           IDE write IRQ comes too early. This hack tries to correct
+           that at the expense of slower write performances. Use this
+           option _only_ to install Windows 2000. You must disable it
+           for normal use. */
+        qemu_mod_timer(s->sector_write_timer, 
+                       qemu_get_clock(vm_clock) + (ticks_per_sec / 1000));
+    } else 
+#endif
+    {
+        ide_set_irq(s);
+    }
 }
 
 /* XXX: handle errors */

Modified: trunk/src/host/qemu-neo1973/hw/mac_nvram.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/mac_nvram.c	2007-11-09 16:32:22 UTC (rev 3386)
+++ trunk/src/host/qemu-neo1973/hw/mac_nvram.c	2007-11-09 17:12:19 UTC (rev 3387)
@@ -26,6 +26,9 @@
 #include "ppc_mac.h"
 
 struct MacIONVRAMState {
+    target_phys_addr_t mem_base;
+    target_phys_addr_t size;
+    int mem_index;
     uint8_t data[0x2000];
 };
 
@@ -58,6 +61,8 @@
                                 target_phys_addr_t addr, uint32_t value)
 {
     MacIONVRAMState *s = opaque;
+
+    addr -= s->mem_base;
     addr = (addr >> 4) & 0x1fff;
     s->data[addr] = value;
     //    printf("macio_nvram_writeb %04x = %02x\n", addr, value);
@@ -68,6 +73,7 @@
     MacIONVRAMState *s = opaque;
     uint32_t value;
 
+    addr -= s->mem_base;
     addr = (addr >> 4) & 0x1fff;
     value = s->data[addr];
     //    printf("macio_nvram_readb %04x = %02x\n", addr, value);
@@ -87,17 +93,29 @@
     &macio_nvram_readb,
 };
 
-MacIONVRAMState *macio_nvram_init (int *mem_index)
+MacIONVRAMState *macio_nvram_init (int *mem_index, target_phys_addr_t size)
 {
     MacIONVRAMState *s;
+
     s = qemu_mallocz(sizeof(MacIONVRAMState));
     if (!s)
         return NULL;
-    *mem_index = cpu_register_io_memory(0, nvram_read, nvram_write, s);
+    s->size = size;
+    s->mem_index = cpu_register_io_memory(0, nvram_read, nvram_write, s);
+    *mem_index = s->mem_index;
 
     return s;
 }
 
+void macio_nvram_map (void *opaque, target_phys_addr_t mem_base)
+{
+    MacIONVRAMState *s;
+
+    s = opaque;
+    s->mem_base = mem_base;
+    cpu_register_physical_memory(mem_base, s->size, s->mem_index);
+}
+
 static uint8_t nvram_chksum (const uint8_t *buf, int n)
 {
     int sum, i;

Modified: trunk/src/host/qemu-neo1973/hw/macio.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/macio.c	2007-11-09 16:32:22 UTC (rev 3386)
+++ trunk/src/host/qemu-neo1973/hw/macio.c	2007-11-09 17:12:19 UTC (rev 3387)
@@ -31,7 +31,7 @@
     int pic_mem_index;
     int dbdma_mem_index;
     int cuda_mem_index;
-    int nvram_mem_index;
+    void *nvram;
     int nb_ide;
     int ide_mem_index[4];
 };
@@ -68,14 +68,12 @@
                                          macio_state->ide_mem_index[i]);
         }
     }
-    if (macio_state->nvram_mem_index >= 0) {
-        cpu_register_physical_memory(addr + 0x60000, 0x20000,
-                                     macio_state->nvram_mem_index);
-    }
+    if (macio_state->nvram != NULL)
+        macio_nvram_map(macio_state->nvram, addr + 0x60000);
 }
 
 void macio_init (PCIBus *bus, int device_id, int is_oldworld, int pic_mem_index,
-                 int dbdma_mem_index, int cuda_mem_index, int nvram_mem_index,
+                 int dbdma_mem_index, int cuda_mem_index, void *nvram,
                  int nb_ide, int *ide_mem_index)
 {
     PCIDevice *d;
@@ -90,7 +88,7 @@
     macio_state->pic_mem_index = pic_mem_index;
     macio_state->dbdma_mem_index = dbdma_mem_index;
     macio_state->cuda_mem_index = cuda_mem_index;
-    macio_state->nvram_mem_index = nvram_mem_index;
+    macio_state->nvram = nvram;
     if (nb_ide > 4)
         nb_ide = 4;
     macio_state->nb_ide = nb_ide;

Modified: trunk/src/host/qemu-neo1973/hw/mc146818rtc.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/mc146818rtc.c	2007-11-09 16:32:22 UTC (rev 3386)
+++ trunk/src/host/qemu-neo1973/hw/mc146818rtc.c	2007-11-09 17:12:19 UTC (rev 3387)
@@ -393,11 +393,16 @@
     int val;
 
     /* set the CMOS date */
-    time(&ti);
-    if (rtc_utc)
+    if (rtc_start_date == -1) {
+        time(&ti);
+        if (rtc_utc)
+            tm = gmtime(&ti);
+        else
+            tm = localtime(&ti);
+    } else {
+        ti = rtc_start_date;
         tm = gmtime(&ti);
-    else
-        tm = localtime(&ti);
+    }
     rtc_set_date(s, tm);
 
     val = to_bcd(s, (tm->tm_year / 100) + 19);

Modified: trunk/src/host/qemu-neo1973/hw/omap.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/omap.c	2007-11-09 16:32:22 UTC (rev 3386)
+++ trunk/src/host/qemu-neo1973/hw/omap.c	2007-11-09 17:12:19 UTC (rev 3387)
@@ -22,28 +22,56 @@
 #include "arm_pic.h"
 
 /* Should signal the TCMI */
+uint32_t omap_badwidth_read8(void *opaque, target_phys_addr_t addr)
+{
+    uint8_t ret;
+
+    OMAP_8B_REG(addr);
+    cpu_physical_memory_read(addr, (void *) &ret, 1);
+    return ret;
+}
+
+void omap_badwidth_write8(void *opaque, target_phys_addr_t addr,
+                uint32_t value)
+{
+    uint8_t val8 = value;
+
+    OMAP_8B_REG(addr);
+    cpu_physical_memory_write(addr, (void *) &val8, 1);
+}
+
 uint32_t omap_badwidth_read16(void *opaque, target_phys_addr_t addr)
 {
+    uint16_t ret;
+
     OMAP_16B_REG(addr);
-    return 0;
+    cpu_physical_memory_read(addr, (void *) &ret, 2);
+    return ret;
 }
 
 void omap_badwidth_write16(void *opaque, target_phys_addr_t addr,
                 uint32_t value)
 {
+    uint16_t val16 = value;
+
     OMAP_16B_REG(addr);
+    cpu_physical_memory_write(addr, (void *) &val16, 2);
 }
 
 uint32_t omap_badwidth_read32(void *opaque, target_phys_addr_t addr)
 {
+    uint32_t ret;
+
     OMAP_32B_REG(addr);
-    return 0;
+    cpu_physical_memory_read(addr, (void *) &ret, 4);
+    return ret;
 }
 
 void omap_badwidth_write32(void *opaque, target_phys_addr_t addr,
                 uint32_t value)
 {
     OMAP_32B_REG(addr);
+    cpu_physical_memory_write(addr, (void *) &value, 4);
 }
 
 /* Interrupt Handlers */
@@ -226,7 +254,7 @@
 
     switch (offset) {
     case 0x00:	/* ITR */
-        s->irqs &= value;
+        s->irqs &= value | 1;
         omap_inth_sir_update(s);
         omap_inth_update(s);
         return;
@@ -772,7 +800,7 @@
 
     case 0x0a:	/* SYS_DMA_CSSA_U_CH0 */
         s->ch[ch].addr[0] &= 0x0000ffff;
-        s->ch[ch].addr[0] |= value << 16;
+        s->ch[ch].addr[0] |= (uint32_t) value << 16;
         break;
 
     case 0x0c:	/* SYS_DMA_CDSA_L_CH0 */
@@ -782,7 +810,7 @@
 
     case 0x0e:	/* SYS_DMA_CDSA_U_CH0 */
         s->ch[ch].addr[1] &= 0x0000ffff;
-        s->ch[ch].addr[1] |= value << 16;
+        s->ch[ch].addr[1] |= (uint32_t) value << 16;
         break;
 
     case 0x10:	/* SYS_DMA_CEN_CH0 */
@@ -964,7 +992,7 @@
     struct omap_dma_s *s = (struct omap_dma_s *) opaque;
 
     if (on) {
-        s->delay = ticks_per_sec >> 5;
+        s->delay = ticks_per_sec >> 7;
         if (s->run_count)
             qemu_mod_timer(s->tm, qemu_get_clock(vm_clock) + s->delay);
     } else {
@@ -1018,37 +1046,37 @@
 }
 
 /* DMA ports */
-int omap_validate_emiff_addr(struct omap_mpu_state_s *s,
+static int omap_validate_emiff_addr(struct omap_mpu_state_s *s,
                 target_phys_addr_t addr)
 {
     return addr >= OMAP_EMIFF_BASE && addr < OMAP_EMIFF_BASE + s->sdram_size;
 }
 
-int omap_validate_emifs_addr(struct omap_mpu_state_s *s,
+static int omap_validate_emifs_addr(struct omap_mpu_state_s *s,
                 target_phys_addr_t addr)
 {
     return addr >= OMAP_EMIFS_BASE && addr < OMAP_EMIFF_BASE;
 }
 
-int omap_validate_imif_addr(struct omap_mpu_state_s *s,
+static int omap_validate_imif_addr(struct omap_mpu_state_s *s,
                 target_phys_addr_t addr)
 {
     return addr >= OMAP_IMIF_BASE && addr < OMAP_IMIF_BASE + s->sram_size;
 }
 
-int omap_validate_tipb_addr(struct omap_mpu_state_s *s,
+static int omap_validate_tipb_addr(struct omap_mpu_state_s *s,
                 target_phys_addr_t addr)
 {
     return addr >= 0xfffb0000 && addr < 0xffff0000;
 }
 
-int omap_validate_local_addr(struct omap_mpu_state_s *s,
+static int omap_validate_local_addr(struct omap_mpu_state_s *s,
                 target_phys_addr_t addr)
 {
     return addr >= OMAP_LOCALBUS_BASE && addr < OMAP_LOCALBUS_BASE + 0x1000000;
 }
 
-int omap_validate_tipb_mpui_addr(struct omap_mpu_state_s *s,
+static int omap_validate_tipb_mpui_addr(struct omap_mpu_state_s *s,
                 target_phys_addr_t addr)
 {
     return addr >= 0xe1010000 && addr < 0xe1020004;
@@ -1095,9 +1123,23 @@
 
     if (timer->enable && timer->st && timer->rate) {
         timer->val = timer->reset_val;	/* Should skip this on clk enable */
-        expires = timer->time + muldiv64(timer->val << (timer->ptv + 1),
+        expires = muldiv64(timer->val << (timer->ptv + 1),
                         ticks_per_sec, timer->rate);
-        qemu_mod_timer(timer->timer, expires);
+
+        /* If timer expiry would be sooner than in about 1 ms and
+         * auto-reload isn't set, then fire immediately.  This is a hack
+         * to make systems like PalmOS run in acceptable time.  PalmOS
+         * sets the interval to a very low value and polls the status bit
+         * in a busy loop when it wants to sleep just a couple of CPU
+         * ticks.  */
+        if (expires > (ticks_per_sec >> 10) || timer->ar)
+            qemu_mod_timer(timer->timer, timer->time + expires);
+        else {
+            timer->val = 0;
+            timer->st = 0;
+            if (timer->it_ena)
+                qemu_irq_raise(timer->irq);
+        }
     } else
         qemu_del_timer(timer->timer);
 }
@@ -1283,8 +1325,10 @@
         s->mode |= (value >> 15) & 1;
         if (s->last_wr == 0xf5) {
             if ((value & 0xff) == 0xa0) {
-                s->mode = 0;
-                omap_clk_put(s->timer.clk);
+                if (s->mode) {
+                    s->mode = 0;
+                    omap_clk_put(s->timer.clk);
+                }
             } else {
                 /* XXX: on T|E hardware somehow this has no effect,
                  * on Zire 71 it works as specified.  */
@@ -1359,7 +1403,7 @@
 static uint32_t omap_os_timer_read(void *opaque, target_phys_addr_t addr)
 {
     struct omap_32khz_timer_s *s = (struct omap_32khz_timer_s *) opaque;
-    int offset = addr - s->timer.base;
+    int offset = addr & OMAP_MPUI_REG_MASK;
 
     switch (offset) {
     case 0x00:	/* TVR */
@@ -1382,7 +1426,7 @@
                 uint32_t value)
 {
     struct omap_32khz_timer_s *s = (struct omap_32khz_timer_s *) opaque;
-    int offset = addr - s->timer.base;
+    int offset = addr & OMAP_MPUI_REG_MASK;
 
     switch (offset) {
     case 0x00:	/* TVR */
@@ -2175,23 +2219,23 @@
     uint32_t ret;
 
     switch (offset) {
-    case 0xfffecc00:	/* IMIF_PRIO */
-    case 0xfffecc04:	/* EMIFS_PRIO */
-    case 0xfffecc08:	/* EMIFF_PRIO */
-    case 0xfffecc0c:	/* EMIFS_CONFIG */
-    case 0xfffecc10:	/* EMIFS_CS0_CONFIG */
-    case 0xfffecc14:	/* EMIFS_CS1_CONFIG */
-    case 0xfffecc18:	/* EMIFS_CS2_CONFIG */
-    case 0xfffecc1c:	/* EMIFS_CS3_CONFIG */
-    case 0xfffecc24:	/* EMIFF_MRS */
-    case 0xfffecc28:	/* TIMEOUT1 */
-    case 0xfffecc2c:	/* TIMEOUT2 */
-    case 0xfffecc30:	/* TIMEOUT3 */
-    case 0xfffecc3c:	/* EMIFF_SDRAM_CONFIG_2 */
-    case 0xfffecc40:	/* EMIFS_CFG_DYN_WAIT */
+    case 0x00:	/* IMIF_PRIO */
+    case 0x04:	/* EMIFS_PRIO */
+    case 0x08:	/* EMIFF_PRIO */
+    case 0x0c:	/* EMIFS_CONFIG */
+    case 0x10:	/* EMIFS_CS0_CONFIG */
+    case 0x14:	/* EMIFS_CS1_CONFIG */
+    case 0x18:	/* EMIFS_CS2_CONFIG */
+    case 0x1c:	/* EMIFS_CS3_CONFIG */
+    case 0x24:	/* EMIFF_MRS */
+    case 0x28:	/* TIMEOUT1 */
+    case 0x2c:	/* TIMEOUT2 */
+    case 0x30:	/* TIMEOUT3 */
+    case 0x3c:	/* EMIFF_SDRAM_CONFIG_2 */
+    case 0x40:	/* EMIFS_CFG_DYN_WAIT */
         return s->tcmi_regs[offset >> 2];
 
-    case 0xfffecc20:	/* EMIFF_SDRAM_CONFIG */
+    case 0x20:	/* EMIFF_SDRAM_CONFIG */
         ret = s->tcmi_regs[offset >> 2];
         s->tcmi_regs[offset >> 2] &= ~1; /* XXX: Clear SLRF on SDRAM access */
         /* XXX: We can try using the VGA_DIRTY flag for this */
@@ -2209,23 +2253,23 @@
     int offset = addr - s->tcmi_base;
 
     switch (offset) {
-    case 0xfffecc00:	/* IMIF_PRIO */
-    case 0xfffecc04:	/* EMIFS_PRIO */
-    case 0xfffecc08:	/* EMIFF_PRIO */
-    case 0xfffecc10:	/* EMIFS_CS0_CONFIG */
-    case 0xfffecc14:	/* EMIFS_CS1_CONFIG */
-    case 0xfffecc18:	/* EMIFS_CS2_CONFIG */
-    case 0xfffecc1c:	/* EMIFS_CS3_CONFIG */
-    case 0xfffecc20:	/* EMIFF_SDRAM_CONFIG */
-    case 0xfffecc24:	/* EMIFF_MRS */
-    case 0xfffecc28:	/* TIMEOUT1 */
-    case 0xfffecc2c:	/* TIMEOUT2 */
-    case 0xfffecc30:	/* TIMEOUT3 */
-    case 0xfffecc3c:	/* EMIFF_SDRAM_CONFIG_2 */
-    case 0xfffecc40:	/* EMIFS_CFG_DYN_WAIT */
+    case 0x00:	/* IMIF_PRIO */
+    case 0x04:	/* EMIFS_PRIO */
+    case 0x08:	/* EMIFF_PRIO */
+    case 0x10:	/* EMIFS_CS0_CONFIG */
+    case 0x14:	/* EMIFS_CS1_CONFIG */
+    case 0x18:	/* EMIFS_CS2_CONFIG */
+    case 0x1c:	/* EMIFS_CS3_CONFIG */
+    case 0x20:	/* EMIFF_SDRAM_CONFIG */
+    case 0x24:	/* EMIFF_MRS */
+    case 0x28:	/* TIMEOUT1 */
+    case 0x2c:	/* TIMEOUT2 */
+    case 0x30:	/* TIMEOUT3 */
+    case 0x3c:	/* EMIFF_SDRAM_CONFIG_2 */
+    case 0x40:	/* EMIFS_CFG_DYN_WAIT */
         s->tcmi_regs[offset >> 2] = value;
         break;
-    case 0xfffecc0c:	/* EMIFS_CONFIG */
+    case 0x0c:	/* EMIFS_CONFIG */
         s->tcmi_regs[offset >> 2] = (value & 0xf) | (1 << 4);
         break;
 
@@ -2399,7 +2443,7 @@
         return s->clkm.arm_rstct2;
 
     case 0x18:	/* ARM_SYSST */
-        return (s->clkm.clocking_scheme < 11) | s->clkm.cold_start;
+        return (s->clkm.clocking_scheme << 11) | s->clkm.cold_start;
 
     case 0x1c:	/* ARM_CKOUT1 */
         return s->clkm.arm_ckout1;
@@ -2678,7 +2722,7 @@
         return s->clkm.dsp_rstct2;
 
     case 0x18:	/* DSP_SYSST */
-        return (s->clkm.clocking_scheme < 11) | s->clkm.cold_start |
+        return (s->clkm.clocking_scheme << 11) | s->clkm.cold_start |
                 (s->env->halted << 6);	/* Quite useless... */
     }
 
@@ -2754,9 +2798,9 @@
     s->clkm.clocking_scheme = 0;
     omap_clkm_ckctl_update(s, ~0, 0x3000);
     s->clkm.arm_ckctl = 0x3000;
-    omap_clkm_idlect1_update(s, s->clkm.arm_idlect1 & 0x0400, 0x0400);
+    omap_clkm_idlect1_update(s, s->clkm.arm_idlect1 ^ 0x0400, 0x0400);
     s->clkm.arm_idlect1 = 0x0400;
-    omap_clkm_idlect2_update(s, s->clkm.arm_idlect2 & 0x0100, 0x0100);
+    omap_clkm_idlect2_update(s, s->clkm.arm_idlect2 ^ 0x0100, 0x0100);
     s->clkm.arm_idlect2 = 0x0100;
     s->clkm.arm_ewupct = 0x003f;
     s->clkm.arm_rstct1 = 0x0000;
@@ -2780,8 +2824,11 @@
 
     s->clkm.mpu_base = mpu_base;
     s->clkm.dsp_base = dsp_base;
+    s->clkm.arm_idlect1 = 0x03ff;
+    s->clkm.arm_idlect2 = 0x0100;
+    s->clkm.dsp_idlect1 = 0x0002;
+    omap_clkm_reset(s);
     s->clkm.cold_start = 0x3a;
-    omap_clkm_reset(s);
 
     cpu_register_physical_memory(s->clkm.mpu_base, 0x100, iomemtype[0]);
     cpu_register_physical_memory(s->clkm.dsp_base, 0x1000, iomemtype[1]);
@@ -2852,7 +2899,7 @@
 static uint32_t omap_mpuio_read(void *opaque, target_phys_addr_t addr)
 {
     struct omap_mpuio_s *s = (struct omap_mpuio_s *) opaque;
-    int offset = addr - s->base;
+    int offset = addr & OMAP_MPUI_REG_MASK;
     uint16_t ret;
 
     switch (offset) {
@@ -2908,15 +2955,14 @@
                 uint32_t value)
 {
     struct omap_mpuio_s *s = (struct omap_mpuio_s *) opaque;
-    int offset = addr - s->base;
+    int offset = addr & OMAP_MPUI_REG_MASK;
     uint16_t diff;
     int ln;
 
     switch (offset) {
     case 0x04:	/* OUTPUT_REG */
-        diff = s->outputs ^ (value & ~s->dir);
+        diff = (s->outputs ^ value) & ~s->dir;
         s->outputs = value;
-	value &= ~s->dir;
         while ((ln = ffs(diff))) {
             ln --;
             if (s->handler[ln])
@@ -3078,6 +3124,7 @@
     uint16_t edge;
     uint16_t mask;
     uint16_t ints;
+    uint16_t pins;
 };
 
 static void omap_gpio_set(void *opaque, int line, int level)
@@ -3100,11 +3147,11 @@
 static uint32_t omap_gpio_read(void *opaque, target_phys_addr_t addr)
 {
     struct omap_gpio_s *s = (struct omap_gpio_s *) opaque;
-    int offset = addr - s->base;
+    int offset = addr & OMAP_MPUI_REG_MASK;
 
     switch (offset) {
     case 0x00:	/* DATA_INPUT */
-        return s->inputs;
+        return s->inputs & s->pins;
 
     case 0x04:	/* DATA_OUTPUT */
         return s->outputs;
@@ -3120,6 +3167,10 @@
 
     case 0x14:	/* INTERRUPT_STATUS */
         return s->ints;
+
+    case 0x18:	/* PIN_CONTROL (not in OMAP310) */
+        OMAP_BAD_REG(addr);
+        return s->pins;
     }
 
     OMAP_BAD_REG(addr);
@@ -3130,7 +3181,7 @@
                 uint32_t value)
 {
     struct omap_gpio_s *s = (struct omap_gpio_s *) opaque;
-    int offset = addr - s->base;
+    int offset = addr & OMAP_MPUI_REG_MASK;
     uint16_t diff;
     int ln;
 
@@ -3140,9 +3191,8 @@
         return;
 
     case 0x04:	/* DATA_OUTPUT */
-        diff = s->outputs ^ (value & ~s->dir);
+        diff = (s->outputs ^ value) & ~s->dir;
         s->outputs = value;
-	value &= ~s->dir;
         while ((ln = ffs(diff))) {
             ln --;
             if (s->handler[ln])
@@ -3178,6 +3228,11 @@
             qemu_irq_lower(s->irq);
         break;
 
+    case 0x18:	/* PIN_CONTROL (not in OMAP310 TRM) */
+        OMAP_BAD_REG(addr);
+        s->pins = value;
+        break;
+
     default:
         OMAP_BAD_REG(addr);
         return;
@@ -3205,6 +3260,7 @@
     s->edge = ~0;
     s->mask = ~0;
     s->ints = 0;
+    s->pins = ~0;
 }
 
 struct omap_gpio_s *omap_gpio_init(target_phys_addr_t base,
@@ -3281,7 +3337,7 @@
 static uint32_t omap_uwire_read(void *opaque, target_phys_addr_t addr)
 {
     struct omap_uwire_s *s = (struct omap_uwire_s *) opaque;
-    int offset = addr - s->base;
+    int offset = addr & OMAP_MPUI_REG_MASK;
 
     switch (offset) {
     case 0x00:	/* RDR */
@@ -3311,16 +3367,17 @@
                 uint32_t value)
 {
     struct omap_uwire_s *s = (struct omap_uwire_s *) opaque;
-    int offset = addr - s->base;
+    int offset = addr & OMAP_MPUI_REG_MASK;
 
     switch (offset) {
     case 0x00:	/* TDR */
         s->txbuf = value;				/* TD */
-        s->control |= 1 << 14;				/* CSRB */
         if ((s->setup[4] & (1 << 2)) &&			/* AUTO_TX_EN */
                         ((s->setup[4] & (1 << 3)) ||	/* CS_TOGGLE_TX_EN */
-                         (s->control & (1 << 12))))	/* CS_CMD */
+                         (s->control & (1 << 12)))) {	/* CS_CMD */
+            s->control |= 1 << 14;			/* CSRB */
             omap_uwire_transfer_start(s);
+        }
         break;
 
     case 0x04:	/* CSR */
@@ -3369,7 +3426,7 @@
 
 void omap_uwire_reset(struct omap_uwire_s *s)
 {
-    s->control= 0;
+    s->control = 0;
     s->setup[0] = 0;
     s->setup[1] = 0;
     s->setup[2] = 0;
@@ -3407,6 +3464,1067 @@
     s->chip[chipselect] = slave;
 }
 
+/* Pseudonoise Pulse-Width Light Modulator */
+void omap_pwl_update(struct omap_mpu_state_s *s)
+{
+    int output = (s->pwl.clk && s->pwl.enable) ? s->pwl.level : 0;
+
+    if (output != s->pwl.output) {
+        s->pwl.output = output;
+        printf("%s: Backlight now at %i/256\n", __FUNCTION__, output);
+    }
+}
+
+static uint32_t omap_pwl_read(void *opaque, target_phys_addr_t addr)
+{
+    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
+    int offset = addr & OMAP_MPUI_REG_MASK;
+
+    switch (offset) {
+    case 0x00:	/* PWL_LEVEL */
+        return s->pwl.level;
+    case 0x04:	/* PWL_CTRL */
+        return s->pwl.enable;
+    }
+    OMAP_BAD_REG(addr);
+    return 0;
+}
+
+static void omap_pwl_write(void *opaque, target_phys_addr_t addr,
+                uint32_t value)
+{
+    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
+    int offset = addr & OMAP_MPUI_REG_MASK;
+
+    switch (offset) {
+    case 0x00:	/* PWL_LEVEL */
+        s->pwl.level = value;
+        omap_pwl_update(s);
+        break;
+    case 0x04:	/* PWL_CTRL */
+        s->pwl.enable = value & 1;
+        omap_pwl_update(s);
+        break;
+    default:
+        OMAP_BAD_REG(addr);
+        return;
+    }
+}
+
+static CPUReadMemoryFunc *omap_pwl_readfn[] = {
+    omap_pwl_read,
+    omap_badwidth_read8,
+    omap_badwidth_read8,
+};
+
+static CPUWriteMemoryFunc *omap_pwl_writefn[] = {
+    omap_pwl_write,
+    omap_badwidth_write8,
+    omap_badwidth_write8,
+};
+
+void omap_pwl_reset(struct omap_mpu_state_s *s)
+{
+    s->pwl.output = 0;
+    s->pwl.level = 0;
+    s->pwl.enable = 0;
+    s->pwl.clk = 1;
+    omap_pwl_update(s);
+}
+
+static void omap_pwl_clk_update(void *opaque, int line, int on)
+{
+    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
+
+    s->pwl.clk = on;
+    omap_pwl_update(s);
+}
+
+static void omap_pwl_init(target_phys_addr_t base, struct omap_mpu_state_s *s,
+                omap_clk clk)
+{
+    int iomemtype;
+
+    omap_pwl_reset(s);
+
+    iomemtype = cpu_register_io_memory(0, omap_pwl_readfn,
+                    omap_pwl_writefn, s);
+    cpu_register_physical_memory(base, 0x800, iomemtype);
+
+    omap_clk_adduser(clk, qemu_allocate_irqs(omap_pwl_clk_update, s, 1)[0]);
+}
+
+/* Pulse-Width Tone module */
+static uint32_t omap_pwt_read(void *opaque, target_phys_addr_t addr)
+{
+    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
+    int offset = addr & OMAP_MPUI_REG_MASK;
+
+    switch (offset) {
+    case 0x00:	/* FRC */
+        return s->pwt.frc;
+    case 0x04:	/* VCR */
+        return s->pwt.vrc;
+    case 0x08:	/* GCR */
+        return s->pwt.gcr;
+    }
+    OMAP_BAD_REG(addr);
+    return 0;
+}
+
+static void omap_pwt_write(void *opaque, target_phys_addr_t addr,
+                uint32_t value)
+{
+    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
+    int offset = addr & OMAP_MPUI_REG_MASK;
+
+    switch (offset) {
+    case 0x00:	/* FRC */
+        s->pwt.frc = value & 0x3f;
+        break;
+    case 0x04:	/* VRC */
+        if ((value ^ s->pwt.vrc) & 1) {
+            if (value & 1)
+                printf("%s: %iHz buzz on\n", __FUNCTION__, (int)
+                                /* 1.5 MHz from a 12-MHz or 13-MHz PWT_CLK */
+                                ((omap_clk_getrate(s->pwt.clk) >> 3) /
+                                 /* Pre-multiplexer divider */
+                                 ((s->pwt.gcr & 2) ? 1 : 154) /
+                                 /* Octave multiplexer */
+                                 (2 << (value & 3)) *
+                                 /* 101/107 divider */
+                                 ((value & (1 << 2)) ? 101 : 107) *
+                                 /*  49/55 divider */
+                                 ((value & (1 << 3)) ?  49 : 55) *
+                                 /*  50/63 divider */
+                                 ((value & (1 << 4)) ?  50 : 63) *
+                                 /*  80/127 divider */
+                                 ((value & (1 << 5)) ?  80 : 127) /
+                                 (107 * 55 * 63 * 127)));
+            else
+                printf("%s: silence!\n", __FUNCTION__);
+        }
+        s->pwt.vrc = value & 0x7f;
+        break;
+    case 0x08:	/* GCR */
+        s->pwt.gcr = value & 3;
+        break;
+    default:
+        OMAP_BAD_REG(addr);
+        return;
+    }
+}
+
+static CPUReadMemoryFunc *omap_pwt_readfn[] = {
+    omap_pwt_read,
+    omap_badwidth_read8,
+    omap_badwidth_read8,
+};
+
+static CPUWriteMemoryFunc *omap_pwt_writefn[] = {
+    omap_pwt_write,
+    omap_badwidth_write8,
+    omap_badwidth_write8,
+};
+
+void omap_pwt_reset(struct omap_mpu_state_s *s)
+{
+    s->pwt.frc = 0;
+    s->pwt.vrc = 0;
+    s->pwt.gcr = 0;
+}
+
+static void omap_pwt_init(target_phys_addr_t base, struct omap_mpu_state_s *s,
+                omap_clk clk)
+{
+    int iomemtype;
+
+    s->pwt.clk = clk;
+    omap_pwt_reset(s);
+
+    iomemtype = cpu_register_io_memory(0, omap_pwt_readfn,
+                    omap_pwt_writefn, s);
+    cpu_register_physical_memory(base, 0x800, iomemtype);
+}
+
+/* Real-time Clock module */
+struct omap_rtc_s {
+    target_phys_addr_t base;
+    qemu_irq irq;
+    qemu_irq alarm;
+    QEMUTimer *clk;
+
+    uint8_t interrupts;
+    uint8_t status;
+    int16_t comp_reg;
+    int running;
+    int pm_am;
+    int auto_comp;
+    int round;
+    struct tm *(*convert)(const time_t *timep, struct tm *result);
+    struct tm alarm_tm;
+    time_t alarm_ti;
+
+    struct tm current_tm;
+    time_t ti;
+    uint64_t tick;
+};
+
+static void omap_rtc_interrupts_update(struct omap_rtc_s *s)
+{
+    qemu_set_irq(s->alarm, (s->status >> 6) & 1);
+}
+
+static void omap_rtc_alarm_update(struct omap_rtc_s *s)
+{
+    s->alarm_ti = mktime(&s->alarm_tm);
+    if (s->alarm_ti == -1)
+        printf("%s: conversion failed\n", __FUNCTION__);
+}
+
+static inline uint8_t omap_rtc_bcd(int num)
+{
+    return ((num / 10) << 4) | (num % 10);
+}
+
+static inline int omap_rtc_bin(uint8_t num)
+{
+    return (num & 15) + 10 * (num >> 4);
+}
+
+static uint32_t omap_rtc_read(void *opaque, target_phys_addr_t addr)
+{
+    struct omap_rtc_s *s = (struct omap_rtc_s *) opaque;
+    int offset = addr & OMAP_MPUI_REG_MASK;
+    uint8_t i;
+
+    switch (offset) {
+    case 0x00:	/* SECONDS_REG */
+        return omap_rtc_bcd(s->current_tm.tm_sec);
+
+    case 0x04:	/* MINUTES_REG */
+        return omap_rtc_bcd(s->current_tm.tm_min);
+
+    case 0x08:	/* HOURS_REG */
+        if (s->pm_am)
+            return ((s->current_tm.tm_hour > 11) << 7) |
+                    omap_rtc_bcd(((s->current_tm.tm_hour - 1) % 12) + 1);
+        else
+            return omap_rtc_bcd(s->current_tm.tm_hour);
+
+    case 0x0c:	/* DAYS_REG */
+        return omap_rtc_bcd(s->current_tm.tm_mday);
+
+    case 0x10:	/* MONTHS_REG */
+        return omap_rtc_bcd(s->current_tm.tm_mon + 1);
+
+    case 0x14:	/* YEARS_REG */
+        return omap_rtc_bcd(s->current_tm.tm_year % 100);
+
+    case 0x18:	/* WEEK_REG */
+        return s->current_tm.tm_wday;
+
+    case 0x20:	/* ALARM_SECONDS_REG */
+        return omap_rtc_bcd(s->alarm_tm.tm_sec);
+
+    case 0x24:	/* ALARM_MINUTES_REG */
+        return omap_rtc_bcd(s->alarm_tm.tm_min);
+
+    case 0x28:	/* ALARM_HOURS_REG */
+        if (s->pm_am)
+            return ((s->alarm_tm.tm_hour > 11) << 7) |
+                    omap_rtc_bcd(((s->alarm_tm.tm_hour - 1) % 12) + 1);
+        else
+            return omap_rtc_bcd(s->alarm_tm.tm_hour);
+
+    case 0x2c:	/* ALARM_DAYS_REG */
+        return omap_rtc_bcd(s->alarm_tm.tm_mday);
+
+    case 0x30:	/* ALARM_MONTHS_REG */
+        return omap_rtc_bcd(s->alarm_tm.tm_mon + 1);
+
+    case 0x34:	/* ALARM_YEARS_REG */
+        return omap_rtc_bcd(s->alarm_tm.tm_year % 100);
+
+    case 0x40:	/* RTC_CTRL_REG */
+        return (s->pm_am << 3) | (s->auto_comp << 2) |
+                (s->round << 1) | s->running;
+
+    case 0x44:	/* RTC_STATUS_REG */
+        i = s->status;
+        s->status &= ~0x3d;
+        return i;
+
+    case 0x48:	/* RTC_INTERRUPTS_REG */
+        return s->interrupts;
+
+    case 0x4c:	/* RTC_COMP_LSB_REG */
+        return ((uint16_t) s->comp_reg) & 0xff;
+
+    case 0x50:	/* RTC_COMP_MSB_REG */
+        return ((uint16_t) s->comp_reg) >> 8;
+    }
+
+    OMAP_BAD_REG(addr);
+    return 0;
+}
+
+static void omap_rtc_write(void *opaque, target_phys_addr_t addr,
+                uint32_t value)
+{
+    struct omap_rtc_s *s = (struct omap_rtc_s *) opaque;
+    int offset = addr & OMAP_MPUI_REG_MASK;
+    struct tm new_tm;
+    time_t ti[2];
+
+    switch (offset) {
+    case 0x00:	/* SECONDS_REG */
+#if ALMDEBUG
+        printf("RTC SEC_REG <-- %02x\n", value);
+#endif
+        s->ti -= s->current_tm.tm_sec;
+        s->ti += omap_rtc_bin(value);
+        return;
+
+    case 0x04:	/* MINUTES_REG */
+#if ALMDEBUG
+        printf("RTC MIN_REG <-- %02x\n", value);
+#endif
+        s->ti -= s->current_tm.tm_min * 60;
+        s->ti += omap_rtc_bin(value) * 60;
+        return;
+
+    case 0x08:	/* HOURS_REG */
+#if ALMDEBUG
+        printf("RTC HRS_REG <-- %02x\n", value);
+#endif
+        s->ti -= s->current_tm.tm_hour * 3600;
+        if (s->pm_am) {
+            s->ti += (omap_rtc_bin(value & 0x3f) & 12) * 3600;
+            s->ti += ((value >> 7) & 1) * 43200;
+        } else
+            s->ti += omap_rtc_bin(value & 0x3f) * 3600;
+        return;
+
+    case 0x0c:	/* DAYS_REG */
+#if ALMDEBUG
+        printf("RTC DAY_REG <-- %02x\n", value);
+#endif
+        s->ti -= s->current_tm.tm_mday * 86400;
+        s->ti += omap_rtc_bin(value) * 86400;
+        return;
+
+    case 0x10:	/* MONTHS_REG */
+#if ALMDEBUG
+        printf("RTC MTH_REG <-- %02x\n", value);
+#endif
+        memcpy(&new_tm, &s->current_tm, sizeof(new_tm));
+        new_tm.tm_mon = omap_rtc_bin(value);
+        ti[0] = mktime(&s->current_tm);
+        ti[1] = mktime(&new_tm);
+
+        if (ti[0] != -1 && ti[1] != -1) {
+            s->ti -= ti[0];
+            s->ti += ti[1];
+        } else {
+            /* A less accurate version */
+            s->ti -= s->current_tm.tm_mon * 2592000;
+            s->ti += omap_rtc_bin(value) * 2592000;
+        }
+        return;
+
+    case 0x14:	/* YEARS_REG */
+#if ALMDEBUG
+        printf("RTC YRS_REG <-- %02x\n", value);
+#endif
+        memcpy(&new_tm, &s->current_tm, sizeof(new_tm));
+        new_tm.tm_year += omap_rtc_bin(value) - (new_tm.tm_year % 100);
+        ti[0] = mktime(&s->current_tm);
+        ti[1] = mktime(&new_tm);
+
+        if (ti[0] != -1 && ti[1] != -1) {
+            s->ti -= ti[0];
+            s->ti += ti[1];
+        } else {
+            /* A less accurate version */
+            s->ti -= (s->current_tm.tm_year % 100) * 31536000;
+            s->ti += omap_rtc_bin(value) * 31536000;
+        }
+        return;
+
+    case 0x18:	/* WEEK_REG */
+        return;	/* Ignored */
+
+    case 0x20:	/* ALARM_SECONDS_REG */
+#if ALMDEBUG
+        printf("ALM SEC_REG <-- %02x\n", value);
+#endif
+        s->alarm_tm.tm_sec = omap_rtc_bin(value);
+        omap_rtc_alarm_update(s);
+        return;
+
+    case 0x24:	/* ALARM_MINUTES_REG */
+#if ALMDEBUG
+        printf("ALM MIN_REG <-- %02x\n", value);
+#endif
+        s->alarm_tm.tm_min = omap_rtc_bin(value);
+        omap_rtc_alarm_update(s);
+        return;
+
+    case 0x28:	/* ALARM_HOURS_REG */
+#if ALMDEBUG
+        printf("ALM HRS_REG <-- %02x\n", value);
+#endif
+        if (s->pm_am)
+            s->alarm_tm.tm_hour =
+                    ((omap_rtc_bin(value & 0x3f)) % 12) +
+                    ((value >> 7) & 1) * 12;
+        else
+            s->alarm_tm.tm_hour = omap_rtc_bin(value);
+        omap_rtc_alarm_update(s);
+        return;
+
+    case 0x2c:	/* ALARM_DAYS_REG */
+#if ALMDEBUG
+        printf("ALM DAY_REG <-- %02x\n", value);
+#endif
+        s->alarm_tm.tm_mday = omap_rtc_bin(value);
+        omap_rtc_alarm_update(s);
+        return;
+
+    case 0x30:	/* ALARM_MONTHS_REG */
+#if ALMDEBUG
+        printf("ALM MON_REG <-- %02x\n", value);
+#endif
+        s->alarm_tm.tm_mon = omap_rtc_bin(value);
+        omap_rtc_alarm_update(s);
+        return;
+
+    case 0x34:	/* ALARM_YEARS_REG */
+#if ALMDEBUG
+        printf("ALM YRS_REG <-- %02x\n", value);
+#endif
+        s->alarm_tm.tm_year = omap_rtc_bin(value);
+        omap_rtc_alarm_update(s);
+        return;
+
+    case 0x40:	/* RTC_CTRL_REG */
+#if ALMDEBUG
+        printf("RTC CONTROL <-- %02x\n", value);
+#endif
+        s->pm_am = (value >> 3) & 1;
+        s->auto_comp = (value >> 2) & 1;
+        s->round = (value >> 1) & 1;
+        s->running = value & 1;
+        s->status &= 0xfd;
+        s->status |= s->running << 1;
+        return;
+
+    case 0x44:	/* RTC_STATUS_REG */
+#if ALMDEBUG
+        printf("RTC STATUSL <-- %02x\n", value);
+#endif
+        s->status &= ~((value & 0xc0) ^ 0x80);
+        omap_rtc_interrupts_update(s);
+        return;
+
+    case 0x48:	/* RTC_INTERRUPTS_REG */
+#if ALMDEBUG
+        printf("RTC INTRS <-- %02x\n", value);
+#endif
+        s->interrupts = value;
+        return;
+
+    case 0x4c:	/* RTC_COMP_LSB_REG */
+#if ALMDEBUG
+        printf("RTC COMPLSB <-- %02x\n", value);
+#endif
+        s->comp_reg &= 0xff00;
+        s->comp_reg |= 0x00ff & value;
+        return;
+
+    case 0x50:	/* RTC_COMP_MSB_REG */
+#if ALMDEBUG
+        printf("RTC COMPMSB <-- %02x\n", value);
+#endif
+        s->comp_reg &= 0x00ff;
+        s->comp_reg |= 0xff00 & (value << 8);
+        return;
+
+    default:
+        OMAP_BAD_REG(addr);
+        return;
+    }
+}
+
+static CPUReadMemoryFunc *omap_rtc_readfn[] = {
+    omap_rtc_read,
+    omap_badwidth_read8,
+    omap_badwidth_read8,
+};
+
+static CPUWriteMemoryFunc *omap_rtc_writefn[] = {
+    omap_rtc_write,
+    omap_badwidth_write8,
+    omap_badwidth_write8,
+};
+
+static void omap_rtc_tick(void *opaque)
+{
+    struct omap_rtc_s *s = opaque;
+
+    if (s->round) {
+        /* Round to nearest full minute.  */
+        if (s->current_tm.tm_sec < 30)
+            s->ti -= s->current_tm.tm_sec;
+        else
+            s->ti += 60 - s->current_tm.tm_sec;
+
+        s->round = 0;
+    }
+
+    localtime_r(&s->ti, &s->current_tm);
+
+    if ((s->interrupts & 0x08) && s->ti == s->alarm_ti) {
+        s->status |= 0x40;
+        omap_rtc_interrupts_update(s);
+    }
+
+    if (s->interrupts & 0x04)
+        switch (s->interrupts & 3) {
+        case 0:
+            s->status |= 0x04;
+            qemu_irq_raise(s->irq);
+            break;
+        case 1:
+            if (s->current_tm.tm_sec)
+                break;
+            s->status |= 0x08;
+            qemu_irq_raise(s->irq);
+            break;
+        case 2:
+            if (s->current_tm.tm_sec || s->current_tm.tm_min)
+                break;
+            s->status |= 0x10;
+            qemu_irq_raise(s->irq);
+            break;
+        case 3:
+            if (s->current_tm.tm_sec ||
+                            s->current_tm.tm_min || s->current_tm.tm_hour)
+                break;
+            s->status |= 0x20;
+            qemu_irq_raise(s->irq);
+            break;
+        }
+
+    /* Move on */
+    if (s->running)
+        s->ti ++;
+    s->tick += 1000;
+
+    /*
+     * Every full hour add a rough approximation of the compensation
+     * register to the 32kHz Timer (which drives the RTC) value. 
+     */
+    if (s->auto_comp && !s->current_tm.tm_sec && !s->current_tm.tm_min)
+        s->tick += s->comp_reg * 1000 / 32768;
+
+    qemu_mod_timer(s->clk, s->tick);
+}
+
+void omap_rtc_reset(struct omap_rtc_s *s)
+{
+    s->interrupts = 0;
+    s->comp_reg = 0;
+    s->running = 0;
+    s->pm_am = 0;
+    s->auto_comp = 0;
+    s->round = 0;
+    s->tick = qemu_get_clock(rt_clock);
+    memset(&s->alarm_tm, 0, sizeof(s->alarm_tm));
+    s->alarm_tm.tm_mday = 0x01;
+    s->status = 1 << 7;
+    time(&s->ti);
+    s->ti = mktime(s->convert(&s->ti, &s->current_tm));
+
+    omap_rtc_alarm_update(s);
+    omap_rtc_tick(s);
+}
+
+struct omap_rtc_s *omap_rtc_init(target_phys_addr_t base,
+                qemu_irq *irq, omap_clk clk)
+{
+    int iomemtype;
+    struct omap_rtc_s *s = (struct omap_rtc_s *)
+            qemu_mallocz(sizeof(struct omap_rtc_s));
+
+    s->base = base;
+    s->irq = irq[0];
+    s->alarm = irq[1];
+    s->clk = qemu_new_timer(rt_clock, omap_rtc_tick, s);
+    s->convert = rtc_utc ? gmtime_r : localtime_r;
+
+    omap_rtc_reset(s);
+
+    iomemtype = cpu_register_io_memory(0, omap_rtc_readfn,
+                    omap_rtc_writefn, s);
+    cpu_register_physical_memory(s->base, 0x800, iomemtype);
+
+    return s;
+}
+
+/* Multi-channel Buffered Serial Port interfaces */
+struct omap_mcbsp_s {
+    target_phys_addr_t base;
+    qemu_irq txirq;
+    qemu_irq rxirq;
+    qemu_irq txdrq;
+    qemu_irq rxdrq;
+
+    uint16_t spcr[2];
+    uint16_t rcr[2];
+    uint16_t xcr[2];
+    uint16_t srgr[2];
+    uint16_t mcr[2];
+    uint16_t pcr;
+    uint16_t rcer[8];
+    uint16_t xcer[8];
+    int tx_rate;
+    int rx_rate;
+    int tx_req;
+
+    struct i2s_codec_s *codec;
+};
+
+static void omap_mcbsp_intr_update(struct omap_mcbsp_s *s)
+{
+    int irq;
+
+    switch ((s->spcr[0] >> 4) & 3) {			/* RINTM */
+    case 0:
+        irq = (s->spcr[0] >> 1) & 1;			/* RRDY */
+        break;
+    case 3:
+        irq = (s->spcr[0] >> 3) & 1;			/* RSYNCERR */
+        break;
+    default:
+        irq = 0;
+        break;
+    }
+
+    qemu_set_irq(s->rxirq, irq);
+
+    switch ((s->spcr[1] >> 4) & 3) {			/* XINTM */
+    case 0:
+        irq = (s->spcr[1] >> 1) & 1;			/* XRDY */
+        break;
+    case 3:
+        irq = (s->spcr[1] >> 3) & 1;			/* XSYNCERR */
+        break;
+    default:
+        irq = 0;
+        break;
+    }
+
+    qemu_set_irq(s->txirq, irq);
+}
+
+static void omap_mcbsp_req_update(struct omap_mcbsp_s *s)
+{
+    int prev = s->tx_req;
+
+    s->tx_req = (s->tx_rate ||
+                    (s->spcr[0] & (1 << 12))) &&	/* CLKSTP */
+            (s->spcr[1] & (1 << 6)) &&			/* GRST */
+            (s->spcr[1] & (1 << 0));			/* XRST */
+
+    if (!s->tx_req && prev) {
+        s->spcr[1] &= ~(1 << 1);			/* XRDY */
+        qemu_irq_lower(s->txdrq);
+        omap_mcbsp_intr_update(s);
+
+        if (s->codec)
+            s->codec->tx_swallow(s->codec->opaque);
+    } else if (s->codec && s->tx_req && !prev) {
+        s->spcr[1] |= 1 << 1;				/* XRDY */
+        qemu_irq_raise(s->txdrq);
+        omap_mcbsp_intr_update(s);
+    }
+}
+
+static void omap_mcbsp_rate_update(struct omap_mcbsp_s *s)
+{
+    int rx_clk = 0, tx_clk = 0;
+    int cpu_rate = 1500000;	/* XXX */
+    if (!s->codec)
+        return;
+
+    if (s->spcr[1] & (1 << 6)) {			/* GRST */
+        if (s->spcr[0] & (1 << 0))			/* RRST */
+            if ((s->srgr[1] & (1 << 13)) &&		/* CLKSM */
+                            (s->pcr & (1 << 8)))	/* CLKRM */
+                if (~s->pcr & (1 << 7))			/* SCLKME */
+                    rx_clk = cpu_rate /
+                            ((s->srgr[0] & 0xff) + 1);	/* CLKGDV */
+        if (s->spcr[1] & (1 << 0))			/* XRST */
+            if ((s->srgr[1] & (1 << 13)) &&		/* CLKSM */
+                            (s->pcr & (1 << 9)))	/* CLKXM */
+                if (~s->pcr & (1 << 7))			/* SCLKME */
+                    tx_clk = cpu_rate /
+                            ((s->srgr[0] & 0xff) + 1);	/* CLKGDV */
+    }
+
+    s->codec->set_rate(s->codec->opaque, rx_clk, tx_clk);
+}
+
+static void omap_mcbsp_rx_start(struct omap_mcbsp_s *s)
+{
+    if (!(s->spcr[0] & 1)) {				/* RRST */
+        if (s->codec)
+            s->codec->in.len = 0;
+        return;
+    }
+
+    if ((s->spcr[0] >> 1) & 1)				/* RRDY */
+        s->spcr[0] |= 1 << 2;				/* RFULL */
+    s->spcr[0] |= 1 << 1;				/* RRDY */
+    qemu_irq_raise(s->rxdrq);
+    omap_mcbsp_intr_update(s);
+}
+
+static void omap_mcbsp_rx_stop(struct omap_mcbsp_s *s)
+{
+    s->spcr[0] &= ~(1 << 1);				/* RRDY */
+    qemu_irq_lower(s->rxdrq);
+    omap_mcbsp_intr_update(s);
+}
+
+static void omap_mcbsp_tx_start(struct omap_mcbsp_s *s)
+{
+    if (s->tx_rate)
+        return;
+    s->tx_rate = 1;
+    omap_mcbsp_req_update(s);
+}
+
+static void omap_mcbsp_tx_stop(struct omap_mcbsp_s *s)
+{
+    s->tx_rate = 0;
+    omap_mcbsp_req_update(s);
+}
+
+static uint32_t omap_mcbsp_read(void *opaque, target_phys_addr_t addr)
+{
+    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
+    int offset = addr & OMAP_MPUI_REG_MASK;
+    uint16_t ret;
+
+    switch (offset) {
+    case 0x00:	/* DRR2 */
+        if (((s->rcr[0] >> 5) & 7) < 3)			/* RWDLEN1 */
+            return 0x0000;
+        /* Fall through.  */
+    case 0x02:	/* DRR1 */
+        if (!s->codec)
+            return 0x0000;
+        if (s->codec->in.len < 2) {
+            printf("%s: Rx FIFO underrun\n", __FUNCTION__);
+            omap_mcbsp_rx_stop(s);
+        } else {
+            s->codec->in.len -= 2;
+            ret = s->codec->in.fifo[s->codec->in.start ++] << 8;
+            ret |= s->codec->in.fifo[s->codec->in.start ++];
+            if (!s->codec->in.len)
+                omap_mcbsp_rx_stop(s);
+            return ret;
+        }
+        return 0x0000;
+
+    case 0x04:	/* DXR2 */
+    case 0x06:	/* DXR1 */
+        return 0x0000;
+
+    case 0x08:	/* SPCR2 */
+        return s->spcr[1];
+    case 0x0a:	/* SPCR1 */
+        return s->spcr[0];
+    case 0x0c:	/* RCR2 */
+        return s->rcr[1];
+    case 0x0e:	/* RCR1 */
+        return s->rcr[0];
+    case 0x10:	/* XCR2 */
+        return s->xcr[1];
+    case 0x12:	/* XCR1 */
+        return s->xcr[0];
+    case 0x14:	/* SRGR2 */
+        return s->srgr[1];
+    case 0x16:	/* SRGR1 */
+        return s->srgr[0];
+    case 0x18:	/* MCR2 */
+        return s->mcr[1];
+    case 0x1a:	/* MCR1 */
+        return s->mcr[0];
+    case 0x1c:	/* RCERA */
+        return s->rcer[0];
+    case 0x1e:	/* RCERB */
+        return s->rcer[1];
+    case 0x20:	/* XCERA */
+        return s->xcer[0];
+    case 0x22:	/* XCERB */
+        return s->xcer[1];
+    case 0x24:	/* PCR0 */
+        return s->pcr;
+    case 0x26:	/* RCERC */
+        return s->rcer[2];
+    case 0x28:	/* RCERD */
+        return s->rcer[3];
+    case 0x2a:	/* XCERC */
+        return s->xcer[2];
+    case 0x2c:	/* XCERD */
+        return s->xcer[3];
+    case 0x2e:	/* RCERE */
+        return s->rcer[4];
+    case 0x30:	/* RCERF */
+        return s->rcer[5];
+    case 0x32:	/* XCERE */
+        return s->xcer[4];
+    case 0x34:	/* XCERF */
+        return s->xcer[5];
+    case 0x36:	/* RCERG */
+        return s->rcer[6];
+    case 0x38:	/* RCERH */
+        return s->rcer[7];
+    case 0x3a:	/* XCERG */
+        return s->xcer[6];
+    case 0x3c:	/* XCERH */
+        return s->xcer[7];
+    }
+
+    OMAP_BAD_REG(addr);
+    return 0;
+}
+
+static void omap_mcbsp_write(void *opaque, target_phys_addr_t addr,
+                uint32_t value)
+{
+    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
+    int offset = addr & OMAP_MPUI_REG_MASK;
+
+    switch (offset) {
+    case 0x00:	/* DRR2 */
+    case 0x02:	/* DRR1 */
+        OMAP_RO_REG(addr);
+        return;
+
+    case 0x04:	/* DXR2 */
+        if (((s->xcr[0] >> 5) & 7) < 3)			/* XWDLEN1 */
+            return;
+        /* Fall through.  */
+    case 0x06:	/* DXR1 */
+        if (!s->codec)
+            return;
+        if (s->tx_req) {
+            if (s->codec->out.len > s->codec->out.size - 2) {
+                printf("%s: Tx FIFO overrun\n", __FUNCTION__);
+                omap_mcbsp_tx_stop(s);
+            } else {
+                s->codec->out.fifo[s->codec->out.len ++] = (value >> 8) & 0xff;
+                s->codec->out.fifo[s->codec->out.len ++] = (value >> 0) & 0xff;
+                if (s->codec->out.len >= s->codec->out.size)
+                    omap_mcbsp_tx_stop(s);
+            }
+        } else
+            printf("%s: Tx FIFO overrun\n", __FUNCTION__);
+        return;
+
+    case 0x08:	/* SPCR2 */
+        s->spcr[1] &= 0x0002;
+        s->spcr[1] |= 0x03f9 & value;
+        s->spcr[1] |= 0x0004 & (value << 2);		/* XEMPTY := XRST */
+        if (~value & 1) {				/* XRST */
+            s->spcr[1] &= ~6;
+            qemu_irq_lower(s->rxdrq);
+            if (s->codec)
+                s->codec->out.len = 0;
+        }
+        if (s->codec)
+            omap_mcbsp_rate_update(s);
+        omap_mcbsp_req_update(s);
+        return;
+    case 0x0a:	/* SPCR1 */
+        s->spcr[0] &= 0x0006;
+        s->spcr[0] |= 0xf8f9 & value;
+        if (value & (1 << 15))				/* DLB */
+            printf("%s: Digital Loopback mode enable attempt\n", __FUNCTION__);
+        if (~value & 1) {				/* RRST */
+            s->spcr[0] &= ~6;
+            qemu_irq_lower(s->txdrq);
+            if (s->codec)
+                s->codec->in.len = 0;
+        }
+        if (s->codec)
+            omap_mcbsp_rate_update(s);
+        omap_mcbsp_req_update(s);
+        return;
+
+    case 0x0c:	/* RCR2 */
+        s->rcr[1] = value & 0xffff;
+        return;
+    case 0x0e:	/* RCR1 */
+        s->rcr[0] = value & 0x7fe0;
+        return;
+    case 0x10:	/* XCR2 */
+        s->xcr[1] = value & 0xffff;
+        return;
+    case 0x12:	/* XCR1 */
+        s->xcr[0] = value & 0x7fe0;
+        return;
+    case 0x14:	/* SRGR2 */
+        s->srgr[1] = value & 0xffff;
+        omap_mcbsp_rate_update(s);
+        return;
+    case 0x16:	/* SRGR1 */
+        s->srgr[0] = value & 0xffff;
+        omap_mcbsp_rate_update(s);
+        return;
+    case 0x18:	/* MCR2 */
+        s->mcr[1] = value & 0x03e3;
+        if (value & 3)					/* XMCM */
+            printf("%s: Tx channel selection mode enable attempt\n",
+                            __FUNCTION__);
+        return;
+    case 0x1a:	/* MCR1 */
+        s->mcr[0] = value & 0x03e1;
+        if (value & 1)					/* RMCM */
+            printf("%s: Rx channel selection mode enable attempt\n",
+                            __FUNCTION__);
+        return;
+    case 0x1c:	/* RCERA */
+        s->rcer[0] = value & 0xffff;
+        return;
+    case 0x1e:	/* RCERB */
+        s->rcer[1] = value & 0xffff;
+        return;
+    case 0x20:	/* XCERA */
+        s->xcer[0] = value & 0xffff;
+        return;
+    case 0x22:	/* XCERB */
+        s->xcer[1] = value & 0xffff;
+        return;
+    case 0x24:	/* PCR0 */
+        s->pcr = value & 0x7faf;
+        return;
+    case 0x26:	/* RCERC */
+        s->rcer[2] = value & 0xffff;
+        return;
+    case 0x28:	/* RCERD */
+        s->rcer[3] = value & 0xffff;
+        return;
+    case 0x2a:	/* XCERC */
+        s->xcer[2] = value & 0xffff;
+        return;
+    case 0x2c:	/* XCERD */
+        s->xcer[3] = value & 0xffff;
+        return;
+    case 0x2e:	/* RCERE */
+        s->rcer[4] = value & 0xffff;
+        return;
+    case 0x30:	/* RCERF */
+        s->rcer[5] = value & 0xffff;
+        return;
+    case 0x32:	/* XCERE */
+        s->xcer[4] = value & 0xffff;
+        return;
+    case 0x34:	/* XCERF */
+        s->xcer[5] = value & 0xffff;
+        return;
+    case 0x36:	/* RCERG */
+        s->rcer[6] = value & 0xffff;
+        return;
+    case 0x38:	/* RCERH */
+        s->rcer[7] = value & 0xffff;
+        return;
+    case 0x3a:	/* XCERG */
+        s->xcer[6] = value & 0xffff;
+        return;
+    case 0x3c:	/* XCERH */
+        s->xcer[7] = value & 0xffff;
+        return;
+    }
+
+    OMAP_BAD_REG(addr);
+}
+
+static CPUReadMemoryFunc *omap_mcbsp_readfn[] = {
+    omap_badwidth_read16,
+    omap_mcbsp_read,
+    omap_badwidth_read16,
+};
+
+static CPUWriteMemoryFunc *omap_mcbsp_writefn[] = {
+    omap_badwidth_write16,
+    omap_mcbsp_write,
+    omap_badwidth_write16,
+};
+
+static void omap_mcbsp_reset(struct omap_mcbsp_s *s)
+{
+    memset(&s->spcr, 0, sizeof(s->spcr));
+    memset(&s->rcr, 0, sizeof(s->rcr));
+    memset(&s->xcr, 0, sizeof(s->xcr));
+    s->srgr[0] = 0x0001;
+    s->srgr[1] = 0x2000;
+    memset(&s->mcr, 0, sizeof(s->mcr));
+    memset(&s->pcr, 0, sizeof(s->pcr));
+    memset(&s->rcer, 0, sizeof(s->rcer));
+    memset(&s->xcer, 0, sizeof(s->xcer));
+    s->tx_req = 0;
+    s->tx_rate = 0;
+    s->rx_rate = 0;
+}
+
+struct omap_mcbsp_s *omap_mcbsp_init(target_phys_addr_t base,
+                qemu_irq *irq, qemu_irq *dma, omap_clk clk)
+{
+    int iomemtype;
+    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *)
+            qemu_mallocz(sizeof(struct omap_mcbsp_s));
+
+    s->base = base;
+    s->txirq = irq[0];
+    s->rxirq = irq[1];
+    s->txdrq = dma[0];
+    s->rxdrq = dma[1];
+    omap_mcbsp_reset(s);
+
+    iomemtype = cpu_register_io_memory(0, omap_mcbsp_readfn,
+                    omap_mcbsp_writefn, s);
+    cpu_register_physical_memory(s->base, 0x800, iomemtype);
+
+    return s;
+}
+
+void omap_mcbsp_i2s_swallow(void *opaque, int line, int level)
+{
+    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
+
+    omap_mcbsp_rx_start(s);
+}
+
+void omap_mcbsp_i2s_start(void *opaque, int line, int level)
+{
+    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
+
+    omap_mcbsp_tx_start(s);
+}
+
+void omap_mcbsp_i2s_attach(struct omap_mcbsp_s *s, struct i2s_codec_s *slave)
+{
+    s->codec = slave;
+    slave->rx_swallow = qemu_allocate_irqs(omap_mcbsp_i2s_swallow, s, 1)[0];
+    slave->tx_start = qemu_allocate_irqs(omap_mcbsp_i2s_start, s, 1)[0];
+}
+
 /* General chip reset */
 static void omap_mpu_reset(void *opaque)
 {
@@ -3437,9 +4555,57 @@
     omap_mpuio_reset(mpu->mpuio);
     omap_gpio_reset(mpu->gpio);
     omap_uwire_reset(mpu->microwire);
+    omap_pwl_reset(mpu);
+    omap_pwt_reset(mpu);
+    omap_i2c_reset(mpu->i2c);
+    omap_rtc_reset(mpu->rtc);
+    omap_mcbsp_reset(mpu->mcbsp1);
+    omap_mcbsp_reset(mpu->mcbsp2);
+    omap_mcbsp_reset(mpu->mcbsp3);
     cpu_reset(mpu->env);
 }
 
+static const struct omap_map_s {
+    target_phys_addr_t phys_dsp;
+    target_phys_addr_t phys_mpu;
+    uint32_t size;
+    const char *name;
+} omap15xx_dsp_mm[] = {
+    /* Strobe 0 */
+    { 0xe1010000, 0xfffb0000, 0x800, "UART1 BT" },		/* CS0 */
+    { 0xe1010800, 0xfffb0800, 0x800, "UART2 COM" },		/* CS1 */
+    { 0xe1011800, 0xfffb1800, 0x800, "McBSP1 audio" },		/* CS3 */
+    { 0xe1012000, 0xfffb2000, 0x800, "MCSI2 communication" },	/* CS4 */
+    { 0xe1012800, 0xfffb2800, 0x800, "MCSI1 BT u-Law" },	/* CS5 */
+    { 0xe1013000, 0xfffb3000, 0x800, "uWire" },			/* CS6 */
+    { 0xe1013800, 0xfffb3800, 0x800, "I^2C" },			/* CS7 */
+    { 0xe1014000, 0xfffb4000, 0x800, "USB W2FC" },		/* CS8 */
+    { 0xe1014800, 0xfffb4800, 0x800, "RTC" },			/* CS9 */
+    { 0xe1015000, 0xfffb5000, 0x800, "MPUIO" },			/* CS10 */
+    { 0xe1015800, 0xfffb5800, 0x800, "PWL" },			/* CS11 */
+    { 0xe1016000, 0xfffb6000, 0x800, "PWT" },			/* CS12 */
+    { 0xe1017000, 0xfffb7000, 0x800, "McBSP3" },		/* CS14 */
+    { 0xe1017800, 0xfffb7800, 0x800, "MMC" },			/* CS15 */
+    { 0xe1019000, 0xfffb9000, 0x800, "32-kHz timer" },		/* CS18 */
+    { 0xe1019800, 0xfffb9800, 0x800, "UART3" },			/* CS19 */
+    { 0xe101c800, 0xfffbc800, 0x800, "TIPB switches" },		/* CS25 */
+    /* Strobe 1 */
+    { 0xe101e000, 0xfffce000, 0x800, "GPIOs" },			/* CS28 */
+
+    { 0 }
+};
+
+static void omap_setup_dsp_mapping(const struct omap_map_s *map)
+{
+    int io;
+
+    for (; map->phys_dsp; map ++) {
+        io = cpu_get_physical_page_desc(map->phys_mpu);
+
+        cpu_register_physical_memory(map->phys_dsp, map->size, io);
+    }
+}
+
 static void omap_mpu_wakeup(void *opaque, int irq, int req)
 {
     struct omap_mpu_state_s *mpu = (struct omap_mpu_state_s *) opaque;
@@ -3553,11 +4719,46 @@
                     s->wakeup, omap_findclk(s, "clk32-kHz"));
 
     s->gpio = omap_gpio_init(0xfffce000, s->irq[0][OMAP_INT_GPIO_BANK1],
-                    omap_findclk(s, "mpuper_ck"));
+                    omap_findclk(s, "arm_gpio_ck"));
 
     s->microwire = omap_uwire_init(0xfffb3000, &s->irq[1][OMAP_INT_uWireTX],
                     s->drq[OMAP_DMA_UWIRE_TX], omap_findclk(s, "mpuper_ck"));
 
+    omap_pwl_init(0xfffb5800, s, omap_findclk(s, "armxor_ck"));
+    omap_pwt_init(0xfffb6000, s, omap_findclk(s, "armxor_ck"));
+
+    s->i2c = omap_i2c_init(0xfffb3800, s->irq[1][OMAP_INT_I2C],
+                    &s->drq[OMAP_DMA_I2C_RX], omap_findclk(s, "mpuper_ck"));
+
+    s->rtc = omap_rtc_init(0xfffb4800, &s->irq[1][OMAP_INT_RTC_TIMER],
+                    omap_findclk(s, "clk32-kHz"));
+
+    s->mcbsp1 = omap_mcbsp_init(0xfffb1800, &s->irq[1][OMAP_INT_McBSP1TX],
+                    &s->drq[OMAP_DMA_MCBSP1_TX], omap_findclk(s, "dspxor_ck"));
+    s->mcbsp2 = omap_mcbsp_init(0xfffb1000, &s->irq[0][OMAP_INT_310_McBSP2_TX],
+                    &s->drq[OMAP_DMA_MCBSP2_TX], omap_findclk(s, "mpuper_ck"));
+    s->mcbsp3 = omap_mcbsp_init(0xfffb7000, &s->irq[1][OMAP_INT_McBSP3TX],
+                    &s->drq[OMAP_DMA_MCBSP3_TX], omap_findclk(s, "dspxor_ck"));
+
+    /* Register mappings not currenlty implemented:
+     * MCSI2 Comm	fffb2000 - fffb27ff (not mapped on OMAP310)
+     * MCSI1 Bluetooth	fffb2800 - fffb2fff (not mapped on OMAP310)
+     * USB W2FC		fffb4000 - fffb47ff
+     * Camera Interface	fffb6800 - fffb6fff
+     * USB Host		fffba000 - fffba7ff
+     * FAC		fffba800 - fffbafff
+     * HDQ/1-Wire	fffbc000 - fffbc7ff
+     * TIPB switches	fffbc800 - fffbcfff
+     * LED1		fffbd000 - fffbd7ff
+     * LED2		fffbd800 - fffbdfff
+     * Mailbox		fffcf000 - fffcf7ff
+     * Local bus IF	fffec100 - fffec1ff
+     * Local bus MMU	fffec200 - fffec2ff
+     * DSP MMU		fffed200 - fffed2ff
+     */
+
+    omap_setup_dsp_mapping(omap15xx_dsp_mm);
+
     qemu_register_reset(omap_mpu_reset, s);
 
     return s;

Modified: trunk/src/host/qemu-neo1973/hw/omap.h
===================================================================
--- trunk/src/host/qemu-neo1973/hw/omap.h	2007-11-09 16:32:22 UTC (rev 3386)
+++ trunk/src/host/qemu-neo1973/hw/omap.h	2007-11-09 17:12:19 UTC (rev 3387)
@@ -475,6 +475,34 @@
 void omap_uwire_attach(struct omap_uwire_s *s,
                 struct uwire_slave_s *slave, int chipselect);
 
+struct omap_rtc_s;
+struct omap_rtc_s *omap_rtc_init(target_phys_addr_t base,
+                qemu_irq *irq, omap_clk clk);
+
+struct i2s_codec_s {
+    void *opaque;
+
+    /* The CPU can call this if it is generating the clock signal on the
+     * i2s port.  The CODEC can ignore it if it is set up as a clock
+     * master and generates its own clock.  */
+    void (*set_rate)(void *opaque, int in, int out);
+
+    void (*tx_swallow)(void *opaque);
+    qemu_irq rx_swallow;
+    qemu_irq tx_start;
+
+    struct i2s_fifo_s {
+        uint8_t *fifo;
+        int len;
+        int start;
+        int size;
+    } in, out;
+};
+struct omap_mcbsp_s;
+struct omap_mcbsp_s *omap_mcbsp_init(target_phys_addr_t base,
+                qemu_irq *irq, qemu_irq *dma, omap_clk clk);
+void omap_mcbsp_i2s_attach(struct omap_mcbsp_s *s, struct i2s_codec_s *slave);
+
 /* omap_lcdc.c */
 struct omap_lcd_panel_s;
 void omap_lcdc_reset(struct omap_lcd_panel_s *s);
@@ -489,6 +517,13 @@
 void omap_mmc_reset(struct omap_mmc_s *s);
 void omap_mmc_handlers(struct omap_mmc_s *s, qemu_irq ro, qemu_irq cover);
 
+/* omap_i2c.c */
+struct omap_i2c_s;
+struct omap_i2c_s *omap_i2c_init(target_phys_addr_t base,
+                qemu_irq irq, qemu_irq *dma, omap_clk clk);
+void omap_i2c_reset(struct omap_i2c_s *s);
+i2c_bus *omap_i2c_bus(struct omap_i2c_s *s);
+
 # define cpu_is_omap310(cpu)		(cpu->mpu_model == omap310)
 # define cpu_is_omap1510(cpu)		(cpu->mpu_model == omap1510)
 # define cpu_is_omap15xx(cpu)		\
@@ -525,6 +560,9 @@
 
     struct omap_gpio_s *gpio;
 
+    struct omap_mcbsp_s *mcbsp1;
+    struct omap_mcbsp_s *mcbsp3;
+
     /* MPU public TIPB peripherals */
     struct omap_32khz_timer_s *os_timer;
 
@@ -534,6 +572,26 @@
 
     struct omap_uwire_s *microwire;
 
+    struct {
+        uint8_t output;
+        uint8_t level;
+        uint8_t enable;
+        int clk;
+    } pwl;
+
+    struct {
+        uint8_t frc;
+        uint8_t vrc;
+        uint8_t gcr;
+        omap_clk clk;
+    } pwt;
+
+    struct omap_i2c_s *i2c;
+
+    struct omap_rtc_s *rtc;
+
+    struct omap_mcbsp_s *mcbsp2;
+
     /* MPU private TIPB peripherals */
     struct omap_intr_handler_s *ih[2];
 
@@ -615,11 +673,119 @@
 # define OMAP_RO_REG(paddr)		\
         printf("%s: Read-only register " OMAP_FMT_plx "\n",	\
                         __FUNCTION__, paddr)
-# define OMAP_16B_REG(paddr)		\
+
+# define TCMI_VERBOSE			1
+//# define MEM_VERBOSE			1
+
+# ifdef TCMI_VERBOSE
+#  define OMAP_8B_REG(paddr)		\
+        printf("%s: 8-bit register " OMAP_FMT_plx "\n",	\
+                        __FUNCTION__, paddr)
+#  define OMAP_16B_REG(paddr)		\
         printf("%s: 16-bit register " OMAP_FMT_plx "\n",	\
                         __FUNCTION__, paddr)
-# define OMAP_32B_REG(paddr)		\
+#  define OMAP_32B_REG(paddr)		\
         printf("%s: 32-bit register " OMAP_FMT_plx "\n",	\
                         __FUNCTION__, paddr)
+# else
+#  define OMAP_8B_REG(paddr)
+#  define OMAP_16B_REG(paddr)
+#  define OMAP_32B_REG(paddr)
+# endif
 
+# define OMAP_MPUI_REG_MASK		0x000007ff
+
+# ifdef MEM_VERBOSE
+struct io_fn {
+    CPUReadMemoryFunc **mem_read;
+    CPUWriteMemoryFunc **mem_write;
+    void *opaque;
+    int in;
+};
+
+static uint32_t io_readb(void *opaque, target_phys_addr_t addr)
+{
+    struct io_fn *s = opaque;
+    uint32_t ret;
+
+    s->in ++;
+    ret = s->mem_read[0](s->opaque, addr);
+    s->in --;
+    if (!s->in)
+        fprintf(stderr, "%08x ---> %02x\n", (uint32_t) addr, ret);
+    return ret;
+}
+static uint32_t io_readh(void *opaque, target_phys_addr_t addr)
+{
+    struct io_fn *s = opaque;
+    uint32_t ret;
+
+    s->in ++;
+    ret = s->mem_read[1](s->opaque, addr);
+    s->in --;
+    if (!s->in)
+        fprintf(stderr, "%08x ---> %04x\n", (uint32_t) addr, ret);
+    return ret;
+}
+static uint32_t io_readw(void *opaque, target_phys_addr_t addr)
+{
+    struct io_fn *s = opaque;
+    uint32_t ret;
+
+    s->in ++;
+    ret = s->mem_read[2](s->opaque, addr);
+    s->in --;
+    if (!s->in)
+        fprintf(stderr, "%08x ---> %08x\n", (uint32_t) addr, ret);
+    return ret;
+}
+static void io_writeb(void *opaque, target_phys_addr_t addr, uint32_t value)
+{
+    struct io_fn *s = opaque;
+
+    if (!s->in)
+        fprintf(stderr, "%08x <--- %02x\n", (uint32_t) addr, value);
+    s->in ++;
+    s->mem_write[0](s->opaque, addr, value);
+    s->in --;
+}
+static void io_writeh(void *opaque, target_phys_addr_t addr, uint32_t value)
+{
+    struct io_fn *s = opaque;
+
+    if (!s->in)
+        fprintf(stderr, "%08x <--- %04x\n", (uint32_t) addr, value);
+    s->in ++;
+    s->mem_write[1](s->opaque, addr, value);
+    s->in --;
+}
+static void io_writew(void *opaque, target_phys_addr_t addr, uint32_t value)
+{
+    struct io_fn *s = opaque;
+
+    if (!s->in)
+        fprintf(stderr, "%08x <--- %08x\n", (uint32_t) addr, value);
+    s->in ++;
+    s->mem_write[2](s->opaque, addr, value);
+    s->in --;
+}
+
+static CPUReadMemoryFunc *io_readfn[] = { io_readb, io_readh, io_readw, };
+static CPUWriteMemoryFunc *io_writefn[] = { io_writeb, io_writeh, io_writew, };
+
+inline static int debug_register_io_memory(int io_index,
+                CPUReadMemoryFunc **mem_read, CPUWriteMemoryFunc **mem_write,
+                void *opaque)
+{
+    struct io_fn *s = qemu_malloc(sizeof(struct io_fn));
+
+    s->mem_read = mem_read;
+    s->mem_write = mem_write;
+    s->opaque = opaque;
+    s->in = 0;
+    return cpu_register_io_memory(io_index, io_readfn, io_writefn, s);
+}
+#  define cpu_register_io_memory	debug_register_io_memory
+# endif
+
 #endif /* hw_omap_h */

Modified: trunk/src/host/qemu-neo1973/hw/omap1_clk.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/omap1_clk.c	2007-11-09 16:32:22 UTC (rev 3386)
+++ trunk/src/host/qemu-neo1973/hw/omap1_clk.c	2007-11-09 17:12:19 UTC (rev 3387)
@@ -307,6 +307,12 @@
     .flags	= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310,
 };
 
+static struct clk hsab_ck = {
+    .name	= "hsab_ck",
+    .parent	= &tc_ck,
+    .flags	= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310,
+};
+
 static struct clk rhea1_ck = {
     .name	= "rhea1_ck",
     .parent	= &tc_ck,
@@ -359,7 +365,7 @@
 static struct clk uart3_1510 = {
     .name	= "uart3_ck",
     /* Direct from ULPD, no real parent */
-    .parent	= &armper_ck,/* either armper_ck or dpll4 */
+    .parent	= &armper_ck,	/* either armper_ck or dpll4 */
     .rate	= 12000000,
     .flags	= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 | ALWAYS_ENABLED,
 };
@@ -395,11 +401,12 @@
     .flags	= CLOCK_IN_OMAP16XX,
 };
 
-static struct clk usb_dc_ck = {
-    .name	= "usb_dc_ck",
-    /* Direct from ULPD, no parent */
+static struct clk usb_w2fc_mclk = {
+    .name	= "usb_w2fc_mclk",
+    .alias	= "usb_w2fc_ck",
+    .parent	= &ck_48m,
     .rate	= 48000000,
-    .flags	= CLOCK_IN_OMAP16XX,
+    .flags	= CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX,
 };
 
 static struct clk mclk_1510 = {
@@ -539,6 +546,7 @@
     &api_ck,
     &lb_ck,
     &lbfree_ck,
+    &hsab_ck,
     &rhea1_ck,
     &rhea2_ck,
     &lcd_ck_16xx,
@@ -551,7 +559,6 @@
     &uart3_16xx,
     &usb_clk0,
     &usb_hhc_ck1510, &usb_hhc_ck16xx,
-    &usb_dc_ck,
     &mclk_1510,  &mclk_16xx, &mclk_310,
     &bclk_1510,  &bclk_16xx, &bclk_310,
     &mmc1_ck,
@@ -560,6 +567,7 @@
     &cam_exclk,
     &cam_lclk,
     &clk32k,
+    &usb_w2fc_mclk,
     /* Virtual clocks */
     &i2c_fck,
     &i2c_ick,
@@ -742,4 +750,8 @@
             j->multiplier = j->multiplier ?: 1;
             j ++;
         }
+    for (j = mpu->clks; count --; j ++) {
+        omap_clk_update(j);
+        omap_clk_rate_update(j);
+    }
 }

Modified: trunk/src/host/qemu-neo1973/hw/omap_mmc.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/omap_mmc.c	2007-11-09 16:32:22 UTC (rev 3386)
+++ trunk/src/host/qemu-neo1973/hw/omap_mmc.c	2007-11-09 17:12:19 UTC (rev 3387)
@@ -269,7 +269,7 @@
 {
     uint16_t i;
     struct omap_mmc_s *s = (struct omap_mmc_s *) opaque;
-    offset -= s->base;
+    offset &= OMAP_MPUI_REG_MASK;
 
     switch (offset) {
     case 0x00:	/* MMC_CMD */
@@ -351,7 +351,7 @@
 {
     int i;
     struct omap_mmc_s *s = (struct omap_mmc_s *) opaque;
-    offset -= s->base;
+    offset &= OMAP_MPUI_REG_MASK;
 
     switch (offset) {
     case 0x00:	/* MMC_CMD */

Modified: trunk/src/host/qemu-neo1973/hw/palm.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/palm.c	2007-11-09 16:32:22 UTC (rev 3386)
+++ trunk/src/host/qemu-neo1973/hw/palm.c	2007-11-09 17:12:19 UTC (rev 3387)
@@ -78,12 +78,18 @@
 
 static void palmte_microwire_setup(struct omap_mpu_state_s *cpu)
 {
-    qemu_irq p_int = omap_gpio_in_get(cpu->gpio)[PALMTE_PINTDAV_GPIO];
+    struct uwire_slave_s *tsc;
+    AudioState *audio = 0;
 
-    omap_uwire_attach(
-                    cpu->microwire,
-                    tsc2102_init(qemu_irq_invert(p_int)),
-                    0);
+#ifdef HAS_AUDIO
+    audio = AUD_init();
+#endif
+
+    tsc = tsc2102_init(omap_gpio_in_get(cpu->gpio)[PALMTE_PINTDAV_GPIO],
+                    audio);
+
+    omap_uwire_attach(cpu->microwire, tsc, 0);
+    omap_mcbsp_i2s_attach(cpu->mcbsp1, tsc210x_codec(tsc));
 }
 
 static struct {
@@ -115,6 +121,62 @@
                         !(keycode & 0x80));
 }
 
+static void palmte_onoff_gpios(void *opaque, int line, int level)
+{
+    switch (line) {
+    case 0:
+        printf("%s: current to MMC/SD card %sabled.\n",
+                        __FUNCTION__, level ? "dis" : "en");
+        break;
+    case 1:
+        printf("%s: internal speaker amplifier %s.\n",
+                        __FUNCTION__, level ? "down" : "on");
+        break;
+
+    /* These LCD & Audio output signals have not been identified yet.  */
+    case 2:
+    case 3:
+    case 4:
+        printf("%s: LCD GPIO%i %s.\n",
+                        __FUNCTION__, line - 1, level ? "high" : "low");
+        break;
+    case 5:
+    case 6:
+        printf("%s: Audio GPIO%i %s.\n",
+                        __FUNCTION__, line - 4, level ? "high" : "low");
+        break;
+    }
+}
+
+static void palmte_gpio_setup(struct omap_mpu_state_s *cpu)
+{
+    qemu_irq *misc_gpio;
+
+    omap_mmc_handlers(cpu->mmc,
+                    omap_gpio_in_get(cpu->gpio)[PALMTE_MMC_WP_GPIO],
+                    qemu_irq_invert(omap_mpuio_in_get(cpu->mpuio)
+                            [PALMTE_MMC_SWITCH_GPIO]));
+
+    misc_gpio = qemu_allocate_irqs(palmte_onoff_gpios, cpu, 7);
+    omap_gpio_out_set(cpu->gpio, PALMTE_MMC_POWER_GPIO,	misc_gpio[0]);
+    omap_gpio_out_set(cpu->gpio, PALMTE_SPEAKER_GPIO,	misc_gpio[1]);
+    omap_gpio_out_set(cpu->gpio, 11,			misc_gpio[2]);
+    omap_gpio_out_set(cpu->gpio, 12,			misc_gpio[3]);
+    omap_gpio_out_set(cpu->gpio, 13,			misc_gpio[4]);
+    omap_mpuio_out_set(cpu->mpuio, 1,			misc_gpio[5]);
+    omap_mpuio_out_set(cpu->mpuio, 3,			misc_gpio[6]);
+
+    /* Reset some inputs to initial state.  */
+    qemu_irq_lower(omap_gpio_in_get(cpu->gpio)[PALMTE_USBDETECT_GPIO]);
+    qemu_irq_lower(omap_gpio_in_get(cpu->gpio)[PALMTE_USB_OR_DC_GPIO]);
+    qemu_irq_lower(omap_gpio_in_get(cpu->gpio)[4]);
+    qemu_irq_lower(omap_gpio_in_get(cpu->gpio)[PALMTE_HEADPHONES_GPIO]);
+    qemu_irq_lower(omap_mpuio_in_get(cpu->mpuio)[PALMTE_DC_GPIO]);
+    qemu_irq_raise(omap_mpuio_in_get(cpu->mpuio)[6]);
+    qemu_irq_raise(omap_mpuio_in_get(cpu->mpuio)[7]);
+    qemu_irq_raise(omap_mpuio_in_get(cpu->mpuio)[11]);
+}
+
 static void palmte_init(int ram_size, int vga_ram_size,
                 const char *boot_device, DisplayState *ds,
                 const char **fd_filename, int snapshot,
@@ -158,10 +220,7 @@
 
     qemu_add_kbd_event_handler(palmte_button_event, cpu);
 
-    omap_mmc_handlers(cpu->mmc,
-                    omap_gpio_in_get(cpu->gpio)[PALMTE_MMC_WP_GPIO],
-                    qemu_irq_invert(omap_mpuio_in_get(cpu->mpuio)
-                            [PALMTE_MMC_SWITCH_GPIO]));
+    palmte_gpio_setup(cpu);
 
     /* Setup initial (reset) machine state */
     if (nb_option_roms) {

Modified: trunk/src/host/qemu-neo1973/hw/pc.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/pc.c	2007-11-09 16:32:22 UTC (rev 3386)
+++ trunk/src/host/qemu-neo1973/hw/pc.c	2007-11-09 17:12:19 UTC (rev 3387)
@@ -482,7 +482,9 @@
     }
 
     /* kernel protocol version */
+#if 0
     fprintf(stderr, "header magic: %#x\n", ldl_p(header+0x202));
+#endif
     if (ldl_p(header+0x202) == 0x53726448)
 	protocol = lduw_p(header+0x206);
     else
@@ -505,6 +507,7 @@
 	prot_addr    = phys_ram_base + 0x100000;
     }
 
+#if 0
     fprintf(stderr,
 	    "qemu: real_addr     = %#zx\n"
 	    "qemu: cmdline_addr  = %#zx\n"
@@ -512,6 +515,7 @@
 	    real_addr-phys_ram_base,
 	    cmdline_addr-phys_ram_base,
 	    prot_addr-phys_ram_base);
+#endif
 
     /* highest address for loading the initrd */
     if (protocol >= 0x203)
@@ -672,7 +676,7 @@
                      DisplayState *ds, const char **fd_filename, int snapshot,
                      const char *kernel_filename, const char *kernel_cmdline,
                      const char *initrd_filename,
-                     int pci_enabled)
+                     int pci_enabled, const char *cpu_model)
 {
     char buf[1024];
     int ret, linux_boot, i;
@@ -688,6 +692,18 @@
     linux_boot = (kernel_filename != NULL);
 
     /* init CPUs */
+    if (cpu_model == NULL) {
+#ifdef TARGET_X86_64
+        cpu_model = "qemu64";
+#else
+        cpu_model = "qemu32";
+#endif
+    }
+    
+    if (x86_find_cpu_by_name(cpu_model)) {
+        fprintf(stderr, "Unable to find x86 CPU definition\n");
+        exit(1);
+    }
     for(i = 0; i < smp_cpus; i++) {
         env = cpu_init();
         if (i != 0)
@@ -956,7 +972,7 @@
     pc_init1(ram_size, vga_ram_size, boot_device,
              ds, fd_filename, snapshot,
              kernel_filename, kernel_cmdline,
-             initrd_filename, 1);
+             initrd_filename, 1, cpu_model);
 }
 
 static void pc_init_isa(int ram_size, int vga_ram_size, const char *boot_device,
@@ -970,7 +986,7 @@
     pc_init1(ram_size, vga_ram_size, boot_device,
              ds, fd_filename, snapshot,
              kernel_filename, kernel_cmdline,
-             initrd_filename, 0);
+             initrd_filename, 0, cpu_model);
 }
 
 QEMUMachine pc_machine = {

Modified: trunk/src/host/qemu-neo1973/hw/ppc_chrp.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/ppc_chrp.c	2007-11-09 16:32:22 UTC (rev 3386)
+++ trunk/src/host/qemu-neo1973/hw/ppc_chrp.c	2007-11-09 17:12:19 UTC (rev 3387)
@@ -264,7 +264,7 @@
     dbdma_init(&dbdma_mem_index);
 
     macio_init(pci_bus, 0x0022, 0, pic_mem_index, dbdma_mem_index,
-               cuda_mem_index, -1, 2, ide_mem_index);
+               cuda_mem_index, NULL, 2, ide_mem_index);
 
     if (usb_enabled) {
         usb_ohci_init_pci(pci_bus, 3, -1);
@@ -274,9 +274,9 @@
         graphic_depth = 15;
 #if 0 /* XXX: this is ugly but needed for now, or OHW won't boot */
     /* The NewWorld NVRAM is not located in the MacIO device */
-    nvr = macio_nvram_init(&nvram_mem_index);
+    nvr = macio_nvram_init(&nvram_mem_index, 0x2000);
     pmac_format_nvram_partition(nvr, 0x2000);
-    cpu_register_physical_memory(0xFFF04000, 0x20000, nvram_mem_index);
+    macio_nvram_map(nvr, 0xFFF04000);
     nvram.opaque = nvr;
     nvram.read_fn = &macio_nvram_read;
     nvram.write_fn = &macio_nvram_write;

Modified: trunk/src/host/qemu-neo1973/hw/ppc_mac.h
===================================================================
--- trunk/src/host/qemu-neo1973/hw/ppc_mac.h	2007-11-09 16:32:22 UTC (rev 3386)
+++ trunk/src/host/qemu-neo1973/hw/ppc_mac.h	2007-11-09 17:12:19 UTC (rev 3387)
@@ -43,7 +43,7 @@
 
 /* MacIO */
 void macio_init (PCIBus *bus, int device_id, int is_oldworld, int pic_mem_index,
-                 int dbdma_mem_index, int cuda_mem_index, int nvram_mem_index,
+                 int dbdma_mem_index, int cuda_mem_index, void *nvram,
                  int nb_ide, int *ide_mem_index);
 
 /* NewWorld PowerMac IDE */
@@ -62,7 +62,8 @@
 /* Mac NVRAM */
 typedef struct MacIONVRAMState MacIONVRAMState;
 
-MacIONVRAMState *macio_nvram_init (int *mem_index);
+MacIONVRAMState *macio_nvram_init (int *mem_index, target_phys_addr_t size);
+void macio_nvram_map (void *opaque, target_phys_addr_t mem_base);
 void pmac_format_nvram_partition (MacIONVRAMState *nvr, int len);
 uint32_t macio_nvram_read (void *opaque, uint32_t addr);
 void macio_nvram_write (void *opaque, uint32_t addr, uint32_t val);

Modified: trunk/src/host/qemu-neo1973/hw/ppc_oldworld.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/ppc_oldworld.c	2007-11-09 16:32:22 UTC (rev 3386)
+++ trunk/src/host/qemu-neo1973/hw/ppc_oldworld.c	2007-11-09 17:12:19 UTC (rev 3387)
@@ -271,13 +271,13 @@
     adb_kbd_init(&adb_bus);
     adb_mouse_init(&adb_bus);
     
-    nvr = macio_nvram_init(&nvram_mem_index);
+    nvr = macio_nvram_init(&nvram_mem_index, 0x2000);
     pmac_format_nvram_partition(nvr, 0x2000);
 
     dbdma_init(&dbdma_mem_index);
     
     macio_init(pci_bus, 0x0017, 1, pic_mem_index, dbdma_mem_index,
-               cuda_mem_index, nvram_mem_index, 0, NULL);
+               cuda_mem_index, nvr, 0, NULL);
 
     if (usb_enabled) {
         usb_ohci_init_pci(pci_bus, 3, -1);

Modified: trunk/src/host/qemu-neo1973/hw/slavio_misc.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/slavio_misc.c	2007-11-09 16:32:22 UTC (rev 3386)
+++ trunk/src/host/qemu-neo1973/hw/slavio_misc.c	2007-11-09 17:12:19 UTC (rev 3387)
@@ -44,10 +44,13 @@
     qemu_irq irq;
     uint8_t config;
     uint8_t aux1, aux2;
-    uint8_t diag, mctrl, sysctrl;
+    uint8_t diag, mctrl;
+    uint32_t sysctrl;
 } MiscState;
 
 #define MISC_SIZE 1
+#define SYSCTRL_MAXADDR 3
+#define SYSCTRL_SIZE (SYSCTRL_MAXADDR + 1)
 
 static void slavio_misc_update_irq(void *opaque)
 {
@@ -83,7 +86,8 @@
     slavio_misc_update_irq(s);
 }
 
-static void slavio_misc_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
+static void slavio_misc_mem_writeb(void *opaque, target_phys_addr_t addr,
+                                   uint32_t val)
 {
     MiscState *s = opaque;
 
@@ -116,13 +120,6 @@
         MISC_DPRINTF("Write modem control %2.2x\n", val & 0xff);
         s->mctrl = val & 0xff;
         break;
-    case 0x1f00000:
-        MISC_DPRINTF("Write system control %2.2x\n", val & 0xff);
-        if (val & 1) {
-            s->sysctrl = 0x2;
-            qemu_system_reset_request();
-        }
-        break;
     case 0xa000000:
         MISC_DPRINTF("Write power management %2.2x\n", val & 0xff);
         cpu_interrupt(cpu_single_env, CPU_INTERRUPT_HALT);
@@ -156,10 +153,6 @@
         ret = s->mctrl;
         MISC_DPRINTF("Read modem control %2.2x\n", ret);
         break;
-    case 0x1f00000:
-        MISC_DPRINTF("Read system control %2.2x\n", ret);
-        ret = s->sysctrl;
-        break;
     case 0xa000000:
         MISC_DPRINTF("Read power management %2.2x\n", ret);
         break;
@@ -179,10 +172,62 @@
     slavio_misc_mem_writeb,
 };
 
+static uint32_t slavio_sysctrl_mem_readl(void *opaque, target_phys_addr_t addr)
+{
+    MiscState *s = opaque;
+    uint32_t ret = 0, saddr;
+
+    saddr = addr & SYSCTRL_MAXADDR;
+    switch (saddr) {
+    case 0:
+        ret = s->sysctrl;
+        break;
+    default:
+        break;
+    }
+    MISC_DPRINTF("Read system control reg 0x" TARGET_FMT_plx " = %x\n", addr,
+                 ret);
+    return ret;
+}
+
+static void slavio_sysctrl_mem_writel(void *opaque, target_phys_addr_t addr,
+                                      uint32_t val)
+{
+    MiscState *s = opaque;
+    uint32_t saddr;
+
+    saddr = addr & SYSCTRL_MAXADDR;
+    MISC_DPRINTF("Write system control reg 0x" TARGET_FMT_plx " =  %x\n", addr,
+                 val);
+    switch (saddr) {
+    case 0:
+        if (val & 1) {
+            s->sysctrl = 0x2;
+            qemu_system_reset_request();
+        }
+        break;
+    default:
+        break;
+    }
+}
+
+static CPUReadMemoryFunc *slavio_sysctrl_mem_read[3] = {
+    slavio_sysctrl_mem_readl,
+    slavio_sysctrl_mem_readl,
+    slavio_sysctrl_mem_readl,
+};
+
+static CPUWriteMemoryFunc *slavio_sysctrl_mem_write[3] = {
+    slavio_sysctrl_mem_writel,
+    slavio_sysctrl_mem_writel,
+    slavio_sysctrl_mem_writel,
+};
+
 static void slavio_misc_save(QEMUFile *f, void *opaque)
 {
     MiscState *s = opaque;
     int tmp;
+    uint8_t tmp8;
 
     tmp = 0;
     qemu_put_be32s(f, &tmp); /* ignored, was IRQ.  */
@@ -191,13 +236,15 @@
     qemu_put_8s(f, &s->aux2);
     qemu_put_8s(f, &s->diag);
     qemu_put_8s(f, &s->mctrl);
-    qemu_put_8s(f, &s->sysctrl);
+    tmp8 = s->sysctrl & 0xff;
+    qemu_put_8s(f, &tmp8);
 }
 
 static int slavio_misc_load(QEMUFile *f, void *opaque, int version_id)
 {
     MiscState *s = opaque;
     int tmp;
+    uint8_t tmp8;
 
     if (version_id != 1)
         return -EINVAL;
@@ -208,7 +255,8 @@
     qemu_get_8s(f, &s->aux2);
     qemu_get_8s(f, &s->diag);
     qemu_get_8s(f, &s->mctrl);
-    qemu_get_8s(f, &s->sysctrl);
+    qemu_get_8s(f, &tmp8);
+    s->sysctrl = (uint32_t)tmp8;
     return 0;
 }
 
@@ -222,7 +270,9 @@
     if (!s)
         return NULL;
 
-    slavio_misc_io_memory = cpu_register_io_memory(0, slavio_misc_mem_read, slavio_misc_mem_write, s);
+    /* 8 bit registers */
+    slavio_misc_io_memory = cpu_register_io_memory(0, slavio_misc_mem_read,
+                                                   slavio_misc_mem_write, s);
     // Slavio control
     cpu_register_physical_memory(base + 0x1800000, MISC_SIZE,
                                  slavio_misc_io_memory);
@@ -238,15 +288,21 @@
     // Modem control
     cpu_register_physical_memory(base + 0x1b00000, MISC_SIZE,
                                  slavio_misc_io_memory);
-    // System control
-    cpu_register_physical_memory(base + 0x1f00000, MISC_SIZE,
-                                 slavio_misc_io_memory);
     // Power management
     cpu_register_physical_memory(power_base, MISC_SIZE, slavio_misc_io_memory);
 
+    /* 32 bit registers */
+    slavio_misc_io_memory = cpu_register_io_memory(0, slavio_sysctrl_mem_read,
+                                                   slavio_sysctrl_mem_write,
+                                                   s);
+    // System control
+    cpu_register_physical_memory(base + 0x1f00000, SYSCTRL_SIZE,
+                                 slavio_misc_io_memory);
+
     s->irq = irq;
 
-    register_savevm("slavio_misc", base, 1, slavio_misc_save, slavio_misc_load, s);
+    register_savevm("slavio_misc", base, 1, slavio_misc_save, slavio_misc_load,
+                    s);
     qemu_register_reset(slavio_misc_reset, s);
     slavio_misc_reset(s);
     return s;

Modified: trunk/src/host/qemu-neo1973/hw/sun4m.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/sun4m.c	2007-11-09 16:32:22 UTC (rev 3386)
+++ trunk/src/host/qemu-neo1973/hw/sun4m.c	2007-11-09 17:12:19 UTC (rev 3387)
@@ -389,8 +389,9 @@
     // Slavio TTYB (base+0, Linux ttyS1) is the second Qemu serial device
     slavio_serial_init(hwdef->serial_base, slavio_irq[hwdef->ser_irq],
                        serial_hds[1], serial_hds[0]);
-    fdctrl_init(slavio_irq[hwdef->fd_irq], 0, 1, hwdef->fd_base, fd_table);
 
+    sun4m_fdctrl_init(slavio_irq[hwdef->fd_irq], hwdef->fd_base, fd_table);
+
     main_esp = esp_init(bs_table, hwdef->esp_base, espdma, *espdma_irq,
                         esp_reset);
 

Modified: trunk/src/host/qemu-neo1973/hw/tsc210x.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/tsc210x.c	2007-11-09 16:32:22 UTC (rev 3386)
+++ trunk/src/host/qemu-neo1973/hw/tsc210x.c	2007-11-09 17:12:19 UTC (rev 3387)
@@ -1,5 +1,5 @@
 /*
- * TI TSC2102 (touchscreen/sensors/audio controller) controller.
+ * TI TSC2102 (touchscreen/sensors/audio controller) emulator.
  *
  * Copyright (c) 2006 Andrzej Zaborowski  <balrog at zabor.org>
  *
@@ -32,7 +32,11 @@
 struct tsc210x_state_s {
     qemu_irq pint;
     QEMUTimer *timer;
+    QEMUSoundCard card;
     struct uwire_slave_s chip;
+    struct i2s_codec_s codec;
+    uint8_t in_fifo[16384];
+    uint8_t out_fifo[16384];
 
     int x, y;
     int pressure;
@@ -63,6 +67,13 @@
     uint16_t dac_power;
     int64_t powerdown;
     uint16_t filter_data[0x14];
+
+    const char *name;
+    SWVoiceIn *adc_voice[1];
+    SWVoiceOut *dac_voice[1];
+    int i2s_rx_rate;
+    int i2s_tx_rate;
+    AudioState *audio;
 };
 
 static const int resolution[4] = { 12, 8, 10, 12 };
@@ -171,9 +182,144 @@
     s->filter_data[0x12] = 0x7d83;
     s->filter_data[0x13] = 0x84ee;
 
-    qemu_set_irq(s->pint, s->irq);
+    s->i2s_tx_rate = 0;
+    s->i2s_rx_rate = 0;
+
+    qemu_set_irq(s->pint, !s->irq);
 }
 
+struct tsc210x_rate_info_s {
+    int rate;
+    int dsor;
+    int fsref;
+};
+
+/*  { rate,  dsor,  fsref } */
+static const struct tsc210x_rate_info_s tsc2101_rates[] = {
+    /* Fsref / 6.0 */
+    { 7350,	7,	1 },
+    { 8000,	7,	0 },
+    /* Fsref / 5.5 */
+    { 8018,	6,	1 },
+    { 8727,	6,	0 },
+    /* Fsref / 5.0 */
+    { 8820,	5,	1 },
+    { 9600,	5,	0 },
+    /* Fsref / 4.0 */
+    { 11025,	4,	1 },
+    { 12000,	4,	0 },
+    /* Fsref / 3.0 */
+    { 14700,	3,	1 },
+    { 16000,	3,	0 },
+    /* Fsref / 2.0 */
+    { 22050,	2,	1 },
+    { 24000,	2,	0 },
+    /* Fsref / 1.5 */
+    { 29400,	1,	1 },
+    { 32000,	1,	0 },
+    /* Fsref */
+    { 44100,	0,	1 },
+    { 48000,	0,	0 },
+
+    { 0,	0, 	0 },
+};
+
+/*  { rate,   dsor, fsref }	*/
+static const struct tsc210x_rate_info_s tsc2102_rates[] = {
+    /* Fsref / 6.0 */
+    { 7350,	63,	1 },
+    { 8000,	63,	0 },
+    /* Fsref / 6.0 */
+    { 7350,	54,	1 },
+    { 8000,	54,	0 },
+    /* Fsref / 5.0 */
+    { 8820,	45,	1 },
+    { 9600,	45,	0 },
+    /* Fsref / 4.0 */
+    { 11025,	36,	1 },
+    { 12000,	36,	0 },
+    /* Fsref / 3.0 */
+    { 14700,	27,	1 },
+    { 16000,	27,	0 },
+    /* Fsref / 2.0 */
+    { 22050,	18,	1 },
+    { 24000,	18,	0 },
+    /* Fsref / 1.5 */
+    { 29400,	9,	1 },
+    { 32000,	9,	0 },
+    /* Fsref */
+    { 44100,	0,	1 },
+    { 48000,	0,	0 },
+
+    { 0,	0, 	0 },
+};
+
+static inline void tsc210x_out_flush(struct tsc210x_state_s *s, int len)
+{
+    uint8_t *data = s->codec.out.fifo + s->codec.out.start;
+    uint8_t *end = data + len;
+
+    while (data < end)
+        data += AUD_write(s->dac_voice[0], data, end - data) ?: (end - data);
+
+    s->codec.out.len -= len;
+    if (s->codec.out.len)
+        memmove(s->codec.out.fifo, end, s->codec.out.len);
+    s->codec.out.start = 0;
+}
+
+static void tsc210x_audio_out_cb(struct tsc210x_state_s *s, int free_b)
+{
+    if (s->codec.out.len >= free_b) {
+        tsc210x_out_flush(s, free_b);
+        return;
+    }
+
+    s->codec.out.size = MIN(free_b, 16384);
+    qemu_irq_raise(s->codec.tx_start);
+}
+
+static void tsc2102_audio_set_format(struct tsc210x_state_s *s)
+{
+    int enable;
+    const struct tsc210x_rate_info_s *rate;
+    audsettings_t fmt;
+
+    if (s->dac_voice[0]) {
+        tsc210x_out_flush(s, s->codec.out.len);
+        s->codec.out.size = 0;
+        AUD_set_active_out(s->dac_voice[0], 0);
+        AUD_close_out(&s->card, s->dac_voice[0]);
+        s->dac_voice[0] = 0;
+    }
+
+    enable =
+            (~s->dac_power & (1 << 15)) &&			/* PWDNC */
+            (~s->dac_power & (1 << 10));			/* DAPWDN */
+    if (!enable)
+        return;
+
+    for (rate = tsc2102_rates; rate->rate; rate ++)
+        if (rate->dsor == (s->audio_ctrl1 & 0x3f) &&		/* DACFS */
+                        rate->fsref == ((s->audio_ctrl3 >> 13) & 1))/* REFFS */
+            break;
+    if (!rate->rate) {
+        printf("%s: unknown sampling rate configured\n", __FUNCTION__);
+        return;
+    }
+
+    /* Force our own sampling rate even in slave DAC mode */
+    fmt.endianness = 0;
+    fmt.nchannels = 2;
+    fmt.freq = rate->rate;
+    fmt.fmt = AUD_FMT_S16;
+
+    s->dac_voice[0] = AUD_open_out(&s->card, s->dac_voice[0],
+                    "tsc2102.sink", s, (void *) tsc210x_audio_out_cb, &fmt);
+    if (s->dac_voice[0])
+        AUD_set_active_out(s->dac_voice[0], 1);
+}
+
 static uint16_t tsc2102_data_register_read(struct tsc210x_state_s *s, int reg)
 {
     switch (reg) {
@@ -437,6 +583,8 @@
             fprintf(stderr, "tsc2102_audio_register_write: "
                             "wrong value written into Audio 1\n");
 #endif
+        if (s->audio)
+            tsc2102_audio_set_format(s);
         return;
 
     case 0x01:
@@ -479,6 +627,8 @@
             fprintf(stderr, "tsc2102_audio_register_write: "
                             "wrong value written into Power\n");
 #endif
+        if (s->audio)
+            tsc2102_audio_set_format(s);
         return;
 
     case 0x06:	/* Audio Control 3 */
@@ -489,6 +639,8 @@
             fprintf(stderr, "tsc2102_audio_register_write: "
                             "wrong value written into Audio 3\n");
 #endif
+        if (s->audio)
+            tsc2102_audio_set_format(s);
         return;
 
     case 0x07:	/* LCH_BASS_BOOST_N0 */
@@ -572,7 +724,7 @@
 
     if (pin_state != s->irq) {
         s->irq = pin_state;
-        qemu_set_irq(s->pint, s->irq);
+        qemu_set_irq(s->pint, !s->irq);
     }
 
     switch (s->nextfunction) {
@@ -718,6 +870,20 @@
         tsc210x_pin_update(s);
 }
 
+static void tsc210x_i2s_swallow(struct tsc210x_state_s *s)
+{
+    if (s->dac_voice[0])
+        tsc210x_out_flush(s, s->codec.out.len);
+    else
+        s->codec.out.len = 0;
+}
+
+static void tsc210x_i2s_set_rate(struct tsc210x_state_s *s, int in, int out)
+{
+    s->i2s_tx_rate = out;
+    s->i2s_rx_rate = in;
+}
+
 static void tsc210x_save(QEMUFile *f, void *opaque)
 {
     struct tsc210x_state_s *s = (struct tsc210x_state_s *) opaque;
@@ -810,14 +976,14 @@
         qemu_get_be16s(f, &s->filter_data[i]);
 
     s->busy = qemu_timer_pending(s->timer);
-    qemu_set_irq(s->pint, s->irq);
+    qemu_set_irq(s->pint, !s->irq);
 
     return 0;
 }
 
 static int tsc2102_iid = 0;
 
-struct uwire_slave_s *tsc2102_init(qemu_irq pint)
+struct uwire_slave_s *tsc2102_init(qemu_irq pint, AudioState *audio)
 {
     struct tsc210x_state_s *s;
 
@@ -830,19 +996,37 @@
     s->precision = s->nextprecision = 0;
     s->timer = qemu_new_timer(vm_clock, tsc210x_timer_tick, s);
     s->pint = pint;
+    s->name = "tsc2102";
+    s->audio = audio;
 
     s->chip.opaque = s;
     s->chip.send = (void *) tsc210x_write;
     s->chip.receive = (void *) tsc210x_read;
 
+    s->codec.opaque = s;
+    s->codec.tx_swallow = (void *) tsc210x_i2s_swallow;
+    s->codec.set_rate = (void *) tsc210x_i2s_set_rate;
+    s->codec.in.fifo = s->in_fifo;
+    s->codec.out.fifo = s->out_fifo;
+
     tsc210x_reset(s);
 
     qemu_add_mouse_event_handler(tsc210x_touchscreen_event, s, 1,
                     "QEMU TSC2102-driven Touchscreen");
 
+    if (s->audio)
+        AUD_register_card(s->audio, s->name, &s->card);
+
     qemu_register_reset((void *) tsc210x_reset, s);
-    register_savevm("tsc2102", tsc2102_iid ++, 0,
+    register_savevm(s->name, tsc2102_iid ++, 0,
                     tsc210x_save, tsc210x_load, s);
 
     return &s->chip;
 }
+
+struct i2s_codec_s *tsc210x_codec(struct uwire_slave_s *chip)
+{
+    struct tsc210x_state_s *s = (struct tsc210x_state_s *) chip->opaque;
+
+    return &s->codec;
+}

Modified: trunk/src/host/qemu-neo1973/linux-user/main.c
===================================================================
--- trunk/src/host/qemu-neo1973/linux-user/main.c	2007-11-09 16:32:22 UTC (rev 3386)
+++ trunk/src/host/qemu-neo1973/linux-user/main.c	2007-11-09 17:12:19 UTC (rev 3387)
@@ -28,11 +28,6 @@
 
 #define DEBUG_LOGFILE "/tmp/qemu.log"
 
-#ifdef __APPLE__
-#include <crt_externs.h>
-# define environ  (*_NSGetEnviron())
-#endif
-
 static const char *interp_prefix = CONFIG_QEMU_PREFIX;
 const char *qemu_uname_release = CONFIG_UNAME_RELEASE;
 
@@ -45,12 +40,20 @@
 /* for recent libc, we add these dummy symbols which are not declared
    when generating a linked object (bug in ld ?) */
 #if (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 3)) && !defined(CONFIG_STATIC)
-long __preinit_array_start[0];
-long __preinit_array_end[0];
-long __init_array_start[0];
-long __init_array_end[0];
-long __fini_array_start[0];
-long __fini_array_end[0];
+asm(".globl __preinit_array_start\n"
+    ".globl __preinit_array_end\n"
+    ".globl __init_array_start\n"
+    ".globl __init_array_end\n"
+    ".globl __fini_array_start\n"
+    ".globl __fini_array_end\n"
+    ".section \".rodata\"\n"
+    "__preinit_array_start:\n"
+    "__preinit_array_end:\n"
+    "__init_array_start:\n"
+    "__init_array_end:\n"
+    "__fini_array_start:\n"
+    "__fini_array_end:\n"
+    ".long 0\n");
 #endif
 
 /* XXX: on x86 MAP_GROWSDOWN only works if ESP <= address + 32, so
@@ -785,7 +788,7 @@
             break;
         case POWERPC_EXCP_ISI:      /* Instruction storage exception         */
             EXCP_DUMP(env, "Invalid instruction fetch: 0x\n" ADDRX "\n",
-                      env->spr[SPR_DAR]);
+                      env->spr[SPR_SRR0]);
             /* XXX: check this */
             switch (env->error_code & 0xFF000000) {
             case 0x40000000:
@@ -1852,9 +1855,6 @@
            "-drop-ld-preload  drop LD_PRELOAD for target process\n"
            "\n"
            "debug options:\n"
-#ifdef USE_CODE_COPY
-           "-no-code-copy   disable code copy acceleration\n"
-#endif
            "-d options   activate log (logfile=%s)\n"
            "-p pagesize  set the host page size to 'pagesize'\n",
            TARGET_ARCH,
@@ -1953,11 +1953,6 @@
         } else if (!strcmp(r, "drop-ld-preload")) {
             drop_ld_preload = 1;
         } else
-#ifdef USE_CODE_COPY
-        if (!strcmp(r, "no-code-copy")) {
-            code_copy_enabled = 0;
-        } else
-#endif
         {
             usage();
         }
@@ -1975,6 +1970,23 @@
     /* Scan interp_prefix dir for replacement files. */
     init_paths(interp_prefix);
 
+#if defined(TARGET_I386)
+    /* must be done before cpu_init() for x86 XXX: suppress this hack
+       by adding a new parameter to cpu_init and by suppressing
+       cpu_xxx_register() */
+    if (cpu_model == NULL) {
+#ifdef TARGET_X86_64
+        cpu_model = "qemu64";
+#else
+        cpu_model = "qemu32";
+#endif
+    }
+    if (x86_find_cpu_by_name(cpu_model)) {
+        fprintf(stderr, "Unable to find x86 CPU definition\n");
+        exit(1);
+    }
+#endif
+
     /* NOTE: we need to init the CPU at this stage to get
        qemu_host_page_size */
     env = cpu_init();
@@ -2213,7 +2225,7 @@
 
         /* Choose and initialise CPU */
         if (cpu_model == NULL)
-#if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)
+#if defined(TARGET_ABI_MIPSN32) || defined(TARGET_ABI_MIPSN64)
             cpu_model = "20Kc";
 #else
             cpu_model = "24Kf";

Modified: trunk/src/host/qemu-neo1973/linux-user/mmap.c
===================================================================
--- trunk/src/host/qemu-neo1973/linux-user/mmap.c	2007-11-09 16:32:22 UTC (rev 3386)
+++ trunk/src/host/qemu-neo1973/linux-user/mmap.c	2007-11-09 17:12:19 UTC (rev 3387)
@@ -37,7 +37,7 @@
 
 #ifdef DEBUG_MMAP
     printf("mprotect: start=0x" TARGET_FMT_lx
-	   "len=0x" TARGET_FMT_lx " prot=%c%c%c\n", start, len,
+           "len=0x" TARGET_FMT_lx " prot=%c%c%c\n", start, len,
            prot & PROT_READ ? 'r' : '-',
            prot & PROT_WRITE ? 'w' : '-',
            prot & PROT_EXEC ? 'x' : '-');
@@ -100,7 +100,7 @@
                      abi_ulong start, abi_ulong end,
                      int prot, int flags, int fd, abi_ulong offset)
 {
-    abi_ulong real_end, ret, addr;
+    abi_ulong real_end, addr;
     void *host_start;
     int prot1, prot_new;
 
@@ -116,10 +116,10 @@
 
     if (prot1 == 0) {
         /* no page was there, so we allocate one */
-        ret = (long)mmap(host_start, qemu_host_page_size, prot,
-                         flags | MAP_ANONYMOUS, -1, 0);
-        if (ret == -1)
-            return ret;
+        void *p = mmap(host_start, qemu_host_page_size, prot,
+                       flags | MAP_ANONYMOUS, -1, 0);
+        if (p == MAP_FAILED)
+            return -1;
         prot1 = prot;
     }
     prot1 &= PAGE_BITS;
@@ -168,7 +168,7 @@
 #ifdef DEBUG_MMAP
     {
         printf("mmap: start=0x" TARGET_FMT_lx
-	       " len=0x" TARGET_FMT_lx " prot=%c%c%c flags=",
+               " len=0x" TARGET_FMT_lx " prot=%c%c%c flags=",
                start, len,
                prot & PROT_READ ? 'r' : '-',
                prot & PROT_WRITE ? 'w' : '-',
@@ -230,16 +230,16 @@
              */
             abi_ulong host_end;
             unsigned long host_aligned_start;
+            void *p;
 
             host_len = HOST_PAGE_ALIGN(host_len + qemu_host_page_size
                                        - qemu_real_host_page_size);
-            host_start = (unsigned long) mmap(real_start ?
-					      g2h(real_start) : NULL,
-					      host_len, prot, flags,
-					      fd, host_offset);
-            if (host_start == -1)
+            p = mmap(real_start ? g2h(real_start) : NULL,
+                     host_len, prot, flags, fd, host_offset);
+            if (p == MAP_FAILED)
                 return -1;
 
+            host_start = (unsigned long)p;
             host_end = host_start + host_len;
 
             /* Find start and end, aligned to the targets pagesize with-in the
@@ -260,11 +260,12 @@
             goto the_end1;
         } else {
             /* if not fixed, no need to do anything */
-            host_start = (long)mmap(real_start ? g2h(real_start) : NULL,
+            void *p = mmap(real_start ? g2h(real_start) : NULL,
                                     host_len, prot, flags, fd, host_offset);
-            if (host_start == -1)
+            if (p == MAP_FAILED)
                 return -1;
             /* update start so that it points to the file position at 'offset' */
+            host_start = (unsigned long)p;
             if (!(flags & MAP_ANONYMOUS))
                 host_start += offset - host_offset;
             start = h2g(host_start);
@@ -333,14 +334,15 @@
 
     /* map the middle (easier) */
     if (real_start < real_end) {
+        void *p;
         unsigned long offset1;
-	if (flags & MAP_ANONYMOUS)
-	  offset1 = 0;
-	else
-	  offset1 = offset + real_start - start;
-        ret = (long)mmap(g2h(real_start), real_end - real_start,
-                         prot, flags, fd, offset1);
-        if (ret == -1)
+        if (flags & MAP_ANONYMOUS)
+          offset1 = 0;
+        else
+          offset1 = offset + real_start - start;
+        p = mmap(g2h(real_start), real_end - real_start,
+                 prot, flags, fd, offset1);
+        if (p == MAP_FAILED)
             return -1;
     }
  the_end1:

Modified: trunk/src/host/qemu-neo1973/linux-user/qemu.h
===================================================================
--- trunk/src/host/qemu-neo1973/linux-user/qemu.h	2007-11-09 16:32:22 UTC (rev 3386)
+++ trunk/src/host/qemu-neo1973/linux-user/qemu.h	2007-11-09 17:12:19 UTC (rev 3387)
@@ -9,10 +9,16 @@
 #ifdef TARGET_ABI32
 typedef uint32_t abi_ulong;
 typedef int32_t abi_long;
+#define TARGET_ABI_FMT_lx "%08x"
+#define TARGET_ABI_FMT_ld "%d"
+#define TARGET_ABI_FMT_lu "%u"
 #define TARGET_ABI_BITS 32
 #else
 typedef target_ulong abi_ulong;
 typedef target_long abi_long;
+#define TARGET_ABI_FMT_lx TARGET_FMT_lx
+#define TARGET_ABI_FMT_ld TARGET_FMT_ld
+#define TARGET_ABI_FMT_lu TARGET_FMT_lu
 #define TARGET_ABI_BITS TARGET_LONG_BITS
 #endif
 
@@ -203,24 +209,25 @@
 #define VERIFY_READ 0
 #define VERIFY_WRITE 1
 
-#define access_ok(type,addr,size) (1)
+#define access_ok(type,addr,size) \
+    (page_check_range((target_ulong)addr,size,(type==VERIFY_READ)?PAGE_READ:PAGE_WRITE)==0)
 
-/* NOTE get_user and put_user use host addresses.  */
-#define __put_user(x,ptr)\
+/* NOTE __get_user and __put_user use host pointers and don't check access. */
+#define __put_user(x, hptr)\
 ({\
-    int size = sizeof(*ptr);\
+    int size = sizeof(*hptr);\
     switch(size) {\
     case 1:\
-        *(uint8_t *)(ptr) = (typeof(*ptr))(x);\
+        *(uint8_t *)(hptr) = (typeof(*hptr))(x);\
         break;\
     case 2:\
-        *(uint16_t *)(ptr) = tswap16((typeof(*ptr))(x));\
+        *(uint16_t *)(hptr) = tswap16((typeof(*hptr))(x));\
         break;\
     case 4:\
-        *(uint32_t *)(ptr) = tswap32((typeof(*ptr))(x));\
+        *(uint32_t *)(hptr) = tswap32((typeof(*hptr))(x));\
         break;\
     case 8:\
-        *(uint64_t *)(ptr) = tswap64((typeof(*ptr))(x));\
+        *(uint64_t *)(hptr) = tswap64((typeof(*hptr))(x));\
         break;\
     default:\
         abort();\
@@ -228,21 +235,21 @@
     0;\
 })
 
-#define __get_user(x, ptr) \
+#define __get_user(x, hptr) \
 ({\
-    int size = sizeof(*ptr);\
+    int size = sizeof(*hptr);\
     switch(size) {\
     case 1:\
-        x = (typeof(*ptr))*(uint8_t *)(ptr);\
+        x = (typeof(*hptr))*(uint8_t *)(hptr);\
         break;\
     case 2:\
-        x = (typeof(*ptr))tswap16(*(uint16_t *)(ptr));\
+        x = (typeof(*hptr))tswap16(*(uint16_t *)(hptr));\
         break;\
     case 4:\
-        x = (typeof(*ptr))tswap32(*(uint32_t *)(ptr));\
+        x = (typeof(*hptr))tswap32(*(uint32_t *)(hptr));\
         break;\
     case 8:\
-        x = (typeof(*ptr))tswap64(*(uint64_t *)(ptr));\
+        x = (typeof(*hptr))tswap64(*(uint64_t *)(hptr));\
         break;\
     default:\
         abort();\

Modified: trunk/src/host/qemu-neo1973/linux-user/signal.c
===================================================================
--- trunk/src/host/qemu-neo1973/linux-user/signal.c	2007-11-09 16:32:22 UTC (rev 3386)
+++ trunk/src/host/qemu-neo1973/linux-user/signal.c	2007-11-09 17:12:19 UTC (rev 3387)
@@ -415,11 +415,7 @@
 
     /* the CPU emulator uses some host signals to detect exceptions,
        we we forward to it some signals */
-    if (host_signum == SIGSEGV || host_signum == SIGBUS
-#if defined(TARGET_I386) && defined(USE_CODE_COPY)
-        || host_signum == SIGFPE
-#endif
-        ) {
+    if (host_signum == SIGSEGV || host_signum == SIGBUS) {
         if (cpu_signal_handler(host_signum, info, puc))
             return;
     }
@@ -1943,7 +1939,7 @@
     force_sig(SIGSEGV);
 }
 #endif
-#elif defined(TARGET_MIPS64)
+#elif defined(TARGET_ABI_MIPSN64)
 
 # warning signal handling not implemented
 
@@ -1972,7 +1968,7 @@
     return -ENOSYS;
 }
 
-#elif defined(TARGET_MIPSN32)
+#elif defined(TARGET_ABI_MIPSN32)
 
 # warning signal handling not implemented
 
@@ -2001,7 +1997,7 @@
     return -ENOSYS;
 }
 
-#elif defined(TARGET_MIPS)
+#elif defined(TARGET_ABI_MIPSO32)
 
 struct target_sigcontext {
     uint32_t   sc_regmask;     /* Unused */

Modified: trunk/src/host/qemu-neo1973/linux-user/strace.c
===================================================================
--- trunk/src/host/qemu-neo1973/linux-user/strace.c	2007-11-09 16:32:22 UTC (rev 3386)
+++ trunk/src/host/qemu-neo1973/linux-user/strace.c	2007-11-09 17:12:19 UTC (rev 3387)
@@ -106,7 +106,8 @@
             return;
 
 	tv = lock_user(tv_addr, sizeof(*tv), 1);
-        gemu_log("{%d,%d}", tv->tv_sec, tv->tv_usec);
+        gemu_log("{" TARGET_ABI_FMT_ld "," TARGET_ABI_FMT_ld "}",
+        	 tv->tv_sec, tv->tv_usec);
         unlock_user(tv, tv_addr, 0);
     } else
         gemu_log("NULL");
@@ -220,12 +221,15 @@
     }
 }
 
+#if 0 /* currently unused */
 static void
 print_syscall_ret_raw(struct syscallname *name, target_long ret)
 {
         gemu_log(" = " TARGET_FMT_lx "\n", ret);
 }
+#endif
 
+#ifdef TARGET_NR__newselect
 static void
 print_syscall_ret_newselect(struct syscallname *name, target_long ret)
 {
@@ -239,6 +243,7 @@
     print_timeval(newselect_arg5);
     gemu_log(")\n");
 }
+#endif
 
 /*
  * An array of all of the syscalls we know about

Modified: trunk/src/host/qemu-neo1973/linux-user/syscall_defs.h
===================================================================
--- trunk/src/host/qemu-neo1973/linux-user/syscall_defs.h	2007-11-09 16:32:22 UTC (rev 3386)
+++ trunk/src/host/qemu-neo1973/linux-user/syscall_defs.h	2007-11-09 17:12:19 UTC (rev 3387)
@@ -307,8 +307,8 @@
 #define TARGET_SA_NODEFER	0x40000000
 #define TARGET_SA_RESTART	0x10000000
 #define TARGET_SA_RESETHAND	0x80000000
-#if !defined(TARGET_MIPSN32) && !defined(TARGET_MIPS64)
-#define TARGET_SA_RESTORER	0x04000000	/* Only for o32 */
+#if !defined(TARGET_ABI_MIPSN32) && !defined(TARGET_ABI_MIPSN64)
+#define TARGET_SA_RESTORER	0x04000000	/* Only for O32 */
 #endif
 #else
 #define TARGET_SA_NOCLDSTOP	0x00000001
@@ -450,7 +450,7 @@
 
 struct target_sigaction {
 	uint32_t	sa_flags;
-#if defined(TARGET_MIPSN32)
+#if defined(TARGET_ABI_MIPSN32)
 	uint32_t	_sa_handler;
 #else
 	abi_ulong	_sa_handler;
@@ -1194,7 +1194,7 @@
 	unsigned long long	st_ino;
 } __attribute__((packed));
 
-#elif defined(TARGET_MIPS64)
+#elif defined(TARGET_ABI_MIPSN64)
 
 /* The memory layout is the same as of struct stat64 of the 32-bit kernel.  */
 struct target_stat {
@@ -1233,7 +1233,7 @@
 	abi_ulong		st_blocks;
 };
 
-#elif defined(TARGET_MIPSN32)
+#elif defined(TARGET_ABI_MIPSN32)
 
 struct target_stat {
 	unsigned	st_dev;
@@ -1304,7 +1304,7 @@
 	int		st_blocks;
 };
 
-#elif defined(TARGET_MIPS)
+#elif defined(TARGET_ABI_MIPSO32)
 
 struct target_stat {
 	unsigned	st_dev;
@@ -1486,7 +1486,7 @@
 } target_fsid_t;
 
 #ifdef TARGET_MIPS
-#ifdef TARGET_MIPSN32
+#ifdef TARGET_ABI_MIPSN32
 struct target_statfs {
 	int32_t			f_type;
 	int32_t			f_bsize;

Modified: trunk/src/host/qemu-neo1973/qemu-doc.texi
===================================================================
--- trunk/src/host/qemu-neo1973/qemu-doc.texi	2007-11-09 16:32:22 UTC (rev 3386)
+++ trunk/src/host/qemu-neo1973/qemu-doc.texi	2007-11-09 17:12:19 UTC (rev 3387)
@@ -83,6 +83,7 @@
 @item Spitz, Akita, Borzoi and Terrier PDAs (PXA270 processor)
 @item Freescale MCF5208EVB (ColdFire V2).
 @item Arnewsh MCF5206 evaluation board (ColdFire V2).
+ at item Palm Tungsten|E PDA (OMAP310 processor)
 @end itemize
 
 For user emulation, x86, PowerPC, ARM, MIPS, Sparc32/64 and ColdFire(m68k) CPUs are supported.
@@ -267,6 +268,11 @@
 time). This option is needed to have correct date in MS-DOS or
 Windows.
 
+ at item -startdate date
+Set the initial date of the real time clock. Valid format for
+ at var{date} are: @code{now} or @code{2006-06-17T16:01:21} or
+ at code{2006-06-17}. The default value is @code{now}.
+
 @item -pidfile file
 Store the QEMU process PID in @var{file}. It is useful if you launch QEMU
 from a script.
@@ -2208,6 +2214,29 @@
 WM8750 audio CODEC on I at math{^2}C and I at math{^2}S busses
 @end itemize
 
+The Palm Tungsten|E PDA (codename "Cheetah") emulation includes the
+following elements:
+
+ at itemize @minus
+ at item
+Texas Instruments OMAP310 System-on-chip (ARM 925T core)
+ at item
+ROM and RAM memories (ROM firmware image can be loaded with -option-rom)
+ at item
+On-chip LCD controller
+ at item
+On-chip Real Time Clock
+ at item
+TI TSC2102i touchscreen controller / analog-digital converter / Audio
+CODEC, connected through MicroWire and I at math{^2}S busses
+ at item
+GPIO-connected matrix keypad
+ at item
+Secure Digital card connected to OMAP MMC/SD host
+ at item
+Three on-chip UARTs
+ at end itemize
+
 A Linux 2.6 test image is available on the QEMU web site. More
 information is available in the QEMU mailing-list archive.
 

Added: trunk/src/host/qemu-neo1973/slirp/.cvsignore
===================================================================
--- trunk/src/host/qemu-neo1973/slirp/.cvsignore	2007-11-09 16:32:22 UTC (rev 3386)
+++ trunk/src/host/qemu-neo1973/slirp/.cvsignore	2007-11-09 17:12:19 UTC (rev 3387)
@@ -0,0 +1 @@
+*.d

Modified: trunk/src/host/qemu-neo1973/slirp/misc.h
===================================================================
--- trunk/src/host/qemu-neo1973/slirp/misc.h	2007-11-09 16:32:22 UTC (rev 3386)
+++ trunk/src/host/qemu-neo1973/slirp/misc.h	2007-11-09 17:12:19 UTC (rev 3387)
@@ -63,7 +63,9 @@
 	struct emu_t *next;
 };
 
+#ifndef CONFIG_QEMU
 extern struct emu_t *tcpemu;
+#endif
 
 extern int x_port, x_server, x_display;
 

Modified: trunk/src/host/qemu-neo1973/slirp/slirp.h
===================================================================
--- trunk/src/host/qemu-neo1973/slirp/slirp.h	2007-11-09 16:32:22 UTC (rev 3386)
+++ trunk/src/host/qemu-neo1973/slirp/slirp.h	2007-11-09 17:12:19 UTC (rev 3387)
@@ -17,7 +17,7 @@
 #ifndef CONFIG_QEMU
 #include "version.h"
 #endif
-#include "config.h"
+#include "config-host.h"
 #include "slirp_config.h"
 
 #ifdef _WIN32

Modified: trunk/src/host/qemu-neo1973/slirp/tcp_subr.c
===================================================================
--- trunk/src/host/qemu-neo1973/slirp/tcp_subr.c	2007-11-09 16:32:22 UTC (rev 3386)
+++ trunk/src/host/qemu-neo1973/slirp/tcp_subr.c	2007-11-09 17:12:19 UTC (rev 3387)
@@ -559,7 +559,10 @@
 	  {0, 0, 0, 0}
 };
 
-static struct emu_t *tcpemu = 0;
+#ifdef CONFIG_QEMU
+static
+#endif
+struct emu_t *tcpemu = 0;
 
 /*
  * Return TOS according to the above table

Modified: trunk/src/host/qemu-neo1973/target-alpha/op.c
===================================================================
--- trunk/src/host/qemu-neo1973/target-alpha/op.c	2007-11-09 16:32:22 UTC (rev 3386)
+++ trunk/src/host/qemu-neo1973/target-alpha/op.c	2007-11-09 17:12:19 UTC (rev 3387)
@@ -22,6 +22,7 @@
 
 #include "config.h"
 #include "exec.h"
+#include "host-utils.h"
 
 #include "op_helper.h"
 

Modified: trunk/src/host/qemu-neo1973/target-i386/cpu.h
===================================================================
--- trunk/src/host/qemu-neo1973/target-i386/cpu.h	2007-11-09 16:32:22 UTC (rev 3386)
+++ trunk/src/host/qemu-neo1973/target-i386/cpu.h	2007-11-09 17:12:19 UTC (rev 3387)
@@ -46,10 +46,6 @@
 
 #include "softfloat.h"
 
-#if defined(__i386__) && !defined(CONFIG_SOFTMMU) && !defined(__APPLE__)
-#define USE_CODE_COPY
-#endif
-
 #define R_EAX 0
 #define R_ECX 1
 #define R_EDX 2
@@ -274,23 +270,56 @@
 #define CPUID_CMOV (1 << 15)
 #define CPUID_PAT  (1 << 16)
 #define CPUID_PSE36   (1 << 17)
+#define CPUID_PN   (1 << 18)
 #define CPUID_CLFLUSH (1 << 19)
-/* ... */
+#define CPUID_DTS (1 << 21)
+#define CPUID_ACPI (1 << 22)
 #define CPUID_MMX  (1 << 23)
 #define CPUID_FXSR (1 << 24)
 #define CPUID_SSE  (1 << 25)
 #define CPUID_SSE2 (1 << 26)
+#define CPUID_SS (1 << 27)
+#define CPUID_HT (1 << 28)
+#define CPUID_TM (1 << 29)
+#define CPUID_IA64 (1 << 30)
+#define CPUID_PBE (1 << 31)
 
 #define CPUID_EXT_SSE3     (1 << 0)
 #define CPUID_EXT_MONITOR  (1 << 3)
+#define CPUID_EXT_DSCPL    (1 << 4)
+#define CPUID_EXT_VMX      (1 << 5)
+#define CPUID_EXT_SMX      (1 << 6)
+#define CPUID_EXT_EST      (1 << 7)
+#define CPUID_EXT_TM2      (1 << 8)
+#define CPUID_EXT_SSSE3    (1 << 9)
+#define CPUID_EXT_CID      (1 << 10)
 #define CPUID_EXT_CX16     (1 << 13)
+#define CPUID_EXT_XTPR     (1 << 14)
+#define CPUID_EXT_DCA      (1 << 17)
+#define CPUID_EXT_POPCNT   (1 << 22)
 
 #define CPUID_EXT2_SYSCALL (1 << 11)
+#define CPUID_EXT2_MP      (1 << 19)
 #define CPUID_EXT2_NX      (1 << 20)
+#define CPUID_EXT2_MMXEXT  (1 << 22)
 #define CPUID_EXT2_FFXSR   (1 << 25)
+#define CPUID_EXT2_PDPE1GB (1 << 26)
+#define CPUID_EXT2_RDTSCP  (1 << 27)
 #define CPUID_EXT2_LM      (1 << 29)
+#define CPUID_EXT2_3DNOWEXT (1 << 30)
+#define CPUID_EXT2_3DNOW   (1 << 31)
 
+#define CPUID_EXT3_LAHF_LM (1 << 0)
+#define CPUID_EXT3_CMP_LEG (1 << 1)
 #define CPUID_EXT3_SVM     (1 << 2)
+#define CPUID_EXT3_EXTAPIC (1 << 3)
+#define CPUID_EXT3_CR8LEG  (1 << 4)
+#define CPUID_EXT3_ABM     (1 << 5)
+#define CPUID_EXT3_SSE4A   (1 << 6)
+#define CPUID_EXT3_MISALIGNSSE (1 << 7)
+#define CPUID_EXT3_3DNOWPREFETCH (1 << 8)
+#define CPUID_EXT3_OSVW    (1 << 9)
+#define CPUID_EXT3_IBS     (1 << 10)
 
 #define EXCP00_DIVZ	0
 #define EXCP01_SSTP	1
@@ -519,13 +548,6 @@
 
     uint64_t pat;
 
-    /* temporary data for USE_CODE_COPY mode */
-#ifdef USE_CODE_COPY
-    uint32_t tmp0;
-    uint32_t saved_esp;
-    int native_fp_regs; /* if true, the FPU state is in the native CPU regs */
-#endif
-
     /* exception/interrupt handling */
     jmp_buf jmp_env;
     int exception_index;
@@ -566,6 +588,9 @@
 CPUX86State *cpu_x86_init(void);
 int cpu_x86_exec(CPUX86State *s);
 void cpu_x86_close(CPUX86State *s);
+int x86_find_cpu_by_name (const unsigned char *name);
+void x86_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt,
+                                                 ...));
 int cpu_get_pic_interrupt(CPUX86State *s);
 /* MSDOS compatibility mode FPU exception support */
 void cpu_set_ferr(CPUX86State *s);
@@ -689,6 +714,7 @@
 #define cpu_exec cpu_x86_exec
 #define cpu_gen_code cpu_x86_gen_code
 #define cpu_signal_handler cpu_x86_signal_handler
+#define cpu_list x86_cpu_list
 
 /* MMU modes definitions */
 #define MMU_MODE0_SUFFIX _kernel

Modified: trunk/src/host/qemu-neo1973/target-i386/helper.c
===================================================================
--- trunk/src/host/qemu-neo1973/target-i386/helper.c	2007-11-09 16:32:22 UTC (rev 3386)
+++ trunk/src/host/qemu-neo1973/target-i386/helper.c	2007-11-09 17:12:19 UTC (rev 3387)
@@ -18,6 +18,7 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 #include "exec.h"
+#include "host-utils.h"
 
 //#define DEBUG_PCALL
 

Modified: trunk/src/host/qemu-neo1973/target-i386/helper2.c
===================================================================
--- trunk/src/host/qemu-neo1973/target-i386/helper2.c	2007-11-09 16:32:22 UTC (rev 3386)
+++ trunk/src/host/qemu-neo1973/target-i386/helper2.c	2007-11-09 17:12:19 UTC (rev 3387)
@@ -31,21 +31,67 @@
 
 //#define DEBUG_MMU
 
-#ifdef USE_CODE_COPY
-#include <asm/ldt.h>
-#include <linux/unistd.h>
-#include <linux/version.h>
+static struct x86_def_t *x86_cpu_def;
+typedef struct x86_def_t x86_def_t;
+static int cpu_x86_register (CPUX86State *env, const x86_def_t *def);
 
-int modify_ldt(int func, void *ptr, unsigned long bytecount)
+static void add_flagname_to_bitmaps(char *flagname, uint32_t *features, 
+                                    uint32_t *ext_features, 
+                                    uint32_t *ext2_features, 
+                                    uint32_t *ext3_features)
 {
-	return syscall(__NR_modify_ldt, func, ptr, bytecount);
+    int i;
+    /* feature flags taken from "Intel Processor Identification and the CPUID
+     * Instruction" and AMD's "CPUID Specification". In cases of disagreement 
+     * about feature names, the Linux name is used. */
+    const char *feature_name[] = {
+        "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce",
+        "cx8", "apic", NULL, "sep", "mtrr", "pge", "mca", "cmov",
+        "pat", "pse36", "pn" /* Intel psn */, "clflush" /* Intel clfsh */, NULL, "ds" /* Intel dts */, "acpi", "mmx",
+        "fxsr", "sse", "sse2", "ss", "ht" /* Intel htt */, "tm", "ia64", "pbe",
+    };
+    const char *ext_feature_name[] = {
+       "pni" /* Intel,AMD sse3 */, NULL, NULL, "monitor", "ds_cpl", "vmx", NULL /* Linux smx */, "est",
+       "tm2", "ssse3", "cid", NULL, NULL, "cx16", "xtpr", NULL,
+       NULL, NULL, "dca", NULL, NULL, NULL, NULL, "popcnt",
+       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+    };
+    const char *ext2_feature_name[] = {
+       "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce",
+       "cx8" /* AMD CMPXCHG8B */, "apic", NULL, "syscall", "mttr", "pge", "mca", "cmov",
+       "pat", "pse36", NULL, NULL /* Linux mp */, "nx" /* Intel xd */, NULL, "mmxext", "mmx",
+       "fxsr", "fxsr_opt" /* AMD ffxsr */, "pdpe1gb" /* AMD Page1GB */, "rdtscp", NULL, "lm" /* Intel 64 */, "3dnowext", "3dnow",
+    };
+    const char *ext3_feature_name[] = {
+       "lahf_lm" /* AMD LahfSahf */, "cmp_legacy", "svm", "extapic" /* AMD ExtApicSpace */, "cr8legacy" /* AMD AltMovCr8 */, "abm", "sse4a", "misalignsse",
+       "3dnowprefetch", "osvw", NULL /* Linux ibs */, NULL, "skinit", "wdt", NULL, NULL,
+       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+    };
+
+    for ( i = 0 ; i < 32 ; i++ ) 
+        if (feature_name[i] && !strcmp (flagname, feature_name[i])) {
+            *features |= 1 << i;
+            return;
+        }
+    for ( i = 0 ; i < 32 ; i++ ) 
+        if (ext_feature_name[i] && !strcmp (flagname, ext_feature_name[i])) {
+            *ext_features |= 1 << i;
+            return;
+        }
+    for ( i = 0 ; i < 32 ; i++ ) 
+        if (ext2_feature_name[i] && !strcmp (flagname, ext2_feature_name[i])) {
+            *ext2_features |= 1 << i;
+            return;
+        }
+    for ( i = 0 ; i < 32 ; i++ ) 
+        if (ext3_features[i] && !strcmp (flagname, ext3_feature_name[i])) {
+            *ext3_features |= 1 << i;
+            return;
+        }
+    fprintf(stderr, "CPU feature %s not found\n", flagname);
 }
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 66)
-#define modify_ldt_ldt_s user_desc
-#endif
-#endif /* USE_CODE_COPY */
-
 CPUX86State *cpu_x86_init(void)
 {
     CPUX86State *env;
@@ -61,90 +107,219 @@
         inited = 1;
         optimize_flags_init();
     }
-#ifdef USE_CODE_COPY
-    /* testing code for code copy case */
+    cpu_x86_register(env, x86_cpu_def);
+    cpu_reset(env);
+#ifdef USE_KQEMU
+    kqemu_init(env);
+#endif
+    return env;
+}
+
+struct x86_def_t {
+    const char *name;
+    uint32_t vendor1, vendor2, vendor3;
+    int family;
+    int model;
+    int stepping;
+    uint32_t features, ext_features, ext2_features, ext3_features;
+    uint32_t xlevel;
+};
+
+#define PPRO_FEATURES (CPUID_FP87 | CPUID_DE | CPUID_PSE | CPUID_TSC | \
+          CPUID_MSR | CPUID_MCE | CPUID_CX8 | CPUID_PGE | CPUID_CMOV | \
+          CPUID_PAT | CPUID_FXSR | CPUID_MMX | CPUID_SSE | CPUID_SSE2 | \
+          CPUID_PAE | CPUID_SEP | CPUID_APIC)
+static x86_def_t x86_defs[] = {
+#ifdef TARGET_X86_64
     {
-        struct modify_ldt_ldt_s ldt;
+        .name = "qemu64",
+        .vendor1 = 0x68747541, /* "Auth" */
+        .vendor2 = 0x69746e65, /* "enti" */
+        .vendor3 = 0x444d4163, /* "cAMD" */
+        .family = 6,
+        .model = 2,
+        .stepping = 3,
+        .features = PPRO_FEATURES | 
+        /* these features are needed for Win64 and aren't fully implemented */
+            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
+        /* this feature is needed for Solaris and isn't fully implemented */
+            CPUID_PSE36,
+        .ext_features = CPUID_EXT_SSE3,
+        .ext2_features = (PPRO_FEATURES & 0x0183F3FF) | 
+            CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
+        .ext3_features = CPUID_EXT3_SVM,
+        .xlevel = 0x80000008,
+    },
+#endif
+    {
+        .name = "qemu32",
+        .family = 6,
+        .model = 3,
+        .stepping = 3,
+        .features = PPRO_FEATURES,
+        .ext_features = CPUID_EXT_SSE3,
+        .xlevel = 0,
+    },
+    {
+        .name = "486",
+        .family = 4,
+        .model = 0,
+        .stepping = 0,
+        .features = 0x0000000B,
+        .xlevel = 0,
+    },
+    {
+        .name = "pentium",
+        .family = 5,
+        .model = 4,
+        .stepping = 3,
+        .features = 0x008001BF,
+        .xlevel = 0,
+    },
+    {
+        .name = "pentium2",
+        .family = 6,
+        .model = 5,
+        .stepping = 2,
+        .features = 0x0183F9FF,
+        .xlevel = 0,
+    },
+    {
+        .name = "pentium3",
+        .family = 6,
+        .model = 7,
+        .stepping = 3,
+        .features = 0x0383F9FF,
+        .xlevel = 0,
+    },
+};
 
-        ldt.entry_number = 1;
-        ldt.base_addr = (unsigned long)env;
-        ldt.limit = (sizeof(CPUState) + 0xfff) >> 12;
-        ldt.seg_32bit = 1;
-        ldt.contents = MODIFY_LDT_CONTENTS_DATA;
-        ldt.read_exec_only = 0;
-        ldt.limit_in_pages = 1;
-        ldt.seg_not_present = 0;
-        ldt.useable = 1;
-        modify_ldt(1, &ldt, sizeof(ldt)); /* write ldt entry */
+int x86_find_cpu_by_name(const unsigned char *cpu_model)
+{
+    int ret;
+    unsigned int i;
 
-        asm volatile ("movl %0, %%fs" : : "r" ((1 << 3) | 7));
+    char *s = strdup(cpu_model);
+    char *featurestr, *name = strtok(s, ",");
+    uint32_t plus_features = 0, plus_ext_features = 0, plus_ext2_features = 0, plus_ext3_features = 0;
+    uint32_t minus_features = 0, minus_ext_features = 0, minus_ext2_features = 0, minus_ext3_features = 0;
+    int family = -1, model = -1, stepping = -1;
+
+    ret = -1;
+    x86_cpu_def = NULL;
+    for (i = 0; i < sizeof(x86_defs) / sizeof(x86_def_t); i++) {
+        if (strcmp(name, x86_defs[i].name) == 0) {
+            x86_cpu_def = &x86_defs[i];
+            ret = 0;
+            break;
+        }
     }
-#endif
-    {
-        int family, model, stepping;
-#ifdef TARGET_X86_64
-        env->cpuid_vendor1 = 0x68747541; /* "Auth" */
-        env->cpuid_vendor2 = 0x69746e65; /* "enti" */
-        env->cpuid_vendor3 = 0x444d4163; /* "cAMD" */
-        family = 6;
-        model = 2;
-        stepping = 3;
-#else
+    if (!x86_cpu_def)
+        goto error;
+
+    featurestr = strtok(NULL, ",");
+
+    while (featurestr) {
+        char *val;
+        if (featurestr[0] == '+') {
+            add_flagname_to_bitmaps(featurestr + 1, &plus_features, &plus_ext_features, &plus_ext2_features, &plus_ext3_features);
+        } else if (featurestr[0] == '-') {
+            add_flagname_to_bitmaps(featurestr + 1, &minus_features, &minus_ext_features, &minus_ext2_features, &minus_ext3_features);
+        } else if ((val = strchr(featurestr, '='))) {
+            *val = 0; val++;
+            if (!strcmp(featurestr, "family")) {
+                char *err;
+                family = strtol(val, &err, 10);
+                if (!*val || *err || family < 0) {
+                    fprintf(stderr, "bad numerical value %s\n", val);
+                    x86_cpu_def = 0;
+                    goto error;
+                }
+                x86_cpu_def->family = family;
+            } else if (!strcmp(featurestr, "model")) {
+                char *err;
+                model = strtol(val, &err, 10);
+                if (!*val || *err || model < 0 || model > 0xf) {
+                    fprintf(stderr, "bad numerical value %s\n", val);
+                    x86_cpu_def = 0;
+                    goto error;
+                }
+                x86_cpu_def->model = model;
+            } else if (!strcmp(featurestr, "stepping")) {
+                char *err;
+                stepping = strtol(val, &err, 10);
+                if (!*val || *err || stepping < 0 || stepping > 0xf) {
+                    fprintf(stderr, "bad numerical value %s\n", val);
+                    x86_cpu_def = 0;
+                    goto error;
+                }
+                x86_cpu_def->stepping = stepping;
+            } else {
+                fprintf(stderr, "unregnized feature %s\n", featurestr);
+                x86_cpu_def = 0;
+                goto error;
+            }
+        } else {
+            fprintf(stderr, "feature string `%s' not in format (+feature|-feature|feature=xyz)\n", featurestr);
+            x86_cpu_def = 0;
+            goto error;
+        }
+        featurestr = strtok(NULL, ",");
+    }
+    x86_cpu_def->features |= plus_features;
+    x86_cpu_def->ext_features |= plus_ext_features;
+    x86_cpu_def->ext2_features |= plus_ext2_features;
+    x86_cpu_def->ext3_features |= plus_ext3_features;
+    x86_cpu_def->features &= ~minus_features;
+    x86_cpu_def->ext_features &= ~minus_ext_features;
+    x86_cpu_def->ext2_features &= ~minus_ext2_features;
+    x86_cpu_def->ext3_features &= ~minus_ext3_features;
+
+error:
+    free(s);
+    return ret;
+}
+
+void x86_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
+{
+    unsigned int i;
+
+    for (i = 0; i < sizeof(x86_defs) / sizeof(x86_def_t); i++)
+        (*cpu_fprintf)(f, "x86 %16s\n", x86_defs[i].name);
+}
+
+int cpu_x86_register (CPUX86State *env, const x86_def_t *def)
+{
+    if (def->vendor1) {
+        env->cpuid_vendor1 = def->vendor1;
+        env->cpuid_vendor2 = def->vendor2;
+        env->cpuid_vendor3 = def->vendor3;
+    } else {
         env->cpuid_vendor1 = 0x756e6547; /* "Genu" */
         env->cpuid_vendor2 = 0x49656e69; /* "ineI" */
         env->cpuid_vendor3 = 0x6c65746e; /* "ntel" */
-#if 0
-        /* pentium 75-200 */
-        family = 5;
-        model = 2;
-        stepping = 11;
-#else
-        /* pentium pro */
-        family = 6;
-        model = 3;
-        stepping = 3;
-#endif
-#endif
-        env->cpuid_level = 2;
-        env->cpuid_version = (family << 8) | (model << 4) | stepping;
-        env->cpuid_features = (CPUID_FP87 | CPUID_DE | CPUID_PSE |
-                               CPUID_TSC | CPUID_MSR | CPUID_MCE |
-                               CPUID_CX8 | CPUID_PGE | CPUID_CMOV |
-                               CPUID_PAT);
-        env->pat = 0x0007040600070406ULL;
-        env->cpuid_ext3_features = CPUID_EXT3_SVM;
-        env->cpuid_ext_features = CPUID_EXT_SSE3;
-        env->cpuid_features |= CPUID_FXSR | CPUID_MMX | CPUID_SSE | CPUID_SSE2 | CPUID_PAE | CPUID_SEP;
-        env->cpuid_features |= CPUID_APIC;
-        env->cpuid_xlevel = 0x8000000e;
-        {
-            const char *model_id = "QEMU Virtual CPU version " QEMU_VERSION;
-            int c, len, i;
-            len = strlen(model_id);
-            for(i = 0; i < 48; i++) {
-                if (i >= len)
-                    c = '\0';
-                else
-                    c = model_id[i];
-                env->cpuid_model[i >> 2] |= c << (8 * (i & 3));
-            }
+    }
+    env->cpuid_level = 2;
+    env->cpuid_version = (def->family << 8) | (def->model << 4) | def->stepping;
+    env->cpuid_features = def->features;
+    env->pat = 0x0007040600070406ULL;
+    env->cpuid_ext_features = def->ext_features;
+    env->cpuid_ext2_features = def->ext2_features;
+    env->cpuid_xlevel = def->xlevel;
+    env->cpuid_ext3_features = def->ext3_features;
+    {
+        const char *model_id = "QEMU Virtual CPU version " QEMU_VERSION;
+        int c, len, i;
+        len = strlen(model_id);
+        for(i = 0; i < 48; i++) {
+            if (i >= len)
+                c = '\0';
+            else
+                c = model_id[i];
+            env->cpuid_model[i >> 2] |= c << (8 * (i & 3));
         }
-#ifdef TARGET_X86_64
-        /* currently not enabled for std i386 because not fully tested */
-        env->cpuid_ext2_features = (env->cpuid_features & 0x0183F3FF);
-        env->cpuid_ext2_features |= CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX;
-
-        /* these features are needed for Win64 and aren't fully implemented */
-        env->cpuid_features |= CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA;
-        /* this feature is needed for Solaris and isn't fully implemented */
-        env->cpuid_features |= CPUID_PSE36;
-#endif
     }
-    cpu_reset(env);
-#ifdef USE_KQEMU
-    kqemu_init(env);
-#endif
-    return env;
+    return 0;
 }
 
 /* NOTE: must be called outside the CPU execute loop */
@@ -184,7 +359,7 @@
     cpu_x86_load_seg_cache(env, R_GS, 0, 0, 0xffff, 0);
 
     env->eip = 0xfff0;
-    env->regs[R_EDX] = 0x600; /* indicate P6 processor */
+    env->regs[R_EDX] = env->cpuid_version;
 
     env->eflags = 0x2;
 
@@ -976,73 +1151,3 @@
     return paddr;
 }
 #endif /* !CONFIG_USER_ONLY */
-
-#if defined(USE_CODE_COPY)
-struct fpstate {
-    uint16_t fpuc;
-    uint16_t dummy1;
-    uint16_t fpus;
-    uint16_t dummy2;
-    uint16_t fptag;
-    uint16_t dummy3;
-
-    uint32_t fpip;
-    uint32_t fpcs;
-    uint32_t fpoo;
-    uint32_t fpos;
-    uint8_t fpregs1[8 * 10];
-};
-
-void restore_native_fp_state(CPUState *env)
-{
-    int fptag, i, j;
-    struct fpstate fp1, *fp = &fp1;
-
-    fp->fpuc = env->fpuc;
-    fp->fpus = (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11;
-    fptag = 0;
-    for (i=7; i>=0; i--) {
-	fptag <<= 2;
-	if (env->fptags[i]) {
-            fptag |= 3;
-        } else {
-            /* the FPU automatically computes it */
-        }
-    }
-    fp->fptag = fptag;
-    j = env->fpstt;
-    for(i = 0;i < 8; i++) {
-        memcpy(&fp->fpregs1[i * 10], &env->fpregs[j].d, 10);
-        j = (j + 1) & 7;
-    }
-    asm volatile ("frstor %0" : "=m" (*fp));
-    env->native_fp_regs = 1;
-}
-
-void save_native_fp_state(CPUState *env)
-{
-    int fptag, i, j;
-    uint16_t fpuc;
-    struct fpstate fp1, *fp = &fp1;
-
-    asm volatile ("fsave %0" : : "m" (*fp));
-    env->fpuc = fp->fpuc;
-    env->fpstt = (fp->fpus >> 11) & 7;
-    env->fpus = fp->fpus & ~0x3800;
-    fptag = fp->fptag;
-    for(i = 0;i < 8; i++) {
-        env->fptags[i] = ((fptag & 3) == 3);
-        fptag >>= 2;
-    }
-    j = env->fpstt;
-    for(i = 0;i < 8; i++) {
-        memcpy(&env->fpregs[j].d, &fp->fpregs1[i * 10], 10);
-        j = (j + 1) & 7;
-    }
-    /* we must restore the default rounding state */
-    /* XXX: we do not restore the exception state */
-    fpuc = 0x037f | (env->fpuc & (3 << 10));
-    asm volatile("fldcw %0" : : "m" (fpuc));
-    env->native_fp_regs = 0;
-}
-#endif

Deleted: trunk/src/host/qemu-neo1973/target-i386/translate-copy.c
===================================================================
--- trunk/src/host/qemu-neo1973/target-i386/translate-copy.c	2007-11-09 16:32:22 UTC (rev 3386)
+++ trunk/src/host/qemu-neo1973/target-i386/translate-copy.c	2007-11-09 17:12:19 UTC (rev 3387)
@@ -1,1323 +0,0 @@
-/*
- *  i386 on i386 translation
- *
- *  Copyright (c) 2003 Fabrice Bellard
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-#include "config.h"
-
-#include <stdarg.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <inttypes.h>
-#include <assert.h>
-
-#include "cpu.h"
-#include "exec-all.h"
-#include "disas.h"
-
-#ifdef USE_CODE_COPY
-
-#include <signal.h>
-#include <sys/mman.h>
-#include <sys/ucontext.h>
-
-extern char exec_loop;
-
-/* operand size */
-enum {
-    OT_BYTE = 0,
-    OT_WORD,
-    OT_LONG,
-    OT_QUAD,
-};
-
-#define PREFIX_REPZ   0x01
-#define PREFIX_REPNZ  0x02
-#define PREFIX_LOCK   0x04
-#define PREFIX_DATA   0x08
-#define PREFIX_ADR    0x10
-
-typedef struct DisasContext {
-    /* current insn context */
-    int override; /* -1 if no override */
-    int prefix;
-    int aflag, dflag;
-    target_ulong pc; /* pc = eip + cs_base */
-    int is_jmp; /* 1 = means jump (stop translation), 2 means CPU
-                   static state change (stop translation) */
-    /* code output */
-    uint8_t *gen_code_ptr;
-    uint8_t *gen_code_start;
-
-    /* current block context */
-    target_ulong cs_base; /* base of CS segment */
-    int pe;     /* protected mode */
-    int code32; /* 32 bit code segment */
-    int f_st;   /* currently unused */
-    int vm86;   /* vm86 mode */
-    int cpl;
-    int iopl;
-    int flags;
-    struct TranslationBlock *tb;
-} DisasContext;
-
-#define CPU_FIELD_OFFSET(field) offsetof(CPUState, field)
-
-#define CPU_SEG 0x64 /* fs override */
-
-static inline void gb(DisasContext *s, uint32_t val)
-{
-    *s->gen_code_ptr++ = val;
-}
-
-static inline void gw(DisasContext *s, uint32_t val)
-{
-    *s->gen_code_ptr++ = val;
-    *s->gen_code_ptr++ = val >> 8;
-}
-
-static inline void gl(DisasContext *s, uint32_t val)
-{
-    *s->gen_code_ptr++ = val;
-    *s->gen_code_ptr++ = val >> 8;
-    *s->gen_code_ptr++ = val >> 16;
-    *s->gen_code_ptr++ = val >> 24;
-}
-
-static inline void gjmp(DisasContext *s, long val)
-{
-    gb(s, 0xe9); /* jmp */
-    gl(s, val - (long)(s->gen_code_ptr + 4));
-}
-
-static inline void gen_movl_addr_im(DisasContext *s,
-                                    uint32_t addr, uint32_t val)
-{
-    gb(s, CPU_SEG); /* seg movl im, addr */
-    gb(s, 0xc7);
-    gb(s, 0x05);
-    gl(s, addr);
-    gl(s, val);
-}
-
-static inline void gen_movw_addr_im(DisasContext *s,
-                                    uint32_t addr, uint32_t val)
-{
-    gb(s, CPU_SEG); /* seg movl im, addr */
-    gb(s, 0x66);
-    gb(s, 0xc7);
-    gb(s, 0x05);
-    gl(s, addr);
-    gw(s, val);
-}
-
-
-static void gen_jmp(DisasContext *s, uint32_t target_eip)
-{
-    TranslationBlock *tb = s->tb;
-
-    gb(s, 0xe9); /* jmp */
-    tb->tb_jmp_offset[0] = s->gen_code_ptr - s->gen_code_start;
-    gl(s, 0);
-
-    tb->tb_next_offset[0] = s->gen_code_ptr - s->gen_code_start;
-    gen_movl_addr_im(s, CPU_FIELD_OFFSET(eip), target_eip);
-    gen_movl_addr_im(s, CPU_FIELD_OFFSET(tmp0), (uint32_t)tb);
-    gjmp(s, (long)&exec_loop);
-
-    s->is_jmp = 1;
-}
-
-static void gen_jcc(DisasContext *s, int op,
-                    uint32_t target_eip, uint32_t next_eip)
-{
-    TranslationBlock *tb = s->tb;
-
-    gb(s, 0x0f); /* jcc */
-    gb(s, 0x80 + op);
-    tb->tb_jmp_offset[0] = s->gen_code_ptr - s->gen_code_start;
-    gl(s, 0);
-    gb(s, 0xe9); /* jmp */
-    tb->tb_jmp_offset[1] = s->gen_code_ptr - s->gen_code_start;
-    gl(s, 0);
-
-    tb->tb_next_offset[0] = s->gen_code_ptr - s->gen_code_start;
-    gen_movl_addr_im(s, CPU_FIELD_OFFSET(eip), target_eip);
-    gen_movl_addr_im(s, CPU_FIELD_OFFSET(tmp0), (uint32_t)tb);
-    gjmp(s, (long)&exec_loop);
-
-    tb->tb_next_offset[1] = s->gen_code_ptr - s->gen_code_start;
-    gen_movl_addr_im(s, CPU_FIELD_OFFSET(eip), next_eip);
-    gen_movl_addr_im(s, CPU_FIELD_OFFSET(tmp0), (uint32_t)tb | 1);
-    gjmp(s, (long)&exec_loop);
-
-    s->is_jmp = 1;
-}
-
-static void gen_eob(DisasContext *s)
-{
-    gen_movl_addr_im(s, CPU_FIELD_OFFSET(tmp0), 0);
-    gjmp(s, (long)&exec_loop);
-
-    s->is_jmp = 1;
-}
-
-static inline void gen_lea_modrm(DisasContext *s, int modrm)
-{
-    int havesib;
-    int base, disp;
-    int index;
-    int scale;
-    int mod, rm, code;
-
-    mod = (modrm >> 6) & 3;
-    rm = modrm & 7;
-
-    if (s->aflag) {
-
-        havesib = 0;
-        base = rm;
-        index = 0;
-        scale = 0;
-
-        if (base == 4) {
-            havesib = 1;
-            code = ldub_code(s->pc++);
-            scale = (code >> 6) & 3;
-            index = (code >> 3) & 7;
-            base = code & 7;
-        }
-
-        switch (mod) {
-        case 0:
-            if (base == 5) {
-                base = -1;
-                disp = ldl_code(s->pc);
-                s->pc += 4;
-            } else {
-                disp = 0;
-            }
-            break;
-        case 1:
-            disp = (int8_t)ldub_code(s->pc++);
-            break;
-        default:
-        case 2:
-            disp = ldl_code(s->pc);
-            s->pc += 4;
-            break;
-        }
-
-    } else {
-        switch (mod) {
-        case 0:
-            if (rm == 6) {
-                disp = lduw_code(s->pc);
-                s->pc += 2;
-            } else {
-                disp = 0;
-            }
-            break;
-        case 1:
-            disp = (int8_t)ldub_code(s->pc++);
-            break;
-        default:
-        case 2:
-            disp = lduw_code(s->pc);
-            s->pc += 2;
-            break;
-        }
-    }
-}
-
-static inline void parse_modrm(DisasContext *s, int modrm)
-{
-    if ((modrm & 0xc0) != 0xc0)
-        gen_lea_modrm(s, modrm);
-}
-
-static inline uint32_t insn_get(DisasContext *s, int ot)
-{
-    uint32_t ret;
-
-    switch(ot) {
-    case OT_BYTE:
-        ret = ldub_code(s->pc);
-        s->pc++;
-        break;
-    case OT_WORD:
-        ret = lduw_code(s->pc);
-        s->pc += 2;
-        break;
-    default:
-    case OT_LONG:
-        ret = ldl_code(s->pc);
-        s->pc += 4;
-        break;
-    }
-    return ret;
-}
-
-/* convert one instruction. s->is_jmp is set if the translation must
-   be stopped.  */
-static int disas_insn(DisasContext *s)
-{
-    target_ulong pc_start, pc_tmp, pc_start_insn;
-    int b, prefixes, aflag, dflag, next_eip, val;
-    int ot;
-    int modrm, mod, op, rm;
-
-    pc_start = s->pc;
-    prefixes = 0;
-    aflag = s->code32;
-    dflag = s->code32;
-    s->override = -1;
- next_byte:
-    b = ldub_code(s->pc);
-    s->pc++;
-    /* check prefixes */
-    switch (b) {
-    case 0xf3:
-        prefixes |= PREFIX_REPZ;
-        goto next_byte;
-    case 0xf2:
-        prefixes |= PREFIX_REPNZ;
-        goto next_byte;
-    case 0xf0:
-        prefixes |= PREFIX_LOCK;
-        goto next_byte;
-    case 0x2e:
-        s->override = R_CS;
-        goto next_byte;
-    case 0x36:
-        s->override = R_SS;
-        goto next_byte;
-    case 0x3e:
-        s->override = R_DS;
-        goto next_byte;
-    case 0x26:
-        s->override = R_ES;
-        goto next_byte;
-    case 0x64:
-        s->override = R_FS;
-        goto next_byte;
-    case 0x65:
-        s->override = R_GS;
-        goto next_byte;
-    case 0x66:
-        prefixes |= PREFIX_DATA;
-        goto next_byte;
-    case 0x67:
-        prefixes |= PREFIX_ADR;
-        goto next_byte;
-    }
-
-    if (prefixes & PREFIX_DATA)
-        dflag ^= 1;
-    if (prefixes & PREFIX_ADR)
-        aflag ^= 1;
-
-    s->prefix = prefixes;
-    s->aflag = aflag;
-    s->dflag = dflag;
-
-    /* lock generation */
-    if (prefixes & PREFIX_LOCK)
-        goto unsupported_op;
-    if (s->override == R_FS || s->override == R_GS || s->override == R_CS)
-        goto unsupported_op;
-
-    pc_start_insn = s->pc - 1;
-    /* now check op code */
- reswitch:
-    switch(b) {
-    case 0x0f:
-        /**************************/
-        /* extended op code */
-        b = ldub_code(s->pc++) | 0x100;
-        goto reswitch;
-
-        /**************************/
-        /* arith & logic */
-    case 0x00 ... 0x05:
-    case 0x08 ... 0x0d:
-    case 0x10 ... 0x15:
-    case 0x18 ... 0x1d:
-    case 0x20 ... 0x25:
-    case 0x28 ... 0x2d:
-    case 0x30 ... 0x35:
-    case 0x38 ... 0x3d:
-        {
-            int f;
-            f = (b >> 1) & 3;
-
-            if ((b & 1) == 0)
-                ot = OT_BYTE;
-            else
-                ot = dflag ? OT_LONG : OT_WORD;
-
-            switch(f) {
-            case 0: /* OP Ev, Gv */
-                modrm = ldub_code(s->pc++);
-                parse_modrm(s, modrm);
-                break;
-            case 1: /* OP Gv, Ev */
-                modrm = ldub_code(s->pc++);
-                parse_modrm(s, modrm);
-                break;
-            case 2: /* OP A, Iv */
-                insn_get(s, ot);
-                break;
-            }
-        }
-        break;
-
-    case 0x80: /* GRP1 */
-    case 0x81:
-    case 0x82:
-    case 0x83:
-        {
-            if ((b & 1) == 0)
-                ot = OT_BYTE;
-            else
-                ot = dflag ? OT_LONG : OT_WORD;
-
-            modrm = ldub_code(s->pc++);
-            parse_modrm(s, modrm);
-
-            switch(b) {
-            default:
-            case 0x80:
-            case 0x81:
-            case 0x82:
-                insn_get(s, ot);
-                break;
-            case 0x83:
-                insn_get(s, OT_BYTE);
-                break;
-            }
-        }
-        break;
-
-        /**************************/
-        /* inc, dec, and other misc arith */
-    case 0x40 ... 0x47: /* inc Gv */
-        break;
-    case 0x48 ... 0x4f: /* dec Gv */
-        break;
-    case 0xf6: /* GRP3 */
-    case 0xf7:
-        if ((b & 1) == 0)
-            ot = OT_BYTE;
-        else
-            ot = dflag ? OT_LONG : OT_WORD;
-
-        modrm = ldub_code(s->pc++);
-        op = (modrm >> 3) & 7;
-        parse_modrm(s, modrm);
-
-        switch(op) {
-        case 0: /* test */
-            insn_get(s, ot);
-            break;
-        case 2: /* not */
-            break;
-        case 3: /* neg */
-            break;
-        case 4: /* mul */
-            break;
-        case 5: /* imul */
-            break;
-        case 6: /* div */
-            break;
-        case 7: /* idiv */
-            break;
-        default:
-            goto illegal_op;
-        }
-        break;
-
-    case 0xfe: /* GRP4 */
-    case 0xff: /* GRP5 */
-        if ((b & 1) == 0)
-            ot = OT_BYTE;
-        else
-            ot = dflag ? OT_LONG : OT_WORD;
-
-        modrm = ldub_code(s->pc++);
-        mod = (modrm >> 6) & 3;
-        op = (modrm >> 3) & 7;
-        if (op >= 2 && b == 0xfe) {
-            goto illegal_op;
-        }
-        pc_tmp = s->pc;
-        parse_modrm(s, modrm);
-
-        switch(op) {
-        case 0: /* inc Ev */
-            break;
-        case 1: /* dec Ev */
-            break;
-        case 2: /* call Ev */
-            /* XXX: optimize and handle MEM exceptions specifically
-               fs movl %eax, regs[0]
-               movl Ev, %eax
-               pushl next_eip
-               fs movl %eax, eip
-            */
-            goto unsupported_op;
-        case 3: /* lcall Ev */
-            goto unsupported_op;
-        case 4: /* jmp Ev */
-            /* XXX: optimize and handle MEM exceptions specifically
-               fs movl %eax, regs[0]
-               movl Ev, %eax
-               fs movl %eax, eip
-            */
-            goto unsupported_op;
-        case 5: /* ljmp Ev */
-            goto unsupported_op;
-        case 6: /* push Ev */
-            break;
-        default:
-            goto illegal_op;
-        }
-        break;
-    case 0xa8: /* test eAX, Iv */
-    case 0xa9:
-        if ((b & 1) == 0)
-            ot = OT_BYTE;
-        else
-            ot = dflag ? OT_LONG : OT_WORD;
-        insn_get(s, ot);
-        break;
-
-    case 0x98: /* CWDE/CBW */
-        break;
-    case 0x99: /* CDQ/CWD */
-        break;
-    case 0x1af: /* imul Gv, Ev */
-    case 0x69: /* imul Gv, Ev, I */
-    case 0x6b:
-        ot = dflag ? OT_LONG : OT_WORD;
-        modrm = ldub_code(s->pc++);
-        parse_modrm(s, modrm);
-        if (b == 0x69) {
-            insn_get(s, ot);
-        } else if (b == 0x6b) {
-            insn_get(s, OT_BYTE);
-        } else {
-        }
-        break;
-
-    case 0x84: /* test Ev, Gv */
-    case 0x85:
-
-    case 0x1c0:
-    case 0x1c1: /* xadd Ev, Gv */
-
-    case 0x1b0:
-    case 0x1b1: /* cmpxchg Ev, Gv */
-
-    case 0x8f: /* pop Ev */
-
-    case 0x88:
-    case 0x89: /* mov Gv, Ev */
-
-    case 0x8a:
-    case 0x8b: /* mov Ev, Gv */
-
-    case 0x1b6: /* movzbS Gv, Eb */
-    case 0x1b7: /* movzwS Gv, Eb */
-    case 0x1be: /* movsbS Gv, Eb */
-    case 0x1bf: /* movswS Gv, Eb */
-
-    case 0x86:
-    case 0x87: /* xchg Ev, Gv */
-
-    case 0xd0:
-    case 0xd1: /* shift Ev,1 */
-
-    case 0xd2:
-    case 0xd3: /* shift Ev,cl */
-
-    case 0x1a5: /* shld cl */
-    case 0x1ad: /* shrd cl */
-
-    case 0x190 ... 0x19f: /* setcc Gv */
-
-    /* XXX: emulate cmov if not available ? */
-    case 0x140 ... 0x14f: /* cmov Gv, Ev */
-
-    case 0x1a3: /* bt Gv, Ev */
-    case 0x1ab: /* bts */
-    case 0x1b3: /* btr */
-    case 0x1bb: /* btc */
-
-    case 0x1bc: /* bsf */
-    case 0x1bd: /* bsr */
-
-        modrm = ldub_code(s->pc++);
-        parse_modrm(s, modrm);
-        break;
-
-    case 0x1c7: /* cmpxchg8b */
-        modrm = ldub_code(s->pc++);
-        mod = (modrm >> 6) & 3;
-        if (mod == 3)
-            goto illegal_op;
-        parse_modrm(s, modrm);
-        break;
-
-        /**************************/
-        /* push/pop */
-    case 0x50 ... 0x57: /* push */
-    case 0x58 ... 0x5f: /* pop */
-    case 0x60: /* pusha */
-    case 0x61: /* popa */
-        break;
-
-    case 0x68: /* push Iv */
-    case 0x6a:
-        ot = dflag ? OT_LONG : OT_WORD;
-        if (b == 0x68)
-            insn_get(s, ot);
-        else
-            insn_get(s, OT_BYTE);
-        break;
-    case 0xc8: /* enter */
-        lduw_code(s->pc);
-        s->pc += 2;
-        ldub_code(s->pc++);
-        break;
-    case 0xc9: /* leave */
-        break;
-
-    case 0x06: /* push es */
-    case 0x0e: /* push cs */
-    case 0x16: /* push ss */
-    case 0x1e: /* push ds */
-        /* XXX: optimize:
-         push segs[n].selector
-        */
-        goto unsupported_op;
-    case 0x1a0: /* push fs */
-    case 0x1a8: /* push gs */
-        goto unsupported_op;
-    case 0x07: /* pop es */
-    case 0x17: /* pop ss */
-    case 0x1f: /* pop ds */
-        goto unsupported_op;
-    case 0x1a1: /* pop fs */
-    case 0x1a9: /* pop gs */
-        goto unsupported_op;
-    case 0x8e: /* mov seg, Gv */
-        /* XXX: optimize:
-           fs movl r, regs[]
-           movl segs[].selector, r
-           mov r, Gv
-           fs movl regs[], r
-        */
-        goto unsupported_op;
-    case 0x8c: /* mov Gv, seg */
-        goto unsupported_op;
-    case 0xc4: /* les Gv */
-        op = R_ES;
-        goto do_lxx;
-    case 0xc5: /* lds Gv */
-        op = R_DS;
-        goto do_lxx;
-    case 0x1b2: /* lss Gv */
-        op = R_SS;
-        goto do_lxx;
-    case 0x1b4: /* lfs Gv */
-        op = R_FS;
-        goto do_lxx;
-    case 0x1b5: /* lgs Gv */
-        op = R_GS;
-    do_lxx:
-        goto unsupported_op;
-        /************************/
-        /* floats */
-    case 0xd8 ... 0xdf:
-#if 1
-        /* currently not stable enough */
-        goto unsupported_op;
-#else
-        if (s->flags & (HF_EM_MASK | HF_TS_MASK))
-            goto unsupported_op;
-#endif
-#if 0
-        /* for testing FPU context switch */
-        {
-            static int count;
-            count = (count + 1) % 3;
-            if (count != 0)
-                goto unsupported_op;
-        }
-#endif
-        modrm = ldub_code(s->pc++);
-        mod = (modrm >> 6) & 3;
-        rm = modrm & 7;
-        op = ((b & 7) << 3) | ((modrm >> 3) & 7);
-        if (mod != 3) {
-            /* memory op */
-            parse_modrm(s, modrm);
-            switch(op) {
-            case 0x00 ... 0x07: /* fxxxs */
-            case 0x10 ... 0x17: /* fixxxl */
-            case 0x20 ... 0x27: /* fxxxl */
-            case 0x30 ... 0x37: /* fixxx */
-                break;
-            case 0x08: /* flds */
-            case 0x0a: /* fsts */
-            case 0x0b: /* fstps */
-            case 0x18: /* fildl */
-            case 0x1a: /* fistl */
-            case 0x1b: /* fistpl */
-            case 0x28: /* fldl */
-            case 0x2a: /* fstl */
-            case 0x2b: /* fstpl */
-            case 0x38: /* filds */
-            case 0x3a: /* fists */
-            case 0x3b: /* fistps */
-            case 0x0c: /* fldenv mem */
-            case 0x0d: /* fldcw mem */
-            case 0x0e: /* fnstenv mem */
-            case 0x0f: /* fnstcw mem */
-            case 0x1d: /* fldt mem */
-            case 0x1f: /* fstpt mem */
-            case 0x2c: /* frstor mem */
-            case 0x2e: /* fnsave mem */
-            case 0x2f: /* fnstsw mem */
-            case 0x3c: /* fbld */
-            case 0x3e: /* fbstp */
-            case 0x3d: /* fildll */
-            case 0x3f: /* fistpll */
-                break;
-            default:
-                goto illegal_op;
-            }
-        } else {
-            /* register float ops */
-            switch(op) {
-            case 0x08: /* fld sti */
-            case 0x09: /* fxchg sti */
-                break;
-            case 0x0a: /* grp d9/2 */
-                switch(rm) {
-                case 0: /* fnop */
-                    break;
-                default:
-                    goto illegal_op;
-                }
-                break;
-            case 0x0c: /* grp d9/4 */
-                switch(rm) {
-                case 0: /* fchs */
-                case 1: /* fabs */
-                case 4: /* ftst */
-                case 5: /* fxam */
-                    break;
-                default:
-                    goto illegal_op;
-                }
-                break;
-            case 0x0d: /* grp d9/5 */
-                switch(rm) {
-                case 0:
-                case 1:
-                case 2:
-                case 3:
-                case 4:
-                case 5:
-                case 6:
-                    break;
-                default:
-                    goto illegal_op;
-                }
-                break;
-            case 0x0e: /* grp d9/6 */
-                break;
-            case 0x0f: /* grp d9/7 */
-                break;
-            case 0x00: case 0x01: case 0x04 ... 0x07: /* fxxx st, sti */
-            case 0x20: case 0x21: case 0x24 ... 0x27: /* fxxx sti, st */
-            case 0x30: case 0x31: case 0x34 ... 0x37: /* fxxxp sti, st */
-                break;
-            case 0x02: /* fcom */
-                break;
-            case 0x03: /* fcomp */
-                break;
-            case 0x15: /* da/5 */
-                switch(rm) {
-                case 1: /* fucompp */
-                    break;
-                default:
-                    goto illegal_op;
-                }
-                break;
-            case 0x1c:
-                switch(rm) {
-                case 0: /* feni (287 only, just do nop here) */
-                case 1: /* fdisi (287 only, just do nop here) */
-                    goto unsupported_op;
-                case 2: /* fclex */
-                case 3: /* fninit */
-                case 4: /* fsetpm (287 only, just do nop here) */
-                    break;
-                default:
-                    goto illegal_op;
-                }
-                break;
-            case 0x1d: /* fucomi */
-                break;
-            case 0x1e: /* fcomi */
-                break;
-            case 0x28: /* ffree sti */
-                break;
-            case 0x2a: /* fst sti */
-                break;
-            case 0x2b: /* fstp sti */
-                break;
-            case 0x2c: /* fucom st(i) */
-                break;
-            case 0x2d: /* fucomp st(i) */
-                break;
-            case 0x33: /* de/3 */
-                switch(rm) {
-                case 1: /* fcompp */
-                    break;
-                default:
-                    goto illegal_op;
-                }
-                break;
-            case 0x3c: /* df/4 */
-                switch(rm) {
-                case 0:
-                    break;
-                default:
-                    goto illegal_op;
-                }
-                break;
-            case 0x3d: /* fucomip */
-                break;
-            case 0x3e: /* fcomip */
-                break;
-            case 0x10 ... 0x13: /* fcmovxx */
-            case 0x18 ... 0x1b:
-                break;
-            default:
-                goto illegal_op;
-            }
-        }
-        s->tb->cflags |= CF_TB_FP_USED;
-        break;
-
-        /**************************/
-        /* mov */
-    case 0xc6:
-    case 0xc7: /* mov Ev, Iv */
-        if ((b & 1) == 0)
-            ot = OT_BYTE;
-        else
-            ot = dflag ? OT_LONG : OT_WORD;
-        modrm = ldub_code(s->pc++);
-        parse_modrm(s, modrm);
-        insn_get(s, ot);
-        break;
-
-    case 0x8d: /* lea */
-        ot = dflag ? OT_LONG : OT_WORD;
-        modrm = ldub_code(s->pc++);
-        mod = (modrm >> 6) & 3;
-        if (mod == 3)
-            goto illegal_op;
-        parse_modrm(s, modrm);
-        break;
-
-    case 0xa0: /* mov EAX, Ov */
-    case 0xa1:
-    case 0xa2: /* mov Ov, EAX */
-    case 0xa3:
-        if ((b & 1) == 0)
-            ot = OT_BYTE;
-        else
-            ot = dflag ? OT_LONG : OT_WORD;
-        if (s->aflag)
-            insn_get(s, OT_LONG);
-        else
-            insn_get(s, OT_WORD);
-        break;
-    case 0xd7: /* xlat */
-        break;
-    case 0xb0 ... 0xb7: /* mov R, Ib */
-        insn_get(s, OT_BYTE);
-        break;
-    case 0xb8 ... 0xbf: /* mov R, Iv */
-        ot = dflag ? OT_LONG : OT_WORD;
-        insn_get(s, ot);
-        break;
-
-    case 0x91 ... 0x97: /* xchg R, EAX */
-        break;
-
-        /************************/
-        /* shifts */
-    case 0xc0:
-    case 0xc1: /* shift Ev,imm */
-
-    case 0x1a4: /* shld imm */
-    case 0x1ac: /* shrd imm */
-        modrm = ldub_code(s->pc++);
-        parse_modrm(s, modrm);
-        ldub_code(s->pc++);
-        break;
-
-        /************************/
-        /* string ops */
-
-    case 0xa4: /* movsS */
-    case 0xa5:
-        break;
-
-    case 0xaa: /* stosS */
-    case 0xab:
-        break;
-
-    case 0xac: /* lodsS */
-    case 0xad:
-        break;
-
-    case 0xae: /* scasS */
-    case 0xaf:
-        break;
-
-    case 0xa6: /* cmpsS */
-    case 0xa7:
-        break;
-
-    case 0x6c: /* insS */
-    case 0x6d:
-        goto unsupported_op;
-
-    case 0x6e: /* outsS */
-    case 0x6f:
-        goto unsupported_op;
-
-        /************************/
-        /* port I/O */
-    case 0xe4:
-    case 0xe5:
-        goto unsupported_op;
-
-    case 0xe6:
-    case 0xe7:
-        goto unsupported_op;
-
-    case 0xec:
-    case 0xed:
-        goto unsupported_op;
-
-    case 0xee:
-    case 0xef:
-        goto unsupported_op;
-
-        /************************/
-        /* control */
-#if 0
-    case 0xc2: /* ret im */
-        val = ldsw_code(s->pc);
-        s->pc += 2;
-        gen_pop_T0(s);
-        gen_stack_update(s, val + (2 << s->dflag));
-        if (s->dflag == 0)
-            gen_op_andl_T0_ffff();
-        gen_op_jmp_T0();
-        gen_eob(s);
-        break;
-#endif
-
-    case 0xc3: /* ret */
-        gb(s, CPU_SEG);
-        if (!s->dflag)
-            gb(s, 0x66); /* d16 */
-        gb(s, 0x8f); /* pop addr */
-        gb(s, 0x05);
-        gl(s, CPU_FIELD_OFFSET(eip));
-        if (!s->dflag) {
-            /* reset high bits of EIP */
-            gen_movw_addr_im(s, CPU_FIELD_OFFSET(eip) + 2, 0);
-        }
-        gen_eob(s);
-        goto no_copy;
-    case 0xca: /* lret im */
-    case 0xcb: /* lret */
-    case 0xcf: /* iret */
-    case 0x9a: /* lcall im */
-    case 0xea: /* ljmp im */
-        goto unsupported_op;
-
-    case 0xe8: /* call im */
-        ot = dflag ? OT_LONG : OT_WORD;
-        val = insn_get(s, ot);
-        next_eip = s->pc - s->cs_base;
-        val += next_eip;
-        if (s->dflag) {
-            gb(s, 0x68); /* pushl imm */
-            gl(s, next_eip);
-        } else {
-            gb(s, 0x66); /* pushw imm */
-            gb(s, 0x68);
-            gw(s, next_eip);
-            val &= 0xffff;
-        }
-        gen_jmp(s, val);
-        goto no_copy;
-    case 0xe9: /* jmp */
-        ot = dflag ? OT_LONG : OT_WORD;
-        val = insn_get(s, ot);
-        val += s->pc - s->cs_base;
-        if (s->dflag == 0)
-            val = val & 0xffff;
-        gen_jmp(s, val);
-        goto no_copy;
-    case 0xeb: /* jmp Jb */
-        val = (int8_t)insn_get(s, OT_BYTE);
-        val += s->pc - s->cs_base;
-        if (s->dflag == 0)
-            val = val & 0xffff;
-        gen_jmp(s, val);
-        goto no_copy;
-    case 0x70 ... 0x7f: /* jcc Jb */
-        val = (int8_t)insn_get(s, OT_BYTE);
-        goto do_jcc;
-    case 0x180 ... 0x18f: /* jcc Jv */
-        if (dflag) {
-            val = insn_get(s, OT_LONG);
-        } else {
-            val = (int16_t)insn_get(s, OT_WORD);
-        }
-    do_jcc:
-        next_eip = s->pc - s->cs_base;
-        val += next_eip;
-        if (s->dflag == 0)
-            val &= 0xffff;
-        gen_jcc(s, b & 0xf, val, next_eip);
-        goto no_copy;
-
-        /************************/
-        /* flags */
-    case 0x9c: /* pushf */
-        /* XXX: put specific code ? */
-        goto unsupported_op;
-    case 0x9d: /* popf */
-        goto unsupported_op;
-
-    case 0x9e: /* sahf */
-    case 0x9f: /* lahf */
-    case 0xf5: /* cmc */
-    case 0xf8: /* clc */
-    case 0xf9: /* stc */
-    case 0xfc: /* cld */
-    case 0xfd: /* std */
-        break;
-
-        /************************/
-        /* bit operations */
-    case 0x1ba: /* bt/bts/btr/btc Gv, im */
-        ot = dflag ? OT_LONG : OT_WORD;
-        modrm = ldub_code(s->pc++);
-        op = (modrm >> 3) & 7;
-        parse_modrm(s, modrm);
-        /* load shift */
-        ldub_code(s->pc++);
-        if (op < 4)
-            goto illegal_op;
-        break;
-        /************************/
-        /* bcd */
-    case 0x27: /* daa */
-        break;
-    case 0x2f: /* das */
-        break;
-    case 0x37: /* aaa */
-        break;
-    case 0x3f: /* aas */
-        break;
-    case 0xd4: /* aam */
-        ldub_code(s->pc++);
-        break;
-    case 0xd5: /* aad */
-        ldub_code(s->pc++);
-        break;
-        /************************/
-        /* misc */
-    case 0x90: /* nop */
-        break;
-    case 0x9b: /* fwait */
-        if ((s->flags & (HF_MP_MASK | HF_TS_MASK)) ==
-            (HF_MP_MASK | HF_TS_MASK)) {
-            goto unsupported_op;
-        }
-        break;
-    case 0xcc: /* int3 */
-        goto unsupported_op;
-    case 0xcd: /* int N */
-        goto unsupported_op;
-    case 0xce: /* into */
-        goto unsupported_op;
-    case 0xf1: /* icebp (undocumented, exits to external debugger) */
-        goto unsupported_op;
-    case 0xfa: /* cli */
-        goto unsupported_op;
-    case 0xfb: /* sti */
-        goto unsupported_op;
-    case 0x62: /* bound */
-        modrm = ldub_code(s->pc++);
-        mod = (modrm >> 6) & 3;
-        if (mod == 3)
-            goto illegal_op;
-        parse_modrm(s, modrm);
-        break;
-    case 0x1c8 ... 0x1cf: /* bswap reg */
-        break;
-    case 0xd6: /* salc */
-        break;
-    case 0xe0: /* loopnz */
-    case 0xe1: /* loopz */
-    case 0xe2: /* loop */
-    case 0xe3: /* jecxz */
-        goto unsupported_op;
-
-    case 0x130: /* wrmsr */
-    case 0x132: /* rdmsr */
-        goto unsupported_op;
-    case 0x131: /* rdtsc */
-        goto unsupported_op;
-    case 0x1a2: /* cpuid */
-        goto unsupported_op;
-    case 0xf4: /* hlt */
-        goto unsupported_op;
-    case 0x100:
-        goto unsupported_op;
-    case 0x101:
-        goto unsupported_op;
-    case 0x108: /* invd */
-    case 0x109: /* wbinvd */
-        goto unsupported_op;
-    case 0x63: /* arpl */
-        goto unsupported_op;
-    case 0x102: /* lar */
-    case 0x103: /* lsl */
-        goto unsupported_op;
-    case 0x118:
-        goto unsupported_op;
-    case 0x120: /* mov reg, crN */
-    case 0x122: /* mov crN, reg */
-        goto unsupported_op;
-    case 0x121: /* mov reg, drN */
-    case 0x123: /* mov drN, reg */
-        goto unsupported_op;
-    case 0x106: /* clts */
-        goto unsupported_op;
-    default:
-        goto illegal_op;
-    }
-
-    /* just copy the code */
-
-    /* no override yet */
-    if (!s->dflag)
-        gb(s, 0x66);
-    if (!s->aflag)
-        gb(s, 0x67);
-    if (prefixes & PREFIX_REPZ)
-        gb(s, 0xf3);
-    else if (prefixes & PREFIX_REPNZ)
-        gb(s, 0xf2);
-    {
-        int len, i;
-        len = s->pc - pc_start_insn;
-        for(i = 0; i < len; i++) {
-            *s->gen_code_ptr++ = ldub_code(pc_start_insn + i);
-        }
-    }
- no_copy:
-    return 0;
- illegal_op:
- unsupported_op:
-    /* fall back to slower code gen necessary */
-    s->pc = pc_start;
-    return -1;
-}
-
-#define GEN_CODE_MAX_SIZE      8192
-#define GEN_CODE_MAX_INSN_SIZE 512
-
-static inline int gen_intermediate_code_internal(CPUState *env,
-                                                 TranslationBlock *tb,
-                                                 uint8_t *gen_code_ptr,
-                                                 int *gen_code_size_ptr,
-                                                 int search_pc,
-                                                 uint8_t *tc_ptr)
-{
-    DisasContext dc1, *dc = &dc1;
-    target_ulong pc_insn, pc_start, cs_base;
-    uint8_t *gen_code_end;
-    int flags, ret;
-
-    if (env->nb_breakpoints > 0 ||
-        env->singlestep_enabled)
-        return -1;
-    flags = tb->flags;
-    if (flags & (HF_TF_MASK | HF_ADDSEG_MASK |
-                 HF_SOFTMMU_MASK | HF_INHIBIT_IRQ_MASK))
-        return -1;
-    if (!(flags & HF_SS32_MASK))
-        return -1;
-    if (tb->cflags & CF_SINGLE_INSN)
-        return -1;
-    gen_code_end = gen_code_ptr +
-        GEN_CODE_MAX_SIZE - GEN_CODE_MAX_INSN_SIZE;
-    dc->gen_code_ptr = gen_code_ptr;
-    dc->gen_code_start = gen_code_ptr;
-
-    /* generate intermediate code */
-    pc_start = tb->pc;
-    cs_base = tb->cs_base;
-    dc->pc = pc_start;
-    dc->cs_base = cs_base;
-    dc->pe = (flags >> HF_PE_SHIFT) & 1;
-    dc->code32 = (flags >> HF_CS32_SHIFT) & 1;
-    dc->f_st = 0;
-    dc->vm86 = (flags >> VM_SHIFT) & 1;
-    dc->cpl = (flags >> HF_CPL_SHIFT) & 3;
-    dc->iopl = (flags >> IOPL_SHIFT) & 3;
-    dc->tb = tb;
-    dc->flags = flags;
-
-    dc->is_jmp = 0;
-
-    for(;;) {
-        pc_insn = dc->pc;
-        ret = disas_insn(dc);
-        if (ret < 0) {
-            /* unsupported insn */
-            if (dc->pc == pc_start) {
-                /* if first instruction, signal that no copying was done */
-                return -1;
-            } else {
-                gen_jmp(dc, dc->pc - dc->cs_base);
-                dc->is_jmp = 1;
-            }
-        }
-        if (search_pc) {
-            /* search pc mode */
-            if (tc_ptr < dc->gen_code_ptr) {
-                env->eip = pc_insn - cs_base;
-                return 0;
-            }
-        }
-        /* stop translation if indicated */
-        if (dc->is_jmp)
-            break;
-        /* if too long translation, stop generation */
-        if (dc->gen_code_ptr >= gen_code_end ||
-            (dc->pc - pc_start) >= (TARGET_PAGE_SIZE - 32)) {
-            gen_jmp(dc, dc->pc - dc->cs_base);
-            break;
-        }
-    }
-
-#ifdef DEBUG_DISAS
-    if (loglevel & CPU_LOG_TB_IN_ASM) {
-        fprintf(logfile, "----------------\n");
-        fprintf(logfile, "IN: COPY: %s fpu=%d\n",
-                lookup_symbol(pc_start),
-                tb->cflags & CF_TB_FP_USED ? 1 : 0);
-	target_disas(logfile, pc_start, dc->pc - pc_start, !dc->code32);
-        fprintf(logfile, "\n");
-    }
-#endif
-
-    if (!search_pc) {
-        *gen_code_size_ptr = dc->gen_code_ptr - dc->gen_code_start;
-        tb->size = dc->pc - pc_start;
-        tb->cflags |= CF_CODE_COPY;
-        return 0;
-    } else {
-        return -1;
-    }
-}
-
-/* generate code by just copying data. Return -1 if cannot generate
-   any code. Return 0 if code was generated */
-int cpu_gen_code_copy(CPUState *env, TranslationBlock *tb,
-                      int max_code_size, int *gen_code_size_ptr)
-{
-    /* generate machine code */
-    tb->tb_next_offset[0] = 0xffff;
-    tb->tb_next_offset[1] = 0xffff;
-#ifdef USE_DIRECT_JUMP
-    /* the following two entries are optional (only used for string ops) */
-    tb->tb_jmp_offset[2] = 0xffff;
-    tb->tb_jmp_offset[3] = 0xffff;
-#endif
-    return gen_intermediate_code_internal(env, tb,
-                                          tb->tc_ptr, gen_code_size_ptr,
-                                          0, NULL);
-}
-
-static uint8_t dummy_gen_code_buf[GEN_CODE_MAX_SIZE];
-
-int cpu_restore_state_copy(TranslationBlock *tb,
-                           CPUState *env, unsigned long searched_pc,
-                           void *puc)
-{
-    struct ucontext *uc = puc;
-    int ret, eflags;
-
-    /* find opc index corresponding to search_pc */
-    if (searched_pc < (unsigned long)tb->tc_ptr)
-        return -1;
-    searched_pc = searched_pc - (long)tb->tc_ptr + (long)dummy_gen_code_buf;
-    ret = gen_intermediate_code_internal(env, tb,
-                                         dummy_gen_code_buf, NULL,
-                                         1, (uint8_t *)searched_pc);
-    if (ret < 0)
-        return ret;
-    /* restore all the CPU state from the CPU context from the
-       signal. The FPU context stays in the host CPU. */
-
-    env->regs[R_EAX] = uc->uc_mcontext.gregs[REG_EAX];
-    env->regs[R_ECX] = uc->uc_mcontext.gregs[REG_ECX];
-    env->regs[R_EDX] = uc->uc_mcontext.gregs[REG_EDX];
-    env->regs[R_EBX] = uc->uc_mcontext.gregs[REG_EBX];
-    env->regs[R_ESP] = uc->uc_mcontext.gregs[REG_ESP];
-    env->regs[R_EBP] = uc->uc_mcontext.gregs[REG_EBP];
-    env->regs[R_ESI] = uc->uc_mcontext.gregs[REG_ESI];
-    env->regs[R_EDI] = uc->uc_mcontext.gregs[REG_EDI];
-    eflags = uc->uc_mcontext.gregs[REG_EFL];
-    env->df = 1 - (2 * ((eflags >> 10) & 1));
-    env->cc_src = eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
-    env->cc_op = CC_OP_EFLAGS;
-    return 0;
-}
-
-#endif /* USE_CODE_COPY */

Modified: trunk/src/host/qemu-neo1973/target-i386/translate.c
===================================================================
--- trunk/src/host/qemu-neo1973/target-i386/translate.c	2007-11-09 16:32:22 UTC (rev 3386)
+++ trunk/src/host/qemu-neo1973/target-i386/translate.c	2007-11-09 17:12:19 UTC (rev 3387)
@@ -4888,9 +4888,6 @@
                 goto illegal_op;
             }
         }
-#ifdef USE_CODE_COPY
-        s->tb->cflags |= CF_TB_FP_USED;
-#endif
         break;
         /************************/
         /* string ops */

Modified: trunk/src/host/qemu-neo1973/target-mips/exec.h
===================================================================
--- trunk/src/host/qemu-neo1973/target-mips/exec.h	2007-11-09 16:32:22 UTC (rev 3386)
+++ trunk/src/host/qemu-neo1973/target-mips/exec.h	2007-11-09 17:12:19 UTC (rev 3387)
@@ -56,7 +56,7 @@
 #include "softmmu_exec.h"
 #endif /* !defined(CONFIG_USER_ONLY) */
 
-#if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)
+#if defined(TARGET_MIPS64)
 #if TARGET_LONG_BITS > HOST_LONG_BITS
 void do_dsll (void);
 void do_dsll32 (void);
@@ -86,7 +86,7 @@
 void do_msub (void);
 void do_msubu (void);
 #endif
-#if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)
+#if defined(TARGET_MIPS64)
 void do_ddiv (void);
 #if TARGET_LONG_BITS > HOST_LONG_BITS
 void do_ddivu (void);
@@ -236,7 +236,7 @@
         !(env->hflags & MIPS_HFLAG_DM)) {
         env->hflags |= (env->CP0_Status >> CP0St_KSU) & MIPS_HFLAG_KSU;
     }
-#if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)
+#if defined(TARGET_MIPS64)
     if (((env->hflags & MIPS_HFLAG_KSU) != MIPS_HFLAG_UM) ||
         (env->CP0_Status & (1 << CP0St_PX)) ||
         (env->CP0_Status & (1 << CP0St_UX)))

Modified: trunk/src/host/qemu-neo1973/target-mips/helper.c
===================================================================
--- trunk/src/host/qemu-neo1973/target-mips/helper.c	2007-11-09 16:32:22 UTC (rev 3386)
+++ trunk/src/host/qemu-neo1973/target-mips/helper.c	2007-11-09 17:12:19 UTC (rev 3387)
@@ -76,7 +76,7 @@
         target_ulong mask = tlb->PageMask | ~(TARGET_PAGE_MASK << 1);
         target_ulong tag = address & ~mask;
         target_ulong VPN = tlb->VPN & ~mask;
-#if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)
+#if defined(TARGET_MIPS64)
         tag &= env->SEGMask;
 #endif
 
@@ -108,7 +108,7 @@
     int user_mode = (env->hflags & MIPS_HFLAG_MODE) == MIPS_HFLAG_UM;
     int supervisor_mode = (env->hflags & MIPS_HFLAG_MODE) == MIPS_HFLAG_SM;
     int kernel_mode = !user_mode && !supervisor_mode;
-#if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)
+#if defined(TARGET_MIPS64)
     int UX = (env->CP0_Status & (1 << CP0St_UX)) != 0;
     int SX = (env->CP0_Status & (1 << CP0St_SX)) != 0;
     int KX = (env->CP0_Status & (1 << CP0St_KX)) != 0;
@@ -130,7 +130,7 @@
         } else {
             ret = env->tlb->map_address(env, physical, prot, address, rw, access_type);
         }
-#if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)
+#if defined(TARGET_MIPS64)
     } else if (address < 0x4000000000000000ULL) {
         /* xuseg */
 	if (UX && address < (0x3FFFFFFFFFFFFFFFULL & env->SEGMask)) {
@@ -305,7 +305,7 @@
 	                   ((address >> 9) &   0x007ffff0);
         env->CP0_EntryHi =
             (env->CP0_EntryHi & 0xFF) | (address & (TARGET_PAGE_MASK << 1));
-#if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)
+#if defined(TARGET_MIPS64)
         env->CP0_EntryHi &= env->SEGMask;
         env->CP0_XContext = (env->CP0_XContext & ((~0ULL) << (env->SEGBITS - 7))) |
                             ((address & 0xC00000000000ULL) >> (env->SEGBITS - 9)) |
@@ -425,7 +425,7 @@
     case EXCP_TLBL:
         cause = 2;
         if (env->error_code == 1 && !(env->CP0_Status & (1 << CP0St_EXL))) {
-#if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)
+#if defined(TARGET_MIPS64)
             int R = env->CP0_BadVAddr >> 62;
             int UX = (env->CP0_Status & (1 << CP0St_UX)) != 0;
             int SX = (env->CP0_Status & (1 << CP0St_SX)) != 0;
@@ -473,7 +473,7 @@
     case EXCP_TLBS:
         cause = 3;
         if (env->error_code == 1 && !(env->CP0_Status & (1 << CP0St_EXL))) {
-#if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)
+#if defined(TARGET_MIPS64)
             int R = env->CP0_BadVAddr >> 62;
             int UX = (env->CP0_Status & (1 << CP0St_UX)) != 0;
             int SX = (env->CP0_Status & (1 << CP0St_SX)) != 0;
@@ -559,7 +559,7 @@
     mask = tlb->PageMask | ~(TARGET_PAGE_MASK << 1);
     if (tlb->V0) {
         addr = tlb->VPN & ~mask;
-#if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)
+#if defined(TARGET_MIPS64)
         if (addr >= (0xFFFFFFFF80000000ULL & env->SEGMask)) {
             addr |= 0x3FFFFF0000000000ULL;
         }
@@ -572,7 +572,7 @@
     }
     if (tlb->V1) {
         addr = (tlb->VPN & ~mask) | ((mask >> 1) + 1);
-#if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)
+#if defined(TARGET_MIPS64)
         if (addr >= (0xFFFFFFFF80000000ULL & env->SEGMask)) {
             addr |= 0x3FFFFF0000000000ULL;
         }

Modified: trunk/src/host/qemu-neo1973/target-mips/mips-defs.h
===================================================================
--- trunk/src/host/qemu-neo1973/target-mips/mips-defs.h	2007-11-09 16:32:22 UTC (rev 3386)
+++ trunk/src/host/qemu-neo1973/target-mips/mips-defs.h	2007-11-09 17:12:19 UTC (rev 3387)
@@ -8,7 +8,7 @@
 #define TARGET_PAGE_BITS 12
 #define MIPS_TLB_MAX 128
 
-#if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)
+#if defined(TARGET_MIPS64)
 #define TARGET_LONG_BITS 64
 #else
 #define TARGET_LONG_BITS 32

Modified: trunk/src/host/qemu-neo1973/target-mips/op.c
===================================================================
--- trunk/src/host/qemu-neo1973/target-mips/op.c	2007-11-09 16:32:22 UTC (rev 3386)
+++ trunk/src/host/qemu-neo1973/target-mips/op.c	2007-11-09 17:12:19 UTC (rev 3387)
@@ -301,7 +301,7 @@
 /* For compatibility with 32-bit code, data reference in user mode
    with Status_UX = 0 should be casted to 32-bit and sign extended.
    See the MIPS64 PRA manual, section 4.10. */
-#if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)
+#if defined(TARGET_MIPS64)
     if (((env->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_UM) &&
         !(env->CP0_Status & (1 << CP0St_UX)))
         T0 = (int64_t)(int32_t)(T0 + T1);
@@ -384,7 +384,7 @@
     RETURN();
 }
 
-#if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)
+#if defined(TARGET_MIPS64)
 /* Arithmetic */
 void op_dadd (void)
 {
@@ -453,7 +453,7 @@
     RETURN();
 }
 #endif
-#endif /* TARGET_MIPSN32 || TARGET_MIPS64 */
+#endif /* TARGET_MIPS64 */
 
 /* Logical */
 void op_and (void)
@@ -552,7 +552,7 @@
     RETURN();
 }
 
-#if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)
+#if defined(TARGET_MIPS64)
 
 #if TARGET_LONG_BITS > HOST_LONG_BITS
 /* Those might call libgcc functions.  */
@@ -743,7 +743,7 @@
     RETURN();
 }
 #endif /* TARGET_LONG_BITS > HOST_LONG_BITS */
-#endif /* TARGET_MIPSN32 || TARGET_MIPS64 */
+#endif /* TARGET_MIPS64 */
 
 /* 64 bits arithmetic */
 #if TARGET_LONG_BITS > HOST_LONG_BITS
@@ -846,7 +846,7 @@
 }
 #endif /* TARGET_LONG_BITS > HOST_LONG_BITS */
 
-#if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)
+#if defined(TARGET_MIPS64)
 void op_dmult (void)
 {
     CALL_FROM_TB4(muls64, &(env->LO[0][env->current_tc]), &(env->HI[0][env->current_tc]), T0, T1);
@@ -950,7 +950,7 @@
     RETURN();
 }
 
-#if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)
+#if defined(TARGET_MIPS64)
 void op_save_btarget64 (void)
 {
     env->btarget = ((uint64_t)PARAM1 << 32) | (uint32_t)PARAM2;
@@ -1784,7 +1784,7 @@
 
     /* 1k pages not implemented */
     val = T0 & ((TARGET_PAGE_MASK << 1) | 0xFF);
-#if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)
+#if defined(TARGET_MIPS64)
     val &= env->SEGMask;
 #endif
     old = env->CP0_EntryHi;
@@ -2011,7 +2011,7 @@
     RETURN();
 }
 
-#if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)
+#if defined(TARGET_MIPS64)
 void op_dmfc0_yqmask (void)
 {
     T0 = env->CP0_YQMask;
@@ -2125,7 +2125,7 @@
     T0 = env->CP0_ErrorEPC;
     RETURN();
 }
-#endif /* TARGET_MIPSN32 || TARGET_MIPS64 */
+#endif /* TARGET_MIPS64 */
 
 /* MIPS MT functions */
 void op_mftgpr(void)
@@ -3039,7 +3039,7 @@
     RETURN();
 }
 
-#if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)
+#if defined(TARGET_MIPS64)
 void op_save_pc64 (void)
 {
     env->PC[env->current_tc] = ((uint64_t)PARAM1 << 32) | (uint32_t)PARAM2;
@@ -3111,7 +3111,7 @@
     RETURN();
 }
 
-#if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)
+#if defined(TARGET_MIPS64)
 void op_dext(void)
 {
     unsigned int pos = PARAM1;

Modified: trunk/src/host/qemu-neo1973/target-mips/op_helper.c
===================================================================
--- trunk/src/host/qemu-neo1973/target-mips/op_helper.c	2007-11-09 16:32:22 UTC (rev 3386)
+++ trunk/src/host/qemu-neo1973/target-mips/op_helper.c	2007-11-09 17:12:19 UTC (rev 3387)
@@ -68,7 +68,7 @@
     do_raise_exception_direct_err (exception, 0);
 }
 
-#if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)
+#if defined(TARGET_MIPS64)
 #if TARGET_LONG_BITS > HOST_LONG_BITS
 /* Those might call libgcc functions.  */
 void do_dsll (void)
@@ -159,7 +159,7 @@
 }
 
 #endif /* TARGET_LONG_BITS > HOST_LONG_BITS */
-#endif /* TARGET_MIPSN32 || TARGET_MIPS64 */
+#endif /* TARGET_MIPS64 */
 
 /* 64 bits arithmetic for 32 bits hosts */
 #if TARGET_LONG_BITS > HOST_LONG_BITS
@@ -228,7 +228,7 @@
 }
 #endif
 
-#if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)
+#if defined(TARGET_MIPS64)
 void do_ddiv (void)
 {
     if (T1 != 0) {
@@ -247,7 +247,7 @@
     }
 }
 #endif
-#endif /* TARGET_MIPSN32 || TARGET_MIPS64 */
+#endif /* TARGET_MIPS64 */
 
 #if defined(CONFIG_USER_ONLY)
 void do_mfc0_random (void)
@@ -392,7 +392,7 @@
     /* XXX: detect conflicting TLBs and raise a MCHECK exception when needed */
     tlb = &env->tlb->mmu.r4k.tlb[idx];
     tlb->VPN = env->CP0_EntryHi & (TARGET_PAGE_MASK << 1);
-#if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)
+#if defined(TARGET_MIPS64)
     tlb->VPN &= env->SEGMask;
 #endif
     tlb->ASID = env->CP0_EntryHi & 0xFF;

Modified: trunk/src/host/qemu-neo1973/target-mips/op_mem.c
===================================================================
--- trunk/src/host/qemu-neo1973/target-mips/op_mem.c	2007-11-09 16:32:22 UTC (rev 3386)
+++ trunk/src/host/qemu-neo1973/target-mips/op_mem.c	2007-11-09 17:12:19 UTC (rev 3387)
@@ -190,7 +190,7 @@
     RETURN();
 }
 
-#if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)
+#if defined(TARGET_MIPS64)
 void glue(op_ld, MEMSUFFIX) (void)
 {
     T0 = glue(ldq, MEMSUFFIX)(T0);
@@ -381,7 +381,7 @@
     }
     RETURN();
 }
-#endif /* TARGET_MIPSN32 || TARGET_MIPS64 */
+#endif /* TARGET_MIPS64 */
 
 void glue(op_lwc1, MEMSUFFIX) (void)
 {

Modified: trunk/src/host/qemu-neo1973/target-mips/op_template.c
===================================================================
--- trunk/src/host/qemu-neo1973/target-mips/op_template.c	2007-11-09 16:32:22 UTC (rev 3386)
+++ trunk/src/host/qemu-neo1973/target-mips/op_template.c	2007-11-09 17:12:19 UTC (rev 3387)
@@ -82,7 +82,7 @@
 
 #undef SET_RESET
 
-#if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)
+#if defined(TARGET_MIPS64)
 #define SET64(treg, tregname)                               \
     void glue(op_set64, tregname)(void)                     \
     {                                                       \

Modified: trunk/src/host/qemu-neo1973/target-mips/translate.c
===================================================================
--- trunk/src/host/qemu-neo1973/target-mips/translate.c	2007-11-09 16:32:22 UTC (rev 3386)
+++ trunk/src/host/qemu-neo1973/target-mips/translate.c	2007-11-09 17:12:19 UTC (rev 3387)
@@ -590,7 +590,7 @@
     }                                                                         \
 } while (0)
 
-#if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)
+#if defined(TARGET_MIPS64)
 #define GEN_LOAD_IMM_TN(Tn, Imm)                                              \
 do {                                                                          \
     if (Imm == 0) {                                                           \
@@ -638,7 +638,7 @@
 
 static always_inline void gen_save_pc(target_ulong pc)
 {
-#if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)
+#if defined(TARGET_MIPS64)
     if (pc == (int32_t)pc) {
         gen_op_save_pc(pc);
     } else {
@@ -651,7 +651,7 @@
 
 static always_inline void gen_save_btarget(target_ulong btarget)
 {
-#if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)
+#if defined(TARGET_MIPS64)
     if (btarget == (int32_t)btarget) {
         gen_op_save_btarget(btarget);
     } else {
@@ -802,7 +802,7 @@
 }
 #endif
 
-#if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)
+#if defined(TARGET_MIPS64)
 OP_LD_TABLE(d);
 OP_LD_TABLE(dl);
 OP_LD_TABLE(dr);
@@ -852,7 +852,7 @@
     /* Don't do NOP if destination is zero: we must perform the actual
        memory access. */
     switch (opc) {
-#if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)
+#if defined(TARGET_MIPS64)
     case OPC_LWU:
         op_ldst(lwu);
         GEN_STORE_TN_REG(rt, T0);
@@ -1048,7 +1048,7 @@
     switch (opc) {
     case OPC_ADDI:
     case OPC_ADDIU:
-#if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)
+#if defined(TARGET_MIPS64)
     case OPC_DADDI:
     case OPC_DADDIU:
 #endif
@@ -1068,7 +1068,7 @@
     case OPC_SLL:
     case OPC_SRA:
     case OPC_SRL:
-#if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)
+#if defined(TARGET_MIPS64)
     case OPC_DSLL:
     case OPC_DSRA:
     case OPC_DSRL:
@@ -1091,7 +1091,7 @@
         gen_op_add();
         opn = "addiu";
         break;
-#if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)
+#if defined(TARGET_MIPS64)
     case OPC_DADDI:
         save_cpu_state(ctx, 1);
         gen_op_daddo();
@@ -1155,7 +1155,7 @@
             break;
         }
         break;
-#if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)
+#if defined(TARGET_MIPS64)
     case OPC_DSLL:
         gen_op_dsll();
         opn = "dsll";
@@ -1260,7 +1260,7 @@
         gen_op_sub();
         opn = "subu";
         break;
-#if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)
+#if defined(TARGET_MIPS64)
     case OPC_DADD:
         save_cpu_state(ctx, 1);
         gen_op_daddo();
@@ -1346,7 +1346,7 @@
             break;
         }
         break;
-#if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)
+#if defined(TARGET_MIPS64)
     case OPC_DSLLV:
         gen_op_dsllv();
         opn = "dsllv";
@@ -1451,7 +1451,7 @@
         gen_op_multu();
         opn = "multu";
         break;
-#if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)
+#if defined(TARGET_MIPS64)
     case OPC_DDIV:
         gen_op_ddiv();
         opn = "ddiv";
@@ -1512,7 +1512,7 @@
         gen_op_clz();
         opn = "clz";
         break;
-#if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)
+#if defined(TARGET_MIPS64)
     case OPC_DCLO:
         gen_op_dclo();
         opn = "dclo";
@@ -2319,7 +2319,7 @@
     case 20:
         switch (sel) {
         case 0:
-#if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)
+#if defined(TARGET_MIPS64)
             check_insn(env, ctx, ISA_MIPS3);
             gen_op_mfc0_xcontext();
             rn = "XContext";
@@ -2523,7 +2523,7 @@
     case 0:
         switch (sel) {
         case 0:
-           gen_op_mtc0_index();
+            gen_op_mtc0_index();
             rn = "Index";
             break;
         case 1:
@@ -2901,7 +2901,7 @@
     case 20:
         switch (sel) {
         case 0:
-#if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)
+#if defined(TARGET_MIPS64)
             check_insn(env, ctx, ISA_MIPS3);
             gen_op_mtc0_xcontext();
             rn = "XContext";
@@ -3111,7 +3111,7 @@
     generate_exception(ctx, EXCP_RI);
 }
 
-#if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)
+#if defined(TARGET_MIPS64)
 static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
 {
     const char *rn = "invalid";
@@ -4254,7 +4254,7 @@
 #endif
     generate_exception(ctx, EXCP_RI);
 }
-#endif /* TARGET_MIPSN32 || TARGET_MIPS64 */
+#endif /* TARGET_MIPS64 */
 
 static void gen_mftr(CPUState *env, DisasContext *ctx, int rt,
                      int u, int sel, int h)
@@ -4604,7 +4604,7 @@
         gen_mtc0(env, ctx, rd, ctx->opcode & 0x7);
         opn = "mtc0";
         break;
-#if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)
+#if defined(TARGET_MIPS64)
     case OPC_DMFC0:
         check_insn(env, ctx, ISA_MIPS3);
         if (rt == 0) {
@@ -5877,7 +5877,7 @@
 /* MIPS16 extension to MIPS32 */
 /* SmartMIPS extension to MIPS32 */
 
-#if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)
+#if defined(TARGET_MIPS64)
 
 /* MDMX extension to MIPS64 */
 
@@ -5987,7 +5987,7 @@
             }
             break;
 
-#if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)
+#if defined(TARGET_MIPS64)
        /* MIPS64 specific opcodes */
         case OPC_DSLL:
         case OPC_DSRL ... OPC_DSRA:
@@ -6043,7 +6043,7 @@
             }
             /* Treat as NOP. */
             break;
-#if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)
+#if defined(TARGET_MIPS64)
         case OPC_DCLZ ... OPC_DCLO:
             check_insn(env, ctx, ISA_MIPS64);
             check_mips_64(ctx);
@@ -6130,7 +6130,7 @@
             gen_op_yield();
             GEN_STORE_TN_REG(rd, T0);
             break;
-#if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)
+#if defined(TARGET_MIPS64)
         case OPC_DEXTM ... OPC_DEXT:
         case OPC_DINSM ... OPC_DINS:
             check_insn(env, ctx, ISA_MIPS64R2);
@@ -6192,7 +6192,7 @@
         case OPC_MTC0:
         case OPC_MFTR:
         case OPC_MTTR:
-#if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)
+#if defined(TARGET_MIPS64)
         case OPC_DMFC0:
         case OPC_DMTC0:
 #endif
@@ -6313,7 +6313,7 @@
             case OPC_CTC1:
                 gen_cp1(ctx, op1, rt, rd);
                 break;
-#if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)
+#if defined(TARGET_MIPS64)
             case OPC_DMFC1:
             case OPC_DMTC1:
                 check_insn(env, ctx, ISA_MIPS3);
@@ -6398,7 +6398,7 @@
         }
         break;
 
-#if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)
+#if defined(TARGET_MIPS64)
     /* MIPS64 opcodes */
     case OPC_LWU:
     case OPC_LDL ... OPC_LDR:
@@ -6665,7 +6665,7 @@
     }
 }
 
-#if (defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
+#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
 /* Debug help: The architecture requires 32bit code to maintain proper
    sign-extened values on 64bit machines.  */
 
@@ -6720,7 +6720,7 @@
                 env->CP0_Config0, env->CP0_Config1, env->CP0_LLAddr);
     if (env->hflags & MIPS_HFLAG_FPU)
         fpu_dump_state(env, f, cpu_fprintf, flags);
-#if (defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
+#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
     cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
 #endif
 }

Modified: trunk/src/host/qemu-neo1973/target-mips/translate_init.c
===================================================================
--- trunk/src/host/qemu-neo1973/target-mips/translate_init.c	2007-11-09 16:32:22 UTC (rev 3386)
+++ trunk/src/host/qemu-neo1973/target-mips/translate_init.c	2007-11-09 17:12:19 UTC (rev 3387)
@@ -201,7 +201,7 @@
                     (0x3fe << CP0SRSC4_SRS14) | (0x3fe << CP0SRSC4_SRS13),
         .insn_flags = CPU_MIPS32R2 | ASE_MIPS16 | ASE_DSP | ASE_MT,
     },
-#if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)
+#if defined(TARGET_MIPS64)
     {
         .name = "R4000",
         .CP0_PRid = 0x00000400,
@@ -437,7 +437,7 @@
     env->CP0_Status_rw_bitmask = def->CP0_Status_rw_bitmask;
     env->CP0_TCStatus_rw_bitmask = def->CP0_TCStatus_rw_bitmask;
     env->CP0_SRSCtl = def->CP0_SRSCtl;
-#if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)
+#if defined(TARGET_MIPS64)
     if (def->insn_flags & ISA_MIPS3)
     {
         env->hflags |= MIPS_HFLAG_64;

Modified: trunk/src/host/qemu-neo1973/target-ppc/cpu.h
===================================================================
--- trunk/src/host/qemu-neo1973/target-ppc/cpu.h	2007-11-09 16:32:22 UTC (rev 3386)
+++ trunk/src/host/qemu-neo1973/target-ppc/cpu.h	2007-11-09 17:12:19 UTC (rev 3387)
@@ -102,6 +102,8 @@
     POWERPC_MMU_BOOKE,
     /* BookE FSL MMU model                                     */
     POWERPC_MMU_BOOKE_FSL,
+    /* PowerPC 601 MMU model (specific BATs format)            */
+    POWERPC_MMU_601,
 #if defined(TARGET_PPC64)
     /* 64 bits PowerPC MMU                                     */
     POWERPC_MMU_64B,
@@ -649,7 +651,8 @@
     /* Those resources are used only in Qemu core */
     jmp_buf jmp_env;
     int user_mode_only; /* user mode only simulation */
-    target_ulong hflags; /* hflags is a MSR & HFLAGS_MASK */
+    target_ulong hflags;      /* hflags is a MSR & HFLAGS_MASK         */
+    target_ulong hflags_nmsr; /* specific hflags, not comming from MSR */
     int mmu_idx;         /* precomputed MMU index to speed up mem accesses */
 
     /* Power management */
@@ -696,6 +699,8 @@
 target_ulong do_load_dbatl (CPUPPCState *env, int nr);
 void do_store_dbatu (CPUPPCState *env, int nr, target_ulong value);
 void do_store_dbatl (CPUPPCState *env, int nr, target_ulong value);
+void do_store_ibatu_601 (CPUPPCState *env, int nr, target_ulong value);
+void do_store_ibatl_601 (CPUPPCState *env, int nr, target_ulong value);
 target_ulong do_load_sdr1 (CPUPPCState *env);
 void do_store_sdr1 (CPUPPCState *env, target_ulong value);
 #if defined(TARGET_PPC64)

Modified: trunk/src/host/qemu-neo1973/target-ppc/exec.h
===================================================================
--- trunk/src/host/qemu-neo1973/target-ppc/exec.h	2007-11-09 16:32:22 UTC (rev 3386)
+++ trunk/src/host/qemu-neo1973/target-ppc/exec.h	2007-11-09 17:12:19 UTC (rev 3387)
@@ -98,7 +98,7 @@
 void do_raise_exception (uint32_t exception);
 
 int get_physical_address (CPUState *env, mmu_ctx_t *ctx, target_ulong vaddr,
-                          int rw, int access_type, int check_BATs);
+                          int rw, int access_type);
 
 void ppc6xx_tlb_store (CPUState *env, target_ulong EPN, int way, int is_code,
                        target_ulong pte0, target_ulong pte1);

Modified: trunk/src/host/qemu-neo1973/target-ppc/helper.c
===================================================================
--- trunk/src/host/qemu-neo1973/target-ppc/helper.c	2007-11-09 16:32:22 UTC (rev 3386)
+++ trunk/src/host/qemu-neo1973/target-ppc/helper.c	2007-11-09 17:12:19 UTC (rev 3387)
@@ -448,12 +448,67 @@
 }
 
 /* Perform BAT hit & translation */
+static always_inline void bat_size_prot (CPUState *env, target_ulong *blp,
+                                         int *validp, int *protp,
+                                         target_ulong *BATu, target_ulong *BATl)
+{
+    target_ulong bl;
+    int pp, valid, prot;
+
+    bl = (*BATu & 0x00001FFC) << 15;
+    valid = 0;
+    prot = 0;
+    if (((msr_pr == 0) && (*BATu & 0x00000002)) ||
+        ((msr_pr != 0) && (*BATu & 0x00000001))) {
+        valid = 1;
+        pp = *BATl & 0x00000003;
+        if (pp != 0) {
+            prot = PAGE_READ | PAGE_EXEC;
+            if (pp == 0x2)
+                prot |= PAGE_WRITE;
+        }
+    }
+    *blp = bl;
+    *validp = valid;
+    *protp = prot;
+}
+
+static always_inline void bat_601_size_prot (CPUState *env,target_ulong *blp,
+                                             int *validp, int *protp,
+                                             target_ulong *BATu,
+                                             target_ulong *BATl)
+{
+    target_ulong bl;
+    int key, pp, valid, prot;
+
+    bl = (*BATl & 0x0000003F) << 17;
+#if defined (DEBUG_BATS)
+    if (loglevel != 0) {
+        fprintf(logfile, "b %02x ==> bl %08x msk %08x\n",
+                *BATl & 0x0000003F, bl, ~bl);
+    }
+#endif
+    prot = 0;
+    valid = (*BATl >> 6) & 1;
+    if (valid) {
+        pp = *BATu & 0x00000003;
+        if (msr_pr == 0)
+            key = (*BATu >> 3) & 1;
+        else
+            key = (*BATu >> 2) & 1;
+        prot = pp_check(key, pp, 0);
+    }
+    *blp = bl;
+    *validp = valid;
+    *protp = prot;
+}
+
 static always_inline int get_bat (CPUState *env, mmu_ctx_t *ctx,
                                   target_ulong virtual, int rw, int type)
 {
     target_ulong *BATlt, *BATut, *BATu, *BATl;
     target_ulong base, BEPIl, BEPIu, bl;
-    int i, pp, pr;
+    int i, valid, prot;
     int ret = -1;
 
 #if defined (DEBUG_BATS)
@@ -462,7 +517,6 @@
                 type == ACCESS_CODE ? 'I' : 'D', virtual);
     }
 #endif
-    pr = msr_pr;
     switch (type) {
     case ACCESS_CODE:
         BATlt = env->IBAT[1];
@@ -480,12 +534,16 @@
     }
 #endif
     base = virtual & 0xFFFC0000;
-    for (i = 0; i < 4; i++) {
+    for (i = 0; i < env->nb_BATs; i++) {
         BATu = &BATut[i];
         BATl = &BATlt[i];
         BEPIu = *BATu & 0xF0000000;
         BEPIl = *BATu & 0x0FFE0000;
-        bl = (*BATu & 0x00001FFC) << 15;
+        if (unlikely(env->mmu_model == POWERPC_MMU_601)) {
+            bat_601_size_prot(env, &bl, &valid, &prot, BATu, BATl);
+        } else {
+            bat_size_prot(env, &bl, &valid, &prot, BATu, BATl);
+        }
 #if defined (DEBUG_BATS)
         if (loglevel != 0) {
             fprintf(logfile, "%s: %cBAT%d v 0x" ADDRX " BATu 0x" ADDRX
@@ -497,20 +555,13 @@
         if ((virtual & 0xF0000000) == BEPIu &&
             ((virtual & 0x0FFE0000) & ~bl) == BEPIl) {
             /* BAT matches */
-            if (((pr == 0) && (*BATu & 0x00000002)) ||
-                ((pr != 0) && (*BATu & 0x00000001))) {
+            if (valid != 0) {
                 /* Get physical address */
                 ctx->raddr = (*BATl & 0xF0000000) |
                     ((virtual & 0x0FFE0000 & bl) | (*BATl & 0x0FFE0000)) |
                     (virtual & 0x0001F000);
                 /* Compute access rights */
-                pp = *BATl & 0x00000003;
-                ctx->prot = 0;
-                if (pp != 0) {
-                    ctx->prot = PAGE_READ | PAGE_EXEC;
-                    if (pp == 0x2)
-                        ctx->prot |= PAGE_WRITE;
-                }
+                ctx->prot = prot;
                 ret = check_prot(ctx->prot, rw, type);
 #if defined (DEBUG_BATS)
                 if (ret == 0 && loglevel != 0) {
@@ -1302,6 +1353,7 @@
     ret = 0;
     switch (env->mmu_model) {
     case POWERPC_MMU_32B:
+    case POWERPC_MMU_601:
     case POWERPC_MMU_SOFT_6xx:
     case POWERPC_MMU_SOFT_74xx:
     case POWERPC_MMU_SOFT_4xx:
@@ -1353,7 +1405,7 @@
 }
 
 int get_physical_address (CPUState *env, mmu_ctx_t *ctx, target_ulong eaddr,
-                          int rw, int access_type, int check_BATs)
+                          int rw, int access_type)
 {
     int ret;
 
@@ -1370,15 +1422,15 @@
         ret = -1;
         switch (env->mmu_model) {
         case POWERPC_MMU_32B:
+        case POWERPC_MMU_601:
         case POWERPC_MMU_SOFT_6xx:
         case POWERPC_MMU_SOFT_74xx:
-            /* Try to find a BAT */
-            if (check_BATs)
-                ret = get_bat(env, ctx, eaddr, rw, access_type);
-            /* No break here */
 #if defined(TARGET_PPC64)
         case POWERPC_MMU_64B:
 #endif
+            /* Try to find a BAT */
+            if (env->nb_BATs != 0)
+                ret = get_bat(env, ctx, eaddr, rw, access_type);
             if (ret < 0) {
                 /* We didn't match any BAT entry or don't have BATs */
                 ret = get_segment(env, ctx, eaddr, rw, access_type);
@@ -1419,7 +1471,7 @@
 {
     mmu_ctx_t ctx;
 
-    if (unlikely(get_physical_address(env, &ctx, addr, 0, ACCESS_INT, 1) != 0))
+    if (unlikely(get_physical_address(env, &ctx, addr, 0, ACCESS_INT) != 0))
         return -1;
 
     return ctx.raddr & TARGET_PAGE_MASK;
@@ -1444,7 +1496,7 @@
         access_type = ACCESS_INT;
         //        access_type = env->access_type;
     }
-    ret = get_physical_address(env, &ctx, address, rw, access_type, 1);
+    ret = get_physical_address(env, &ctx, address, rw, access_type);
     if (ret == 0) {
         ret = tlb_set_page_exec(env, address & TARGET_PAGE_MASK,
                                 ctx.raddr & TARGET_PAGE_MASK, ctx.prot,
@@ -1476,6 +1528,7 @@
                     env->spr[SPR_40x_ESR] = 0x00000000;
                     break;
                 case POWERPC_MMU_32B:
+                case POWERPC_MMU_601:
 #if defined(TARGET_PPC64)
                 case POWERPC_MMU_64B:
 #endif
@@ -1567,6 +1620,7 @@
                         env->spr[SPR_40x_ESR] = 0x00000000;
                     break;
                 case POWERPC_MMU_32B:
+                case POWERPC_MMU_601:
 #if defined(TARGET_PPC64)
                 case POWERPC_MMU_64B:
 #endif
@@ -1784,6 +1838,76 @@
     env->DBAT[1][nr] = value;
 }
 
+void do_store_ibatu_601 (CPUPPCState *env, int nr, target_ulong value)
+{
+    target_ulong mask;
+    int do_inval;
+
+    dump_store_bat(env, 'I', 0, nr, value);
+    if (env->IBAT[0][nr] != value) {
+        do_inval = 0;
+        mask = (env->IBAT[1][nr] << 17) & 0x0FFE0000UL;
+        if (env->IBAT[1][nr] & 0x40) {
+            /* Invalidate BAT only if it is valid */
+#if !defined(FLUSH_ALL_TLBS)
+            do_invalidate_BAT(env, env->IBAT[0][nr], mask);
+#else
+            do_inval = 1;
+#endif
+        }
+        /* When storing valid upper BAT, mask BEPI and BRPN
+         * and invalidate all TLBs covered by this BAT
+         */
+        env->IBAT[0][nr] = (value & 0x00001FFFUL) |
+            (value & ~0x0001FFFFUL & ~mask);
+        env->DBAT[0][nr] = env->IBAT[0][nr];
+        if (env->IBAT[1][nr] & 0x40) {
+#if !defined(FLUSH_ALL_TLBS)
+            do_invalidate_BAT(env, env->IBAT[0][nr], mask);
+#else
+            do_inval = 1;
+#endif
+        }
+#if defined(FLUSH_ALL_TLBS)
+        if (do_inval)
+            tlb_flush(env, 1);
+#endif
+    }
+}
+
+void do_store_ibatl_601 (CPUPPCState *env, int nr, target_ulong value)
+{
+    target_ulong mask;
+    int do_inval;
+
+    dump_store_bat(env, 'I', 1, nr, value);
+    if (env->IBAT[1][nr] != value) {
+        do_inval = 0;
+        if (env->IBAT[1][nr] & 0x40) {
+#if !defined(FLUSH_ALL_TLBS)
+            mask = (env->IBAT[1][nr] << 17) & 0x0FFE0000UL;
+            do_invalidate_BAT(env, env->IBAT[0][nr], mask);
+#else
+            do_inval = 1;
+#endif
+        }
+        if (value & 0x40) {
+#if !defined(FLUSH_ALL_TLBS)
+            mask = (value << 17) & 0x0FFE0000UL;
+            do_invalidate_BAT(env, env->IBAT[0][nr], mask);
+#else
+            do_inval = 1;
+#endif
+        }
+        env->IBAT[1][nr] = value;
+        env->DBAT[1][nr] = value;
+#if defined(FLUSH_ALL_TLBS)
+        if (do_inval)
+            tlb_flush(env, 1);
+#endif
+    }
+}
+
 /*****************************************************************************/
 /* TLB management */
 void ppc_tlb_invalidate_all (CPUPPCState *env)
@@ -1809,6 +1933,7 @@
         cpu_abort(env, "MMU model not implemented\n");
         break;
     case POWERPC_MMU_32B:
+    case POWERPC_MMU_601:
 #if defined(TARGET_PPC64)
     case POWERPC_MMU_64B:
 #endif /* defined(TARGET_PPC64) */
@@ -1848,6 +1973,7 @@
         cpu_abort(env, "MMU model not implemented\n");
         break;
     case POWERPC_MMU_32B:
+    case POWERPC_MMU_601:
         /* tlbie invalidate TLBs for all segments */
         addr &= ~((target_ulong)-1 << 28);
         /* XXX: this case should be optimized,
@@ -2146,10 +2272,9 @@
                 new_msr |= (target_ulong)1 << MSR_HV;
 #endif
             msr |= 0x00100000;
-            if (msr_fe0 != msr_fe1) {
-                msr |= 0x00010000;
-                goto store_current;
-            }
+            if (msr_fe0 == msr_fe1)
+                goto store_next;
+            msr |= 0x00010000;
             break;
         case POWERPC_EXCP_INVAL:
 #if defined (DEBUG_EXCEPTIONS)
@@ -2187,7 +2312,7 @@
                       env->error_code);
             break;
         }
-        goto store_next;
+        goto store_current;
     case POWERPC_EXCP_FPU:       /* Floating-point unavailable exception     */
         new_msr &= ~((target_ulong)1 << MSR_RI);
 #if defined(TARGET_PPC64H)
@@ -2631,6 +2756,7 @@
      *      any special case that could occur. Just store MSR and update hflags
      */
     env->msr = new_msr;
+    env->hflags_nmsr = 0x00000000;
     hreg_compute_hflags(env);
     env->nip = vector;
     /* Reset exception state */

Modified: trunk/src/host/qemu-neo1973/target-ppc/helper_regs.h
===================================================================
--- trunk/src/host/qemu-neo1973/target-ppc/helper_regs.h	2007-11-09 16:32:22 UTC (rev 3386)
+++ trunk/src/host/qemu-neo1973/target-ppc/helper_regs.h	2007-11-09 17:12:19 UTC (rev 3387)
@@ -58,6 +58,17 @@
     env->tgpr[3] = tmp;
 }
 
+static always_inline void hreg_compute_mem_idx (CPUPPCState *env)
+{
+#if defined (TARGET_PPC64H)
+    /* Precompute MMU index */
+    if (msr_pr == 0 && msr_hv != 0)
+        env->mmu_idx = 2;
+    else
+#endif
+        env->mmu_idx = 1 - msr_pr;
+}
+
 static always_inline void hreg_compute_hflags (CPUPPCState *env)
 {
     target_ulong hflags_mask;
@@ -70,14 +81,12 @@
     hflags_mask |= (1ULL << MSR_CM) | (1ULL << MSR_SF);
 #if defined (TARGET_PPC64H)
     hflags_mask |= 1ULL << MSR_HV;
-    /* Precompute MMU index */
-    if (msr_pr == 0 && msr_hv != 0)
-        env->mmu_idx = 2;
-    else
 #endif
 #endif
-        env->mmu_idx = 1 - msr_pr;
+    hreg_compute_mem_idx(env);
     env->hflags = env->msr & hflags_mask;
+    /* Merge with hflags coming from other registers */
+    env->hflags |= env->hflags_nmsr;
 }
 
 static always_inline int hreg_store_msr (CPUPPCState *env, target_ulong value)

Modified: trunk/src/host/qemu-neo1973/target-ppc/op.c
===================================================================
--- trunk/src/host/qemu-neo1973/target-ppc/op.c	2007-11-09 16:32:22 UTC (rev 3386)
+++ trunk/src/host/qemu-neo1973/target-ppc/op.c	2007-11-09 17:12:19 UTC (rev 3387)
@@ -2190,30 +2190,27 @@
     RETURN();
 }
 
+void OPPROTO op_store_hid0_601 (void)
+{
+    do_store_hid0_601();
+    RETURN();
+}
+
 void OPPROTO op_load_601_bat (void)
 {
     T0 = env->IBAT[PARAM1][PARAM2];
     RETURN();
 }
-#endif /* !defined(CONFIG_USER_ONLY) */
 
-/* 601 unified BATs store.
- * To avoid using specific MMU code for 601, we store BATs in
- * IBAT and DBAT simultaneously, then emulate unified BATs.
- */
-#if !defined(CONFIG_USER_ONLY)
 void OPPROTO op_store_601_batl (void)
 {
-    int nr = PARAM1;
-
-    env->IBAT[1][nr] = T0;
-    env->DBAT[1][nr] = T0;
+    do_store_ibatl_601(env, PARAM1, T0);
     RETURN();
 }
 
 void OPPROTO op_store_601_batu (void)
 {
-    do_store_601_batu(PARAM1);
+    do_store_ibatu_601(env, PARAM1, T0);
     RETURN();
 }
 #endif /* !defined(CONFIG_USER_ONLY) */

Modified: trunk/src/host/qemu-neo1973/target-ppc/op_helper.c
===================================================================
--- trunk/src/host/qemu-neo1973/target-ppc/op_helper.c	2007-11-09 16:32:22 UTC (rev 3386)
+++ trunk/src/host/qemu-neo1973/target-ppc/op_helper.c	2007-11-09 17:12:19 UTC (rev 3387)
@@ -1682,15 +1682,18 @@
 #if !defined (CONFIG_USER_ONLY)
 void do_POWER_rac (void)
 {
-#if 0
     mmu_ctx_t ctx;
+    int nb_BATs;
 
     /* We don't have to generate many instances of this instruction,
      * as rac is supervisor only.
      */
-    if (get_physical_address(env, &ctx, T0, 0, ACCESS_INT, 1) == 0)
+    /* XXX: FIX THIS: Pretend we have no BAT */
+    nb_BATs = env->nb_BATs;
+    env->nb_BATs = 0;
+    if (get_physical_address(env, &ctx, T0, 0, ACCESS_INT) == 0)
         T0 = ctx.raddr;
-#endif
+    env->nb_BATs = nb_BATs;
 }
 
 void do_POWER_rfsvc (void)
@@ -1698,12 +1701,23 @@
     __do_rfi(env->lr, env->ctr, 0x0000FFFF, 0);
 }
 
-/* PowerPC 601 BAT management helper */
-void do_store_601_batu (int nr)
+void do_store_hid0_601 (void)
 {
-    do_store_ibatu(env, nr, (uint32_t)T0);
-    env->DBAT[0][nr] = env->IBAT[0][nr];
-    env->DBAT[1][nr] = env->IBAT[1][nr];
+    uint32_t hid0;
+
+    hid0 = env->spr[SPR_HID0];
+    if ((T0 ^ hid0) & 0x00000008) {
+        /* Change current endianness */
+        env->hflags &= ~(1 << MSR_LE);
+        env->hflags_nmsr &= ~(1 << MSR_LE);
+        env->hflags_nmsr |= (1 << MSR_LE) & (((T0 >> 3) & 1) << MSR_LE);
+        env->hflags |= env->hflags_nmsr;
+        if (loglevel != 0) {
+            fprintf(logfile, "%s: set endianness to %c => " ADDRX "\n",
+                    __func__, T0 & 0x8 ? 'l' : 'b', env->hflags);
+        }
+    }
+    env->spr[SPR_HID0] = T0;
 }
 #endif
 

Modified: trunk/src/host/qemu-neo1973/target-ppc/op_helper.h
===================================================================
--- trunk/src/host/qemu-neo1973/target-ppc/op_helper.h	2007-11-09 16:32:22 UTC (rev 3386)
+++ trunk/src/host/qemu-neo1973/target-ppc/op_helper.h	2007-11-09 17:12:19 UTC (rev 3387)
@@ -155,7 +155,6 @@
 #endif
 
 /* POWER / PowerPC 601 specific helpers */
-void do_store_601_batu (int nr);
 void do_POWER_abso (void);
 void do_POWER_clcs (void);
 void do_POWER_div (void);
@@ -168,6 +167,7 @@
 #if !defined(CONFIG_USER_ONLY)
 void do_POWER_rac (void);
 void do_POWER_rfsvc (void);
+void do_store_hid0_601 (void);
 #endif
 
 /* PowerPC 602 specific helper */

Modified: trunk/src/host/qemu-neo1973/target-ppc/translate.c
===================================================================
--- trunk/src/host/qemu-neo1973/target-ppc/translate.c	2007-11-09 16:32:22 UTC (rev 3386)
+++ trunk/src/host/qemu-neo1973/target-ppc/translate.c	2007-11-09 17:12:19 UTC (rev 3387)
@@ -3550,20 +3550,28 @@
             gen_op_store_T0_gpr(rD(ctx->opcode));
         } else {
             /* Privilege exception */
-            if (loglevel != 0) {
-                fprintf(logfile, "Trying to read privileged spr %d %03x\n",
-                        sprn, sprn);
+            /* This is a hack to avoid warnings when running Linux:
+             * this OS breaks the PowerPC virtualisation model,
+             * allowing userland application to read the PVR
+             */
+            if (sprn != SPR_PVR) {
+                if (loglevel != 0) {
+                    fprintf(logfile, "Trying to read privileged spr %d %03x at"
+                            ADDRX "\n", sprn, sprn, ctx->nip);
+                }
+                printf("Trying to read privileged spr %d %03x at " ADDRX "\n",
+                       sprn, sprn, ctx->nip);
             }
-            printf("Trying to read privileged spr %d %03x\n", sprn, sprn);
             GEN_EXCP_PRIVREG(ctx);
         }
     } else {
         /* Not defined */
         if (loglevel != 0) {
-            fprintf(logfile, "Trying to read invalid spr %d %03x\n",
-                    sprn, sprn);
+            fprintf(logfile, "Trying to read invalid spr %d %03x at "
+                    ADDRX "\n", sprn, sprn, ctx->nip);
         }
-        printf("Trying to read invalid spr %d %03x\n", sprn, sprn);
+        printf("Trying to read invalid spr %d %03x at " ADDRX "\n",
+               sprn, sprn, ctx->nip);
         GEN_EXCP(ctx, POWERPC_EXCP_PROGRAM,
                  POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_SPR);
     }
@@ -3683,19 +3691,21 @@
         } else {
             /* Privilege exception */
             if (loglevel != 0) {
-                fprintf(logfile, "Trying to write privileged spr %d %03x\n",
-                        sprn, sprn);
+                fprintf(logfile, "Trying to write privileged spr %d %03x at "
+                        ADDRX "\n", sprn, sprn, ctx->nip);
             }
-            printf("Trying to write privileged spr %d %03x\n", sprn, sprn);
+            printf("Trying to write privileged spr %d %03x at " ADDRX "\n",
+                   sprn, sprn, ctx->nip);
             GEN_EXCP_PRIVREG(ctx);
         }
     } else {
         /* Not defined */
         if (loglevel != 0) {
-            fprintf(logfile, "Trying to write invalid spr %d %03x\n",
-                    sprn, sprn);
+            fprintf(logfile, "Trying to write invalid spr %d %03x at "
+                    ADDRX "\n", sprn, sprn, ctx->nip);
         }
-        printf("Trying to write invalid spr %d %03x\n", sprn, sprn);
+        printf("Trying to write invalid spr %d %03x at " ADDRX "\n",
+               sprn, sprn, ctx->nip);
         GEN_EXCP(ctx, POWERPC_EXCP_PROGRAM,
                  POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_SPR);
     }
@@ -6679,24 +6689,23 @@
 
     int i;
 
-    cpu_fprintf(f, "NIP " ADDRX " LR " ADDRX " CTR " ADDRX " idx %d\n",
-                env->nip, env->lr, env->ctr, env->mmu_idx);
-    cpu_fprintf(f, "MSR " REGX FILL " XER %08x      "
+    cpu_fprintf(f, "NIP " ADDRX "   LR " ADDRX " CTR " ADDRX " XER %08x\n",
+                env->nip, env->lr, env->ctr, hreg_load_xer(env));
+    cpu_fprintf(f, "MSR " REGX FILL " HID0 " REGX FILL "  HF " REGX FILL
+                " idx %d\n",
+                env->msr, env->hflags, env->spr[SPR_HID0], env->mmu_idx);
 #if !defined(NO_TIMER_DUMP)
-                "TB %08x %08x "
+    cpu_fprintf(f, "TB %08x %08x "
 #if !defined(CONFIG_USER_ONLY)
                 "DECR %08x"
 #endif
-#endif
                 "\n",
-                env->msr, hreg_load_xer(env)
-#if !defined(NO_TIMER_DUMP)
-                , cpu_ppc_load_tbu(env), cpu_ppc_load_tbl(env)
+                cpu_ppc_load_tbu(env), cpu_ppc_load_tbl(env)
 #if !defined(CONFIG_USER_ONLY)
                 , cpu_ppc_load_decr(env)
 #endif
+                );
 #endif
-                );
     for (i = 0; i < 32; i++) {
         if ((i & (RGPL - 1)) == 0)
             cpu_fprintf(f, "GPR%02d", i);
@@ -6727,8 +6736,7 @@
             cpu_fprintf(f, "\n");
     }
 #if !defined(CONFIG_USER_ONLY)
-    cpu_fprintf(f, "SRR0 " REGX " SRR1 " REGX "         " FILL FILL FILL
-                "SDR1 " REGX "\n",
+    cpu_fprintf(f, "SRR0 " REGX " SRR1 " REGX " SDR1 " REGX "\n",
                 env->spr[SPR_SRR0], env->spr[SPR_SRR1], env->sdr1);
 #endif
 
@@ -6793,7 +6801,7 @@
     opc_handler_t **table, *handler;
     target_ulong pc_start;
     uint16_t *gen_opc_end;
-    int supervisor;
+    int supervisor, little_endian;
     int single_step, branch_step;
     int j, lj = -1;
 
@@ -6813,11 +6821,12 @@
 #if !defined(CONFIG_USER_ONLY)
     ctx.supervisor = supervisor;
 #endif
+    little_endian = env->hflags & (1 << MSR_LE) ? 1 : 0;
 #if defined(TARGET_PPC64)
     ctx.sf_mode = msr_sf;
-    ctx.mem_idx = (supervisor << 2) | (msr_sf << 1) | msr_le;
+    ctx.mem_idx = (supervisor << 2) | (msr_sf << 1) | little_endian;
 #else
-    ctx.mem_idx = (supervisor << 1) | msr_le;
+    ctx.mem_idx = (supervisor << 1) | little_endian;
 #endif
     ctx.dcache_line_size = env->dcache_line_size;
     ctx.fpu_enabled = msr_fp;
@@ -6872,18 +6881,16 @@
                     ctx.nip, supervisor, (int)msr_ir);
         }
 #endif
-        ctx.opcode = ldl_code(ctx.nip);
-        if (msr_le) {
-            ctx.opcode = ((ctx.opcode & 0xFF000000) >> 24) |
-                ((ctx.opcode & 0x00FF0000) >> 8) |
-                ((ctx.opcode & 0x0000FF00) << 8) |
-                ((ctx.opcode & 0x000000FF) << 24);
+        if (unlikely(little_endian)) {
+            ctx.opcode = bswap32(ldl_code(ctx.nip));
+        } else {
+            ctx.opcode = ldl_code(ctx.nip);
         }
 #if defined PPC_DEBUG_DISAS
         if (loglevel & CPU_LOG_TB_IN_ASM) {
             fprintf(logfile, "translate opcode %08x (%02x %02x %02x) (%s)\n",
                     ctx.opcode, opc1(ctx.opcode), opc2(ctx.opcode),
-                    opc3(ctx.opcode), msr_le ? "little" : "big");
+                    opc3(ctx.opcode), little_endian ? "little" : "big");
         }
 #endif
         ctx.nip += 4;
@@ -6978,7 +6985,7 @@
     if (loglevel & CPU_LOG_TB_IN_ASM) {
         int flags;
         flags = env->bfd_mach;
-        flags |= msr_le << 16;
+        flags |= little_endian << 16;
         fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
         target_disas(logfile, pc_start, ctx.nip - pc_start, flags);
         fprintf(logfile, "\n");

Modified: trunk/src/host/qemu-neo1973/target-ppc/translate_init.c
===================================================================
--- trunk/src/host/qemu-neo1973/target-ppc/translate_init.c	2007-11-09 16:32:22 UTC (rev 3386)
+++ trunk/src/host/qemu-neo1973/target-ppc/translate_init.c	2007-11-09 17:12:19 UTC (rev 3387)
@@ -241,7 +241,7 @@
 
 static void spr_read_dbat_h (void *opaque, int sprn)
 {
-    gen_op_load_dbat(sprn & 1, (sprn - SPR_DBAT4U) / 2);
+    gen_op_load_dbat(sprn & 1, ((sprn - SPR_DBAT4U) / 2) + 4);
 }
 
 static void spr_write_dbatu (void *opaque, int sprn)
@@ -251,7 +251,7 @@
 
 static void spr_write_dbatu_h (void *opaque, int sprn)
 {
-    gen_op_store_dbatu((sprn - SPR_DBAT4U) / 2);
+    gen_op_store_dbatu(((sprn - SPR_DBAT4U) / 2) + 4);
 }
 
 static void spr_write_dbatl (void *opaque, int sprn)
@@ -261,7 +261,7 @@
 
 static void spr_write_dbatl_h (void *opaque, int sprn)
 {
-    gen_op_store_dbatl((sprn - SPR_DBAT4L) / 2);
+    gen_op_store_dbatl(((sprn - SPR_DBAT4L) / 2) + 4);
 }
 
 /* SDR1 */
@@ -314,6 +314,15 @@
 {
     gen_op_store_601_rtcl();
 }
+
+static void spr_write_hid0_601 (void *opaque, int sprn)
+{
+    DisasContext *ctx = opaque;
+
+    gen_op_store_hid0_601();
+    /* Must stop the translation as endianness may have changed */
+    GEN_STOP(ctx);
+}
 #endif
 
 /* Unified bats */
@@ -2246,9 +2255,9 @@
     env->excp_vectors[POWERPC_EXCP_FIT]      = 0x00001010;
     env->excp_vectors[POWERPC_EXCP_WDT]      = 0x00001020;
     env->excp_vectors[POWERPC_EXCP_DEBUG]    = 0x00002000;
-    env->excp_prefix = 0x00000000;
-    env->ivor_mask = 0x0000FFF0;
-    env->ivpr_mask = 0xFFFF0000;
+    env->excp_prefix = 0x00000000UL;
+    env->ivor_mask = 0x0000FFF0UL;
+    env->ivpr_mask = 0xFFFF0000UL;
     /* Hardware reset vector */
     env->hreset_vector = 0xFFFFFFFCUL;
 #endif
@@ -2271,9 +2280,9 @@
     env->excp_vectors[POWERPC_EXCP_DTLB]     = 0x00001100;
     env->excp_vectors[POWERPC_EXCP_ITLB]     = 0x00001200;
     env->excp_vectors[POWERPC_EXCP_DEBUG]    = 0x00002000;
-    env->excp_prefix = 0x00000000;
-    env->ivor_mask = 0x0000FFF0;
-    env->ivpr_mask = 0xFFFF0000;
+    env->excp_prefix = 0x00000000UL;
+    env->ivor_mask = 0x0000FFF0UL;
+    env->ivpr_mask = 0xFFFF0000UL;
     /* Hardware reset vector */
     env->hreset_vector = 0xFFFFFFFCUL;
 #endif
@@ -2298,9 +2307,9 @@
     env->excp_vectors[POWERPC_EXCP_DTLB]     = 0x00000000;
     env->excp_vectors[POWERPC_EXCP_ITLB]     = 0x00000000;
     env->excp_vectors[POWERPC_EXCP_DEBUG]    = 0x00000000;
-    env->excp_prefix = 0x00000000;
-    env->ivor_mask = 0x0000FFE0;
-    env->ivpr_mask = 0xFFFF0000;
+    env->excp_prefix = 0x00000000UL;
+    env->ivor_mask = 0x0000FFE0UL;
+    env->ivpr_mask = 0xFFFF0000UL;
     /* Hardware reset vector */
     env->hreset_vector = 0xFFFFFFFCUL;
 #endif
@@ -2321,7 +2330,7 @@
     env->excp_vectors[POWERPC_EXCP_IO]       = 0x00000A00;
     env->excp_vectors[POWERPC_EXCP_SYSCALL]  = 0x00000C00;
     env->excp_vectors[POWERPC_EXCP_RUNM]     = 0x00002000;
-    env->excp_prefix = 0xFFF00000;
+    env->excp_prefix = 0xFFF00000UL;
     /* Hardware reset vector */
     env->hreset_vector = 0x00000100UL;
 #endif
@@ -2349,7 +2358,7 @@
     env->excp_vectors[POWERPC_EXCP_SMI]      = 0x00001400;
     env->excp_vectors[POWERPC_EXCP_WDT]      = 0x00001500;
     env->excp_vectors[POWERPC_EXCP_EMUL]     = 0x00001600;
-    env->excp_prefix = 0xFFF00000;
+    env->excp_prefix = 0xFFF00000UL;
     /* Hardware reset vector */
     env->hreset_vector = 0xFFFFFFFCUL;
 #endif
@@ -2374,6 +2383,7 @@
     env->excp_vectors[POWERPC_EXCP_DSTLB]    = 0x00001200;
     env->excp_vectors[POWERPC_EXCP_IABR]     = 0x00001300;
     env->excp_vectors[POWERPC_EXCP_SMI]      = 0x00001400;
+    env->excp_prefix = 0x00000000UL;
     /* Hardware reset vector */
     env->hreset_vector = 0xFFFFFFFCUL;
 #endif
@@ -2399,6 +2409,7 @@
     env->excp_vectors[POWERPC_EXCP_DSTLB]    = 0x00001200;
     env->excp_vectors[POWERPC_EXCP_IABR]     = 0x00001300;
     env->excp_vectors[POWERPC_EXCP_SMI]      = 0x00001400;
+    env->excp_prefix = 0x00000000UL;
     /* Hardware reset vector */
     env->hreset_vector = 0xFFFFFFFCUL;
 #endif
@@ -2421,6 +2432,7 @@
     env->excp_vectors[POWERPC_EXCP_PERFM]    = 0x00000F00;
     env->excp_vectors[POWERPC_EXCP_IABR]     = 0x00001300;
     env->excp_vectors[POWERPC_EXCP_SMI]      = 0x00001400;
+    env->excp_prefix = 0x00000000UL;
     /* Hardware reset vector */
     env->hreset_vector = 0xFFFFFFFCUL;
 #endif
@@ -2433,7 +2445,9 @@
     env->excp_vectors[POWERPC_EXCP_RESET]    = 0x00000100;
     env->excp_vectors[POWERPC_EXCP_MCHECK]   = 0x00000200;
     env->excp_vectors[POWERPC_EXCP_DSI]      = 0x00000300;
+    env->excp_vectors[POWERPC_EXCP_DSEG]     = 0x00000380;
     env->excp_vectors[POWERPC_EXCP_ISI]      = 0x00000400;
+    env->excp_vectors[POWERPC_EXCP_ISEG]     = 0x00000480;
     env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
     env->excp_vectors[POWERPC_EXCP_ALIGN]    = 0x00000600;
     env->excp_vectors[POWERPC_EXCP_PROGRAM]  = 0x00000700;
@@ -2445,8 +2459,9 @@
     env->excp_vectors[POWERPC_EXCP_PERFM]    = 0x00000F00;
     env->excp_vectors[POWERPC_EXCP_IABR]     = 0x00001300;
     env->excp_vectors[POWERPC_EXCP_SMI]      = 0x00001400;
+    env->excp_prefix = 0xFFF00000UL;
     /* Hardware reset vector */
-    env->hreset_vector = 0x0000000000000100ULL; /* ? */
+    env->hreset_vector = 0x0000000000000100ULL;
 #endif
 }
 #endif /* defined(TARGET_PPC64) */
@@ -2468,6 +2483,7 @@
     env->excp_vectors[POWERPC_EXCP_PERFM]    = 0x00000F00;
     env->excp_vectors[POWERPC_EXCP_IABR]     = 0x00001300;
     env->excp_vectors[POWERPC_EXCP_THERM]    = 0x00001700;
+    env->excp_prefix = 0x00000000UL;
     /* Hardware reset vector */
     env->hreset_vector = 0xFFFFFFFCUL;
 #endif
@@ -2491,6 +2507,7 @@
     env->excp_vectors[POWERPC_EXCP_IABR]     = 0x00001300;
     env->excp_vectors[POWERPC_EXCP_SMI]      = 0x00001400;
     env->excp_vectors[POWERPC_EXCP_THERM]    = 0x00001700;
+    env->excp_prefix = 0x00000000UL;
     /* Hardware reset vector */
     env->hreset_vector = 0xFFFFFFFCUL;
 #endif
@@ -2517,6 +2534,7 @@
     env->excp_vectors[POWERPC_EXCP_PERFM]    = 0x00000F00;
     env->excp_vectors[POWERPC_EXCP_IABR]     = 0x00001300;
     env->excp_vectors[POWERPC_EXCP_SMI]      = 0x00001400;
+    env->excp_prefix = 0x00000000UL;
     /* Hardware reset vector */
     env->hreset_vector = 0xFFFFFFFCUL;
 #endif
@@ -2542,6 +2560,7 @@
     env->excp_vectors[POWERPC_EXCP_SMI]      = 0x00001400;
     env->excp_vectors[POWERPC_EXCP_VPUA]     = 0x00001600;
     env->excp_vectors[POWERPC_EXCP_THERM]    = 0x00001700;
+    env->excp_prefix = 0x00000000UL;
     /* Hardware reset vector */
     env->hreset_vector = 0xFFFFFFFCUL;
 #endif
@@ -2569,6 +2588,7 @@
     env->excp_vectors[POWERPC_EXCP_IABR]     = 0x00001300;
     env->excp_vectors[POWERPC_EXCP_SMI]      = 0x00001400;
     env->excp_vectors[POWERPC_EXCP_VPUA]     = 0x00001600;
+    env->excp_prefix = 0x00000000UL;
     /* Hardware reset vector */
     env->hreset_vector = 0xFFFFFFFCUL;
 #endif
@@ -2600,6 +2620,7 @@
     env->excp_vectors[POWERPC_EXCP_MAINT]    = 0x00001600;
     env->excp_vectors[POWERPC_EXCP_VPUA]     = 0x00001700;
     env->excp_vectors[POWERPC_EXCP_THERM]    = 0x00001800;
+    env->excp_prefix   = 0x00000000FFF00000ULL;
     /* Hardware reset vector */
     env->hreset_vector = 0x0000000000000100ULL;
 #endif
@@ -3232,7 +3253,7 @@
 #define POWERPC_INSNS_601    (POWERPC_INSNS_6xx | PPC_CACHE_DCBZ |            \
                               PPC_SEGMENT | PPC_EXTERN | PPC_POWER_BR)
 #define POWERPC_MSRM_601     (0x000000000000FD70ULL)
-#define POWERPC_MMU_601      (POWERPC_MMU_32B)
+//#define POWERPC_MMU_601      (POWERPC_MMU_601)
 //#define POWERPC_EXCP_601     (POWERPC_EXCP_601)
 #define POWERPC_INPUT_601    (PPC_FLAGS_INPUT_6xx)
 #define POWERPC_BFDM_601     (bfd_mach_ppc_601)
@@ -3247,8 +3268,8 @@
     /* XXX : not implemented */
     spr_register(env, SPR_HID0, "HID0",
                  SPR_NOACCESS, SPR_NOACCESS,
-                 &spr_read_generic, &spr_write_generic,
-                 0x00000000);
+                 &spr_read_generic, &spr_write_hid0_601,
+                 0x80010080);
     /* XXX : not implemented */
     spr_register(env, SPR_HID1, "HID1",
                  SPR_NOACCESS, SPR_NOACCESS,
@@ -3278,7 +3299,8 @@
     init_excp_601(env);
     env->dcache_line_size = 64;
     env->icache_line_size = 64;
-    /* XXX: TODO: allocate internal IRQ controller */
+    /* Allocate hardware IRQ controller */
+    ppc6xx_irq_init(env);
 }
 
 /* PowerPC 602                                                               */
@@ -4183,9 +4205,6 @@
                  &spr_read_generic, &spr_write_generic,
                  0xFFF00000); /* XXX: This is a hack */
 #if !defined(CONFIG_USER_ONLY)
-    env->excp_prefix = 0xFFF00000;
-#endif
-#if !defined(CONFIG_USER_ONLY)
     env->slb_nr = 32;
 #endif
     init_excp_970(env);
@@ -4260,9 +4279,6 @@
                  &spr_read_generic, &spr_write_generic,
                  0xFFF00000); /* XXX: This is a hack */
 #if !defined(CONFIG_USER_ONLY)
-    env->excp_prefix = 0xFFF00000;
-#endif
-#if !defined(CONFIG_USER_ONLY)
     env->slb_nr = 32;
 #endif
     init_excp_970(env);
@@ -4337,9 +4353,6 @@
                  &spr_read_generic, &spr_write_generic,
                  0xFFF00000); /* XXX: This is a hack */
 #if !defined(CONFIG_USER_ONLY)
-    env->excp_prefix = 0xFFF00000;
-#endif
-#if !defined(CONFIG_USER_ONLY)
     env->slb_nr = 32;
 #endif
     init_excp_970(env);
@@ -4414,9 +4427,6 @@
                  &spr_read_generic, &spr_write_generic,
                  0xFFF00000); /* XXX: This is a hack */
 #if !defined(CONFIG_USER_ONLY)
-    env->excp_prefix = 0xFFF00000;
-#endif
-#if !defined(CONFIG_USER_ONLY)
     env->slb_nr = 32;
 #endif
     init_excp_970(env);
@@ -4432,7 +4442,7 @@
 #define POWERPC_MSRM_620     (0x800000000005FF73ULL)
 #define POWERPC_MMU_620      (POWERPC_MMU_64B)
 #define POWERPC_EXCP_620     (POWERPC_EXCP_970)
-#define POWERPC_INPUT_620    (PPC_FLAGS_INPUT_970)
+#define POWERPC_INPUT_620    (PPC_FLAGS_INPUT_6xx)
 #define POWERPC_BFDM_620     (bfd_mach_ppc64)
 #define POWERPC_FLAG_620     (POWERPC_FLAG_SE | POWERPC_FLAG_BE)
 #define check_pow_620        check_pow_nocheck /* Check this */
@@ -4456,7 +4466,8 @@
     init_excp_620(env);
     env->dcache_line_size = 64;
     env->icache_line_size = 64;
-    /* XXX: TODO: initialize internal interrupt controller */
+    /* Allocate hardware IRQ controller */
+    ppc6xx_irq_init(env);
 }
 #endif /* defined (TARGET_PPC64) */
 
@@ -5771,10 +5782,8 @@
     POWERPC_DEF("7457v1.2",    CPU_POWERPC_74x7_v12,    0xFFFFFFFF, 7455),
     /* 64 bits PowerPC                                                       */
 #if defined (TARGET_PPC64)
-#if defined (TODO)
     /* PowerPC 620                                                           */
     POWERPC_DEF("620",         CPU_POWERPC_620,         0xFFFFFFFF, 620),
-#endif
 #if defined (TODO)
     /* PowerPC 630 (POWER3)                                                  */
     POWERPC_DEF("630",         CPU_POWERPC_630,         0xFFFFFFFF, 630),

Modified: trunk/src/host/qemu-neo1973/target-sparc/cpu.h
===================================================================
--- trunk/src/host/qemu-neo1973/target-sparc/cpu.h	2007-11-09 16:32:22 UTC (rev 3386)
+++ trunk/src/host/qemu-neo1973/target-sparc/cpu.h	2007-11-09 17:12:19 UTC (rev 3387)
@@ -147,7 +147,6 @@
 /* MMU */
 #define MMU_E     (1<<0)
 #define MMU_NF    (1<<1)
-#define MMU_BM    (1<<14)
 
 #define PTE_ENTRYTYPE_MASK 3
 #define PTE_ACCESS_MASK    0x1c
@@ -200,6 +199,7 @@
     int interrupt_index;
     int interrupt_request;
     int halted;
+    uint32_t mmu_bm;
     /* NOTE: we allow 8 more registers to handle wrapping */
     target_ulong regbase[NWINDOWS * 16 + 8];
 

Modified: trunk/src/host/qemu-neo1973/target-sparc/helper.c
===================================================================
--- trunk/src/host/qemu-neo1973/target-sparc/helper.c	2007-11-09 16:32:22 UTC (rev 3386)
+++ trunk/src/host/qemu-neo1973/target-sparc/helper.c	2007-11-09 17:12:19 UTC (rev 3387)
@@ -114,7 +114,7 @@
 
     if ((env->mmuregs[0] & MMU_E) == 0) { /* MMU disabled */
         // Boot mode: instruction fetches are taken from PROM
-        if (rw == 2 && (env->mmuregs[0] & MMU_BM)) {
+        if (rw == 2 && (env->mmuregs[0] & env->mmu_bm)) {
             *physical = 0xff0000000ULL | (address & 0x3ffffULL);
             *prot = PAGE_READ | PAGE_EXEC;
             return 0;

Modified: trunk/src/host/qemu-neo1973/target-sparc/op_helper.c
===================================================================
--- trunk/src/host/qemu-neo1973/target-sparc/op_helper.c	2007-11-09 16:32:22 UTC (rev 3386)
+++ trunk/src/host/qemu-neo1973/target-sparc/op_helper.c	2007-11-09 17:12:19 UTC (rev 3387)
@@ -493,8 +493,8 @@
             oldreg = env->mmuregs[reg];
             switch(reg) {
             case 0:
-                env->mmuregs[reg] &= ~(MMU_E | MMU_NF | MMU_BM);
-                env->mmuregs[reg] |= T1 & (MMU_E | MMU_NF | MMU_BM);
+                env->mmuregs[reg] &= ~(MMU_E | MMU_NF | env->mmu_bm);
+                env->mmuregs[reg] |= T1 & (MMU_E | MMU_NF | env->mmu_bm);
                 // Mappings generated during no-fault mode or MMU
                 // disabled mode are invalid in normal mode
                 if (oldreg != env->mmuregs[reg])

Modified: trunk/src/host/qemu-neo1973/target-sparc/translate.c
===================================================================
--- trunk/src/host/qemu-neo1973/target-sparc/translate.c	2007-11-09 16:32:22 UTC (rev 3386)
+++ trunk/src/host/qemu-neo1973/target-sparc/translate.c	2007-11-09 17:12:19 UTC (rev 3387)
@@ -59,6 +59,7 @@
     target_ulong iu_version;
     uint32_t fpu_version;
     uint32_t mmu_version;
+    uint32_t mmu_bm;
 };
 
 static uint16_t *gen_opc_ptr;
@@ -3482,7 +3483,7 @@
 #else
     env->pc = 0;
     env->mmuregs[0] &= ~(MMU_E | MMU_NF);
-    env->mmuregs[0] |= MMU_BM;
+    env->mmuregs[0] |= env->mmu_bm;
 #endif
     env->npc = env->pc + 4;
 #endif
@@ -3496,7 +3497,6 @@
     if (!env)
         return NULL;
     cpu_exec_init(env);
-    cpu_reset(env);
     return (env);
 }
 
@@ -3515,30 +3515,35 @@
         .iu_version = 0x04 << 24, /* Impl 0, ver 4 */
         .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
         .mmu_version = 0x04 << 24, /* Impl 0, ver 4 */
+        .mmu_bm = 0x00004000,
     },
     {
         .name = "Fujitsu MB86907",
         .iu_version = 0x05 << 24, /* Impl 0, ver 5 */
         .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
         .mmu_version = 0x05 << 24, /* Impl 0, ver 5 */
+        .mmu_bm = 0x00004000,
     },
     {
         .name = "TI MicroSparc I",
         .iu_version = 0x41000000,
         .fpu_version = 4 << 17,
         .mmu_version = 0x41000000,
+        .mmu_bm = 0x00004000,
     },
     {
         .name = "TI SuperSparc II",
         .iu_version = 0x40000000,
         .fpu_version = 0 << 17,
         .mmu_version = 0x04000000,
+        .mmu_bm = 0x00002000,
     },
     {
         .name = "Ross RT620",
         .iu_version = 0x1e000000,
         .fpu_version = 1 << 17,
         .mmu_version = 0x17000000,
+        .mmu_bm = 0x00004000,
     },
 #endif
 };
@@ -3579,9 +3584,11 @@
     env->version = def->iu_version;
     env->fsr = def->fpu_version;
 #if !defined(TARGET_SPARC64)
+    env->mmu_bm = def->mmu_bm;
     env->mmuregs[0] |= def->mmu_version;
     env->mxccregs[7] = ((cpu + 8) & 0xf) << 24;
 #endif
+    cpu_reset(env);
     return 0;
 }
 

Modified: trunk/src/host/qemu-neo1973/tests/qruncom.c
===================================================================
--- trunk/src/host/qemu-neo1973/tests/qruncom.c	2007-11-09 16:32:22 UTC (rev 3386)
+++ trunk/src/host/qemu-neo1973/tests/qruncom.c	2007-11-09 17:12:19 UTC (rev 3387)
@@ -193,9 +193,6 @@
         act.sa_sigaction = host_segv_handler;
         sigaction(SIGSEGV, &act, NULL);
         sigaction(SIGBUS, &act, NULL);
-#if defined (TARGET_I386) && defined(USE_CODE_COPY)
-        sigaction(SIGFPE, &act, NULL);
-#endif
     }
 
     //    cpu_set_log(CPU_LOG_TB_IN_ASM | CPU_LOG_TB_OUT_ASM | CPU_LOG_EXEC);

Modified: trunk/src/host/qemu-neo1973/translate-all.c
===================================================================
--- trunk/src/host/qemu-neo1973/translate-all.c	2007-11-09 16:32:22 UTC (rev 3386)
+++ trunk/src/host/qemu-neo1973/translate-all.c	2007-11-09 17:12:19 UTC (rev 3387)
@@ -144,35 +144,27 @@
     uint8_t *gen_code_buf;
     int gen_code_size;
 
-#ifdef USE_CODE_COPY
-    if (code_copy_enabled &&
-        cpu_gen_code_copy(env, tb, max_code_size, &gen_code_size) == 0) {
-        /* nothing more to do */
-    } else
-#endif
-    {
-        if (gen_intermediate_code(env, tb) < 0)
-            return -1;
-
-        /* generate machine code */
-        tb->tb_next_offset[0] = 0xffff;
-        tb->tb_next_offset[1] = 0xffff;
-        gen_code_buf = tb->tc_ptr;
+    if (gen_intermediate_code(env, tb) < 0)
+        return -1;
+    
+    /* generate machine code */
+    tb->tb_next_offset[0] = 0xffff;
+    tb->tb_next_offset[1] = 0xffff;
+    gen_code_buf = tb->tc_ptr;
 #ifdef USE_DIRECT_JUMP
-        /* the following two entries are optional (only used for string ops) */
-        tb->tb_jmp_offset[2] = 0xffff;
-        tb->tb_jmp_offset[3] = 0xffff;
+    /* the following two entries are optional (only used for string ops) */
+    tb->tb_jmp_offset[2] = 0xffff;
+    tb->tb_jmp_offset[3] = 0xffff;
 #endif
-        dyngen_labels(gen_labels, nb_gen_labels, gen_code_buf, gen_opc_buf);
-
-        gen_code_size = dyngen_code(gen_code_buf, tb->tb_next_offset,
+    dyngen_labels(gen_labels, nb_gen_labels, gen_code_buf, gen_opc_buf);
+    
+    gen_code_size = dyngen_code(gen_code_buf, tb->tb_next_offset,
 #ifdef USE_DIRECT_JUMP
-                                    tb->tb_jmp_offset,
+                                tb->tb_jmp_offset,
 #else
-                                    NULL,
+                                NULL,
 #endif
-                                    gen_opc_buf, gen_opparam_buf, gen_labels);
-    }
+                                gen_opc_buf, gen_opparam_buf, gen_labels);
     *gen_code_size_ptr = gen_code_size;
 #ifdef DEBUG_DISAS
     if (loglevel & CPU_LOG_TB_OUT_ASM) {
@@ -195,11 +187,6 @@
     unsigned long tc_ptr;
     uint16_t *opc_ptr;
 
-#ifdef USE_CODE_COPY
-    if (tb->cflags & CF_CODE_COPY) {
-        return cpu_restore_state_copy(tb, env, searched_pc, puc);
-    }
-#endif
     if (gen_intermediate_code_pc(env, tb) < 0)
         return -1;
 

Modified: trunk/src/host/qemu-neo1973/vl.c
===================================================================
--- trunk/src/host/qemu-neo1973/vl.c	2007-11-09 16:32:22 UTC (rev 3386)
+++ trunk/src/host/qemu-neo1973/vl.c	2007-11-09 17:12:19 UTC (rev 3387)
@@ -174,6 +174,7 @@
 NICInfo nd_table[MAX_NICS];
 int vm_running;
 int rtc_utc = 1;
+int rtc_start_date = -1; /* -1 means now */
 int cirrus_vga_enabled = 1;
 int vmsvga_enabled = 0;
 #ifdef TARGET_SPARC
@@ -1223,9 +1224,6 @@
     /* timer signal */
     sigfillset(&act.sa_mask);
     act.sa_flags = 0;
-#if defined (TARGET_I386) && defined(USE_CODE_COPY)
-    act.sa_flags |= SA_ONSTACK;
-#endif
     act.sa_handler = host_alarm_handler;
 
     sigaction(SIGIO, &act, NULL);
@@ -1323,9 +1321,6 @@
 
     sigfillset(&act.sa_mask);
     act.sa_flags = 0;
-#if defined(TARGET_I386) && defined(USE_CODE_COPY)
-    act.sa_flags |= SA_ONSTACK;
-#endif
     act.sa_handler = host_alarm_handler;
 
     sigaction(SIGALRM, &act, NULL);
@@ -1400,9 +1395,6 @@
     /* timer signal */
     sigfillset(&act.sa_mask);
     act.sa_flags = 0;
-#if defined(TARGET_I386) && defined(USE_CODE_COPY)
-    act.sa_flags |= SA_ONSTACK;
-#endif
     act.sa_handler = host_alarm_handler;
 
     sigaction(SIGALRM, &act, NULL);
@@ -7310,9 +7302,6 @@
            "-kernel-kqemu   enable KQEMU full virtualization (default is user mode only)\n"
            "-no-kqemu       disable KQEMU kernel module usage\n"
 #endif
-#ifdef USE_CODE_COPY
-           "-no-code-copy   disable code copy acceleration\n"
-#endif
 #ifdef TARGET_I386
            "-std-vga        simulate a standard VGA card with VESA Bochs Extensions\n"
            "                (default is CL-GD5446 PCI VGA)\n"
@@ -7431,6 +7420,7 @@
     QEMU_OPTION_prom_env,
     QEMU_OPTION_old_param,
     QEMU_OPTION_clock,
+    QEMU_OPTION_startdate,
 };
 
 typedef struct QEMUOption {
@@ -7538,18 +7528,10 @@
     { "old-param", 0, QEMU_OPTION_old_param },
 #endif
     { "clock", HAS_ARG, QEMU_OPTION_clock },
+    { "startdate", HAS_ARG, QEMU_OPTION_startdate },
     { NULL },
 };
 
-#if defined (TARGET_I386) && defined(USE_CODE_COPY)
-
-/* this stack is only used during signal handling */
-#define SIGNAL_STACK_SIZE 32768
-
-static uint8_t *signal_stack;
-
-#endif
-
 /* password input */
 
 int qemu_key_check(BlockDriverState *bs, const char *name)
@@ -8343,6 +8325,42 @@
             case QEMU_OPTION_clock:
                 configure_alarms(optarg);
                 break;
+            case QEMU_OPTION_startdate:
+                {
+                    struct tm tm;
+                    if (!strcmp(optarg, "now")) {
+                        rtc_start_date = -1;
+                    } else {
+                        if (sscanf(optarg, "%d-%d-%dT%d:%d:%d",
+                               &tm.tm_year,
+                               &tm.tm_mon,
+                               &tm.tm_mday,
+                               &tm.tm_hour,
+                               &tm.tm_min,
+                               &tm.tm_sec) == 6) {
+                            /* OK */
+                        } else if (sscanf(optarg, "%d-%d-%d",
+                                          &tm.tm_year,
+                                          &tm.tm_mon,
+                                          &tm.tm_mday) == 3) {
+                            tm.tm_hour = 0;
+                            tm.tm_min = 0;
+                            tm.tm_sec = 0;
+                        } else {
+                            goto date_fail;
+                        }
+                        tm.tm_year -= 1900;
+                        tm.tm_mon--;
+                        rtc_start_date = timegm(&tm);
+                        if (rtc_start_date == -1) {
+                        date_fail:
+                            fprintf(stderr, "Invalid date format. Valid format are:\n"
+                                    "'now' or '2006-06-17T16:01:21' or '2006-06-17'\n");
+                            exit(1);
+                        }
+                    }
+                }
+                break;
             }
         }
     }

Modified: trunk/src/host/qemu-neo1973/vl.h
===================================================================
--- trunk/src/host/qemu-neo1973/vl.h	2007-11-09 16:32:22 UTC (rev 3386)
+++ trunk/src/host/qemu-neo1973/vl.h	2007-11-09 17:12:19 UTC (rev 3387)
@@ -72,8 +72,8 @@
 
 #ifdef QEMU_TOOL
 
-/* we use QEMU_TOOL in the command line tools which do not depend on
-   the target CPU type */
+/* we use QEMU_TOOL on code which does not depend on the target CPU
+   type */
 #include "config-host.h"
 #include <setjmp.h>
 #include "osdep.h"
@@ -81,7 +81,6 @@
 
 #else
 
-#include "audio/audio.h"
 #include "cpu.h"
 
 #endif /* !defined(QEMU_TOOL) */
@@ -117,6 +116,8 @@
 #endif
 #endif
 
+#include "audio/audio.h"
+
 /* cutils.c */
 void pstrcpy(char *buf, int buf_size, const char *str);
 char *pstrcat(char *buf, int buf_size, const char *s);
@@ -166,6 +167,7 @@
 extern int ram_size;
 extern int bios_size;
 extern int rtc_utc;
+extern int rtc_start_date;
 extern int cirrus_vga_enabled;
 extern int vmsvga_enabled;
 extern int graphic_width;
@@ -361,6 +363,38 @@
 typedef struct DisplayState DisplayState;
 typedef struct TextConsole TextConsole;
 
+struct DisplayState {
+    uint8_t *data;
+    int linesize;
+    int depth;
+    int bgr; /* BGR color order instead of RGB. Only valid for depth == 32 */
+    int width;
+    int height;
+    void *opaque;
+    struct QEMUTimer *gui_timer;
+
+    void (*dpy_update)(struct DisplayState *s, int x, int y, int w, int h);
+    void (*dpy_resize)(struct DisplayState *s, int w, int h);
+    void (*dpy_refresh)(struct DisplayState *s);
+    void (*dpy_copy)(struct DisplayState *s, int src_x, int src_y,
+                     int dst_x, int dst_y, int w, int h);
+    void (*dpy_fill)(struct DisplayState *s, int x, int y,
+                     int w, int h, uint32_t c);
+    void (*mouse_set)(int x, int y, int on);
+    void (*cursor_define)(int width, int height, int bpp, int hot_x, int hot_y,
+                          uint8_t *image, uint8_t *mask);
+};
+
+static inline void dpy_update(DisplayState *s, int x, int y, int w, int h)
+{
+    s->dpy_update(s, x, y, w, h);
+}
+
+static inline void dpy_resize(DisplayState *s, int w, int h)
+{
+    s->dpy_resize(s, w, h);
+}
+
 typedef void (*vga_hw_update_ptr)(void *);
 typedef void (*vga_hw_invalidate_ptr)(void *);
 typedef void (*vga_hw_screen_dump_ptr)(void *, const char *);
@@ -730,6 +764,33 @@
                   const char *base_path,
                   const char *filename);
 
+
+/* monitor.c */
+void monitor_init(CharDriverState *hd, int show_banner);
+void term_puts(const char *str);
+void term_vprintf(const char *fmt, va_list ap);
+void term_printf(const char *fmt, ...) __attribute__ ((__format__ (__printf__, 1, 2)));
+void term_print_filename(const char *filename);
+void term_flush(void);
+void term_print_help(void);
+void monitor_readline(const char *prompt, int is_password,
+                      char *buf, int buf_size);
+
+/* readline.c */
+typedef void ReadLineFunc(void *opaque, const char *str);
+
+extern int completion_index;
+void add_completion(const char *str);
+void readline_handle_byte(int ch);
+void readline_find_completion(const char *cmdline);
+const char *readline_get_history(unsigned int index);
+void readline_start(const char *prompt, int is_password,
+                    ReadLineFunc *readline_func, void *opaque);
+void readline_history_save(void);
+void readline_history_restore(void);
+
+void kqemu_record_dump(void);
+
 #ifndef QEMU_TOOL
 
 typedef void QEMUMachineInitFunc(int ram_size, int vga_ram_size,
@@ -917,38 +978,6 @@
 #define VGA_RAM_SIZE (9 * 1024 * 1024)
 #endif
 
-struct DisplayState {
-    uint8_t *data;
-    int linesize;
-    int depth;
-    int bgr; /* BGR color order instead of RGB. Only valid for depth == 32 */
-    int width;
-    int height;
-    void *opaque;
-    QEMUTimer *gui_timer;
-
-    void (*dpy_update)(struct DisplayState *s, int x, int y, int w, int h);
-    void (*dpy_resize)(struct DisplayState *s, int w, int h);
-    void (*dpy_refresh)(struct DisplayState *s);
-    void (*dpy_copy)(struct DisplayState *s, int src_x, int src_y,
-                     int dst_x, int dst_y, int w, int h);
-    void (*dpy_fill)(struct DisplayState *s, int x, int y,
-                     int w, int h, uint32_t c);
-    void (*mouse_set)(int x, int y, int on);
-    void (*cursor_define)(int width, int height, int bpp, int hot_x, int hot_y,
-                          uint8_t *image, uint8_t *mask);
-};
-
-static inline void dpy_update(DisplayState *s, int x, int y, int w, int h)
-{
-    s->dpy_update(s, x, y, w, h);
-}
-
-static inline void dpy_resize(DisplayState *s, int w, int h)
-{
-    s->dpy_resize(s, w, h);
-}
-
 int isa_vga_init(DisplayState *ds, uint8_t *vga_ram_base,
                  unsigned long vga_ram_offset, int vga_ram_size);
 int pci_vga_init(PCIBus *bus, DisplayState *ds, uint8_t *vga_ram_base,
@@ -1043,6 +1072,8 @@
 fdctrl_t *fdctrl_init (qemu_irq irq, int dma_chann, int mem_mapped,
                        target_phys_addr_t io_base,
                        BlockDriverState **fds);
+fdctrl_t *sun4m_fdctrl_init (qemu_irq irq, target_phys_addr_t io_base,
+                             BlockDriverState **fds);
 int fdctrl_get_drive_type(fdctrl_t *fdctrl, int drive_num);
 
 /* eepro100.c */
@@ -1691,12 +1722,14 @@
 void qemu_get_ptimer(QEMUFile *f, ptimer_state *s);
 
 #include "hw/pxa.h"
+
 #include "hw/s3c.h"
 
 #include "hw/omap.h"
 
 /* tsc210x.c */
-struct uwire_slave_s *tsc2102_init(qemu_irq pint);
+struct uwire_slave_s *tsc2102_init(qemu_irq pint, AudioState *audio);
+struct i2s_codec_s *tsc210x_codec(struct uwire_slave_s *chip);
 
 /* mcf_uart.c */
 uint32_t mcf_uart_read(void *opaque, target_phys_addr_t addr);
@@ -1723,31 +1756,4 @@
 #include "gdbstub.h"
 
 #endif /* defined(QEMU_TOOL) */
-
-/* monitor.c */
-void monitor_init(CharDriverState *hd, int show_banner);
-void term_puts(const char *str);
-void term_vprintf(const char *fmt, va_list ap);
-void term_printf(const char *fmt, ...) __attribute__ ((__format__ (__printf__, 1, 2)));
-void term_print_filename(const char *filename);
-void term_flush(void);
-void term_print_help(void);
-void monitor_readline(const char *prompt, int is_password,
-                      char *buf, int buf_size);
-
-/* readline.c */
-typedef void ReadLineFunc(void *opaque, const char *str);
-
-extern int completion_index;
-void add_completion(const char *str);
-void readline_handle_byte(int ch);
-void readline_find_completion(const char *cmdline);
-const char *readline_get_history(unsigned int index);
-void readline_start(const char *prompt, int is_password,
-                    ReadLineFunc *readline_func, void *opaque);
-void readline_history_save(void);
-void readline_history_restore(void);
-
-void kqemu_record_dump(void);
-
 #endif /* VL_H */





More information about the commitlog mailing list