r3303 - in trunk/src/host/qemu-neo1973: . darwin-user hw linux-user linux-user/alpha linux-user/arm linux-user/cris linux-user/i386 linux-user/m68k linux-user/mips linux-user/ppc linux-user/sh4 linux-user/sparc linux-user/sparc64 linux-user/x86_64 pc-bios slirp target-alpha target-arm target-cris target-i386 target-m68k target-mips target-ppc target-sh4 target-sparc tests

andrew at sita.openmoko.org andrew at sita.openmoko.org
Mon Oct 29 22:16:21 CET 2007


Author: andrew
Date: 2007-10-29 22:14:04 +0100 (Mon, 29 Oct 2007)
New Revision: 3303

Added:
   trunk/src/host/qemu-neo1973/cris-dis.c
   trunk/src/host/qemu-neo1973/host-utils.h
   trunk/src/host/qemu-neo1973/hw/ecc.c
   trunk/src/host/qemu-neo1973/hw/etraxfs.c
   trunk/src/host/qemu-neo1973/hw/etraxfs_ser.c
   trunk/src/host/qemu-neo1973/hw/etraxfs_timer.c
   trunk/src/host/qemu-neo1973/hw/mac_dbdma.c
   trunk/src/host/qemu-neo1973/hw/mac_nvram.c
   trunk/src/host/qemu-neo1973/hw/macio.c
   trunk/src/host/qemu-neo1973/hw/mips_mipssim.c
   trunk/src/host/qemu-neo1973/hw/mipsnet.c
   trunk/src/host/qemu-neo1973/hw/ppc4xx.h
   trunk/src/host/qemu-neo1973/hw/ppc4xx_devs.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/r2d.c
   trunk/src/host/qemu-neo1973/hw/sh_intc.c
   trunk/src/host/qemu-neo1973/hw/sh_intc.h
   trunk/src/host/qemu-neo1973/hw/sh_serial.c
   trunk/src/host/qemu-neo1973/hw/sh_timer.c
   trunk/src/host/qemu-neo1973/hw/tsc210x.c
   trunk/src/host/qemu-neo1973/linux-user/alpha/target_signal.h
   trunk/src/host/qemu-neo1973/linux-user/arm/target_signal.h
   trunk/src/host/qemu-neo1973/linux-user/cris/
   trunk/src/host/qemu-neo1973/linux-user/cris/syscall.h
   trunk/src/host/qemu-neo1973/linux-user/cris/syscall_nr.h
   trunk/src/host/qemu-neo1973/linux-user/cris/target_signal.h
   trunk/src/host/qemu-neo1973/linux-user/cris/termbits.h
   trunk/src/host/qemu-neo1973/linux-user/elfload32.c
   trunk/src/host/qemu-neo1973/linux-user/i386/target_signal.h
   trunk/src/host/qemu-neo1973/linux-user/m68k/target_signal.h
   trunk/src/host/qemu-neo1973/linux-user/mips/target_signal.h
   trunk/src/host/qemu-neo1973/linux-user/ppc/target_signal.h
   trunk/src/host/qemu-neo1973/linux-user/sh4/target_signal.h
   trunk/src/host/qemu-neo1973/linux-user/sparc/target_signal.h
   trunk/src/host/qemu-neo1973/linux-user/sparc64/target_signal.h
   trunk/src/host/qemu-neo1973/linux-user/x86_64/target_signal.h
   trunk/src/host/qemu-neo1973/target-alpha/STATUS
   trunk/src/host/qemu-neo1973/target-cris/
   trunk/src/host/qemu-neo1973/target-cris/cpu.h
   trunk/src/host/qemu-neo1973/target-cris/crisv32-decode.h
   trunk/src/host/qemu-neo1973/target-cris/exec.h
   trunk/src/host/qemu-neo1973/target-cris/helper.c
   trunk/src/host/qemu-neo1973/target-cris/mmu.c
   trunk/src/host/qemu-neo1973/target-cris/mmu.h
   trunk/src/host/qemu-neo1973/target-cris/op.c
   trunk/src/host/qemu-neo1973/target-cris/op_helper.c
   trunk/src/host/qemu-neo1973/target-cris/op_mem.c
   trunk/src/host/qemu-neo1973/target-cris/op_template.h
   trunk/src/host/qemu-neo1973/target-cris/opcode-cris.h
   trunk/src/host/qemu-neo1973/target-cris/translate.c
   trunk/src/host/qemu-neo1973/target-i386/svm.h
   trunk/src/host/qemu-neo1973/target-ppc/helper_regs.h
Removed:
   trunk/src/host/qemu-neo1973/ecc.h
   trunk/src/host/qemu-neo1973/linux-user/ppc64/
   trunk/src/host/qemu-neo1973/target-mips/op_helper_mem.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/block-raw.c
   trunk/src/host/qemu-neo1973/block-vmdk.c
   trunk/src/host/qemu-neo1973/block-vvfat.c
   trunk/src/host/qemu-neo1973/configure
   trunk/src/host/qemu-neo1973/cpu-all.h
   trunk/src/host/qemu-neo1973/cpu-defs.h
   trunk/src/host/qemu-neo1973/cpu-exec.c
   trunk/src/host/qemu-neo1973/darwin-user/main.c
   trunk/src/host/qemu-neo1973/dis-asm.h
   trunk/src/host/qemu-neo1973/disas.c
   trunk/src/host/qemu-neo1973/elf.h
   trunk/src/host/qemu-neo1973/elf_ops.h
   trunk/src/host/qemu-neo1973/exec-all.h
   trunk/src/host/qemu-neo1973/exec.c
   trunk/src/host/qemu-neo1973/gdbstub.c
   trunk/src/host/qemu-neo1973/host-utils.c
   trunk/src/host/qemu-neo1973/hw/acpi.c
   trunk/src/host/qemu-neo1973/hw/alpha_palcode.c
   trunk/src/host/qemu-neo1973/hw/apb_pci.c
   trunk/src/host/qemu-neo1973/hw/apic.c
   trunk/src/host/qemu-neo1973/hw/cs4231.c
   trunk/src/host/qemu-neo1973/hw/cuda.c
   trunk/src/host/qemu-neo1973/hw/esp.c
   trunk/src/host/qemu-neo1973/hw/grackle_pci.c
   trunk/src/host/qemu-neo1973/hw/gt64xxx.c
   trunk/src/host/qemu-neo1973/hw/heathrow_pic.c
   trunk/src/host/qemu-neo1973/hw/i8259.c
   trunk/src/host/qemu-neo1973/hw/iommu.c
   trunk/src/host/qemu-neo1973/hw/irq.c
   trunk/src/host/qemu-neo1973/hw/irq.h
   trunk/src/host/qemu-neo1973/hw/m48t59.c
   trunk/src/host/qemu-neo1973/hw/m48t59.h
   trunk/src/host/qemu-neo1973/hw/mips_malta.c
   trunk/src/host/qemu-neo1973/hw/mips_pica61.c
   trunk/src/host/qemu-neo1973/hw/mips_r4k.c
   trunk/src/host/qemu-neo1973/hw/mips_timer.c
   trunk/src/host/qemu-neo1973/hw/omap.c
   trunk/src/host/qemu-neo1973/hw/omap.h
   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/pckbd.c
   trunk/src/host/qemu-neo1973/hw/piix_pci.c
   trunk/src/host/qemu-neo1973/hw/pl110.c
   trunk/src/host/qemu-neo1973/hw/pl110_template.h
   trunk/src/host/qemu-neo1973/hw/ppc.c
   trunk/src/host/qemu-neo1973/hw/ppc405.h
   trunk/src/host/qemu-neo1973/hw/ppc405_boards.c
   trunk/src/host/qemu-neo1973/hw/ppc405_uc.c
   trunk/src/host/qemu-neo1973/hw/ppc_chrp.c
   trunk/src/host/qemu-neo1973/hw/ppc_prep.c
   trunk/src/host/qemu-neo1973/hw/prep_pci.c
   trunk/src/host/qemu-neo1973/hw/pxa.h
   trunk/src/host/qemu-neo1973/hw/pxa2xx_gpio.c
   trunk/src/host/qemu-neo1973/hw/sh7750.c
   trunk/src/host/qemu-neo1973/hw/sh7750_regnames.c
   trunk/src/host/qemu-neo1973/hw/sh7750_regs.h
   trunk/src/host/qemu-neo1973/hw/shix.c
   trunk/src/host/qemu-neo1973/hw/slavio_intctl.c
   trunk/src/host/qemu-neo1973/hw/slavio_misc.c
   trunk/src/host/qemu-neo1973/hw/slavio_serial.c
   trunk/src/host/qemu-neo1973/hw/slavio_timer.c
   trunk/src/host/qemu-neo1973/hw/spitz.c
   trunk/src/host/qemu-neo1973/hw/sun4m.c
   trunk/src/host/qemu-neo1973/hw/sun4u.c
   trunk/src/host/qemu-neo1973/hw/tcx.c
   trunk/src/host/qemu-neo1973/hw/usb-uhci.c
   trunk/src/host/qemu-neo1973/hw/vmport.c
   trunk/src/host/qemu-neo1973/linux-user/alpha/syscall.h
   trunk/src/host/qemu-neo1973/linux-user/alpha/syscall_nr.h
   trunk/src/host/qemu-neo1973/linux-user/arm/syscall.h
   trunk/src/host/qemu-neo1973/linux-user/arm/syscall_nr.h
   trunk/src/host/qemu-neo1973/linux-user/arm/termbits.h
   trunk/src/host/qemu-neo1973/linux-user/elfload.c
   trunk/src/host/qemu-neo1973/linux-user/flat.h
   trunk/src/host/qemu-neo1973/linux-user/flatload.c
   trunk/src/host/qemu-neo1973/linux-user/i386/syscall.h
   trunk/src/host/qemu-neo1973/linux-user/i386/syscall_nr.h
   trunk/src/host/qemu-neo1973/linux-user/i386/termbits.h
   trunk/src/host/qemu-neo1973/linux-user/linuxload.c
   trunk/src/host/qemu-neo1973/linux-user/m68k/syscall.h
   trunk/src/host/qemu-neo1973/linux-user/m68k/syscall_nr.h
   trunk/src/host/qemu-neo1973/linux-user/m68k/termbits.h
   trunk/src/host/qemu-neo1973/linux-user/main.c
   trunk/src/host/qemu-neo1973/linux-user/mips/syscall.h
   trunk/src/host/qemu-neo1973/linux-user/mips/syscall_nr.h
   trunk/src/host/qemu-neo1973/linux-user/mips/termbits.h
   trunk/src/host/qemu-neo1973/linux-user/mmap.c
   trunk/src/host/qemu-neo1973/linux-user/ppc/syscall.h
   trunk/src/host/qemu-neo1973/linux-user/ppc/syscall_nr.h
   trunk/src/host/qemu-neo1973/linux-user/ppc/termbits.h
   trunk/src/host/qemu-neo1973/linux-user/qemu.h
   trunk/src/host/qemu-neo1973/linux-user/sh4/syscall_nr.h
   trunk/src/host/qemu-neo1973/linux-user/signal.c
   trunk/src/host/qemu-neo1973/linux-user/sparc/syscall.h
   trunk/src/host/qemu-neo1973/linux-user/sparc/syscall_nr.h
   trunk/src/host/qemu-neo1973/linux-user/sparc/termbits.h
   trunk/src/host/qemu-neo1973/linux-user/sparc64/syscall.h
   trunk/src/host/qemu-neo1973/linux-user/sparc64/syscall_nr.h
   trunk/src/host/qemu-neo1973/linux-user/sparc64/termbits.h
   trunk/src/host/qemu-neo1973/linux-user/syscall.c
   trunk/src/host/qemu-neo1973/linux-user/syscall_defs.h
   trunk/src/host/qemu-neo1973/linux-user/vm86.c
   trunk/src/host/qemu-neo1973/linux-user/x86_64/syscall.h
   trunk/src/host/qemu-neo1973/linux-user/x86_64/syscall_nr.h
   trunk/src/host/qemu-neo1973/loader.c
   trunk/src/host/qemu-neo1973/monitor.c
   trunk/src/host/qemu-neo1973/pc-bios/README
   trunk/src/host/qemu-neo1973/pc-bios/openbios-sparc32
   trunk/src/host/qemu-neo1973/pc-bios/ppc_rom.bin
   trunk/src/host/qemu-neo1973/qemu-binfmt-conf.sh
   trunk/src/host/qemu-neo1973/qemu-doc.texi
   trunk/src/host/qemu-neo1973/qemu-img.c
   trunk/src/host/qemu-neo1973/qemu-tech.texi
   trunk/src/host/qemu-neo1973/readline.c
   trunk/src/host/qemu-neo1973/slirp/bootp.c
   trunk/src/host/qemu-neo1973/slirp/debug.c
   trunk/src/host/qemu-neo1973/slirp/debug.h
   trunk/src/host/qemu-neo1973/slirp/icmp_var.h
   trunk/src/host/qemu-neo1973/slirp/if.c
   trunk/src/host/qemu-neo1973/slirp/if.h
   trunk/src/host/qemu-neo1973/slirp/ip.h
   trunk/src/host/qemu-neo1973/slirp/ip_icmp.c
   trunk/src/host/qemu-neo1973/slirp/ip_input.c
   trunk/src/host/qemu-neo1973/slirp/ip_output.c
   trunk/src/host/qemu-neo1973/slirp/libslirp.h
   trunk/src/host/qemu-neo1973/slirp/main.h
   trunk/src/host/qemu-neo1973/slirp/mbuf.c
   trunk/src/host/qemu-neo1973/slirp/mbuf.h
   trunk/src/host/qemu-neo1973/slirp/misc.c
   trunk/src/host/qemu-neo1973/slirp/misc.h
   trunk/src/host/qemu-neo1973/slirp/sbuf.c
   trunk/src/host/qemu-neo1973/slirp/sbuf.h
   trunk/src/host/qemu-neo1973/slirp/slirp.c
   trunk/src/host/qemu-neo1973/slirp/slirp.h
   trunk/src/host/qemu-neo1973/slirp/socket.c
   trunk/src/host/qemu-neo1973/slirp/socket.h
   trunk/src/host/qemu-neo1973/slirp/tcp.h
   trunk/src/host/qemu-neo1973/slirp/tcp_input.c
   trunk/src/host/qemu-neo1973/slirp/tcp_output.c
   trunk/src/host/qemu-neo1973/slirp/tcp_subr.c
   trunk/src/host/qemu-neo1973/slirp/tcp_timer.c
   trunk/src/host/qemu-neo1973/slirp/tcp_timer.h
   trunk/src/host/qemu-neo1973/slirp/tcp_var.h
   trunk/src/host/qemu-neo1973/slirp/tftp.c
   trunk/src/host/qemu-neo1973/slirp/udp.c
   trunk/src/host/qemu-neo1973/slirp/udp.h
   trunk/src/host/qemu-neo1973/softmmu_exec.h
   trunk/src/host/qemu-neo1973/softmmu_header.h
   trunk/src/host/qemu-neo1973/softmmu_template.h
   trunk/src/host/qemu-neo1973/sparc-dis.c
   trunk/src/host/qemu-neo1973/sparc.ld
   trunk/src/host/qemu-neo1973/sparc64.ld
   trunk/src/host/qemu-neo1973/target-alpha/cpu.h
   trunk/src/host/qemu-neo1973/target-alpha/exec.h
   trunk/src/host/qemu-neo1973/target-alpha/helper.c
   trunk/src/host/qemu-neo1973/target-alpha/op.c
   trunk/src/host/qemu-neo1973/target-alpha/op_helper.c
   trunk/src/host/qemu-neo1973/target-alpha/op_helper.h
   trunk/src/host/qemu-neo1973/target-alpha/op_mem.h
   trunk/src/host/qemu-neo1973/target-alpha/translate.c
   trunk/src/host/qemu-neo1973/target-arm/cpu.h
   trunk/src/host/qemu-neo1973/target-arm/exec.h
   trunk/src/host/qemu-neo1973/target-arm/helper.c
   trunk/src/host/qemu-neo1973/target-arm/op_helper.c
   trunk/src/host/qemu-neo1973/target-i386/cpu.h
   trunk/src/host/qemu-neo1973/target-i386/exec.h
   trunk/src/host/qemu-neo1973/target-i386/helper.c
   trunk/src/host/qemu-neo1973/target-i386/helper2.c
   trunk/src/host/qemu-neo1973/target-i386/op.c
   trunk/src/host/qemu-neo1973/target-i386/translate.c
   trunk/src/host/qemu-neo1973/target-m68k/cpu.h
   trunk/src/host/qemu-neo1973/target-m68k/exec.h
   trunk/src/host/qemu-neo1973/target-m68k/helper.c
   trunk/src/host/qemu-neo1973/target-m68k/op_helper.c
   trunk/src/host/qemu-neo1973/target-mips/TODO
   trunk/src/host/qemu-neo1973/target-mips/cpu.h
   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/STATUS
   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/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/op_helper_mem.h
   trunk/src/host/qemu-neo1973/target-ppc/op_mem.h
   trunk/src/host/qemu-neo1973/target-ppc/op_template.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-sh4/cpu.h
   trunk/src/host/qemu-neo1973/target-sh4/exec.h
   trunk/src/host/qemu-neo1973/target-sh4/helper.c
   trunk/src/host/qemu-neo1973/target-sh4/op_helper.c
   trunk/src/host/qemu-neo1973/target-sh4/translate.c
   trunk/src/host/qemu-neo1973/target-sparc/cpu.h
   trunk/src/host/qemu-neo1973/target-sparc/exec.h
   trunk/src/host/qemu-neo1973/target-sparc/helper.c
   trunk/src/host/qemu-neo1973/target-sparc/op.c
   trunk/src/host/qemu-neo1973/target-sparc/op_helper.c
   trunk/src/host/qemu-neo1973/target-sparc/op_mem.h
   trunk/src/host/qemu-neo1973/target-sparc/translate.c
   trunk/src/host/qemu-neo1973/tests/Makefile
   trunk/src/host/qemu-neo1973/thunk.c
   trunk/src/host/qemu-neo1973/thunk.h
   trunk/src/host/qemu-neo1973/usb-linux.c
   trunk/src/host/qemu-neo1973/vl.c
   trunk/src/host/qemu-neo1973/vl.h
   trunk/src/host/qemu-neo1973/vnc.c
Log:
Pull changes from cvs.savannah.nongnu.org.


Modified: trunk/src/host/qemu-neo1973/Changelog
===================================================================
--- trunk/src/host/qemu-neo1973/Changelog	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/Changelog	2007-10-29 21:14:04 UTC (rev 3303)
@@ -3,7 +3,7 @@
   - Monitor multiplexing to several I/O channels (Jason Wessel)
   - ds1225y nvram support (Herve Poussineau)
   - CPU model selection support (J. Mayer, Paul Brook, Herve Poussineau)
-  - Several Sparc fixes (Aurelien Jarno, Blue Swirl)
+  - Several Sparc fixes (Aurelien Jarno, Blue Swirl, Robert Reif)
   - MIPS 64-bit FPU support (Thiemo Seufer)
   - Xscale PDA emulation (Andrzei Zaborowski)
   - ColdFire system emulation (Paul Brook)
@@ -11,6 +11,9 @@
   - MIPS64 support (Aurelien Jarno, Thiemo Seufer)
   - Preliminary Alpha guest support (J. Mayer)
   - Read-only support for Parallels disk images (Alex Beregszaszi)
+  - SVM (x86 virtualization) support (Alexander Graf)
+  - CRIS emulation (Edgar E. Iglesias)
+  - SPARC32PLUS execution support (Blue Swirl)
 
 version 0.9.0:
 

Modified: trunk/src/host/qemu-neo1973/Makefile
===================================================================
--- trunk/src/host/qemu-neo1973/Makefile	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/Makefile	2007-10-29 21:14:04 UTC (rev 3303)
@@ -13,7 +13,6 @@
 
 CPPFLAGS += -I. -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE
 LIBS=
-TOOLS=qemu-img$(EXESUF) raw2flash$(EXESUF) flash2raw$(EXESUF)
 ifdef CONFIG_STATIC
 BASE_LDFLAGS += -static
 endif
@@ -80,7 +79,9 @@
 
 install: all $(if $(BUILD_DOCS),install-doc)
 	mkdir -p "$(DESTDIR)$(bindir)"
+ifneq ($(TOOLS),)
 	$(INSTALL) -m 755 -s $(TOOLS) "$(DESTDIR)$(bindir)"
+endif
 	mkdir -p "$(DESTDIR)$(datadir)"
 	for x in bios.bin vgabios.bin vgabios-cirrus.bin ppc_rom.bin \
 		video.x openbios-sparc32 pxe-ne2k_pci.bin \
@@ -150,7 +151,7 @@
 
 # generate a binary distribution
 tarbin:
-	( cd / ; tar zcvf ~/qemu-$(VERSION)-i386.tar.gz \
+	( cd / ; tar zcvf ~/qemu-$(VERSION)-$(ARCH).tar.gz \
 	$(bindir)/qemu \
 	$(bindir)/qemu-system-ppc \
 	$(bindir)/qemu-system-ppc64 \
@@ -162,6 +163,8 @@
 	$(bindir)/qemu-system-mips64 \
 	$(bindir)/qemu-system-mips64el \
 	$(bindir)/qemu-system-arm \
+	$(bindir)/qemu-system-m68k \
+	$(bindir)/qemu-system-sh4 \
 	$(bindir)/qemu-i386 \
         $(bindir)/qemu-arm \
         $(bindir)/qemu-armeb \
@@ -170,7 +173,13 @@
         $(bindir)/qemu-ppc64 \
         $(bindir)/qemu-mips \
         $(bindir)/qemu-mipsel \
+        $(bindir)/qemu-mipsn32 \
+        $(bindir)/qemu-mipsn32el \
+        $(bindir)/qemu-mips64 \
+        $(bindir)/qemu-mips64el \
         $(bindir)/qemu-alpha \
+        $(bindir)/qemu-m68k \
+        $(bindir)/qemu-sh4 \
         $(bindir)/qemu-img \
 	$(datadir)/bios.bin \
 	$(datadir)/vgabios.bin \

Modified: trunk/src/host/qemu-neo1973/Makefile.target
===================================================================
--- trunk/src/host/qemu-neo1973/Makefile.target	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/Makefile.target	2007-10-29 21:14:04 UTC (rev 3303)
@@ -4,12 +4,18 @@
 ifeq ($(TARGET_ARCH), x86_64)
 TARGET_BASE_ARCH:=i386
 endif
+ifeq ($(TARGET_ARCH), mipsn32)
+TARGET_BASE_ARCH:=mips
+endif
 ifeq ($(TARGET_ARCH), mips64)
 TARGET_BASE_ARCH:=mips
 endif
 ifeq ($(TARGET_ARCH), ppc64)
 TARGET_BASE_ARCH:=ppc
 endif
+ifeq ($(TARGET_ARCH), ppc64h)
+TARGET_BASE_ARCH:=ppc
+endif
 ifeq ($(TARGET_ARCH), ppcemb)
 TARGET_BASE_ARCH:=ppc
 endif
@@ -18,15 +24,18 @@
 endif
 TARGET_PATH=$(SRC_PATH)/target-$(TARGET_BASE_ARCH)
 VPATH=$(SRC_PATH):$(TARGET_PATH):$(SRC_PATH)/hw:$(SRC_PATH)/audio
-CPPFLAGS=-I. -I.. -I$(TARGET_PATH) -I$(SRC_PATH)
+CPPFLAGS=-I. -I.. -I$(TARGET_PATH) -I$(SRC_PATH) -MMD -MP
 ifdef CONFIG_DARWIN_USER
 VPATH+=:$(SRC_PATH)/darwin-user
 CPPFLAGS+=-I$(SRC_PATH)/darwin-user -I$(SRC_PATH)/darwin-user/$(TARGET_ARCH)
 endif
 ifdef CONFIG_LINUX_USER
 VPATH+=:$(SRC_PATH)/linux-user
-CPPFLAGS+=-I$(SRC_PATH)/linux-user -I$(SRC_PATH)/linux-user/$(TARGET_ARCH)
+ifndef TARGET_ABI_DIR
+  TARGET_ABI_DIR=$(TARGET_ARCH)
 endif
+CPPFLAGS+=-I$(SRC_PATH)/linux-user -I$(SRC_PATH)/linux-user/$(TARGET_ABI_DIR)
+endif
 BASE_CFLAGS=
 BASE_LDFLAGS=
 #CFLAGS+=-Werror
@@ -50,11 +59,21 @@
     TARGET_ARCH2=mipsel
   endif
 endif
+ifeq ($(TARGET_ARCH),mipsn32)
+  ifneq ($(TARGET_WORDS_BIGENDIAN),yes)
+    TARGET_ARCH2=mipsn32el
+  endif
+endif
 ifeq ($(TARGET_ARCH),mips64)
   ifneq ($(TARGET_WORDS_BIGENDIAN),yes)
     TARGET_ARCH2=mips64el
   endif
 endif
+ifeq ($(TARGET_ARCH),sparc64)
+  ifeq ($(TARGET_ABI_DIR),sparc)
+    TARGET_ARCH2=sparc32plus
+  endif
+endif
 QEMU_USER=qemu-$(TARGET_ARCH2)
 # system emulator name
 ifdef CONFIG_SOFTMMU
@@ -246,6 +265,10 @@
 ifdef TARGET_HAS_BFLT
 OBJS+= flatload.o
 endif
+ifdef TARGET_HAS_ELFLOAD32
+OBJS+= elfload32.o
+elfload32.o: elfload.c
+endif
 
 ifeq ($(TARGET_ARCH), i386)
 OBJS+= vm86.o
@@ -269,7 +292,7 @@
 
 # cpu emulator library
 LIBOBJS=exec.o kqemu.o translate-op.o translate-all.o cpu-exec.o\
-        translate.o op.o
+        translate.o op.o host-utils.o
 ifdef CONFIG_SOFTFLOAT
 LIBOBJS+=fpu/softfloat.o
 else
@@ -316,6 +339,15 @@
 LIBOBJS+= op_helper.o helper.o alpha_palcode.o
 endif
 
+ifeq ($(TARGET_BASE_ARCH), cris)
+LIBOBJS+= op_helper.o helper.o
+LIBOBJS+= cris-dis.o
+
+ifndef CONFIG_USER_ONLY
+LIBOBJS+= mmu.o
+endif
+endif
+
 # NOTE: the disassembler code is only needed for debugging
 LIBOBJS+=disas.o
 ifeq ($(findstring i386, $(TARGET_ARCH) $(ARCH)),i386)
@@ -369,7 +401,6 @@
 # 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+=host-utils.o
 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
@@ -446,20 +477,36 @@
 CPPFLAGS += -DHAS_AUDIO -DHAS_AUDIO_CHOICE
 endif
 ifeq ($(TARGET_BASE_ARCH), ppc)
-VL_OBJS+= ppc.o ide.o pckbd.o ps2.o vga.o $(SOUND_HW) dma.o $(AUDIODRV)
-VL_OBJS+= mc146818rtc.o serial.o i8259.o i8254.o fdc.o m48t59.o pflash_cfi02.o
-VL_OBJS+= ppc_prep.o ppc_chrp.o cuda.o adb.o openpic.o heathrow_pic.o
-VL_OBJS+= grackle_pci.o prep_pci.o unin_pci.o ppc405_uc.o ppc405_boards.o
 CPPFLAGS += -DHAS_AUDIO -DHAS_AUDIO_CHOICE
+# shared objects
+VL_OBJS+= ppc.o ide.o vga.o $(SOUND_HW) dma.o openpic.o $(AUDIODRV)
+# 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
+# Mac shared devices
+VL_OBJS+= macio.o cuda.o adb.o mac_nvram.o mac_dbdma.o
+# OldWorld PowerMac
+VL_OBJS+= heathrow_pic.o grackle_pci.o ppc_oldworld.o
+# NewWorld PowerMac
+VL_OBJS+= unin_pci.o ppc_chrp.o
+# PowerPC 4xx boards
+VL_OBJS+= pflash_cfi02.o ppc4xx_devs.o ppc405_uc.o ppc405_boards.o
 endif
 ifeq ($(TARGET_BASE_ARCH), mips)
-VL_OBJS+= mips_r4k.o mips_malta.o mips_pica61.o
+VL_OBJS+= mips_r4k.o mips_malta.o mips_pica61.o mips_mipssim.o
 VL_OBJS+= mips_timer.o mips_int.o dma.o vga.o serial.o i8254.o i8259.o
 VL_OBJS+= jazz_led.o
 VL_OBJS+= ide.o gt64xxx.o pckbd.o ps2.o fdc.o mc146818rtc.o usb-uhci.o acpi.o ds1225y.o
 VL_OBJS+= piix_pci.o smbus_eeprom.o parallel.o mixeng.o cirrus_vga.o $(SOUND_HW) $(AUDIODRV)
+VL_OBJS+= mipsnet.o
 CPPFLAGS += -DHAS_AUDIO
 endif
+ifeq ($(TARGET_BASE_ARCH), cris)
+VL_OBJS+= etraxfs.o
+VL_OBJS+= ptimer.o
+VL_OBJS+= etraxfs_timer.o
+VL_OBJS+= etraxfs_ser.o
+endif
 ifeq ($(TARGET_BASE_ARCH), sparc)
 ifeq ($(TARGET_ARCH), sparc64)
 VL_OBJS+= sun4u.o ide.o pckbd.o ps2.o vga.o apb_pci.o
@@ -479,15 +526,17 @@
 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 $(AUDIODRV) wm8750.o wm8753.o
+VL_OBJS+= spitz.o ads7846.o ide.o serial.o nand.o ecc.o
+VL_OBJS+= $(AUDIODRV) 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
 VL_OBJS+= $(GSM_OBJS) modem.o
-VL_OBJS+= omap.o omap_lcdc.o omap1_clk.o omap_mmc.o palm.o
+VL_OBJS+= omap.o omap_lcdc.o omap1_clk.o omap_mmc.o palm.o tsc210x.o
 CPPFLAGS+= -DHAS_AUDIO $(GSM_CPPFLAGS)
 endif
 ifeq ($(TARGET_BASE_ARCH), sh4)
-VL_OBJS+= shix.o sh7750.o sh7750_regnames.o tc58128.o
+VL_OBJS+= shix.o r2d.o sh7750.o sh7750_regnames.o tc58128.o
+VL_OBJS+= sh_timer.o ptimer.o sh_serial.o sh_intc.o
 endif
 ifeq ($(TARGET_BASE_ARCH), m68k)
 VL_OBJS+= an5206.o mcf5206.o ptimer.o mcf_uart.o mcf_intc.o mcf5208.o mcf_fec.o
@@ -615,58 +664,6 @@
 signal.o: signal.c
 	$(CC) $(HELPER_CFLAGS) $(CPPFLAGS) $(BASE_CFLAGS) -c -o $@ $<
 
-vga.o: pixel_ops.h
-
-tcx.o: pixel_ops.h
-
-ifeq ($(TARGET_BASE_ARCH), i386)
-op.o: op.c opreg_template.h ops_template.h ops_template_mem.h ops_mem.h ops_sse.h
-endif
-
-ifeq ($(TARGET_ARCH), arm)
-op.o: op.c op_template.h
-pl110.o: pl110_template.h
-endif
-
-ifeq ($(TARGET_BASE_ARCH), sparc)
-helper.o: cpu.h exec-all.h
-op.o: op.c op_template.h op_mem.h fop_template.h fbranch_template.h exec.h cpu.h
-op_helper.o: exec.h softmmu_template.h cpu.h
-translate.o: cpu.h exec-all.h disas.h
-endif
-
-ifeq ($(TARGET_BASE_ARCH), ppc)
-op.o: op.c op_template.h op_mem.h
-op_helper.o: op_helper_mem.h
-translate.o: translate.c translate_init.c
-endif
-
-ifeq ($(TARGET_BASE_ARCH), mips)
-helper.o: cpu.h exec-all.h
-op.o: op_template.c fop_template.c op_mem.c exec.h cpu.h
-op_helper.o: op_helper_mem.c exec.h softmmu_template.h cpu.h
-translate.o: translate_init.c exec-all.h disas.h
-endif
-
-loader.o: loader.c elf_ops.h
-
-ifeq ($(TARGET_ARCH), sh4)
-op.o: op.c op_mem.c cpu.h
-op_helper.o: op_helper.c exec.h cpu.h
-helper.o: helper.c exec.h cpu.h
-sh7750.o: sh7750.c sh7750_regs.h sh7750_regnames.h cpu.h
-shix.o: shix.c sh7750_regs.h sh7750_regnames.h
-sh7750_regnames.o: sh7750_regnames.c sh7750_regnames.h sh7750_regs.h
-tc58128.o: tc58128.c
-endif
-
-ifeq ($(TARGET_BASE_ARCH), alpha)
-op.o: op.c op_template.h op_mem.h
-op_helper.o: op_helper_mem.h
-endif
-
-$(OBJS) $(LIBOBJS) $(VL_OBJS): config.h ../config-host.h
-
 %.o: %.c
 	$(CC) $(CFLAGS) $(CPPFLAGS) $(BASE_CFLAGS) -c -o $@ $<
 
@@ -674,7 +671,8 @@
 	$(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 slirp/*.o fpu/*.o
+	rm -f *.d */*.d
 
 install: all
 ifneq ($(PROGS),)
@@ -690,3 +688,6 @@
 fmodaudio.o alsaaudio.o mixeng.o sb16.o es1370.o gus.o adlib.o: \
 CFLAGS := $(CFLAGS) -Wall -Werror -W -Wsign-compare
 endif
+
+# Include automatically generated dependency files
+-include $(wildcard *.d */*.d)

Modified: trunk/src/host/qemu-neo1973/block-raw.c
===================================================================
--- trunk/src/host/qemu-neo1973/block-raw.c	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/block-raw.c	2007-10-29 21:14:04 UTC (rev 3303)
@@ -151,7 +151,8 @@
     if (lseek(s->fd, offset, SEEK_SET) == (off_t)-1) {
         ++(s->lseek_err_cnt);
         if(s->lseek_err_cnt <= 10) {
-            DEBUG_BLOCK_PRINT("raw_pread(%d:%s, %lld, %p, %d) [%lld] lseek failed : %d = %s\n",
+            DEBUG_BLOCK_PRINT("raw_pread(%d:%s, %" PRId64 ", %p, %d) [%" PRId64
+                              "] lseek failed : %d = %s\n",
                               s->fd, bs->filename, offset, buf, count,
                               bs->total_sectors, errno, strerror(errno));
         }
@@ -163,7 +164,8 @@
     if (ret == count)
         goto label__raw_read__success;
 
-    DEBUG_BLOCK_PRINT("raw_pread(%d:%s, %lld, %p, %d) [%lld] read failed %d : %d = %s\n",
+    DEBUG_BLOCK_PRINT("raw_pread(%d:%s, %" PRId64 ", %p, %d) [%" PRId64
+                      "] read failed %d : %d = %s\n",
                       s->fd, bs->filename, offset, buf, count,
                       bs->total_sectors, ret, errno, strerror(errno));
 
@@ -178,7 +180,8 @@
         if (ret == count)
             goto label__raw_read__success;
 
-        DEBUG_BLOCK_PRINT("raw_pread(%d:%s, %lld, %p, %d) [%lld] retry read failed %d : %d = %s\n",
+        DEBUG_BLOCK_PRINT("raw_pread(%d:%s, %" PRId64 ", %p, %d) [%" PRId64
+                          "] retry read failed %d : %d = %s\n",
                           s->fd, bs->filename, offset, buf, count,
                           bs->total_sectors, ret, errno, strerror(errno));
     }
@@ -201,7 +204,8 @@
     if (lseek(s->fd, offset, SEEK_SET) == (off_t)-1) {
         ++(s->lseek_err_cnt);
         if(s->lseek_err_cnt) {
-            DEBUG_BLOCK_PRINT("raw_pwrite(%d:%s, %lld, %p, %d) [%lld] lseek failed : %d = %s\n",
+            DEBUG_BLOCK_PRINT("raw_pwrite(%d:%s, %" PRId64 ", %p, %d) [%"
+                              PRId64 "] lseek failed : %d = %s\n",
                               s->fd, bs->filename, offset, buf, count,
                               bs->total_sectors, errno, strerror(errno));
         }
@@ -213,7 +217,8 @@
     if (ret == count)
         goto label__raw_write__success;
 
-    DEBUG_BLOCK_PRINT("raw_pwrite(%d:%s, %lld, %p, %d) [%lld] write failed %d : %d = %s\n",
+    DEBUG_BLOCK_PRINT("raw_pwrite(%d:%s, %" PRId64 ", %p, %d) [%" PRId64
+                      "] write failed %d : %d = %s\n",
                       s->fd, bs->filename, offset, buf, count,
                       bs->total_sectors, ret, errno, strerror(errno));
 
@@ -1169,7 +1174,7 @@
     BDRVRawState *s = bs->opaque;
     LARGE_INTEGER l;
     ULARGE_INTEGER available, total, total_free;
-    DISK_GEOMETRY dg;
+    DISK_GEOMETRY_EX dg;
     DWORD count;
     BOOL status;
 
@@ -1185,11 +1190,10 @@
         l.QuadPart = total.QuadPart;
         break;
     case FTYPE_HARDDISK:
-        status = DeviceIoControl(s->hfile, IOCTL_DISK_GET_DRIVE_GEOMETRY,
+        status = DeviceIoControl(s->hfile, IOCTL_DISK_GET_DRIVE_GEOMETRY_EX,
                                  NULL, 0, &dg, sizeof(dg), &count, NULL);
-        if (status != FALSE) {
-            l.QuadPart = dg.Cylinders.QuadPart * dg.TracksPerCylinder
-                * dg.SectorsPerTrack * dg.BytesPerSector;
+        if (status != 0) {
+            l = dg.DiskSize;
         }
         break;
     default:

Modified: trunk/src/host/qemu-neo1973/block-vmdk.c
===================================================================
--- trunk/src/host/qemu-neo1973/block-vmdk.c	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/block-vmdk.c	2007-10-29 21:14:04 UTC (rev 3303)
@@ -659,7 +659,8 @@
 
     if (sector_num > bs->total_sectors) {
         fprintf(stderr,
-                "(VMDK) Wrong offset: sector_num=0x%llx total_sectors=0x%llx\n",
+                "(VMDK) Wrong offset: sector_num=0x%" PRIx64
+                " total_sectors=0x%" PRIx64 "\n",
                 sector_num, bs->total_sectors);
         return -1;
     }

Modified: trunk/src/host/qemu-neo1973/block-vvfat.c
===================================================================
--- trunk/src/host/qemu-neo1973/block-vvfat.c	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/block-vvfat.c	2007-10-29 21:14:04 UTC (rev 3303)
@@ -242,21 +242,25 @@
     uint8_t magic[2];
 } __attribute__((packed)) bootsector_t;
 
+typedef struct {
+    uint8_t head;
+    uint8_t sector;
+    uint8_t cylinder;
+} mbr_chs_t;
+
 typedef struct partition_t {
     uint8_t attributes; /* 0x80 = bootable */
-    uint8_t start_head;
-    uint8_t start_sector;
-    uint8_t start_cylinder;
-    uint8_t fs_type; /* 0x1 = FAT12, 0x6 = FAT16, 0xb = FAT32 */
-    uint8_t end_head;
-    uint8_t end_sector;
-    uint8_t end_cylinder;
+    mbr_chs_t start_CHS;
+    uint8_t   fs_type; /* 0x1 = FAT12, 0x6 = FAT16, 0xe = FAT16_LBA, 0xb = FAT32, 0xc = FAT32_LBA */
+    mbr_chs_t end_CHS;
     uint32_t start_sector_long;
-    uint32_t end_sector_long;
+    uint32_t length_sector_long;
 } __attribute__((packed)) partition_t;
 
 typedef struct mbr_t {
-    uint8_t ignored[0x1be];
+    uint8_t ignored[0x1b8];
+    uint32_t nt_id;
+    uint8_t ignored2[2];
     partition_t partition[4];
     uint8_t magic[2];
 } __attribute__((packed)) mbr_t;
@@ -350,26 +354,57 @@
     int downcase_short_names;
 } BDRVVVFATState;
 
+/* take the sector position spos and convert it to Cylinder/Head/Sector position
+ * if the position is outside the specified geometry, fill maximum value for CHS
+ * and return 1 to signal overflow.
+ */
+static int sector2CHS(BlockDriverState* bs, mbr_chs_t * chs, int spos){
+    int head,sector;
+    sector   = spos % (bs->secs);  spos/= bs->secs;
+    head     = spos % (bs->heads); spos/= bs->heads;
+    if(spos >= bs->cyls){
+        /* Overflow,
+        it happens if 32bit sector positions are used, while CHS is only 24bit.
+        Windows/Dos is said to take 1023/255/63 as nonrepresentable CHS */
+        chs->head     = 0xFF;
+        chs->sector   = 0xFF;
+        chs->cylinder = 0xFF;
+        return 1;
+    }
+    chs->head     = (uint8_t)head;
+    chs->sector   = (uint8_t)( (sector+1) | ((spos>>8)<<6) );
+    chs->cylinder = (uint8_t)spos;
+    return 0;
+}
 
 static void init_mbr(BDRVVVFATState* s)
 {
     /* TODO: if the files mbr.img and bootsect.img exist, use them */
     mbr_t* real_mbr=(mbr_t*)s->first_sectors;
     partition_t* partition=&(real_mbr->partition[0]);
+    int lba;
 
     memset(s->first_sectors,0,512);
 
+    /* Win NT Disk Signature */
+    real_mbr->nt_id= cpu_to_le32(0xbe1afdfa);
+
     partition->attributes=0x80; /* bootable */
-    partition->start_head=1;
-    partition->start_sector=1;
-    partition->start_cylinder=0;
+
+    /* LBA is used when partition is outside the CHS geometry */
+    lba = sector2CHS(s->bs, &partition->start_CHS, s->first_sectors_number-1);
+    lba|= sector2CHS(s->bs, &partition->end_CHS,   s->sector_count);
+
+    /*LBA partitions are identified only by start/length_sector_long not by CHS*/
+    partition->start_sector_long =cpu_to_le32(s->first_sectors_number-1);
+    partition->length_sector_long=cpu_to_le32(s->sector_count - s->first_sectors_number+1);
+
     /* FAT12/FAT16/FAT32 */
-    partition->fs_type=(s->fat_type==12?0x1:s->fat_type==16?0x6:0xb);
-    partition->end_head=s->bs->heads-1;
-    partition->end_sector=0xff; /* end sector & upper 2 bits of cylinder */;
-    partition->end_cylinder=0xff; /* lower 8 bits of end cylinder */;
-    partition->start_sector_long=cpu_to_le32(s->bs->secs);
-    partition->end_sector_long=cpu_to_le32(s->sector_count);
+    /* DOS uses different types when partition is LBA,
+       probably to prevent older versions from using CHS on them */
+    partition->fs_type= s->fat_type==12 ? 0x1:
+                        s->fat_type==16 ? (lba?0xe:0x06):
+                         /*fat_tyoe==32*/ (lba?0xc:0x0b);
 
     real_mbr->magic[0]=0x55; real_mbr->magic[1]=0xaa;
 }
@@ -973,10 +1008,9 @@
 
     s->fat_type=16;
     /* LATER TODO: if FAT32, adjust */
-    s->sector_count=0xec04f;
     s->sectors_per_cluster=0x10;
-    /* LATER TODO: this could be wrong for FAT32 */
-    bs->cyls=1023; bs->heads=15; bs->secs=63;
+    /* 504MB disk*/
+    bs->cyls=1024; bs->heads=16; bs->secs=63;
 
     s->current_cluster=0xffffffff;
 
@@ -991,12 +1025,6 @@
     if (!strstart(dirname, "fat:", NULL))
 	return -1;
 
-    if (strstr(dirname, ":rw:")) {
-	if (enable_write_target(s))
-	    return -1;
-	bs->read_only = 0;
-    }
-
     if (strstr(dirname, ":floppy:")) {
 	floppy = 1;
 	s->fat_type = 12;
@@ -1005,6 +1033,8 @@
 	bs->cyls = 80; bs->heads = 2; bs->secs = 36;
     }
 
+    s->sector_count=bs->cyls*bs->heads*bs->secs;
+
     if (strstr(dirname, ":32:")) {
 	fprintf(stderr, "Big fat greek warning: FAT32 has not been tested. You are welcome to do so!\n");
 	s->fat_type = 32;
@@ -1015,6 +1045,12 @@
 	s->sector_count=2880;
     }
 
+    if (strstr(dirname, ":rw:")) {
+	if (enable_write_target(s))
+	    return -1;
+	bs->read_only = 0;
+    }
+
     i = strrchr(dirname, ':') - dirname;
     assert(i >= 3);
     if (dirname[i-2] == ':' && isalpha(dirname[i-1]))
@@ -1024,11 +1060,12 @@
 	dirname += i+1;
 
     bs->total_sectors=bs->cyls*bs->heads*bs->secs;
-    if (s->sector_count > bs->total_sectors)
-	s->sector_count = bs->total_sectors;
+
     if(init_directories(s, dirname))
 	return -1;
 
+    s->sector_count = s->faked_sectors + s->sectors_per_cluster*s->cluster_count;
+
     if(s->first_sectors_number==0x40)
 	init_mbr(s);
 

Modified: trunk/src/host/qemu-neo1973/configure
===================================================================
--- trunk/src/host/qemu-neo1973/configure	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/configure	2007-10-29 21:14:04 UTC (rev 3303)
@@ -53,6 +53,9 @@
   mips64)
     cpu="mips64"
   ;;
+  cris)
+    cpu="cris"
+  ;;
   s390*)
     cpu="s390"
   ;;
@@ -501,11 +504,11 @@
 if test -z "$target_list" ; then
 # these targets are portable
     if [ "$softmmu" = "yes" ] ; then
-        target_list="i386-softmmu ppc-softmmu sparc-softmmu x86_64-softmmu mips-softmmu mipsel-softmmu mips64-softmmu mips64el-softmmu arm-softmmu ppc64-softmmu ppcemb-softmmu m68k-softmmu"
+        target_list="i386-softmmu sparc-softmmu x86_64-softmmu mips-softmmu mipsel-softmmu mips64-softmmu mips64el-softmmu arm-softmmu ppc-softmmu ppcemb-softmmu ppc64-softmmu m68k-softmmu sh4-softmmu cris-softmmu"
     fi
 # the following are Linux specific
     if [ "$linux_user" = "yes" ] ; then
-        target_list="i386-linux-user arm-linux-user armeb-linux-user sparc-linux-user ppc-linux-user mips-linux-user mipsel-linux-user m68k-linux-user alpha-linux-user $target_list"
+        target_list="i386-linux-user arm-linux-user armeb-linux-user sparc-linux-user sparc64-linux-user sparc32plus-linux-user mips-linux-user mipsel-linux-user m68k-linux-user alpha-linux-user sh4-linux-user ppc-linux-user ppcemb-linux-user ppc64-linux-user ppc64abi32-linux-user x86_64-linux-user cris-linux-user $target_list"
     fi
 # the following are Darwin specific
     if [ "$darwin_user" = "yes" ] ; then
@@ -826,6 +829,9 @@
 elif test "$cpu" = "mips64" ; then
   echo "ARCH=mips64" >> $config_mak
   echo "#define HOST_MIPS64 1" >> $config_h
+elif test "$cpu" = "cris" ; then
+  echo "ARCH=cris" >> $config_mak
+  echo "#define HOST_CRIS 1" >> $config_h
 elif test "$cpu" = "s390" ; then
   echo "ARCH=s390" >> $config_mak
   echo "#define HOST_S390 1" >> $config_h
@@ -967,6 +973,12 @@
   echo "#define INTERNAL_MODEM \"gnokiigsm\"" >> $config_h
 fi
 
+if test `expr "$target_list" : ".*softmmu.*"` != 0 ; then
+  tools="raw2flash\$(EXESUF) flash2raw\$(EXESUF) $tools"
+  tools="qemu-img\$(EXESUF) $tools"
+fi
+echo "TOOLS=$tools" >> $config_mak
+
 test -f ${config_h}~ && cmp -s $config_h ${config_h}~ && mv ${config_h}~ $config_h
 
 for target in $target_list; do
@@ -978,10 +990,14 @@
 [ "$target_cpu" = "armeb" ] && target_bigendian=yes
 [ "$target_cpu" = "sparc" ] && target_bigendian=yes
 [ "$target_cpu" = "sparc64" ] && target_bigendian=yes
+[ "$target_cpu" = "sparc32plus" ] && target_bigendian=yes
 [ "$target_cpu" = "ppc" ] && target_bigendian=yes
+[ "$target_cpu" = "ppcemb" ] && target_bigendian=yes
 [ "$target_cpu" = "ppc64" ] && target_bigendian=yes
-[ "$target_cpu" = "ppcemb" ] && target_bigendian=yes
+[ "$target_cpu" = "ppc64abi32" ] && target_bigendian=yes
+[ "$target_cpu" = "ppc64h" ] && target_bigendian=yes
 [ "$target_cpu" = "mips" ] && target_bigendian=yes
+[ "$target_cpu" = "mipsn32" ] && target_bigendian=yes
 [ "$target_cpu" = "mips64" ] && target_bigendian=yes
 [ "$target_cpu" = "sh4eb" ] && target_bigendian=yes
 [ "$target_cpu" = "m68k" ] && target_bigendian=yes
@@ -1046,6 +1062,7 @@
 echo "#include \"../config-host.h\"" >> $config_h
 
 bflt="no"
+elfload32="no"
 interp_prefix1=`echo "$interp_prefix" | sed "s/%M/$target_cpu/g"`
 echo "#define CONFIG_QEMU_PREFIX \"$interp_prefix1\"" >> $config_h
 
@@ -1070,20 +1087,44 @@
   echo "#define TARGET_ARCH \"sparc64\"" >> $config_h
   echo "#define TARGET_SPARC 1" >> $config_h
   echo "#define TARGET_SPARC64 1" >> $config_h
+  elfload32="yes"
+elif test "$target_cpu" = "sparc32plus" ; then
+  echo "TARGET_ARCH=sparc64" >> $config_mak
+  echo "TARGET_ABI_DIR=sparc" >> $config_mak
+  echo "#define TARGET_ARCH \"sparc64\"" >> $config_h
+  echo "#define TARGET_SPARC 1" >> $config_h
+  echo "#define TARGET_SPARC64 1" >> $config_h
+  echo "#define TARGET_ABI32 1" >> $config_h
 elif test "$target_cpu" = "ppc" ; then
   echo "TARGET_ARCH=ppc" >> $config_mak
   echo "#define TARGET_ARCH \"ppc\"" >> $config_h
   echo "#define TARGET_PPC 1" >> $config_h
+elif test "$target_cpu" = "ppcemb" ; then
+  echo "TARGET_ARCH=ppcemb" >> $config_mak
+  echo "TARGET_ABI_DIR=ppc" >> $config_mak
+  echo "#define TARGET_ARCH \"ppcemb\"" >> $config_h
+  echo "#define TARGET_PPC 1" >> $config_h
+  echo "#define TARGET_PPCEMB 1" >> $config_h
 elif test "$target_cpu" = "ppc64" ; then
   echo "TARGET_ARCH=ppc64" >> $config_mak
   echo "#define TARGET_ARCH \"ppc64\"" >> $config_h
+  echo "TARGET_ABI_DIR=ppc" >> $config_mak
   echo "#define TARGET_PPC 1" >> $config_h
   echo "#define TARGET_PPC64 1" >> $config_h
-elif test "$target_cpu" = "ppcemb" ; then
-  echo "TARGET_ARCH=ppcemb" >> $config_mak
-  echo "#define TARGET_ARCH \"ppcemb\"" >> $config_h
+elif test "$target_cpu" = "ppc64abi32" ; then
+  echo "TARGET_ARCH=ppc64" >> $config_mak
+  echo "#define TARGET_ARCH \"ppc64\"" >> $config_h
+  echo "TARGET_ABI_DIR=ppc" >> $config_mak
   echo "#define TARGET_PPC 1" >> $config_h
-  echo "#define TARGET_PPCEMB 1" >> $config_h
+  echo "#define TARGET_PPC64 1" >> $config_h
+  echo "#define TARGET_ABI32 1" >> $config_h
+elif test "$target_cpu" = "ppc64h" ; then
+  echo "TARGET_ARCH=ppc64h" >> $config_mak
+  echo "#define TARGET_ARCH \"ppc64h\"" >> $config_h
+  echo "TARGET_ABI_DIR=ppc" >> $config_mak
+  echo "#define TARGET_PPC 1" >> $config_h
+  echo "#define TARGET_PPC64 1" >> $config_h
+  echo "#define TARGET_PPC64H 1" >> $config_h
 elif test "$target_cpu" = "x86_64" ; then
   echo "TARGET_ARCH=x86_64" >> $config_mak
   echo "#define TARGET_ARCH \"x86_64\"" >> $config_h
@@ -1096,13 +1137,20 @@
   echo "TARGET_ARCH=mips" >> $config_mak
   echo "#define TARGET_ARCH \"mips\"" >> $config_h
   echo "#define TARGET_MIPS 1" >> $config_h
-  echo "CONFIG_SOFTFLOAT=yes" >> $config_mak
-  echo "#define CONFIG_SOFTFLOAT 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
 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
+elif test "$target_cpu" = "cris" ; then
+  echo "TARGET_ARCH=cris" >> $config_mak
+  echo "#define TARGET_ARCH \"cris\"" >> $config_h
+  echo "#define TARGET_CRIS 1" >> $config_h
   echo "CONFIG_SOFTFLOAT=yes" >> $config_mak
   echo "#define CONFIG_SOFTFLOAT 1" >> $config_h
 elif test "$target_cpu" = "sh4" -o "$target_cpu" = "sh4eb" ; then
@@ -1144,7 +1192,7 @@
   echo "#define CONFIG_DARWIN_USER 1" >> $config_h
 fi
 
-if test "$target_cpu" = "arm" -o "$target_cpu" = "armeb" -o "$target_cpu" = "sparc" -o "$target_cpu" = "sparc64" -o "$target_cpu" = "m68k"; then
+if test "$target_cpu" = "arm" -o "$target_cpu" = "armeb" -o "$target_cpu" = "sparc" -o "$target_cpu" = "sparc64"  -o "$target_cpu" = "sparc32plus" -o "$target_cpu" = "m68k" -o "$target_cpu" = "mips" -o "$target_cpu" = "mipsel" -o "$target_cpu" = "mipsn32" -o "$target_cpu" = "mipsn32el" -o "$target_cpu" = "mips64" -o "$target_cpu" = "mips64el"; then
   echo "CONFIG_SOFTFLOAT=yes" >> $config_mak
   echo "#define CONFIG_SOFTFLOAT 1" >> $config_h
 fi
@@ -1152,6 +1200,11 @@
   echo "TARGET_HAS_BFLT=yes" >> $config_mak
   echo "#define TARGET_HAS_BFLT 1" >> $config_h
 fi
+# 32 bit ELF loader in addition to native 64 bit loader?
+if test "$target_user_only" = "yes" -a "$elfload32" = "yes"; then
+  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
@@ -1187,8 +1240,9 @@
 
 # build tree in object directory if source path is different from current one
 if test "$source_path_used" = "yes" ; then
-    DIRS="tests"
+    DIRS="tests tests/cris"
     FILES="Makefile tests/Makefile"
+    FILES="$FILES tests/cris/Makefile tests/cris/.gdbinit"
     for dir in $DIRS ; do
             mkdir -p $dir
     done

Modified: trunk/src/host/qemu-neo1973/cpu-all.h
===================================================================
--- trunk/src/host/qemu-neo1973/cpu-all.h	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/cpu-all.h	2007-10-29 21:14:04 UTC (rev 3303)
@@ -716,6 +716,7 @@
 #define CPU_INTERRUPT_HALT   0x20 /* CPU halt wanted */
 #define CPU_INTERRUPT_SMI    0x40 /* (x86 only) SMI interrupt pending */
 #define CPU_INTERRUPT_DEBUG  0x80 /* Debug event occured.  */
+#define CPU_INTERRUPT_VIRQ   0x100 /* virtual interrupt pending.  */
 
 void cpu_interrupt(CPUState *s, int mask);
 void cpu_reset_interrupt(CPUState *env, int mask);

Modified: trunk/src/host/qemu-neo1973/cpu-defs.h
===================================================================
--- trunk/src/host/qemu-neo1973/cpu-defs.h	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/cpu-defs.h	2007-10-29 21:14:04 UTC (rev 3303)
@@ -112,15 +112,6 @@
     target_phys_addr_t addend;
 } CPUTLBEntry;
 
-/* Alpha has 4 different running levels */
-#if defined(TARGET_ALPHA)
-#define NB_MMU_MODES 4
-#elif defined(TARGET_PPC64H) /* PowerPC 64 with hypervisor mode support */
-#define NB_MMU_MODES 3
-#else
-#define NB_MMU_MODES 2
-#endif
-
 #define CPU_COMMON                                                      \
     struct TranslationBlock *current_tb; /* currently executing TB  */  \
     /* soft mmu support */                                              \
@@ -131,7 +122,7 @@
                                    written */                           \
     target_ulong mem_write_vaddr; /* target virtual addr at which the   \
                                      memory was written */              \
-    /* 0 = kernel, 1 = user */                                          \
+    /* The meaning of the MMU modes is defined in the target code. */   \
     CPUTLBEntry tlb_table[NB_MMU_MODES][CPU_TLB_SIZE];                  \
     struct TranslationBlock *tb_jmp_cache[TB_JMP_CACHE_SIZE];           \
                                                                         \

Modified: trunk/src/host/qemu-neo1973/cpu-exec.c
===================================================================
--- trunk/src/host/qemu-neo1973/cpu-exec.c	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/cpu-exec.c	2007-10-29 21:14:04 UTC (rev 3303)
@@ -77,7 +77,7 @@
 
 static TranslationBlock *tb_find_slow(target_ulong pc,
                                       target_ulong cs_base,
-                                      unsigned int flags)
+                                      uint64_t flags)
 {
     TranslationBlock *tb, **ptb1;
     int code_gen_size;
@@ -155,7 +155,7 @@
 {
     TranslationBlock *tb;
     target_ulong cs_base, pc;
-    unsigned int flags;
+    uint64_t flags;
 
     /* we record a subset of the CPU state. It will
        always be the same before a given translated block
@@ -163,6 +163,7 @@
 #if defined(TARGET_I386)
     flags = env->hflags;
     flags |= (env->eflags & (IOPL_MASK | TF_MASK | VM_MASK));
+    flags |= env->intercept;
     cs_base = env->segs[R_CS].base;
     pc = cs_base + env->eip;
 #elif defined(TARGET_ARM)
@@ -180,8 +181,9 @@
     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 enabled . MMU no-fault . Supervisor
-    flags = (env->psref << 3) | ((env->mmuregs[0] & (MMU_E | MMU_NF)) << 1)
+    // 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;
 #endif
     cs_base = env->npc;
@@ -208,6 +210,10 @@
     flags = env->ps;
     cs_base = 0;
     pc = env->pc;
+#elif defined(TARGET_CRIS)
+    flags = 0;
+    cs_base = 0;
+    pc = env->pc;
 #else
 #error unsupported CPU
 #endif
@@ -282,6 +288,7 @@
 #elif defined(TARGET_PPC)
 #elif defined(TARGET_MIPS)
 #elif defined(TARGET_SH4)
+#elif defined(TARGET_CRIS)
     /* XXXXX */
 #else
 #error unsupported target CPU
@@ -333,6 +340,8 @@
 		    do_interrupt(env);
 #elif defined(TARGET_ALPHA)
                     do_interrupt(env);
+#elif defined(TARGET_CRIS)
+                    do_interrupt(env);
 #elif defined(TARGET_M68K)
                     do_interrupt(0);
 #endif
@@ -372,14 +381,18 @@
                 tmp_T0 = T0;
 #endif
                 interrupt_request = env->interrupt_request;
-                if (__builtin_expect(interrupt_request, 0)) {
+                if (__builtin_expect(interrupt_request, 0)
+#if defined(TARGET_I386)
+			&& env->hflags & HF_GIF_MASK
+#endif
+				) {
                     if (interrupt_request & CPU_INTERRUPT_DEBUG) {
                         env->interrupt_request &= ~CPU_INTERRUPT_DEBUG;
                         env->exception_index = EXCP_DEBUG;
                         cpu_loop_exit();
                     }
 #if defined(TARGET_ARM) || defined(TARGET_SPARC) || defined(TARGET_MIPS) || \
-    defined(TARGET_PPC) || defined(TARGET_ALPHA)
+    defined(TARGET_PPC) || defined(TARGET_ALPHA) || defined(TARGET_CRIS)
                     if (interrupt_request & CPU_INTERRUPT_HALT) {
                         env->interrupt_request &= ~CPU_INTERRUPT_HALT;
                         env->halted = 1;
@@ -390,6 +403,7 @@
 #if defined(TARGET_I386)
                     if ((interrupt_request & CPU_INTERRUPT_SMI) &&
                         !(env->hflags & HF_SMM_MASK)) {
+                        svm_check_intercept(SVM_EXIT_SMI);
                         env->interrupt_request &= ~CPU_INTERRUPT_SMI;
                         do_smm_enter();
 #if defined(__sparc__) && !defined(HOST_SOLARIS)
@@ -398,10 +412,11 @@
                         T0 = 0;
 #endif
                     } else if ((interrupt_request & CPU_INTERRUPT_HARD) &&
-                        (env->eflags & IF_MASK) &&
+                        (env->eflags & IF_MASK || env->hflags & HF_HIF_MASK) &&
                         !(env->hflags & HF_INHIBIT_IRQ_MASK)) {
                         int intno;
-                        env->interrupt_request &= ~CPU_INTERRUPT_HARD;
+                        svm_check_intercept(SVM_EXIT_INTR);
+                        env->interrupt_request &= ~(CPU_INTERRUPT_HARD | CPU_INTERRUPT_VIRQ);
                         intno = cpu_get_pic_interrupt(env);
                         if (loglevel & CPU_LOG_TB_IN_ASM) {
                             fprintf(logfile, "Servicing hardware INT=0x%02x\n", intno);
@@ -414,6 +429,25 @@
 #else
                         T0 = 0;
 #endif
+#if !defined(CONFIG_USER_ONLY)
+                    } else if ((interrupt_request & CPU_INTERRUPT_VIRQ) &&
+                        (env->eflags & IF_MASK) && !(env->hflags & HF_INHIBIT_IRQ_MASK)) {
+                         int intno;
+                         /* FIXME: this should respect TPR */
+                         env->interrupt_request &= ~CPU_INTERRUPT_VIRQ;
+                         svm_check_intercept(SVM_EXIT_VINTR);
+                         intno = ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_vector));
+                         if (loglevel & CPU_LOG_TB_IN_ASM)
+                             fprintf(logfile, "Servicing virtual hardware INT=0x%02x\n", intno);
+	                 do_interrupt(intno, 0, 0, -1, 1);
+                         stl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_ctl),
+                                  ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_ctl)) & ~V_IRQ_MASK);
+#if defined(__sparc__) && !defined(HOST_SOLARIS)
+                         tmp_T0 = 0;
+#else
+                         T0 = 0;
+#endif
+#endif
                     }
 #elif defined(TARGET_PPC)
 #if 0
@@ -490,6 +524,11 @@
                     if (interrupt_request & CPU_INTERRUPT_HARD) {
                         do_interrupt(env);
                     }
+#elif defined(TARGET_CRIS)
+                    if (interrupt_request & CPU_INTERRUPT_HARD) {
+                        do_interrupt(env);
+			env->interrupt_request &= ~CPU_INTERRUPT_HARD;
+                    }
 #elif defined(TARGET_M68K)
                     if (interrupt_request & CPU_INTERRUPT_HARD
                         && ((env->sr & SR_I) >> SR_I_SHIFT)
@@ -549,6 +588,8 @@
 		    cpu_dump_state(env, logfile, fprintf, 0);
 #elif defined(TARGET_ALPHA)
                     cpu_dump_state(env, logfile, fprintf, 0);
+#elif defined(TARGET_CRIS)
+                    cpu_dump_state(env, logfile, fprintf, 0);
 #else
 #error unsupported target CPU
 #endif
@@ -742,6 +783,7 @@
 #elif defined(TARGET_MIPS)
 #elif defined(TARGET_SH4)
 #elif defined(TARGET_ALPHA)
+#elif defined(TARGET_CRIS)
     /* XXXXX */
 #else
 #error unsupported target CPU
@@ -842,8 +884,7 @@
     }
 
     /* see if it is an MMU fault */
-    ret = cpu_x86_handle_mmu_fault(env, address, is_write,
-                                   ((env->hflags & HF_CPL_MASK) == 3), 0);
+    ret = cpu_x86_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
     if (ret < 0)
         return 0; /* not an MMU fault */
     if (ret == 0)
@@ -892,7 +933,7 @@
         return 1;
     }
     /* see if it is an MMU fault */
-    ret = cpu_arm_handle_mmu_fault(env, address, is_write, 1, 0);
+    ret = cpu_arm_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
     if (ret < 0)
         return 0; /* not an MMU fault */
     if (ret == 0)
@@ -928,7 +969,7 @@
         return 1;
     }
     /* see if it is an MMU fault */
-    ret = cpu_sparc_handle_mmu_fault(env, address, is_write, 1, 0);
+    ret = cpu_sparc_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
     if (ret < 0)
         return 0; /* not an MMU fault */
     if (ret == 0)
@@ -965,7 +1006,7 @@
     }
 
     /* see if it is an MMU fault */
-    ret = cpu_ppc_handle_mmu_fault(env, address, is_write, msr_pr, 0);
+    ret = cpu_ppc_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
     if (ret < 0)
         return 0; /* not an MMU fault */
     if (ret == 0)
@@ -1014,7 +1055,7 @@
         return 1;
     }
     /* see if it is an MMU fault */
-    ret = cpu_m68k_handle_mmu_fault(env, address, is_write, 1, 0);
+    ret = cpu_m68k_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
     if (ret < 0)
         return 0; /* not an MMU fault */
     if (ret == 0)
@@ -1054,7 +1095,7 @@
     }
 
     /* see if it is an MMU fault */
-    ret = cpu_mips_handle_mmu_fault(env, address, is_write, 1, 0);
+    ret = cpu_mips_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
     if (ret < 0)
         return 0; /* not an MMU fault */
     if (ret == 0)
@@ -1104,7 +1145,7 @@
     }
 
     /* see if it is an MMU fault */
-    ret = cpu_sh4_handle_mmu_fault(env, address, is_write, 1, 0);
+    ret = cpu_sh4_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
     if (ret < 0)
         return 0; /* not an MMU fault */
     if (ret == 0)
@@ -1149,7 +1190,7 @@
     }
 
     /* see if it is an MMU fault */
-    ret = cpu_alpha_handle_mmu_fault(env, address, is_write, 1, 0);
+    ret = cpu_alpha_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
     if (ret < 0)
         return 0; /* not an MMU fault */
     if (ret == 0)
@@ -1173,6 +1214,51 @@
     /* never comes here */
     return 1;
 }
+#elif defined (TARGET_CRIS)
+static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
+                                    int is_write, sigset_t *old_set,
+                                    void *puc)
+{
+    TranslationBlock *tb;
+    int ret;
+
+    if (cpu_single_env)
+        env = cpu_single_env; /* XXX: find a correct solution for multithread */
+#if defined(DEBUG_SIGNAL)
+    printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
+           pc, address, is_write, *(unsigned long *)old_set);
+#endif
+    /* XXX: locking issue */
+    if (is_write && page_unprotect(h2g(address), pc, puc)) {
+        return 1;
+    }
+
+    /* see if it is an MMU fault */
+    ret = cpu_cris_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
+    if (ret < 0)
+        return 0; /* not an MMU fault */
+    if (ret == 0)
+        return 1; /* the MMU fault was handled without causing real CPU fault */
+
+    /* 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, puc);
+    }
+#if 0
+        printf("PF exception: NIP=0x%08x error=0x%x %p\n",
+               env->nip, env->error_code, tb);
+#endif
+    /* we restore the process signal mask as the sigreturn should
+       do it (XXX: use sigsetjmp) */
+    sigprocmask(SIG_SETMASK, old_set, NULL);
+    cpu_loop_exit();
+    /* never comes here */
+    return 1;
+}
+
 #else
 #error unsupported target CPU
 #endif

Added: trunk/src/host/qemu-neo1973/cris-dis.c
===================================================================
--- trunk/src/host/qemu-neo1973/cris-dis.c	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/cris-dis.c	2007-10-29 21:14:04 UTC (rev 3303)
@@ -0,0 +1,2907 @@
+/* Disassembler code for CRIS.
+   Copyright 2000, 2001, 2002, 2004, 2005, 2006 Free Software Foundation, Inc.
+   Contributed by Axis Communications AB, Lund, Sweden.
+   Written by Hans-Peter Nilsson.
+
+   This file is part of the GNU binutils and GDB, the GNU debugger.
+
+   This program is free software; you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published by the
+   Free Software Foundation; either version 2, or (at your option) any later
+   version.
+
+   This program 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 General Public License for
+   more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+#include "dis-asm.h"
+//#include "sysdep.h"
+#include "target-cris/opcode-cris.h"
+//#include "libiberty.h"
+
+
+#define FALSE 0
+#define TRUE 1
+#define CONST_STRNEQ(STR1,STR2) (strncmp ((STR1), (STR2), sizeof (STR2) - 1) == 0)
+
+/* cris-opc.c -- Table of opcodes for the CRIS processor.
+   Copyright 2000, 2001, 2004 Free Software Foundation, Inc.
+   Contributed by Axis Communications AB, Lund, Sweden.
+   Originally written for GAS 1.38.1 by Mikael Asker.
+   Reorganized by Hans-Peter Nilsson.
+
+This file is part of GAS, GDB and the GNU binutils.
+
+GAS, GDB, and GNU binutils is free software; you can redistribute it
+and/or modify it under the terms of the GNU General Public License as
+published by the Free Software Foundation; either version 2, or (at your
+option) any later version.
+
+GAS, GDB, and GNU binutils are distributed in the hope that they will be
+useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
+
+#ifndef NULL
+#define NULL (0)
+#endif
+
+/* This table isn't used for CRISv32 and the size of immediate operands.  */
+const struct cris_spec_reg
+cris_spec_regs[] =
+{
+  {"bz",  0,  1, cris_ver_v32p,	   NULL},
+  {"p0",  0,  1, 0,		   NULL},
+  {"vr",  1,  1, 0,		   NULL},
+  {"p1",  1,  1, 0,		   NULL},
+  {"pid", 2,  1, cris_ver_v32p,    NULL},
+  {"p2",  2,  1, cris_ver_v32p,	   NULL},
+  {"p2",  2,  1, cris_ver_warning, NULL},
+  {"srs", 3,  1, cris_ver_v32p,    NULL},
+  {"p3",  3,  1, cris_ver_v32p,	   NULL},
+  {"p3",  3,  1, cris_ver_warning, NULL},
+  {"wz",  4,  2, cris_ver_v32p,	   NULL},
+  {"p4",  4,  2, 0,		   NULL},
+  {"ccr", 5,  2, cris_ver_v0_10,   NULL},
+  {"exs", 5,  4, cris_ver_v32p,	   NULL},
+  {"p5",  5,  2, cris_ver_v0_10,   NULL},
+  {"p5",  5,  4, cris_ver_v32p,	   NULL},
+  {"dcr0",6,  2, cris_ver_v0_3,	   NULL},
+  {"eda", 6,  4, cris_ver_v32p,	   NULL},
+  {"p6",  6,  2, cris_ver_v0_3,	   NULL},
+  {"p6",  6,  4, cris_ver_v32p,	   NULL},
+  {"dcr1/mof", 7, 4, cris_ver_v10p,
+   "Register `dcr1/mof' with ambiguous size specified.  Guessing 4 bytes"},
+  {"dcr1/mof", 7, 2, cris_ver_v0_3,
+   "Register `dcr1/mof' with ambiguous size specified.  Guessing 2 bytes"},
+  {"mof", 7,  4, cris_ver_v10p,	   NULL},
+  {"dcr1",7,  2, cris_ver_v0_3,	   NULL},
+  {"p7",  7,  4, cris_ver_v10p,	   NULL},
+  {"p7",  7,  2, cris_ver_v0_3,	   NULL},
+  {"dz",  8,  4, cris_ver_v32p,	   NULL},
+  {"p8",  8,  4, 0,		   NULL},
+  {"ibr", 9,  4, cris_ver_v0_10,   NULL},
+  {"ebp", 9,  4, cris_ver_v32p,	   NULL},
+  {"p9",  9,  4, 0,		   NULL},
+  {"irp", 10, 4, cris_ver_v0_10,   NULL},
+  {"erp", 10, 4, cris_ver_v32p,	   NULL},
+  {"p10", 10, 4, 0,		   NULL},
+  {"srp", 11, 4, 0,		   NULL},
+  {"p11", 11, 4, 0,		   NULL},
+  /* For disassembly use only.  Accept at assembly with a warning.  */
+  {"bar/dtp0", 12, 4, cris_ver_warning,
+   "Ambiguous register `bar/dtp0' specified"},
+  {"nrp", 12, 4, cris_ver_v32p,	   NULL},
+  {"bar", 12, 4, cris_ver_v8_10,   NULL},
+  {"dtp0",12, 4, cris_ver_v0_3,	   NULL},
+  {"p12", 12, 4, 0,		   NULL},
+  /* For disassembly use only.  Accept at assembly with a warning.  */
+  {"dccr/dtp1",13, 4, cris_ver_warning,
+   "Ambiguous register `dccr/dtp1' specified"},
+  {"ccs", 13, 4, cris_ver_v32p,	   NULL},
+  {"dccr",13, 4, cris_ver_v8_10,   NULL},
+  {"dtp1",13, 4, cris_ver_v0_3,	   NULL},
+  {"p13", 13, 4, 0,		   NULL},
+  {"brp", 14, 4, cris_ver_v3_10,   NULL},
+  {"usp", 14, 4, cris_ver_v32p,	   NULL},
+  {"p14", 14, 4, cris_ver_v3p,	   NULL},
+  {"usp", 15, 4, cris_ver_v10,	   NULL},
+  {"spc", 15, 4, cris_ver_v32p,	   NULL},
+  {"p15", 15, 4, cris_ver_v10p,	   NULL},
+  {NULL, 0, 0, cris_ver_version_all, NULL}
+};
+
+/* Add version specifiers to this table when necessary.
+   The (now) regular coding of register names suggests a simpler
+   implementation.  */
+const struct cris_support_reg cris_support_regs[] =
+{
+  {"s0", 0},
+  {"s1", 1},
+  {"s2", 2},
+  {"s3", 3},
+  {"s4", 4},
+  {"s5", 5},
+  {"s6", 6},
+  {"s7", 7},
+  {"s8", 8},
+  {"s9", 9},
+  {"s10", 10},
+  {"s11", 11},
+  {"s12", 12},
+  {"s13", 13},
+  {"s14", 14},
+  {"s15", 15},
+  {NULL, 0}
+};
+
+/* All CRIS opcodes are 16 bits.
+
+   - The match component is a mask saying which bits must match a
+     particular opcode in order for an instruction to be an instance
+     of that opcode.
+
+   - The args component is a string containing characters symbolically
+     matching the operands of an instruction.  Used for both assembly
+     and disassembly.
+
+     Operand-matching characters:
+     [ ] , space
+        Verbatim.
+     A	The string "ACR" (case-insensitive).
+     B	Not really an operand.  It causes a "BDAP -size,SP" prefix to be
+	output for the PUSH alias-instructions and recognizes a push-
+	prefix at disassembly.  This letter isn't recognized for v32.
+	Must be followed by a R or P letter.
+     !	Non-match pattern, will not match if there's a prefix insn.
+     b	Non-matching operand, used for branches with 16-bit
+	displacement. Only recognized by the disassembler.
+     c	5-bit unsigned immediate in bits <4:0>.
+     C	4-bit unsigned immediate in bits <3:0>.
+     d  At assembly, optionally (as in put other cases before this one)
+	".d" or ".D" at the start of the operands, followed by one space
+	character.  At disassembly, nothing.
+     D	General register in bits <15:12> and <3:0>.
+     f	List of flags in bits <15:12> and <3:0>.
+     i	6-bit signed immediate in bits <5:0>.
+     I	6-bit unsigned immediate in bits <5:0>.
+     M	Size modifier (B, W or D) for CLEAR instructions.
+     m	Size modifier (B, W or D) in bits <5:4>
+     N  A 32-bit dword, like in the difference between s and y.
+        This has no effect on bits in the opcode.  Can also be expressed
+	as "[pc+]" in input.
+     n  As N, but PC-relative (to the start of the instruction).
+     o	[-128..127] word offset in bits <7:1> and <0>.  Used by 8-bit
+	branch instructions.
+     O	[-128..127] offset in bits <7:0>.  Also matches a comma and a
+	general register after the expression, in bits <15:12>.  Used
+	only for the BDAP prefix insn (in v32 the ADDOQ insn; same opcode).
+     P	Special register in bits <15:12>.
+     p	Indicates that the insn is a prefix insn.  Must be first
+	character.
+     Q  As O, but don't relax; force an 8-bit offset.
+     R	General register in bits <15:12>.
+     r	General register in bits <3:0>.
+     S	Source operand in bit <10> and a prefix; a 3-operand prefix
+	without side-effect.
+     s	Source operand in bits <10> and <3:0>, optionally with a
+	side-effect prefix, except [pc] (the name, not R15 as in ACR)
+	isn't allowed for v32 and higher.
+     T  Support register in bits <15:12>.
+     u  4-bit (PC-relative) unsigned immediate word offset in bits <3:0>.
+     U  Relaxes to either u or n, instruction is assumed LAPCQ or LAPC.
+	Not recognized at disassembly.
+     x	Register-dot-modifier, for example "r5.w" in bits <15:12> and <5:4>.
+     y	Like 's' but do not allow an integer at assembly.
+     Y	The difference s-y; only an integer is allowed.
+     z	Size modifier (B or W) in bit <4>.  */
+
+
+/* Please note the order of the opcodes in this table is significant.
+   The assembler requires that all instances of the same mnemonic must
+   be consecutive.  If they aren't, the assembler might not recognize
+   them, or may indicate an internal error.
+
+   The disassembler should not normally care about the order of the
+   opcodes, but will prefer an earlier alternative if the "match-score"
+   (see cris-dis.c) is computed as equal.
+
+   It should not be significant for proper execution that this table is
+   in alphabetical order, but please follow that convention for an easy
+   overview.  */
+
+const struct cris_opcode
+cris_opcodes[] =
+{
+  {"abs",     0x06B0, 0x0940,		  "r,R",     0, SIZE_NONE,     0,
+   cris_abs_op},
+
+  {"add",     0x0600, 0x09c0,		  "m r,R",   0, SIZE_NONE,     0,
+   cris_reg_mode_add_sub_cmp_and_or_move_op},
+
+  {"add",     0x0A00, 0x01c0,		  "m s,R",   0, SIZE_FIELD,    0,
+   cris_none_reg_mode_add_sub_cmp_and_or_move_op},
+
+  {"add",     0x0A00, 0x01c0,		  "m S,D",   0, SIZE_NONE,
+   cris_ver_v0_10,
+   cris_none_reg_mode_add_sub_cmp_and_or_move_op},
+
+  {"add",     0x0a00, 0x05c0,		  "m S,R,r", 0, SIZE_NONE,
+   cris_ver_v0_10,
+   cris_three_operand_add_sub_cmp_and_or_op},
+
+  {"add",     0x0A00, 0x01c0,		  "m s,R",   0, SIZE_FIELD,
+   cris_ver_v32p,
+   cris_none_reg_mode_add_sub_cmp_and_or_move_op},
+
+  {"addc",    0x0570, 0x0A80,		  "r,R",     0, SIZE_FIX_32,
+   cris_ver_v32p,
+   cris_not_implemented_op},
+
+  {"addc",    0x09A0, 0x0250,		  "s,R",     0, SIZE_FIX_32,
+   cris_ver_v32p,
+   cris_not_implemented_op},
+
+  {"addi",    0x0540, 0x0A80,		  "x,r,A",   0, SIZE_NONE,
+   cris_ver_v32p,
+   cris_addi_op},
+
+  {"addi",    0x0500, 0x0Ac0,		  "x,r",     0, SIZE_NONE,     0,
+   cris_addi_op},
+
+  /* This collates after "addo", but we want to disassemble as "addoq",
+     not "addo".  */
+  {"addoq",   0x0100, 0x0E00,		  "Q,A",     0, SIZE_NONE,
+   cris_ver_v32p,
+   cris_not_implemented_op},
+
+  {"addo",    0x0940, 0x0280,		  "m s,R,A", 0, SIZE_FIELD_SIGNED,
+   cris_ver_v32p,
+   cris_not_implemented_op},
+
+  /* This must be located after the insn above, lest we misinterpret
+     "addo.b -1,r0,acr" as "addo .b-1,r0,acr".  FIXME: Sounds like a
+     parser bug.  */
+  {"addo",   0x0100, 0x0E00,		  "O,A",     0, SIZE_NONE,
+   cris_ver_v32p,
+   cris_not_implemented_op},
+
+  {"addq",    0x0200, 0x0Dc0,		  "I,R",     0, SIZE_NONE,     0,
+   cris_quick_mode_add_sub_op},
+
+  {"adds",    0x0420, 0x0Bc0,		  "z r,R",   0, SIZE_NONE,     0,
+   cris_reg_mode_add_sub_cmp_and_or_move_op},
+
+  /* FIXME: SIZE_FIELD_SIGNED and all necessary changes.  */
+  {"adds",    0x0820, 0x03c0,		  "z s,R",   0, SIZE_FIELD,    0,
+   cris_none_reg_mode_add_sub_cmp_and_or_move_op},
+
+  {"adds",    0x0820, 0x03c0,		  "z S,D",   0, SIZE_NONE,
+   cris_ver_v0_10,
+   cris_none_reg_mode_add_sub_cmp_and_or_move_op},
+
+  {"adds",    0x0820, 0x07c0,		  "z S,R,r", 0, SIZE_NONE,
+   cris_ver_v0_10,
+   cris_three_operand_add_sub_cmp_and_or_op},
+
+  {"addu",    0x0400, 0x0be0,		  "z r,R",   0, SIZE_NONE,     0,
+   cris_reg_mode_add_sub_cmp_and_or_move_op},
+
+  /* FIXME: SIZE_FIELD_UNSIGNED and all necessary changes.  */
+  {"addu",    0x0800, 0x03e0,		  "z s,R",   0, SIZE_FIELD,    0,
+   cris_none_reg_mode_add_sub_cmp_and_or_move_op},
+
+  {"addu",    0x0800, 0x03e0,		  "z S,D",   0, SIZE_NONE,
+   cris_ver_v0_10,
+   cris_none_reg_mode_add_sub_cmp_and_or_move_op},
+
+  {"addu",    0x0800, 0x07e0,		  "z S,R,r", 0, SIZE_NONE,
+   cris_ver_v0_10,
+   cris_three_operand_add_sub_cmp_and_or_op},
+
+  {"and",     0x0700, 0x08C0,		  "m r,R",   0, SIZE_NONE,     0,
+   cris_reg_mode_add_sub_cmp_and_or_move_op},
+
+  {"and",     0x0B00, 0x00C0,		  "m s,R",   0, SIZE_FIELD,    0,
+   cris_none_reg_mode_add_sub_cmp_and_or_move_op},
+
+  {"and",     0x0B00, 0x00C0,		  "m S,D",   0, SIZE_NONE,
+   cris_ver_v0_10,
+   cris_none_reg_mode_add_sub_cmp_and_or_move_op},
+
+  {"and",     0x0B00, 0x04C0,		  "m S,R,r", 0, SIZE_NONE,
+   cris_ver_v0_10,
+   cris_three_operand_add_sub_cmp_and_or_op},
+
+  {"andq",    0x0300, 0x0CC0,		  "i,R",     0, SIZE_NONE,     0,
+   cris_quick_mode_and_cmp_move_or_op},
+
+  {"asr",     0x0780, 0x0840,		  "m r,R",   0, SIZE_NONE,     0,
+   cris_asr_op},
+
+  {"asrq",    0x03a0, 0x0c40,		  "c,R",     0, SIZE_NONE,     0,
+   cris_asrq_op},
+
+  {"ax",      0x15B0, 0xEA4F,		  "",	     0, SIZE_NONE,     0,
+   cris_ax_ei_setf_op},
+
+  /* FIXME: Should use branch #defines.  */
+  {"b",	      0x0dff, 0x0200,		  "b",	     1, SIZE_NONE,     0,
+   cris_sixteen_bit_offset_branch_op},
+
+  {"ba",
+   BA_QUICK_OPCODE,
+   0x0F00+(0xF-CC_A)*0x1000,		  "o",	     1, SIZE_NONE,     0,
+   cris_eight_bit_offset_branch_op},
+
+  /* Needs to come after the usual "ba o", which might be relaxed to
+     this one.  */
+  {"ba",     BA_DWORD_OPCODE,
+   0xffff & (~BA_DWORD_OPCODE),		  "n",	     0, SIZE_FIX_32,
+   cris_ver_v32p,
+   cris_none_reg_mode_jump_op},
+
+  {"bas",     0x0EBF, 0x0140,		  "n,P",     0, SIZE_FIX_32,
+   cris_ver_v32p,
+   cris_none_reg_mode_jump_op},
+
+  {"basc",     0x0EFF, 0x0100,		  "n,P",     0, SIZE_FIX_32,
+   cris_ver_v32p,
+   cris_none_reg_mode_jump_op},
+
+  {"bcc",
+   BRANCH_QUICK_OPCODE+CC_CC*0x1000,
+   0x0f00+(0xF-CC_CC)*0x1000,		  "o",	     1, SIZE_NONE,     0,
+   cris_eight_bit_offset_branch_op},
+
+  {"bcs",
+   BRANCH_QUICK_OPCODE+CC_CS*0x1000,
+   0x0f00+(0xF-CC_CS)*0x1000,		  "o",	     1, SIZE_NONE,     0,
+   cris_eight_bit_offset_branch_op},
+
+  {"bdap",
+   BDAP_INDIR_OPCODE, BDAP_INDIR_Z_BITS,  "pm s,R",  0, SIZE_FIELD_SIGNED,
+   cris_ver_v0_10,
+   cris_bdap_prefix},
+
+  {"bdap",
+   BDAP_QUICK_OPCODE, BDAP_QUICK_Z_BITS,  "pO",	     0, SIZE_NONE,
+   cris_ver_v0_10,
+   cris_quick_mode_bdap_prefix},
+
+  {"beq",
+   BRANCH_QUICK_OPCODE+CC_EQ*0x1000,
+   0x0f00+(0xF-CC_EQ)*0x1000,		  "o",	     1, SIZE_NONE,     0,
+   cris_eight_bit_offset_branch_op},
+
+  /* This is deliberately put before "bext" to trump it, even though not
+     in alphabetical order, since we don't do excluding version checks
+     for v0..v10.  */
+  {"bwf",
+   BRANCH_QUICK_OPCODE+CC_EXT*0x1000,
+   0x0f00+(0xF-CC_EXT)*0x1000,		  "o",	     1, SIZE_NONE,
+   cris_ver_v10,
+   cris_eight_bit_offset_branch_op},
+
+  {"bext",
+   BRANCH_QUICK_OPCODE+CC_EXT*0x1000,
+   0x0f00+(0xF-CC_EXT)*0x1000,		  "o",	     1, SIZE_NONE,
+   cris_ver_v0_3,
+   cris_eight_bit_offset_branch_op},
+
+  {"bge",
+   BRANCH_QUICK_OPCODE+CC_GE*0x1000,
+   0x0f00+(0xF-CC_GE)*0x1000,		  "o",	     1, SIZE_NONE,     0,
+   cris_eight_bit_offset_branch_op},
+
+  {"bgt",
+   BRANCH_QUICK_OPCODE+CC_GT*0x1000,
+   0x0f00+(0xF-CC_GT)*0x1000,		  "o",	     1, SIZE_NONE,     0,
+   cris_eight_bit_offset_branch_op},
+
+  {"bhi",
+   BRANCH_QUICK_OPCODE+CC_HI*0x1000,
+   0x0f00+(0xF-CC_HI)*0x1000,		  "o",	     1, SIZE_NONE,     0,
+   cris_eight_bit_offset_branch_op},
+
+  {"bhs",
+   BRANCH_QUICK_OPCODE+CC_HS*0x1000,
+   0x0f00+(0xF-CC_HS)*0x1000,		  "o",	     1, SIZE_NONE,     0,
+   cris_eight_bit_offset_branch_op},
+
+  {"biap", BIAP_OPCODE, BIAP_Z_BITS,	  "pm r,R",  0, SIZE_NONE,
+   cris_ver_v0_10,
+   cris_biap_prefix},
+
+  {"ble",
+   BRANCH_QUICK_OPCODE+CC_LE*0x1000,
+   0x0f00+(0xF-CC_LE)*0x1000,		  "o",	     1, SIZE_NONE,     0,
+   cris_eight_bit_offset_branch_op},
+
+  {"blo",
+   BRANCH_QUICK_OPCODE+CC_LO*0x1000,
+   0x0f00+(0xF-CC_LO)*0x1000,		  "o",	     1, SIZE_NONE,     0,
+   cris_eight_bit_offset_branch_op},
+
+  {"bls",
+   BRANCH_QUICK_OPCODE+CC_LS*0x1000,
+   0x0f00+(0xF-CC_LS)*0x1000,		  "o",	     1, SIZE_NONE,     0,
+   cris_eight_bit_offset_branch_op},
+
+  {"blt",
+   BRANCH_QUICK_OPCODE+CC_LT*0x1000,
+   0x0f00+(0xF-CC_LT)*0x1000,		  "o",	     1, SIZE_NONE,     0,
+   cris_eight_bit_offset_branch_op},
+
+  {"bmi",
+   BRANCH_QUICK_OPCODE+CC_MI*0x1000,
+   0x0f00+(0xF-CC_MI)*0x1000,		  "o",	     1, SIZE_NONE,     0,
+   cris_eight_bit_offset_branch_op},
+
+  {"bmod",    0x0ab0, 0x0140,		  "s,R",     0, SIZE_FIX_32,
+   cris_ver_sim_v0_10,
+   cris_not_implemented_op},
+
+  {"bmod",    0x0ab0, 0x0140,		  "S,D",     0, SIZE_NONE,
+   cris_ver_sim_v0_10,
+   cris_not_implemented_op},
+
+  {"bmod",    0x0ab0, 0x0540,		  "S,R,r",   0, SIZE_NONE,
+   cris_ver_sim_v0_10,
+   cris_not_implemented_op},
+
+  {"bne",
+   BRANCH_QUICK_OPCODE+CC_NE*0x1000,
+   0x0f00+(0xF-CC_NE)*0x1000,		  "o",	     1, SIZE_NONE,     0,
+   cris_eight_bit_offset_branch_op},
+
+  {"bound",   0x05c0, 0x0A00,		  "m r,R",   0, SIZE_NONE,     0,
+   cris_two_operand_bound_op},
+  /* FIXME: SIZE_FIELD_UNSIGNED and all necessary changes.  */
+  {"bound",   0x09c0, 0x0200,		  "m s,R",   0, SIZE_FIELD,
+   cris_ver_v0_10,
+   cris_two_operand_bound_op},
+  /* FIXME: SIZE_FIELD_UNSIGNED and all necessary changes.  */
+  {"bound",   0x0dcf, 0x0200,		  "m Y,R",   0, SIZE_FIELD,    0,
+   cris_two_operand_bound_op},
+  {"bound",   0x09c0, 0x0200,		  "m S,D",   0, SIZE_NONE,
+   cris_ver_v0_10,
+   cris_two_operand_bound_op},
+  {"bound",   0x09c0, 0x0600,		  "m S,R,r", 0, SIZE_NONE,
+   cris_ver_v0_10,
+   cris_three_operand_bound_op},
+
+  {"bpl",
+   BRANCH_QUICK_OPCODE+CC_PL*0x1000,
+   0x0f00+(0xF-CC_PL)*0x1000,		  "o",	     1, SIZE_NONE,     0,
+   cris_eight_bit_offset_branch_op},
+
+  {"break",   0xe930, 0x16c0,		  "C",	     0, SIZE_NONE,
+   cris_ver_v3p,
+   cris_break_op},
+
+  {"bsb",
+   BRANCH_QUICK_OPCODE+CC_EXT*0x1000,
+   0x0f00+(0xF-CC_EXT)*0x1000,		  "o",	     1, SIZE_NONE,
+   cris_ver_v32p,
+   cris_eight_bit_offset_branch_op},
+
+  {"bsr",     0xBEBF, 0x4140,		  "n",	     0, SIZE_FIX_32,
+   cris_ver_v32p,
+   cris_none_reg_mode_jump_op},
+
+  {"bsrc",     0xBEFF, 0x4100,		  "n",	     0, SIZE_FIX_32,
+   cris_ver_v32p,
+   cris_none_reg_mode_jump_op},
+
+  {"bstore",  0x0af0, 0x0100,		  "s,R",     0, SIZE_FIX_32,
+   cris_ver_warning,
+   cris_not_implemented_op},
+
+  {"bstore",  0x0af0, 0x0100,		  "S,D",     0, SIZE_NONE,
+   cris_ver_warning,
+   cris_not_implemented_op},
+
+  {"bstore",  0x0af0, 0x0500,		  "S,R,r",   0, SIZE_NONE,
+   cris_ver_warning,
+   cris_not_implemented_op},
+
+  {"btst",    0x04F0, 0x0B00,		  "r,R",     0, SIZE_NONE,     0,
+   cris_btst_nop_op},
+  {"btstq",   0x0380, 0x0C60,		  "c,R",     0, SIZE_NONE,     0,
+   cris_btst_nop_op},
+
+  {"bvc",
+   BRANCH_QUICK_OPCODE+CC_VC*0x1000,
+   0x0f00+(0xF-CC_VC)*0x1000,		  "o",	     1, SIZE_NONE,     0,
+   cris_eight_bit_offset_branch_op},
+
+  {"bvs",
+   BRANCH_QUICK_OPCODE+CC_VS*0x1000,
+   0x0f00+(0xF-CC_VS)*0x1000,		  "o",	     1, SIZE_NONE,     0,
+   cris_eight_bit_offset_branch_op},
+
+  {"clear",   0x0670, 0x3980,		  "M r",     0, SIZE_NONE,     0,
+   cris_reg_mode_clear_op},
+
+  {"clear",   0x0A70, 0x3180,		  "M y",     0, SIZE_NONE,     0,
+   cris_none_reg_mode_clear_test_op},
+
+  {"clear",   0x0A70, 0x3180,		  "M S",     0, SIZE_NONE,
+   cris_ver_v0_10,
+   cris_none_reg_mode_clear_test_op},
+
+  {"clearf",  0x05F0, 0x0A00,		  "f",	     0, SIZE_NONE,     0,
+   cris_clearf_di_op},
+
+  {"cmp",     0x06C0, 0x0900,		  "m r,R",   0, SIZE_NONE,     0,
+   cris_reg_mode_add_sub_cmp_and_or_move_op},
+
+  {"cmp",     0x0Ac0, 0x0100,		  "m s,R",   0, SIZE_FIELD,    0,
+   cris_none_reg_mode_add_sub_cmp_and_or_move_op},
+
+  {"cmp",     0x0Ac0, 0x0100,		  "m S,D",   0, SIZE_NONE,
+   cris_ver_v0_10,
+   cris_none_reg_mode_add_sub_cmp_and_or_move_op},
+
+  {"cmpq",    0x02C0, 0x0D00,		  "i,R",     0, SIZE_NONE,     0,
+   cris_quick_mode_and_cmp_move_or_op},
+
+  /* FIXME: SIZE_FIELD_SIGNED and all necessary changes.  */
+  {"cmps",    0x08e0, 0x0300,		  "z s,R",   0, SIZE_FIELD,    0,
+   cris_none_reg_mode_add_sub_cmp_and_or_move_op},
+
+  {"cmps",    0x08e0, 0x0300,		  "z S,D",   0, SIZE_NONE,
+   cris_ver_v0_10,
+   cris_none_reg_mode_add_sub_cmp_and_or_move_op},
+
+  /* FIXME: SIZE_FIELD_UNSIGNED and all necessary changes.  */
+  {"cmpu",    0x08c0, 0x0320,		  "z s,R" ,  0, SIZE_FIELD,    0,
+   cris_none_reg_mode_add_sub_cmp_and_or_move_op},
+
+  {"cmpu",    0x08c0, 0x0320,		  "z S,D",   0, SIZE_NONE,
+   cris_ver_v0_10,
+   cris_none_reg_mode_add_sub_cmp_and_or_move_op},
+
+  {"di",      0x25F0, 0xDA0F,		  "",	     0, SIZE_NONE,     0,
+   cris_clearf_di_op},
+
+  {"dip",     DIP_OPCODE, DIP_Z_BITS,	  "ps",	     0, SIZE_FIX_32,
+   cris_ver_v0_10,
+   cris_dip_prefix},
+
+  {"div",     0x0980, 0x0640,		  "m R,r",   0, SIZE_FIELD,    0,
+   cris_not_implemented_op},
+
+  {"dstep",   0x06f0, 0x0900,		  "r,R",     0, SIZE_NONE,     0,
+   cris_dstep_logshift_mstep_neg_not_op},
+
+  {"ei",      0x25B0, 0xDA4F,		  "",	     0, SIZE_NONE,     0,
+   cris_ax_ei_setf_op},
+
+  {"fidxd",    0x0ab0, 0xf540,		  "[r]",     0, SIZE_NONE,
+   cris_ver_v32p,
+   cris_not_implemented_op},
+
+  {"fidxi",    0x0d30, 0xF2C0,		  "[r]",     0, SIZE_NONE,
+   cris_ver_v32p,
+   cris_not_implemented_op},
+
+  {"ftagd",    0x1AB0, 0xE540,		  "[r]",     0, SIZE_NONE,
+   cris_ver_v32p,
+   cris_not_implemented_op},
+
+  {"ftagi",    0x1D30, 0xE2C0,		  "[r]",     0, SIZE_NONE,
+   cris_ver_v32p,
+   cris_not_implemented_op},
+
+  {"halt",    0xF930, 0x06CF,		  "",	     0, SIZE_NONE,
+   cris_ver_v32p,
+   cris_not_implemented_op},
+
+  {"jas",    0x09B0, 0x0640,		  "r,P",     0, SIZE_NONE,
+   cris_ver_v32p,
+   cris_reg_mode_jump_op},
+
+  {"jas",    0x0DBF, 0x0240,		  "N,P",     0, SIZE_FIX_32,
+   cris_ver_v32p,
+   cris_reg_mode_jump_op},
+
+  {"jasc",    0x0B30, 0x04C0,		  "r,P",     0, SIZE_NONE,
+   cris_ver_v32p,
+   cris_reg_mode_jump_op},
+
+  {"jasc",    0x0F3F, 0x00C0,		  "N,P",     0, SIZE_FIX_32,
+   cris_ver_v32p,
+   cris_reg_mode_jump_op},
+
+  {"jbrc",    0x69b0, 0x9640,		  "r",	     0, SIZE_NONE,
+   cris_ver_v8_10,
+   cris_reg_mode_jump_op},
+
+  {"jbrc",    0x6930, 0x92c0,		  "s",	     0, SIZE_FIX_32,
+   cris_ver_v8_10,
+   cris_none_reg_mode_jump_op},
+
+  {"jbrc",    0x6930, 0x92c0,		  "S",	     0, SIZE_NONE,
+   cris_ver_v8_10,
+   cris_none_reg_mode_jump_op},
+
+  {"jir",     0xA9b0, 0x5640,		  "r",	     0, SIZE_NONE,
+   cris_ver_v8_10,
+   cris_reg_mode_jump_op},
+
+  {"jir",     0xA930, 0x52c0,		  "s",	     0, SIZE_FIX_32,
+   cris_ver_v8_10,
+   cris_none_reg_mode_jump_op},
+
+  {"jir",     0xA930, 0x52c0,		  "S",	     0, SIZE_NONE,
+   cris_ver_v8_10,
+   cris_none_reg_mode_jump_op},
+
+  {"jirc",    0x29b0, 0xd640,		  "r",	     0, SIZE_NONE,
+   cris_ver_v8_10,
+   cris_reg_mode_jump_op},
+
+  {"jirc",    0x2930, 0xd2c0,		  "s",	     0, SIZE_FIX_32,
+   cris_ver_v8_10,
+   cris_none_reg_mode_jump_op},
+
+  {"jirc",    0x2930, 0xd2c0,		  "S",	     0, SIZE_NONE,
+   cris_ver_v8_10,
+   cris_none_reg_mode_jump_op},
+
+  {"jsr",     0xB9b0, 0x4640,		  "r",	     0, SIZE_NONE,     0,
+   cris_reg_mode_jump_op},
+
+  {"jsr",     0xB930, 0x42c0,		  "s",	     0, SIZE_FIX_32,
+   cris_ver_v0_10,
+   cris_none_reg_mode_jump_op},
+
+  {"jsr",     0xBDBF, 0x4240,		  "N",	     0, SIZE_FIX_32,
+   cris_ver_v32p,
+   cris_none_reg_mode_jump_op},
+
+  {"jsr",     0xB930, 0x42c0,		  "S",	     0, SIZE_NONE,
+   cris_ver_v0_10,
+   cris_none_reg_mode_jump_op},
+
+  {"jsrc",    0x39b0, 0xc640,		  "r",	     0, SIZE_NONE,
+   cris_ver_v8_10,
+   cris_reg_mode_jump_op},
+
+  {"jsrc",    0x3930, 0xc2c0,		  "s",	     0, SIZE_FIX_32,
+   cris_ver_v8_10,
+   cris_none_reg_mode_jump_op},
+
+  {"jsrc",    0x3930, 0xc2c0,		  "S",	     0, SIZE_NONE,
+   cris_ver_v8_10,
+   cris_none_reg_mode_jump_op},
+
+  {"jsrc",    0xBB30, 0x44C0,		  "r",       0, SIZE_NONE,
+   cris_ver_v32p,
+   cris_reg_mode_jump_op},
+
+  {"jsrc",    0xBF3F, 0x40C0,		  "N",	     0, SIZE_FIX_32,
+   cris_ver_v32p,
+   cris_reg_mode_jump_op},
+
+  {"jump",    0x09b0, 0xF640,		  "r",	     0, SIZE_NONE,     0,
+   cris_reg_mode_jump_op},
+
+  {"jump",
+   JUMP_INDIR_OPCODE, JUMP_INDIR_Z_BITS,  "s",	     0, SIZE_FIX_32,
+   cris_ver_v0_10,
+   cris_none_reg_mode_jump_op},
+
+  {"jump",
+   JUMP_INDIR_OPCODE, JUMP_INDIR_Z_BITS,  "S",	     0, SIZE_NONE,
+   cris_ver_v0_10,
+   cris_none_reg_mode_jump_op},
+
+  {"jump",    0x09F0, 0x060F,		  "P",	     0, SIZE_NONE,
+   cris_ver_v32p,
+   cris_none_reg_mode_jump_op},
+
+  {"jump",
+   JUMP_PC_INCR_OPCODE_V32,
+   (0xffff & ~JUMP_PC_INCR_OPCODE_V32),	  "N",	     0, SIZE_FIX_32,
+   cris_ver_v32p,
+   cris_none_reg_mode_jump_op},
+
+  {"jmpu",    0x8930, 0x72c0,		  "s",	     0, SIZE_FIX_32,
+   cris_ver_v10,
+   cris_none_reg_mode_jump_op},
+
+  {"jmpu",    0x8930, 0x72c0,		   "S",	     0, SIZE_NONE,
+   cris_ver_v10,
+   cris_none_reg_mode_jump_op},
+
+  {"lapc",    0x0970, 0x0680,		  "U,R",    0, SIZE_NONE,
+   cris_ver_v32p,
+   cris_not_implemented_op},
+
+  {"lapc",    0x0D7F, 0x0280,		  "dn,R",    0, SIZE_FIX_32,
+   cris_ver_v32p,
+   cris_not_implemented_op},
+
+  {"lapcq",   0x0970, 0x0680,		  "u,R",     0, SIZE_NONE,
+   cris_ver_v32p,
+   cris_addi_op},
+
+  {"lsl",     0x04C0, 0x0B00,		  "m r,R",   0, SIZE_NONE,     0,
+   cris_dstep_logshift_mstep_neg_not_op},
+
+  {"lslq",    0x03c0, 0x0C20,		  "c,R",     0, SIZE_NONE,     0,
+   cris_dstep_logshift_mstep_neg_not_op},
+
+  {"lsr",     0x07C0, 0x0800,		  "m r,R",   0, SIZE_NONE,     0,
+   cris_dstep_logshift_mstep_neg_not_op},
+
+  {"lsrq",    0x03e0, 0x0C00,		  "c,R",     0, SIZE_NONE,     0,
+   cris_dstep_logshift_mstep_neg_not_op},
+
+  {"lz",      0x0730, 0x08C0,		  "r,R",     0, SIZE_NONE,
+   cris_ver_v3p,
+   cris_not_implemented_op},
+
+  {"mcp",      0x07f0, 0x0800,		  "P,r",     0, SIZE_NONE,
+   cris_ver_v32p,
+   cris_not_implemented_op},
+
+  {"move",    0x0640, 0x0980,		  "m r,R",   0, SIZE_NONE,     0,
+   cris_reg_mode_add_sub_cmp_and_or_move_op},
+
+  {"move",    0x0A40, 0x0180,		  "m s,R",   0, SIZE_FIELD,    0,
+   cris_none_reg_mode_add_sub_cmp_and_or_move_op},
+
+  {"move",    0x0A40, 0x0180,		  "m S,D",   0, SIZE_NONE,
+   cris_ver_v0_10,
+   cris_none_reg_mode_add_sub_cmp_and_or_move_op},
+
+  {"move",    0x0630, 0x09c0,		  "r,P",     0, SIZE_NONE,     0,
+   cris_move_to_preg_op},
+
+  {"move",    0x0670, 0x0980,		  "P,r",     0, SIZE_NONE,     0,
+   cris_reg_mode_move_from_preg_op},
+
+  {"move",    0x0BC0, 0x0000,		  "m R,y",   0, SIZE_FIELD,    0,
+   cris_none_reg_mode_add_sub_cmp_and_or_move_op},
+
+  {"move",    0x0BC0, 0x0000,		  "m D,S",   0, SIZE_NONE,
+   cris_ver_v0_10,
+   cris_none_reg_mode_add_sub_cmp_and_or_move_op},
+
+  {"move",
+   MOVE_M_TO_PREG_OPCODE, MOVE_M_TO_PREG_ZBITS,
+   "s,P",   0, SIZE_SPEC_REG, 0,
+   cris_move_to_preg_op},
+
+  {"move",    0x0A30, 0x01c0,		  "S,P",     0, SIZE_NONE,
+   cris_ver_v0_10,
+   cris_move_to_preg_op},
+
+  {"move",    0x0A70, 0x0180,		  "P,y",     0, SIZE_SPEC_REG, 0,
+   cris_none_reg_mode_move_from_preg_op},
+
+  {"move",    0x0A70, 0x0180,		  "P,S",     0, SIZE_NONE,
+   cris_ver_v0_10,
+   cris_none_reg_mode_move_from_preg_op},
+
+  {"move",    0x0B70, 0x0480,		  "r,T",     0, SIZE_NONE,
+   cris_ver_v32p,
+   cris_not_implemented_op},
+
+  {"move",    0x0F70, 0x0080,		  "T,r",     0, SIZE_NONE,
+   cris_ver_v32p,
+   cris_not_implemented_op},
+
+  {"movem",   0x0BF0, 0x0000,		  "R,y",     0, SIZE_FIX_32,   0,
+   cris_move_reg_to_mem_movem_op},
+
+  {"movem",   0x0BF0, 0x0000,		  "D,S",     0, SIZE_NONE,
+   cris_ver_v0_10,
+   cris_move_reg_to_mem_movem_op},
+
+  {"movem",   0x0BB0, 0x0040,		  "s,R",     0, SIZE_FIX_32,   0,
+   cris_move_mem_to_reg_movem_op},
+
+  {"movem",   0x0BB0, 0x0040,		  "S,D",     0, SIZE_NONE,
+   cris_ver_v0_10,
+   cris_move_mem_to_reg_movem_op},
+
+  {"moveq",   0x0240, 0x0D80,		  "i,R",     0, SIZE_NONE,     0,
+   cris_quick_mode_and_cmp_move_or_op},
+
+  {"movs",    0x0460, 0x0B80,		  "z r,R",   0, SIZE_NONE,     0,
+   cris_reg_mode_add_sub_cmp_and_or_move_op},
+
+  /* FIXME: SIZE_FIELD_SIGNED and all necessary changes.  */
+  {"movs",    0x0860, 0x0380,		  "z s,R",   0, SIZE_FIELD,    0,
+   cris_none_reg_mode_add_sub_cmp_and_or_move_op},
+
+  {"movs",    0x0860, 0x0380,		  "z S,D",   0, SIZE_NONE,
+   cris_ver_v0_10,
+   cris_none_reg_mode_add_sub_cmp_and_or_move_op},
+
+  {"movu",    0x0440, 0x0Ba0,		  "z r,R",   0, SIZE_NONE,     0,
+   cris_reg_mode_add_sub_cmp_and_or_move_op},
+
+  /* FIXME: SIZE_FIELD_UNSIGNED and all necessary changes.  */
+  {"movu",    0x0840, 0x03a0,		  "z s,R",   0, SIZE_FIELD,    0,
+   cris_none_reg_mode_add_sub_cmp_and_or_move_op},
+
+  {"movu",    0x0840, 0x03a0,		  "z S,D",   0, SIZE_NONE,
+   cris_ver_v0_10,
+   cris_none_reg_mode_add_sub_cmp_and_or_move_op},
+
+  {"mstep",   0x07f0, 0x0800,		  "r,R",     0, SIZE_NONE,
+   cris_ver_v0_10,
+   cris_dstep_logshift_mstep_neg_not_op},
+
+  {"muls",    0x0d00, 0x02c0,		  "m r,R",   0, SIZE_NONE,
+   cris_ver_v10p,
+   cris_muls_op},
+
+  {"mulu",    0x0900, 0x06c0,		  "m r,R",   0, SIZE_NONE,
+   cris_ver_v10p,
+   cris_mulu_op},
+
+  {"neg",     0x0580, 0x0A40,		  "m r,R",   0, SIZE_NONE,     0,
+   cris_dstep_logshift_mstep_neg_not_op},
+
+  {"nop",     NOP_OPCODE, NOP_Z_BITS,	  "",	     0, SIZE_NONE,
+   cris_ver_v0_10,
+   cris_btst_nop_op},
+
+  {"nop",     NOP_OPCODE_V32, NOP_Z_BITS_V32, "",    0, SIZE_NONE,
+   cris_ver_v32p,
+   cris_btst_nop_op},
+
+  {"not",     0x8770, 0x7880,		  "r",	     0, SIZE_NONE,     0,
+   cris_dstep_logshift_mstep_neg_not_op},
+
+  {"or",      0x0740, 0x0880,		  "m r,R",   0, SIZE_NONE,     0,
+   cris_reg_mode_add_sub_cmp_and_or_move_op},
+
+  {"or",      0x0B40, 0x0080,		  "m s,R",   0, SIZE_FIELD,    0,
+   cris_none_reg_mode_add_sub_cmp_and_or_move_op},
+
+  {"or",      0x0B40, 0x0080,		  "m S,D",   0, SIZE_NONE,
+   cris_ver_v0_10,
+   cris_none_reg_mode_add_sub_cmp_and_or_move_op},
+
+  {"or",      0x0B40, 0x0480,		  "m S,R,r", 0, SIZE_NONE,
+   cris_ver_v0_10,
+   cris_three_operand_add_sub_cmp_and_or_op},
+
+  {"orq",     0x0340, 0x0C80,		  "i,R",     0, SIZE_NONE,     0,
+   cris_quick_mode_and_cmp_move_or_op},
+
+  {"pop",     0x0E6E, 0x0191,		  "!R",	     0, SIZE_NONE,
+   cris_ver_v0_10,
+   cris_none_reg_mode_add_sub_cmp_and_or_move_op},
+
+  {"pop",     0x0e3e, 0x01c1,		  "!P",	     0, SIZE_NONE,
+   cris_ver_v0_10,
+   cris_none_reg_mode_move_from_preg_op},
+
+  {"push",    0x0FEE, 0x0011,		  "BR",	     0, SIZE_NONE,
+   cris_ver_v0_10,
+   cris_none_reg_mode_add_sub_cmp_and_or_move_op},
+
+  {"push",    0x0E7E, 0x0181,		  "BP",	     0, SIZE_NONE,
+   cris_ver_v0_10,
+   cris_move_to_preg_op},
+
+  {"rbf",     0x3b30, 0xc0c0,		  "y",	     0, SIZE_NONE,
+   cris_ver_v10,
+   cris_not_implemented_op},
+
+  {"rbf",     0x3b30, 0xc0c0,		  "S",	     0, SIZE_NONE,
+   cris_ver_v10,
+   cris_not_implemented_op},
+
+  {"rfe",     0x2930, 0xD6CF,		  "",	     0, SIZE_NONE,
+   cris_ver_v32p,
+   cris_not_implemented_op},
+
+  {"rfg",     0x4930, 0xB6CF,		  "",	     0, SIZE_NONE,
+   cris_ver_v32p,
+   cris_not_implemented_op},
+
+  {"rfn",     0x5930, 0xA6CF,		  "",	     0, SIZE_NONE,
+   cris_ver_v32p,
+   cris_not_implemented_op},
+
+  {"ret",     0xB67F, 0x4980,		  "",	     1, SIZE_NONE,
+   cris_ver_v0_10,
+   cris_reg_mode_move_from_preg_op},
+
+  {"ret",     0xB9F0, 0x460F,		  "",	     1, SIZE_NONE,
+   cris_ver_v32p,
+   cris_reg_mode_move_from_preg_op},
+
+  {"retb",    0xe67f, 0x1980,		  "",	     1, SIZE_NONE,
+   cris_ver_v0_10,
+   cris_reg_mode_move_from_preg_op},
+
+  {"rete",     0xA9F0, 0x560F,		  "",	     1, SIZE_NONE,
+   cris_ver_v32p,
+   cris_reg_mode_move_from_preg_op},
+
+  {"reti",    0xA67F, 0x5980,		  "",	     1, SIZE_NONE,
+   cris_ver_v0_10,
+   cris_reg_mode_move_from_preg_op},
+
+  {"retn",     0xC9F0, 0x360F,		  "",	     1, SIZE_NONE,
+   cris_ver_v32p,
+   cris_reg_mode_move_from_preg_op},
+
+  {"sbfs",    0x3b70, 0xc080,		  "y",	     0, SIZE_NONE,
+   cris_ver_v10,
+   cris_not_implemented_op},
+
+  {"sbfs",    0x3b70, 0xc080,		  "S",	     0, SIZE_NONE,
+   cris_ver_v10,
+   cris_not_implemented_op},
+
+  {"sa",
+   0x0530+CC_A*0x1000,
+   0x0AC0+(0xf-CC_A)*0x1000,		  "r",	     0, SIZE_NONE,     0,
+   cris_scc_op},
+
+  {"ssb",
+   0x0530+CC_EXT*0x1000,
+   0x0AC0+(0xf-CC_EXT)*0x1000,		  "r",	     0, SIZE_NONE,
+   cris_ver_v32p,
+   cris_scc_op},
+
+  {"scc",
+   0x0530+CC_CC*0x1000,
+   0x0AC0+(0xf-CC_CC)*0x1000,		  "r",	     0, SIZE_NONE,     0,
+   cris_scc_op},
+
+  {"scs",
+   0x0530+CC_CS*0x1000,
+   0x0AC0+(0xf-CC_CS)*0x1000,		  "r",	     0, SIZE_NONE,     0,
+   cris_scc_op},
+
+  {"seq",
+   0x0530+CC_EQ*0x1000,
+   0x0AC0+(0xf-CC_EQ)*0x1000,		  "r",	     0, SIZE_NONE,     0,
+   cris_scc_op},
+
+  {"setf",    0x05b0, 0x0A40,		  "f",	     0, SIZE_NONE,     0,
+   cris_ax_ei_setf_op},
+
+  {"sfe",    0x3930, 0xC6CF,		  "",	     0, SIZE_NONE,
+   cris_ver_v32p,
+   cris_not_implemented_op},
+
+  /* Need to have "swf" in front of "sext" so it is the one displayed in
+     disassembly.  */
+  {"swf",
+   0x0530+CC_EXT*0x1000,
+   0x0AC0+(0xf-CC_EXT)*0x1000,		  "r",	     0, SIZE_NONE,
+   cris_ver_v10,
+   cris_scc_op},
+
+  {"sext",
+   0x0530+CC_EXT*0x1000,
+   0x0AC0+(0xf-CC_EXT)*0x1000,		  "r",	     0, SIZE_NONE,
+   cris_ver_v0_3,
+   cris_scc_op},
+
+  {"sge",
+   0x0530+CC_GE*0x1000,
+   0x0AC0+(0xf-CC_GE)*0x1000,		  "r",	     0, SIZE_NONE,     0,
+   cris_scc_op},
+
+  {"sgt",
+   0x0530+CC_GT*0x1000,
+   0x0AC0+(0xf-CC_GT)*0x1000,		  "r",	     0, SIZE_NONE,     0,
+   cris_scc_op},
+
+  {"shi",
+   0x0530+CC_HI*0x1000,
+   0x0AC0+(0xf-CC_HI)*0x1000,		  "r",	     0, SIZE_NONE,     0,
+   cris_scc_op},
+
+  {"shs",
+   0x0530+CC_HS*0x1000,
+   0x0AC0+(0xf-CC_HS)*0x1000,		  "r",	     0, SIZE_NONE,     0,
+   cris_scc_op},
+
+  {"sle",
+   0x0530+CC_LE*0x1000,
+   0x0AC0+(0xf-CC_LE)*0x1000,		  "r",	     0, SIZE_NONE,     0,
+   cris_scc_op},
+
+  {"slo",
+   0x0530+CC_LO*0x1000,
+   0x0AC0+(0xf-CC_LO)*0x1000,		  "r",	     0, SIZE_NONE,     0,
+   cris_scc_op},
+
+  {"sls",
+   0x0530+CC_LS*0x1000,
+   0x0AC0+(0xf-CC_LS)*0x1000,		  "r",	     0, SIZE_NONE,     0,
+   cris_scc_op},
+
+  {"slt",
+   0x0530+CC_LT*0x1000,
+   0x0AC0+(0xf-CC_LT)*0x1000,		  "r",	     0, SIZE_NONE,     0,
+   cris_scc_op},
+
+  {"smi",
+   0x0530+CC_MI*0x1000,
+   0x0AC0+(0xf-CC_MI)*0x1000,		  "r",	     0, SIZE_NONE,     0,
+   cris_scc_op},
+
+  {"sne",
+   0x0530+CC_NE*0x1000,
+   0x0AC0+(0xf-CC_NE)*0x1000,		  "r",	     0, SIZE_NONE,     0,
+   cris_scc_op},
+
+  {"spl",
+   0x0530+CC_PL*0x1000,
+   0x0AC0+(0xf-CC_PL)*0x1000,		  "r",	     0, SIZE_NONE,     0,
+   cris_scc_op},
+
+  {"sub",     0x0680, 0x0940,		  "m r,R",   0, SIZE_NONE,     0,
+   cris_reg_mode_add_sub_cmp_and_or_move_op},
+
+  {"sub",     0x0a80, 0x0140,		  "m s,R",   0, SIZE_FIELD,    0,
+   cris_none_reg_mode_add_sub_cmp_and_or_move_op},
+
+  {"sub",     0x0a80, 0x0140,		  "m S,D",   0, SIZE_NONE,
+   cris_ver_v0_10,
+   cris_none_reg_mode_add_sub_cmp_and_or_move_op},
+
+  {"sub",     0x0a80, 0x0540,		  "m S,R,r", 0, SIZE_NONE,
+   cris_ver_v0_10,
+   cris_three_operand_add_sub_cmp_and_or_op},
+
+  {"subq",    0x0280, 0x0d40,		  "I,R",     0, SIZE_NONE,     0,
+   cris_quick_mode_add_sub_op},
+
+  {"subs",    0x04a0, 0x0b40,		  "z r,R",   0, SIZE_NONE,     0,
+   cris_reg_mode_add_sub_cmp_and_or_move_op},
+
+  /* FIXME: SIZE_FIELD_SIGNED and all necessary changes.  */
+  {"subs",    0x08a0, 0x0340,		  "z s,R",   0, SIZE_FIELD,    0,
+   cris_none_reg_mode_add_sub_cmp_and_or_move_op},
+
+  {"subs",    0x08a0, 0x0340,		  "z S,D",   0, SIZE_NONE,
+   cris_ver_v0_10,
+   cris_none_reg_mode_add_sub_cmp_and_or_move_op},
+
+  {"subs",    0x08a0, 0x0740,		  "z S,R,r", 0, SIZE_NONE,
+   cris_ver_v0_10,
+   cris_three_operand_add_sub_cmp_and_or_op},
+
+  {"subu",    0x0480, 0x0b60,		  "z r,R",   0, SIZE_NONE,     0,
+   cris_reg_mode_add_sub_cmp_and_or_move_op},
+
+  /* FIXME: SIZE_FIELD_UNSIGNED and all necessary changes.  */
+  {"subu",    0x0880, 0x0360,		  "z s,R",   0, SIZE_FIELD,    0,
+   cris_none_reg_mode_add_sub_cmp_and_or_move_op},
+
+  {"subu",    0x0880, 0x0360,		  "z S,D",   0, SIZE_NONE,
+   cris_ver_v0_10,
+   cris_none_reg_mode_add_sub_cmp_and_or_move_op},
+
+  {"subu",    0x0880, 0x0760,		  "z S,R,r", 0, SIZE_NONE,
+   cris_ver_v0_10,
+   cris_three_operand_add_sub_cmp_and_or_op},
+
+  {"svc",
+   0x0530+CC_VC*0x1000,
+   0x0AC0+(0xf-CC_VC)*0x1000,		  "r",	     0, SIZE_NONE,     0,
+   cris_scc_op},
+
+  {"svs",
+   0x0530+CC_VS*0x1000,
+   0x0AC0+(0xf-CC_VS)*0x1000,		  "r",	     0, SIZE_NONE,     0,
+   cris_scc_op},
+
+  /* The insn "swapn" is the same as "not" and will be disassembled as
+     such, but the swap* family of mnmonics are generally v8-and-higher
+     only, so count it in.  */
+  {"swapn",   0x8770, 0x7880,		  "r",	     0, SIZE_NONE,
+   cris_ver_v8p,
+   cris_not_implemented_op},
+
+  {"swapw",   0x4770, 0xb880,		  "r",	     0, SIZE_NONE,
+   cris_ver_v8p,
+   cris_not_implemented_op},
+
+  {"swapnw",  0xc770, 0x3880,		  "r",	     0, SIZE_NONE,
+   cris_ver_v8p,
+   cris_not_implemented_op},
+
+  {"swapb",   0x2770, 0xd880,		  "r",	     0, SIZE_NONE,
+   cris_ver_v8p,
+   cris_not_implemented_op},
+
+  {"swapnb",  0xA770, 0x5880,		  "r",	     0, SIZE_NONE,
+   cris_ver_v8p,
+   cris_not_implemented_op},
+
+  {"swapwb",  0x6770, 0x9880,		  "r",	     0, SIZE_NONE,
+   cris_ver_v8p,
+   cris_not_implemented_op},
+
+  {"swapnwb", 0xE770, 0x1880,		  "r",	     0, SIZE_NONE,
+   cris_ver_v8p,
+   cris_not_implemented_op},
+
+  {"swapr",   0x1770, 0xe880,		  "r",	     0, SIZE_NONE,
+   cris_ver_v8p,
+   cris_not_implemented_op},
+
+  {"swapnr",  0x9770, 0x6880,		  "r",	     0, SIZE_NONE,
+   cris_ver_v8p,
+   cris_not_implemented_op},
+
+  {"swapwr",  0x5770, 0xa880,		  "r",	     0, SIZE_NONE,
+   cris_ver_v8p,
+   cris_not_implemented_op},
+
+  {"swapnwr", 0xd770, 0x2880,		  "r",	     0, SIZE_NONE,
+   cris_ver_v8p,
+   cris_not_implemented_op},
+
+  {"swapbr",  0x3770, 0xc880,		  "r",	     0, SIZE_NONE,
+   cris_ver_v8p,
+   cris_not_implemented_op},
+
+  {"swapnbr", 0xb770, 0x4880,		  "r",	     0, SIZE_NONE,
+   cris_ver_v8p,
+   cris_not_implemented_op},
+
+  {"swapwbr", 0x7770, 0x8880,		  "r",	     0, SIZE_NONE,
+   cris_ver_v8p,
+   cris_not_implemented_op},
+
+  {"swapnwbr", 0xf770, 0x0880,		  "r",	     0, SIZE_NONE,
+   cris_ver_v8p,
+   cris_not_implemented_op},
+
+  {"test",    0x0640, 0x0980,		  "m D",     0, SIZE_NONE,
+   cris_ver_v0_10,
+   cris_reg_mode_test_op},
+
+  {"test",    0x0b80, 0xf040,		  "m y",     0, SIZE_FIELD,    0,
+   cris_none_reg_mode_clear_test_op},
+
+  {"test",    0x0b80, 0xf040,		  "m S",     0, SIZE_NONE,
+   cris_ver_v0_10,
+   cris_none_reg_mode_clear_test_op},
+
+  {"xor",     0x07B0, 0x0840,		  "r,R",     0, SIZE_NONE,     0,
+   cris_xor_op},
+
+  {NULL, 0, 0, NULL, 0, 0, 0, cris_not_implemented_op}
+};
+
+/* Condition-names, indexed by the CC_* numbers as found in cris.h. */
+const char * const
+cris_cc_strings[] =
+{
+  "hs",
+  "lo",
+  "ne",
+  "eq",
+  "vc",
+  "vs",
+  "pl",
+  "mi",
+  "ls",
+  "hi",
+  "ge",
+  "lt",
+  "gt",
+  "le",
+  "a",
+  /* This is a placeholder.  In v0, this would be "ext".  In v32, this
+     is "sb".  See cris_conds15.  */
+  "wf"
+};
+
+/* Different names and semantics for condition 1111 (0xf).  */
+const struct cris_cond15 cris_cond15s[] =
+{
+  /* FIXME: In what version did condition "ext" disappear?  */
+  {"ext", cris_ver_v0_3},
+  {"wf", cris_ver_v10},
+  {"sb", cris_ver_v32p},
+  {NULL, 0}
+};
+
+
+/*
+ * Local variables:
+ * eval: (c-set-style "gnu")
+ * indent-tabs-mode: t
+ * End:
+ */
+
+
+/* No instruction will be disassembled longer than this.  In theory, and
+   in silicon, address prefixes can be cascaded.  In practice, cascading
+   is not used by GCC, and not supported by the assembler.  */
+#ifndef MAX_BYTES_PER_CRIS_INSN
+#define MAX_BYTES_PER_CRIS_INSN 8
+#endif
+
+/* Whether or not to decode prefixes, folding it into the following
+   instruction.  FIXME: Make this optional later.  */
+#ifndef PARSE_PREFIX
+#define PARSE_PREFIX 1
+#endif
+
+/* Sometimes we prefix all registers with this character.  */
+#define REGISTER_PREFIX_CHAR '$'
+
+/* Whether or not to trace the following sequence:
+   sub* X,r%d
+   bound* Y,r%d
+   adds.w [pc+r%d.w],pc
+
+   This is the assembly form of a switch-statement in C.
+   The "sub is optional.  If there is none, then X will be zero.
+   X is the value of the first case,
+   Y is the number of cases (including default).
+
+   This results in case offsets printed on the form:
+    case N: -> case_address
+   where N is an estimation on the corresponding 'case' operand in C,
+   and case_address is where execution of that case continues after the
+   sequence presented above.
+
+   The old style of output was to print the offsets as instructions,
+   which made it hard to follow "case"-constructs in the disassembly,
+   and caused a lot of annoying warnings about undefined instructions.
+
+   FIXME: Make this optional later.  */
+#ifndef TRACE_CASE
+#define TRACE_CASE (disdata->trace_case)
+#endif
+
+enum cris_disass_family
+ { cris_dis_v0_v10, cris_dis_common_v10_v32, cris_dis_v32 };
+
+/* Stored in the disasm_info->private_data member.  */
+struct cris_disasm_data
+{
+  /* Whether to print something less confusing if we find something
+     matching a switch-construct.  */
+  bfd_boolean trace_case;
+
+  /* Whether this code is flagged as crisv32.  FIXME: Should be an enum
+     that includes "compatible".  */
+  enum cris_disass_family distype;
+};
+
+/* Value of first element in switch.  */
+static long case_offset = 0;
+
+/* How many more case-offsets to print.  */
+static long case_offset_counter = 0;
+
+/* Number of case offsets.  */
+static long no_of_case_offsets = 0;
+
+/* Candidate for next case_offset.  */
+static long last_immediate = 0;
+
+static int cris_constraint
+  (const char *, unsigned, unsigned, struct cris_disasm_data *);
+
+/* Parse disassembler options and store state in info.  FIXME: For the
+   time being, we abuse static variables.  */
+
+static bfd_boolean
+cris_parse_disassembler_options (disassemble_info *info,
+				 enum cris_disass_family distype)
+{
+  struct cris_disasm_data *disdata;
+
+  info->private_data = calloc (1, sizeof (struct cris_disasm_data));
+  disdata = (struct cris_disasm_data *) info->private_data;
+  if (disdata == NULL)
+    return FALSE;
+
+  /* Default true.  */
+  disdata->trace_case
+    = (info->disassembler_options == NULL
+       || (strcmp (info->disassembler_options, "nocase") != 0));
+
+  disdata->distype = distype;
+  return TRUE;
+}
+
+static const struct cris_spec_reg *
+spec_reg_info (unsigned int sreg, enum cris_disass_family distype)
+{
+  int i;
+
+  for (i = 0; cris_spec_regs[i].name != NULL; i++)
+    {
+      if (cris_spec_regs[i].number == sreg)
+	{
+	  if (distype == cris_dis_v32)
+	    switch (cris_spec_regs[i].applicable_version)
+	      {
+	      case cris_ver_warning:
+	      case cris_ver_version_all:
+	      case cris_ver_v3p:
+	      case cris_ver_v8p:
+	      case cris_ver_v10p:
+	      case cris_ver_v32p:
+		/* No ambiguous sizes or register names with CRISv32.  */
+		if (cris_spec_regs[i].warning == NULL)
+		  return &cris_spec_regs[i];
+	      default:
+		;
+	      }
+	  else if (cris_spec_regs[i].applicable_version != cris_ver_v32p)
+	    return &cris_spec_regs[i];
+	}
+    }
+
+  return NULL;
+}
+
+/* Return the number of bits in the argument.  */
+
+static int
+number_of_bits (unsigned int val)
+{
+  int bits;
+
+  for (bits = 0; val != 0; val &= val - 1)
+    bits++;
+
+  return bits;
+}
+
+/* Get an entry in the opcode-table.  */
+
+static const struct cris_opcode *
+get_opcode_entry (unsigned int insn,
+		  unsigned int prefix_insn,
+		  struct cris_disasm_data *disdata)
+{
+  /* For non-prefixed insns, we keep a table of pointers, indexed by the
+     insn code.  Each entry is initialized when found to be NULL.  */
+  static const struct cris_opcode **opc_table = NULL;
+
+  const struct cris_opcode *max_matchedp = NULL;
+  const struct cris_opcode **prefix_opc_table = NULL;
+
+  /* We hold a table for each prefix that need to be handled differently.  */
+  static const struct cris_opcode **dip_prefixes = NULL;
+  static const struct cris_opcode **bdapq_m1_prefixes = NULL;
+  static const struct cris_opcode **bdapq_m2_prefixes = NULL;
+  static const struct cris_opcode **bdapq_m4_prefixes = NULL;
+  static const struct cris_opcode **rest_prefixes = NULL;
+
+  /* Allocate and clear the opcode-table.  */
+  if (opc_table == NULL)
+    {
+      opc_table = malloc (65536 * sizeof (opc_table[0]));
+      if (opc_table == NULL)
+	return NULL;
+
+      memset (opc_table, 0, 65536 * sizeof (const struct cris_opcode *));
+
+      dip_prefixes
+	= malloc (65536 * sizeof (const struct cris_opcode **));
+      if (dip_prefixes == NULL)
+	return NULL;
+
+      memset (dip_prefixes, 0, 65536 * sizeof (dip_prefixes[0]));
+
+      bdapq_m1_prefixes
+	= malloc (65536 * sizeof (const struct cris_opcode **));
+      if (bdapq_m1_prefixes == NULL)
+	return NULL;
+
+      memset (bdapq_m1_prefixes, 0, 65536 * sizeof (bdapq_m1_prefixes[0]));
+
+      bdapq_m2_prefixes
+	= malloc (65536 * sizeof (const struct cris_opcode **));
+      if (bdapq_m2_prefixes == NULL)
+	return NULL;
+
+      memset (bdapq_m2_prefixes, 0, 65536 * sizeof (bdapq_m2_prefixes[0]));
+
+      bdapq_m4_prefixes
+	= malloc (65536 * sizeof (const struct cris_opcode **));
+      if (bdapq_m4_prefixes == NULL)
+	return NULL;
+
+      memset (bdapq_m4_prefixes, 0, 65536 * sizeof (bdapq_m4_prefixes[0]));
+
+      rest_prefixes
+	= malloc (65536 * sizeof (const struct cris_opcode **));
+      if (rest_prefixes == NULL)
+	return NULL;
+
+      memset (rest_prefixes, 0, 65536 * sizeof (rest_prefixes[0]));
+    }
+
+  /* Get the right table if this is a prefix.
+     This code is connected to cris_constraints in that it knows what
+     prefixes play a role in recognition of patterns; the necessary
+     state is reflected by which table is used.  If constraints
+     involving match or non-match of prefix insns are changed, then this
+     probably needs changing too.  */
+  if (prefix_insn != NO_CRIS_PREFIX)
+    {
+      const struct cris_opcode *popcodep
+	= (opc_table[prefix_insn] != NULL
+	   ? opc_table[prefix_insn]
+	   : get_opcode_entry (prefix_insn, NO_CRIS_PREFIX, disdata));
+
+      if (popcodep == NULL)
+	return NULL;
+
+      if (popcodep->match == BDAP_QUICK_OPCODE)
+	{
+	  /* Since some offsets are recognized with "push" macros, we
+	     have to have different tables for them.  */
+	  int offset = (prefix_insn & 255);
+
+	  if (offset > 127)
+	    offset -= 256;
+
+	  switch (offset)
+	    {
+	    case -4:
+	      prefix_opc_table = bdapq_m4_prefixes;
+	      break;
+
+	    case -2:
+	      prefix_opc_table = bdapq_m2_prefixes;
+	      break;
+
+	    case -1:
+	      prefix_opc_table = bdapq_m1_prefixes;
+	      break;
+
+	    default:
+	      prefix_opc_table = rest_prefixes;
+	      break;
+	    }
+	}
+      else if (popcodep->match == DIP_OPCODE)
+	/* We don't allow postincrement when the prefix is DIP, so use a
+	   different table for DIP.  */
+	prefix_opc_table = dip_prefixes;
+      else
+	prefix_opc_table = rest_prefixes;
+    }
+
+  if (prefix_insn != NO_CRIS_PREFIX
+      && prefix_opc_table[insn] != NULL)
+    max_matchedp = prefix_opc_table[insn];
+  else if (prefix_insn == NO_CRIS_PREFIX && opc_table[insn] != NULL)
+    max_matchedp = opc_table[insn];
+  else
+    {
+      const struct cris_opcode *opcodep;
+      int max_level_of_match = -1;
+
+      for (opcodep = cris_opcodes;
+	   opcodep->name != NULL;
+	   opcodep++)
+	{
+	  int level_of_match;
+
+	  if (disdata->distype == cris_dis_v32)
+	    {
+	      switch (opcodep->applicable_version)
+		{
+		case cris_ver_version_all:
+		  break;
+
+		case cris_ver_v0_3:
+		case cris_ver_v0_10:
+		case cris_ver_v3_10:
+		case cris_ver_sim_v0_10:
+		case cris_ver_v8_10:
+		case cris_ver_v10:
+		case cris_ver_warning:
+		  continue;
+
+		case cris_ver_v3p:
+		case cris_ver_v8p:
+		case cris_ver_v10p:
+		case cris_ver_v32p:
+		  break;
+
+		case cris_ver_v8:
+		  abort ();
+		default:
+		  abort ();
+		}
+	    }
+	  else
+	    {
+	      switch (opcodep->applicable_version)
+		{
+		case cris_ver_version_all:
+		case cris_ver_v0_3:
+		case cris_ver_v3p:
+		case cris_ver_v0_10:
+		case cris_ver_v8p:
+		case cris_ver_v8_10:
+		case cris_ver_v10:
+		case cris_ver_sim_v0_10:
+		case cris_ver_v10p:
+		case cris_ver_warning:
+		  break;
+
+		case cris_ver_v32p:
+		  continue;
+
+		case cris_ver_v8:
+		  abort ();
+		default:
+		  abort ();
+		}
+	    }
+
+	  /* We give a double lead for bits matching the template in
+	     cris_opcodes.  Not even, because then "move p8,r10" would
+	     be given 2 bits lead over "clear.d r10".  When there's a
+	     tie, the first entry in the table wins.  This is
+	     deliberate, to avoid a more complicated recognition
+	     formula.  */
+	  if ((opcodep->match & insn) == opcodep->match
+	      && (opcodep->lose & insn) == 0
+	      && ((level_of_match
+		   = cris_constraint (opcodep->args,
+				      insn,
+				      prefix_insn,
+				      disdata))
+		  >= 0)
+	      && ((level_of_match
+		   += 2 * number_of_bits (opcodep->match
+					  | opcodep->lose))
+			  > max_level_of_match))
+		    {
+		      max_matchedp = opcodep;
+		      max_level_of_match = level_of_match;
+
+		      /* If there was a full match, never mind looking
+			 further.  */
+		      if (level_of_match >= 2 * 16)
+			break;
+		    }
+		}
+      /* Fill in the new entry.
+
+	 If there are changes to the opcode-table involving prefixes, and
+	 disassembly then does not work correctly, try removing the
+	 else-clause below that fills in the prefix-table.  If that
+	 helps, you need to change the prefix_opc_table setting above, or
+	 something related.  */
+      if (prefix_insn == NO_CRIS_PREFIX)
+	opc_table[insn] = max_matchedp;
+      else
+	prefix_opc_table[insn] = max_matchedp;
+    }
+
+  return max_matchedp;
+}
+
+/* Return -1 if the constraints of a bitwise-matched instruction say
+   that there is no match.  Otherwise return a nonnegative number
+   indicating the confidence in the match (higher is better).  */
+
+static int
+cris_constraint (const char *cs,
+		 unsigned int insn,
+		 unsigned int prefix_insn,
+		 struct cris_disasm_data *disdata)
+{
+  int retval = 0;
+  int tmp;
+  int prefix_ok = 0;
+  const char *s;
+
+  for (s = cs; *s; s++)
+    switch (*s)
+      {
+      case '!':
+	/* Do not recognize "pop" if there's a prefix and then only for
+           v0..v10.  */
+	if (prefix_insn != NO_CRIS_PREFIX
+	    || disdata->distype != cris_dis_v0_v10)
+	  return -1;
+	break;
+
+      case 'U':
+	/* Not recognized at disassembly.  */
+	return -1;
+
+      case 'M':
+	/* Size modifier for "clear", i.e. special register 0, 4 or 8.
+	   Check that it is one of them.  Only special register 12 could
+	   be mismatched, but checking for matches is more logical than
+	   checking for mismatches when there are only a few cases.  */
+	tmp = ((insn >> 12) & 0xf);
+	if (tmp != 0 && tmp != 4 && tmp != 8)
+	  return -1;
+	break;
+
+      case 'm':
+	if ((insn & 0x30) == 0x30)
+	  return -1;
+	break;
+
+      case 'S':
+	/* A prefix operand without side-effect.  */
+	if (prefix_insn != NO_CRIS_PREFIX && (insn & 0x400) == 0)
+	  {
+	    prefix_ok = 1;
+	    break;
+	  }
+	else
+	  return -1;
+
+      case 's':
+      case 'y':
+      case 'Y':
+	/* If this is a prefixed insn with postincrement (side-effect),
+	   the prefix must not be DIP.  */
+	if (prefix_insn != NO_CRIS_PREFIX)
+	  {
+	    if (insn & 0x400)
+	      {
+		const struct cris_opcode *prefix_opcodep
+		  = get_opcode_entry (prefix_insn, NO_CRIS_PREFIX, disdata);
+
+		if (prefix_opcodep->match == DIP_OPCODE)
+		  return -1;
+	      }
+
+	    prefix_ok = 1;
+	  }
+	break;
+
+      case 'B':
+	/* If we don't fall through, then the prefix is ok.  */
+	prefix_ok = 1;
+
+	/* A "push" prefix.  Check for valid "push" size.
+	   In case of special register, it may be != 4.  */
+	if (prefix_insn != NO_CRIS_PREFIX)
+	  {
+	    /* Match the prefix insn to BDAPQ.  */
+	    const struct cris_opcode *prefix_opcodep
+	      = get_opcode_entry (prefix_insn, NO_CRIS_PREFIX, disdata);
+
+	    if (prefix_opcodep->match == BDAP_QUICK_OPCODE)
+	      {
+		int pushsize = (prefix_insn & 255);
+
+		if (pushsize > 127)
+		  pushsize -= 256;
+
+		if (s[1] == 'P')
+		  {
+		    unsigned int spec_reg = (insn >> 12) & 15;
+		    const struct cris_spec_reg *sregp
+		      = spec_reg_info (spec_reg, disdata->distype);
+
+		    /* For a special-register, the "prefix size" must
+		       match the size of the register.  */
+		    if (sregp && sregp->reg_size == (unsigned int) -pushsize)
+		      break;
+		  }
+		else if (s[1] == 'R')
+		  {
+		    if ((insn & 0x30) == 0x20 && pushsize == -4)
+		      break;
+		  }
+		/* FIXME:  Should abort here; next constraint letter
+		   *must* be 'P' or 'R'.  */
+	      }
+	  }
+	return -1;
+
+      case 'D':
+	retval = (((insn >> 12) & 15) == (insn & 15));
+	if (!retval)
+	  return -1;
+	else
+	  retval += 4;
+	break;
+
+      case 'P':
+	{
+	  const struct cris_spec_reg *sregp
+	    = spec_reg_info ((insn >> 12) & 15, disdata->distype);
+
+	  /* Since we match four bits, we will give a value of 4-1 = 3
+	     in a match.  If there is a corresponding exact match of a
+	     special register in another pattern, it will get a value of
+	     4, which will be higher.  This should be correct in that an
+	     exact pattern would match better than a general pattern.
+
+	     Note that there is a reason for not returning zero; the
+	     pattern for "clear" is partly  matched in the bit-pattern
+	     (the two lower bits must be zero), while the bit-pattern
+	     for a move from a special register is matched in the
+	     register constraint.  */
+
+	  if (sregp != NULL)
+	    {
+	      retval += 3;
+	      break;
+	    }
+	  else
+	    return -1;
+	}
+      }
+
+  if (prefix_insn != NO_CRIS_PREFIX && ! prefix_ok)
+    return -1;
+
+  return retval;
+}
+
+/* Format number as hex with a leading "0x" into outbuffer.  */
+
+static char *
+format_hex (unsigned long number,
+	    char *outbuffer,
+	    struct cris_disasm_data *disdata)
+{
+  /* Truncate negative numbers on >32-bit hosts.  */
+  number &= 0xffffffff;
+
+  sprintf (outbuffer, "0x%lx", number);
+
+  /* Save this value for the "case" support.  */
+  if (TRACE_CASE)
+    last_immediate = number;
+
+  return outbuffer + strlen (outbuffer);
+}
+
+/* Format number as decimal into outbuffer.  Parameter signedp says
+   whether the number should be formatted as signed (!= 0) or
+   unsigned (== 0).  */
+
+static char *
+format_dec (long number, char *outbuffer, int signedp)
+{
+  last_immediate = number;
+  sprintf (outbuffer, signedp ? "%ld" : "%lu", number);
+
+  return outbuffer + strlen (outbuffer);
+}
+
+/* Format the name of the general register regno into outbuffer.  */
+
+static char *
+format_reg (struct cris_disasm_data *disdata,
+	    int regno,
+	    char *outbuffer_start,
+	    bfd_boolean with_reg_prefix)
+{
+  char *outbuffer = outbuffer_start;
+
+  if (with_reg_prefix)
+    *outbuffer++ = REGISTER_PREFIX_CHAR;
+
+  switch (regno)
+    {
+    case 15:
+      /* For v32, there is no context in which we output PC.  */
+      if (disdata->distype == cris_dis_v32)
+	strcpy (outbuffer, "acr");
+      else
+	strcpy (outbuffer, "pc");
+      break;
+
+    case 14:
+      strcpy (outbuffer, "sp");
+      break;
+
+    default:
+      sprintf (outbuffer, "r%d", regno);
+      break;
+    }
+
+  return outbuffer_start + strlen (outbuffer_start);
+}
+
+/* Format the name of a support register into outbuffer.  */
+
+static char *
+format_sup_reg (unsigned int regno,
+		char *outbuffer_start,
+		bfd_boolean with_reg_prefix)
+{
+  char *outbuffer = outbuffer_start;
+  int i;
+
+  if (with_reg_prefix)
+    *outbuffer++ = REGISTER_PREFIX_CHAR;
+
+  for (i = 0; cris_support_regs[i].name != NULL; i++)
+    if (cris_support_regs[i].number == regno)
+      {
+	sprintf (outbuffer, "%s", cris_support_regs[i].name);
+	return outbuffer_start + strlen (outbuffer_start);
+      }
+
+  /* There's supposed to be register names covering all numbers, though
+     some may be generic names.  */
+  sprintf (outbuffer, "format_sup_reg-BUG");
+  return outbuffer_start + strlen (outbuffer_start);
+}
+
+/* Return the length of an instruction.  */
+
+static unsigned
+bytes_to_skip (unsigned int insn,
+	       const struct cris_opcode *matchedp,
+	       enum cris_disass_family distype,
+	       const struct cris_opcode *prefix_matchedp)
+{
+  /* Each insn is a word plus "immediate" operands.  */
+  unsigned to_skip = 2;
+  const char *template = matchedp->args;
+  const char *s;
+
+  for (s = template; *s; s++)
+    if ((*s == 's' || *s == 'N' || *s == 'Y')
+	&& (insn & 0x400) && (insn & 15) == 15
+	&& prefix_matchedp == NULL)
+      {
+	/* Immediate via [pc+], so we have to check the size of the
+	   operand.  */
+	int mode_size = 1 << ((insn >> 4) & (*template == 'z' ? 1 : 3));
+
+	if (matchedp->imm_oprnd_size == SIZE_FIX_32)
+	  to_skip += 4;
+	else if (matchedp->imm_oprnd_size == SIZE_SPEC_REG)
+	  {
+	    const struct cris_spec_reg *sregp
+	      = spec_reg_info ((insn >> 12) & 15, distype);
+
+	    /* FIXME: Improve error handling; should have been caught
+	       earlier.  */
+	    if (sregp == NULL)
+	      return 2;
+
+	    /* PC is incremented by two, not one, for a byte.  Except on
+	       CRISv32, where constants are always DWORD-size for
+	       special registers.  */
+	    to_skip +=
+	      distype == cris_dis_v32 ? 4 : (sregp->reg_size + 1) & ~1;
+	  }
+	else
+	  to_skip += (mode_size + 1) & ~1;
+      }
+    else if (*s == 'n')
+      to_skip += 4;
+    else if (*s == 'b')
+      to_skip += 2;
+
+  return to_skip;
+}
+
+/* Print condition code flags.  */
+
+static char *
+print_flags (struct cris_disasm_data *disdata, unsigned int insn, char *cp)
+{
+  /* Use the v8 (Etrax 100) flag definitions for disassembly.
+     The differences with v0 (Etrax 1..4) vs. Svinto are:
+      v0 'd' <=> v8 'm'
+      v0 'e' <=> v8 'b'.
+     FIXME: Emit v0..v3 flag names somehow.  */
+  static const char v8_fnames[] = "cvznxibm";
+  static const char v32_fnames[] = "cvznxiup";
+  const char *fnames
+    = disdata->distype == cris_dis_v32 ? v32_fnames : v8_fnames;
+
+  unsigned char flagbits = (((insn >> 8) & 0xf0) | (insn & 15));
+  int i;
+
+  for (i = 0; i < 8; i++)
+    if (flagbits & (1 << i))
+      *cp++ = fnames[i];
+
+  return cp;
+}
+
+/* Print out an insn with its operands, and update the info->insn_type
+   fields.  The prefix_opcodep and the rest hold a prefix insn that is
+   supposed to be output as an address mode.  */
+
+static void
+print_with_operands (const struct cris_opcode *opcodep,
+		     unsigned int insn,
+		     unsigned char *buffer,
+		     bfd_vma addr,
+		     disassemble_info *info,
+		     /* If a prefix insn was before this insn (and is supposed
+			to be output as an address), here is a description of
+			it.  */
+		     const struct cris_opcode *prefix_opcodep,
+		     unsigned int prefix_insn,
+		     unsigned char *prefix_buffer,
+		     bfd_boolean with_reg_prefix)
+{
+  /* Get a buffer of somewhat reasonable size where we store
+     intermediate parts of the insn.  */
+  char temp[sizeof (".d [$r13=$r12-2147483648],$r10") * 2];
+  char *tp = temp;
+  static const char mode_char[] = "bwd?";
+  const char *s;
+  const char *cs;
+  struct cris_disasm_data *disdata
+    = (struct cris_disasm_data *) info->private_data;
+
+  /* Print out the name first thing we do.  */
+  (*info->fprintf_func) (info->stream, "%s", opcodep->name);
+
+  cs = opcodep->args;
+  s = cs;
+
+  /* Ignore any prefix indicator.  */
+  if (*s == 'p')
+    s++;
+
+  if (*s == 'm' || *s == 'M' || *s == 'z')
+    {
+      *tp++ = '.';
+
+      /* Get the size-letter.  */
+      *tp++ = *s == 'M'
+	? (insn & 0x8000 ? 'd'
+	   : insn & 0x4000 ? 'w' : 'b')
+	: mode_char[(insn >> 4) & (*s == 'z' ? 1 : 3)];
+
+      /* Ignore the size and the space character that follows.  */
+      s += 2;
+    }
+
+  /* Add a space if this isn't a long-branch, because for those will add
+     the condition part of the name later.  */
+  if (opcodep->match != (BRANCH_PC_LOW + BRANCH_INCR_HIGH * 256))
+    *tp++ = ' ';
+
+  /* Fill in the insn-type if deducible from the name (and there's no
+     better way).  */
+  if (opcodep->name[0] == 'j')
+    {
+      if (CONST_STRNEQ (opcodep->name, "jsr"))
+	/* It's "jsr" or "jsrc".  */
+	info->insn_type = dis_jsr;
+      else
+	/* Any other jump-type insn is considered a branch.  */
+	info->insn_type = dis_branch;
+    }
+
+  /* We might know some more fields right now.  */
+  info->branch_delay_insns = opcodep->delayed;
+
+  /* Handle operands.  */
+  for (; *s; s++)
+    {
+    switch (*s)
+      {
+      case 'T':
+	tp = format_sup_reg ((insn >> 12) & 15, tp, with_reg_prefix);
+	break;
+
+      case 'A':
+	if (with_reg_prefix)
+	  *tp++ = REGISTER_PREFIX_CHAR;
+	*tp++ = 'a';
+	*tp++ = 'c';
+	*tp++ = 'r';
+	break;
+
+      case '[':
+      case ']':
+      case ',':
+	*tp++ = *s;
+	break;
+
+      case '!':
+	/* Ignore at this point; used at earlier stages to avoid
+	   recognition if there's a prefix at something that in other
+	   ways looks like a "pop".  */
+	break;
+
+      case 'd':
+	/* Ignore.  This is an optional ".d " on the large one of
+	   relaxable insns.  */
+	break;
+
+      case 'B':
+	/* This was the prefix that made this a "push".  We've already
+	   handled it by recognizing it, so signal that the prefix is
+	   handled by setting it to NULL.  */
+	prefix_opcodep = NULL;
+	break;
+
+      case 'D':
+      case 'r':
+	tp = format_reg (disdata, insn & 15, tp, with_reg_prefix);
+	break;
+
+      case 'R':
+	tp = format_reg (disdata, (insn >> 12) & 15, tp, with_reg_prefix);
+	break;
+
+      case 'n':
+	{
+	  /* Like N but pc-relative to the start of the insn.  */
+	  unsigned long number
+	    = (buffer[2] + buffer[3] * 256 + buffer[4] * 65536
+	       + buffer[5] * 0x1000000 + addr);
+
+	  /* Finish off and output previous formatted bytes.  */
+	  *tp = 0;
+	  if (temp[0])
+	    (*info->fprintf_func) (info->stream, "%s", temp);
+	  tp = temp;
+
+	  (*info->print_address_func) ((bfd_vma) number, info);
+	}
+	break;
+
+      case 'u':
+	{
+	  /* Like n but the offset is bits <3:0> in the instruction.  */
+	  unsigned long number = (buffer[0] & 0xf) * 2 + addr;
+
+	  /* Finish off and output previous formatted bytes.  */
+	  *tp = 0;
+	  if (temp[0])
+	    (*info->fprintf_func) (info->stream, "%s", temp);
+	  tp = temp;
+
+	  (*info->print_address_func) ((bfd_vma) number, info);
+	}
+	break;
+
+      case 'N':
+      case 'y':
+      case 'Y':
+      case 'S':
+      case 's':
+	/* Any "normal" memory operand.  */
+	if ((insn & 0x400) && (insn & 15) == 15 && prefix_opcodep == NULL)
+	  {
+	    /* We're looking at [pc+], i.e. we need to output an immediate
+	       number, where the size can depend on different things.  */
+	    long number;
+	    int signedp
+	      = ((*cs == 'z' && (insn & 0x20))
+		 || opcodep->match == BDAP_QUICK_OPCODE);
+	    int nbytes;
+
+	    if (opcodep->imm_oprnd_size == SIZE_FIX_32)
+	      nbytes = 4;
+	    else if (opcodep->imm_oprnd_size == SIZE_SPEC_REG)
+	      {
+		const struct cris_spec_reg *sregp
+		  = spec_reg_info ((insn >> 12) & 15, disdata->distype);
+
+		/* A NULL return should have been as a non-match earlier,
+		   so catch it as an internal error in the error-case
+		   below.  */
+		if (sregp == NULL)
+		  /* Whatever non-valid size.  */
+		  nbytes = 42;
+		else
+		  /* PC is always incremented by a multiple of two.
+		     For CRISv32, immediates are always 4 bytes for
+		     special registers.  */
+		  nbytes = disdata->distype == cris_dis_v32
+		    ? 4 : (sregp->reg_size + 1) & ~1;
+	      }
+	    else
+	      {
+		int mode_size = 1 << ((insn >> 4) & (*cs == 'z' ? 1 : 3));
+
+		if (mode_size == 1)
+		  nbytes = 2;
+		else
+		  nbytes = mode_size;
+	      }
+
+	    switch (nbytes)
+	      {
+	      case 1:
+		number = buffer[2];
+		if (signedp && number > 127)
+		  number -= 256;
+		break;
+
+	      case 2:
+		number = buffer[2] + buffer[3] * 256;
+		if (signedp && number > 32767)
+		  number -= 65536;
+		break;
+
+	      case 4:
+		number
+		  = buffer[2] + buffer[3] * 256 + buffer[4] * 65536
+		  + buffer[5] * 0x1000000;
+		break;
+
+	      default:
+		strcpy (tp, "bug");
+		tp += 3;
+		number = 42;
+	      }
+
+	    if ((*cs == 'z' && (insn & 0x20))
+		|| (opcodep->match == BDAP_QUICK_OPCODE
+		    && (nbytes <= 2 || buffer[1 + nbytes] == 0)))
+	      tp = format_dec (number, tp, signedp);
+	    else
+	      {
+		unsigned int highbyte = (number >> 24) & 0xff;
+
+		/* Either output this as an address or as a number.  If it's
+		   a dword with the same high-byte as the address of the
+		   insn, assume it's an address, and also if it's a non-zero
+		   non-0xff high-byte.  If this is a jsr or a jump, then
+		   it's definitely an address.  */
+		if (nbytes == 4
+		    && (highbyte == ((addr >> 24) & 0xff)
+			|| (highbyte != 0 && highbyte != 0xff)
+			|| info->insn_type == dis_branch
+			|| info->insn_type == dis_jsr))
+		  {
+		    /* Finish off and output previous formatted bytes.  */
+		    *tp = 0;
+		    tp = temp;
+		    if (temp[0])
+		      (*info->fprintf_func) (info->stream, "%s", temp);
+
+		    (*info->print_address_func) ((bfd_vma) number, info);
+
+		    info->target = number;
+		  }
+		else
+		  tp = format_hex (number, tp, disdata);
+	      }
+	  }
+	else
+	  {
+	    /* Not an immediate number.  Then this is a (possibly
+	       prefixed) memory operand.  */
+	    if (info->insn_type != dis_nonbranch)
+	      {
+		int mode_size
+		  = 1 << ((insn >> 4)
+			  & (opcodep->args[0] == 'z' ? 1 : 3));
+		int size;
+		info->insn_type = dis_dref;
+		info->flags |= CRIS_DIS_FLAG_MEMREF;
+
+		if (opcodep->imm_oprnd_size == SIZE_FIX_32)
+		  size = 4;
+		else if (opcodep->imm_oprnd_size == SIZE_SPEC_REG)
+		  {
+		    const struct cris_spec_reg *sregp
+		      = spec_reg_info ((insn >> 12) & 15, disdata->distype);
+
+		    /* FIXME: Improve error handling; should have been caught
+		       earlier.  */
+		    if (sregp == NULL)
+		      size = 4;
+		    else
+		      size = sregp->reg_size;
+		  }
+		else
+		  size = mode_size;
+
+		info->data_size = size;
+	      }
+
+	    *tp++ = '[';
+
+	    if (prefix_opcodep
+		/* We don't match dip with a postincremented field
+		   as a side-effect address mode.  */
+		&& ((insn & 0x400) == 0
+		    || prefix_opcodep->match != DIP_OPCODE))
+	      {
+		if (insn & 0x400)
+		  {
+		    tp = format_reg (disdata, insn & 15, tp, with_reg_prefix);
+		    *tp++ = '=';
+		  }
+
+
+		/* We mainly ignore the prefix format string when the
+		   address-mode syntax is output.  */
+		switch (prefix_opcodep->match)
+		  {
+		  case DIP_OPCODE:
+		    /* It's [r], [r+] or [pc+].  */
+		    if ((prefix_insn & 0x400) && (prefix_insn & 15) == 15)
+		      {
+			/* It's [pc+].  This cannot possibly be anything
+			   but an address.  */
+			unsigned long number
+			  = prefix_buffer[2] + prefix_buffer[3] * 256
+			  + prefix_buffer[4] * 65536
+			  + prefix_buffer[5] * 0x1000000;
+
+			info->target = (bfd_vma) number;
+
+			/* Finish off and output previous formatted
+			   data.  */
+			*tp = 0;
+			tp = temp;
+			if (temp[0])
+			  (*info->fprintf_func) (info->stream, "%s", temp);
+
+			(*info->print_address_func) ((bfd_vma) number, info);
+		      }
+		    else
+		      {
+			/* For a memref in an address, we use target2.
+			   In this case, target is zero.  */
+			info->flags
+			  |= (CRIS_DIS_FLAG_MEM_TARGET2_IS_REG
+			      | CRIS_DIS_FLAG_MEM_TARGET2_MEM);
+
+			info->target2 = prefix_insn & 15;
+
+			*tp++ = '[';
+			tp = format_reg (disdata, prefix_insn & 15, tp,
+					 with_reg_prefix);
+			if (prefix_insn & 0x400)
+			  *tp++ = '+';
+			*tp++ = ']';
+		      }
+		    break;
+
+		  case BDAP_QUICK_OPCODE:
+		    {
+		      int number;
+
+		      number = prefix_buffer[0];
+		      if (number > 127)
+			number -= 256;
+
+		      /* Output "reg+num" or, if num < 0, "reg-num".  */
+		      tp = format_reg (disdata, (prefix_insn >> 12) & 15, tp,
+				       with_reg_prefix);
+		      if (number >= 0)
+			*tp++ = '+';
+		      tp = format_dec (number, tp, 1);
+
+		      info->flags |= CRIS_DIS_FLAG_MEM_TARGET_IS_REG;
+		      info->target = (prefix_insn >> 12) & 15;
+		      info->target2 = (bfd_vma) number;
+		      break;
+		    }
+
+		  case BIAP_OPCODE:
+		    /* Output "r+R.m".  */
+		    tp = format_reg (disdata, prefix_insn & 15, tp,
+				     with_reg_prefix);
+		    *tp++ = '+';
+		    tp = format_reg (disdata, (prefix_insn >> 12) & 15, tp,
+				     with_reg_prefix);
+		    *tp++ = '.';
+		    *tp++ = mode_char[(prefix_insn >> 4) & 3];
+
+		    info->flags
+		      |= (CRIS_DIS_FLAG_MEM_TARGET2_IS_REG
+			  | CRIS_DIS_FLAG_MEM_TARGET_IS_REG
+
+			  | ((prefix_insn & 0x8000)
+			     ? CRIS_DIS_FLAG_MEM_TARGET2_MULT4
+			     : ((prefix_insn & 0x8000)
+				? CRIS_DIS_FLAG_MEM_TARGET2_MULT2 : 0)));
+
+		    /* Is it the casejump?  It's a "adds.w [pc+r%d.w],pc".  */
+		    if (insn == 0xf83f && (prefix_insn & ~0xf000) == 0x55f)
+		      /* Then start interpreting data as offsets.  */
+		      case_offset_counter = no_of_case_offsets;
+		    break;
+
+		  case BDAP_INDIR_OPCODE:
+		    /* Output "r+s.m", or, if "s" is [pc+], "r+s" or
+		       "r-s".  */
+		    tp = format_reg (disdata, (prefix_insn >> 12) & 15, tp,
+				     with_reg_prefix);
+
+		    if ((prefix_insn & 0x400) && (prefix_insn & 15) == 15)
+		      {
+			long number;
+			unsigned int nbytes;
+
+			/* It's a value.  Get its size.  */
+			int mode_size = 1 << ((prefix_insn >> 4) & 3);
+
+			if (mode_size == 1)
+			  nbytes = 2;
+			else
+			  nbytes = mode_size;
+
+			switch (nbytes)
+			  {
+			  case 1:
+			    number = prefix_buffer[2];
+			    if (number > 127)
+			      number -= 256;
+			    break;
+
+			  case 2:
+			    number = prefix_buffer[2] + prefix_buffer[3] * 256;
+			    if (number > 32767)
+			      number -= 65536;
+			    break;
+
+			  case 4:
+			    number
+			      = prefix_buffer[2] + prefix_buffer[3] * 256
+			      + prefix_buffer[4] * 65536
+			      + prefix_buffer[5] * 0x1000000;
+			    break;
+
+			  default:
+			    strcpy (tp, "bug");
+			    tp += 3;
+			    number = 42;
+			  }
+
+			info->flags |= CRIS_DIS_FLAG_MEM_TARGET_IS_REG;
+			info->target2 = (bfd_vma) number;
+
+			/* If the size is dword, then assume it's an
+			   address.  */
+			if (nbytes == 4)
+			  {
+			    /* Finish off and output previous formatted
+			       bytes.  */
+			    *tp++ = '+';
+			    *tp = 0;
+			    tp = temp;
+			    (*info->fprintf_func) (info->stream, "%s", temp);
+
+			    (*info->print_address_func) ((bfd_vma) number, info);
+			  }
+			else
+			  {
+			    if (number >= 0)
+			      *tp++ = '+';
+			    tp = format_dec (number, tp, 1);
+			  }
+		      }
+		    else
+		      {
+			/* Output "r+[R].m" or "r+[R+].m".  */
+			*tp++ = '+';
+			*tp++ = '[';
+			tp = format_reg (disdata, prefix_insn & 15, tp,
+					 with_reg_prefix);
+			if (prefix_insn & 0x400)
+			  *tp++ = '+';
+			*tp++ = ']';
+			*tp++ = '.';
+			*tp++ = mode_char[(prefix_insn >> 4) & 3];
+
+			info->flags
+			  |= (CRIS_DIS_FLAG_MEM_TARGET2_IS_REG
+			      | CRIS_DIS_FLAG_MEM_TARGET2_MEM
+			      | CRIS_DIS_FLAG_MEM_TARGET_IS_REG
+
+			      | (((prefix_insn >> 4) == 2)
+				 ? 0
+				 : (((prefix_insn >> 4) & 3) == 1
+				    ? CRIS_DIS_FLAG_MEM_TARGET2_MEM_WORD
+				    : CRIS_DIS_FLAG_MEM_TARGET2_MEM_BYTE)));
+		      }
+		    break;
+
+		  default:
+		    (*info->fprintf_func) (info->stream, "?prefix-bug");
+		  }
+
+		/* To mark that the prefix is used, reset it.  */
+		prefix_opcodep = NULL;
+	      }
+	    else
+	      {
+		tp = format_reg (disdata, insn & 15, tp, with_reg_prefix);
+
+		info->flags |= CRIS_DIS_FLAG_MEM_TARGET_IS_REG;
+		info->target = insn & 15;
+
+		if (insn & 0x400)
+		  *tp++ = '+';
+	      }
+	    *tp++ = ']';
+	  }
+	break;
+
+      case 'x':
+	tp = format_reg (disdata, (insn >> 12) & 15, tp, with_reg_prefix);
+	*tp++ = '.';
+	*tp++ = mode_char[(insn >> 4) & 3];
+	break;
+
+      case 'I':
+	tp = format_dec (insn & 63, tp, 0);
+	break;
+
+      case 'b':
+	{
+	  int where = buffer[2] + buffer[3] * 256;
+
+	  if (where > 32767)
+	    where -= 65536;
+
+	  where += addr + ((disdata->distype == cris_dis_v32) ? 0 : 4);
+
+	  if (insn == BA_PC_INCR_OPCODE)
+	    info->insn_type = dis_branch;
+	  else
+	    info->insn_type = dis_condbranch;
+
+	  info->target = (bfd_vma) where;
+
+	  *tp = 0;
+	  tp = temp;
+	  (*info->fprintf_func) (info->stream, "%s%s ",
+				 temp, cris_cc_strings[insn >> 12]);
+
+	  (*info->print_address_func) ((bfd_vma) where, info);
+	}
+      break;
+
+    case 'c':
+      tp = format_dec (insn & 31, tp, 0);
+      break;
+
+    case 'C':
+      tp = format_dec (insn & 15, tp, 0);
+      break;
+
+    case 'o':
+      {
+	long offset = insn & 0xfe;
+	bfd_vma target;
+
+	if (insn & 1)
+	  offset |= ~0xff;
+
+	if (opcodep->match == BA_QUICK_OPCODE)
+	  info->insn_type = dis_branch;
+	else
+	  info->insn_type = dis_condbranch;
+
+	target = addr + ((disdata->distype == cris_dis_v32) ? 0 : 2) + offset;
+	info->target = target;
+	*tp = 0;
+	tp = temp;
+	(*info->fprintf_func) (info->stream, "%s", temp);
+	(*info->print_address_func) (target, info);
+      }
+      break;
+
+    case 'Q':
+    case 'O':
+      {
+	long number = buffer[0];
+
+	if (number > 127)
+	  number = number - 256;
+
+	tp = format_dec (number, tp, 1);
+	*tp++ = ',';
+	tp = format_reg (disdata, (insn >> 12) & 15, tp, with_reg_prefix);
+      }
+      break;
+
+    case 'f':
+      tp = print_flags (disdata, insn, tp);
+      break;
+
+    case 'i':
+      tp = format_dec ((insn & 32) ? (insn & 31) | ~31L : insn & 31, tp, 1);
+      break;
+
+    case 'P':
+      {
+	const struct cris_spec_reg *sregp
+	  = spec_reg_info ((insn >> 12) & 15, disdata->distype);
+
+	if (sregp->name == NULL)
+	  /* Should have been caught as a non-match eariler.  */
+	  *tp++ = '?';
+	else
+	  {
+	    if (with_reg_prefix)
+	      *tp++ = REGISTER_PREFIX_CHAR;
+	    strcpy (tp, sregp->name);
+	    tp += strlen (tp);
+	  }
+      }
+      break;
+
+    default:
+      strcpy (tp, "???");
+      tp += 3;
+    }
+  }
+
+  *tp = 0;
+
+  if (prefix_opcodep)
+    (*info->fprintf_func) (info->stream, " (OOPS unused prefix \"%s: %s\")",
+			   prefix_opcodep->name, prefix_opcodep->args);
+
+  (*info->fprintf_func) (info->stream, "%s", temp);
+
+  /* Get info for matching case-tables, if we don't have any active.
+     We assume that the last constant seen is used; either in the insn
+     itself or in a "move.d const,rN, sub.d rN,rM"-like sequence.  */
+  if (TRACE_CASE && case_offset_counter == 0)
+    {
+      if (CONST_STRNEQ (opcodep->name, "sub"))
+	case_offset = last_immediate;
+
+      /* It could also be an "add", if there are negative case-values.  */
+      else if (CONST_STRNEQ (opcodep->name, "add"))
+	/* The first case is the negated operand to the add.  */
+	case_offset = -last_immediate;
+
+      /* A bound insn will tell us the number of cases.  */
+      else if (CONST_STRNEQ (opcodep->name, "bound"))
+	no_of_case_offsets = last_immediate + 1;
+
+      /* A jump or jsr or branch breaks the chain of insns for a
+	 case-table, so assume default first-case again.  */
+      else if (info->insn_type == dis_jsr
+	       || info->insn_type == dis_branch
+	       || info->insn_type == dis_condbranch)
+	case_offset = 0;
+    }
+}
+
+
+/* Print the CRIS instruction at address memaddr on stream.  Returns
+   length of the instruction, in bytes.  Prefix register names with `$' if
+   WITH_REG_PREFIX.  */
+
+static int
+print_insn_cris_generic (bfd_vma memaddr,
+			 disassemble_info *info,
+			 bfd_boolean with_reg_prefix)
+{
+  int nbytes;
+  unsigned int insn;
+  const struct cris_opcode *matchedp;
+  int advance = 0;
+  struct cris_disasm_data *disdata
+    = (struct cris_disasm_data *) info->private_data;
+
+  /* No instruction will be disassembled as longer than this number of
+     bytes; stacked prefixes will not be expanded.  */
+  unsigned char buffer[MAX_BYTES_PER_CRIS_INSN];
+  unsigned char *bufp;
+  int status = 0;
+  bfd_vma addr;
+
+  /* There will be an "out of range" error after the last instruction.
+     Reading pairs of bytes in decreasing number, we hope that we will get
+     at least the amount that we will consume.
+
+     If we can't get any data, or we do not get enough data, we print
+     the error message.  */
+
+  for (nbytes = MAX_BYTES_PER_CRIS_INSN; nbytes > 0; nbytes -= 2)
+    {
+      status = (*info->read_memory_func) (memaddr, buffer, nbytes, info);
+      if (status == 0)
+	break;
+    }
+
+  /* If we did not get all we asked for, then clear the rest.
+     Hopefully this makes a reproducible result in case of errors.  */
+  if (nbytes != MAX_BYTES_PER_CRIS_INSN)
+    memset (buffer + nbytes, 0, MAX_BYTES_PER_CRIS_INSN - nbytes);
+
+  addr = memaddr;
+  bufp = buffer;
+
+  /* Set some defaults for the insn info.  */
+  info->insn_info_valid = 1;
+  info->branch_delay_insns = 0;
+  info->data_size = 0;
+  info->insn_type = dis_nonbranch;
+  info->flags = 0;
+  info->target = 0;
+  info->target2 = 0;
+
+  /* If we got any data, disassemble it.  */
+  if (nbytes != 0)
+    {
+      matchedp = NULL;
+
+      insn = bufp[0] + bufp[1] * 256;
+
+      /* If we're in a case-table, don't disassemble the offsets.  */
+      if (TRACE_CASE && case_offset_counter != 0)
+	{
+	  info->insn_type = dis_noninsn;
+	  advance += 2;
+
+	  /* If to print data as offsets, then shortcut here.  */
+	  (*info->fprintf_func) (info->stream, "case %ld%s: -> ",
+				 case_offset + no_of_case_offsets
+				 - case_offset_counter,
+				 case_offset_counter == 1 ? "/default" :
+				 "");
+
+	  (*info->print_address_func) ((bfd_vma)
+				       ((short) (insn)
+					+ (long) (addr
+						  - (no_of_case_offsets
+						     - case_offset_counter)
+						  * 2)), info);
+	  case_offset_counter--;
+
+	  /* The default case start (without a "sub" or "add") must be
+	     zero.  */
+	  if (case_offset_counter == 0)
+	    case_offset = 0;
+	}
+      else if (insn == 0)
+	{
+	  /* We're often called to disassemble zeroes.  While this is a
+	     valid "bcc .+2" insn, it is also useless enough and enough
+	     of a nuiscance that we will just output "bcc .+2" for it
+	     and signal it as a noninsn.  */
+	  (*info->fprintf_func) (info->stream,
+				 disdata->distype == cris_dis_v32
+				 ? "bcc ." : "bcc .+2");
+	  info->insn_type = dis_noninsn;
+	  advance += 2;
+	}
+      else
+	{
+	  const struct cris_opcode *prefix_opcodep = NULL;
+	  unsigned char *prefix_buffer = bufp;
+	  unsigned int prefix_insn = insn;
+	  int prefix_size = 0;
+
+	  matchedp = get_opcode_entry (insn, NO_CRIS_PREFIX, disdata);
+
+	  /* Check if we're supposed to write out prefixes as address
+	     modes and if this was a prefix.  */
+	  if (matchedp != NULL && PARSE_PREFIX && matchedp->args[0] == 'p')
+	    {
+	      /* If it's a prefix, put it into the prefix vars and get the
+		 main insn.  */
+	      prefix_size = bytes_to_skip (prefix_insn, matchedp,
+					   disdata->distype, NULL);
+	      prefix_opcodep = matchedp;
+
+	      insn = bufp[prefix_size] + bufp[prefix_size + 1] * 256;
+	      matchedp = get_opcode_entry (insn, prefix_insn, disdata);
+
+	      if (matchedp != NULL)
+		{
+		  addr += prefix_size;
+		  bufp += prefix_size;
+		  advance += prefix_size;
+		}
+	      else
+		{
+		  /* The "main" insn wasn't valid, at least not when
+		     prefixed.  Put back things enough to output the
+		     prefix insn only, as a normal insn.  */
+		  matchedp = prefix_opcodep;
+		  insn = prefix_insn;
+		  prefix_opcodep = NULL;
+		}
+	    }
+
+	  if (matchedp == NULL)
+	    {
+	      (*info->fprintf_func) (info->stream, "??0x%x", insn);
+	      advance += 2;
+
+	      info->insn_type = dis_noninsn;
+	    }
+	  else
+	    {
+	      advance
+		+= bytes_to_skip (insn, matchedp, disdata->distype,
+				  prefix_opcodep);
+
+	      /* The info_type and assorted fields will be set according
+		 to the operands.   */
+	      print_with_operands (matchedp, insn, bufp, addr, info,
+				   prefix_opcodep, prefix_insn,
+				   prefix_buffer, with_reg_prefix);
+	    }
+	}
+    }
+  else
+    info->insn_type = dis_noninsn;
+
+  /* If we read less than MAX_BYTES_PER_CRIS_INSN, i.e. we got an error
+     status when reading that much, and the insn decoding indicated a
+     length exceeding what we read, there is an error.  */
+  if (status != 0 && (nbytes == 0 || advance > nbytes))
+    {
+      (*info->memory_error_func) (status, memaddr, info);
+      return -1;
+    }
+
+  /* Max supported insn size with one folded prefix insn.  */
+  info->bytes_per_line = MAX_BYTES_PER_CRIS_INSN;
+
+  /* I would like to set this to a fixed value larger than the actual
+     number of bytes to print in order to avoid spaces between bytes,
+     but objdump.c (2.9.1) does not like that, so we print 16-bit
+     chunks, which is the next choice.  */
+  info->bytes_per_chunk = 2;
+
+  /* Printing bytes in order of increasing addresses makes sense,
+     especially on a little-endian target.
+     This is completely the opposite of what you think; setting this to
+     BFD_ENDIAN_LITTLE will print bytes in order N..0 rather than the 0..N
+     we want.  */
+  info->display_endian = BFD_ENDIAN_BIG;
+
+  return advance;
+}
+
+/* Disassemble, prefixing register names with `$'.  CRIS v0..v10.  */
+#if 0
+static int
+print_insn_cris_with_register_prefix (bfd_vma vma,
+				      disassemble_info *info)
+{
+  if (info->private_data == NULL
+      && !cris_parse_disassembler_options (info, cris_dis_v0_v10))
+    return -1;
+  return print_insn_cris_generic (vma, info, TRUE);
+}
+#endif
+/* Disassemble, prefixing register names with `$'.  CRIS v32.  */
+
+static int
+print_insn_crisv32_with_register_prefix (bfd_vma vma,
+					 disassemble_info *info)
+{
+  if (info->private_data == NULL
+      && !cris_parse_disassembler_options (info, cris_dis_v32))
+    return -1;
+  return print_insn_cris_generic (vma, info, TRUE);
+}
+
+#if 0
+/* Disassemble, prefixing register names with `$'.
+   Common v10 and v32 subset.  */
+
+static int
+print_insn_crisv10_v32_with_register_prefix (bfd_vma vma,
+					     disassemble_info *info)
+{
+  if (info->private_data == NULL
+      && !cris_parse_disassembler_options (info, cris_dis_common_v10_v32))
+    return -1;
+  return print_insn_cris_generic (vma, info, TRUE);
+}
+
+/* Disassemble, no prefixes on register names.  CRIS v0..v10.  */
+
+static int
+print_insn_cris_without_register_prefix (bfd_vma vma,
+					 disassemble_info *info)
+{
+  if (info->private_data == NULL
+      && !cris_parse_disassembler_options (info, cris_dis_v0_v10))
+    return -1;
+  return print_insn_cris_generic (vma, info, FALSE);
+}
+
+/* Disassemble, no prefixes on register names.  CRIS v32.  */
+
+static int
+print_insn_crisv32_without_register_prefix (bfd_vma vma,
+					    disassemble_info *info)
+{
+  if (info->private_data == NULL
+      && !cris_parse_disassembler_options (info, cris_dis_v32))
+    return -1;
+  return print_insn_cris_generic (vma, info, FALSE);
+}
+
+/* Disassemble, no prefixes on register names.
+   Common v10 and v32 subset.  */
+
+static int
+print_insn_crisv10_v32_without_register_prefix (bfd_vma vma,
+						disassemble_info *info)
+{
+  if (info->private_data == NULL
+      && !cris_parse_disassembler_options (info, cris_dis_common_v10_v32))
+    return -1;
+  return print_insn_cris_generic (vma, info, FALSE);
+}
+#endif
+
+int
+print_insn_crisv32 (bfd_vma vma,
+		    disassemble_info *info)
+{
+  return print_insn_crisv32_with_register_prefix(vma, info);
+}
+
+/* Return a disassembler-function that prints registers with a `$' prefix,
+   or one that prints registers without a prefix.
+   FIXME: We should improve the solution to avoid the multitude of
+   functions seen above.  */
+#if 0
+disassembler_ftype
+cris_get_disassembler (bfd *abfd)
+{
+  /* If there's no bfd in sight, we return what is valid as input in all
+     contexts if fed back to the assembler: disassembly *with* register
+     prefix.  Unfortunately this will be totally wrong for v32.  */
+  if (abfd == NULL)
+    return print_insn_cris_with_register_prefix;
+
+  if (bfd_get_symbol_leading_char (abfd) == 0)
+    {
+      if (bfd_get_mach (abfd) == bfd_mach_cris_v32)
+	return print_insn_crisv32_with_register_prefix;
+      if (bfd_get_mach (abfd) == bfd_mach_cris_v10_v32)
+	return print_insn_crisv10_v32_with_register_prefix;
+
+      /* We default to v10.  This may be specifically specified in the
+	 bfd mach, but is also the default setting.  */
+      return print_insn_cris_with_register_prefix;
+    }
+
+  if (bfd_get_mach (abfd) == bfd_mach_cris_v32)
+    return print_insn_crisv32_without_register_prefix;
+  if (bfd_get_mach (abfd) == bfd_mach_cris_v10_v32)
+    return print_insn_crisv10_v32_without_register_prefix;
+  return print_insn_cris_without_register_prefix;
+}
+#endif
+/* Local variables:
+   eval: (c-set-style "gnu")
+   indent-tabs-mode: t
+   End:  */

Modified: trunk/src/host/qemu-neo1973/darwin-user/main.c
===================================================================
--- trunk/src/host/qemu-neo1973/darwin-user/main.c	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/darwin-user/main.c	2007-10-29 21:14:04 UTC (rev 3303)
@@ -124,47 +124,47 @@
     return cpu_ppc_get_tb(env) >> 32;
 }
 
-static void cpu_ppc_store_tb (CPUState *env, uint64_t value)
+uint32_t cpu_ppc_load_atbl (CPUState *env)
 {
-    /* TO FIX */
+    return cpu_ppc_get_tb(env) & 0xFFFFFFFF;
 }
 
-void cpu_ppc_store_tbu (CPUState *env, uint32_t value)
+uint32_t cpu_ppc_load_atbu (CPUState *env)
 {
-    cpu_ppc_store_tb(env, ((uint64_t)value << 32) | cpu_ppc_load_tbl(env));
+    return cpu_ppc_get_tb(env) >> 32;
 }
 
-void cpu_ppc_store_tbl (CPUState *env, uint32_t value)
+uint32_t cpu_ppc601_load_rtcu (CPUState *env)
 {
-    cpu_ppc_store_tb(env, ((uint64_t)cpu_ppc_load_tbl(env) << 32) | value);
+    cpu_ppc_load_tbu(env);
 }
 
-uint32_t cpu_ppc_load_decr (CPUState *env)
+uint32_t cpu_ppc601_load_rtcl (CPUState *env)
 {
-    /* TO FIX */
-    return -1;
+    return cpu_ppc_load_tbl(env) & 0x3FFFFF80;
 }
 
-void cpu_ppc_store_decr (CPUState *env, uint32_t value)
+/* XXX: to be fixed */
+int ppc_dcr_read (ppc_dcr_t *dcr_env, int dcrn, target_ulong *valp)
 {
-    /* TO FIX */
+    return -1;
 }
 
-void cpu_ppc601_store_rtcu (CPUState *env, uint32_t value)
+int ppc_dcr_write (ppc_dcr_t *dcr_env, int dcrn, target_ulong val)
 {
-    cpu_ppc_store_tbu( env, value );
+    return -1;
 }
 
-uint32_t cpu_ppc601_load_rtcu (CPUState *env)
-{
-    cpu_ppc_load_tbu(env);
-}
+#define EXCP_DUMP(env, fmt, args...)                                         \
+do {                                                                          \
+    fprintf(stderr, fmt , ##args);                                            \
+    cpu_dump_state(env, stderr, fprintf, 0);                                  \
+    if (loglevel != 0) {                                                      \
+        fprintf(logfile, fmt , ##args);                                       \
+        cpu_dump_state(env, logfile, fprintf, 0);                             \
+    }                                                                         \
+} while (0)
 
-uint32_t cpu_ppc601_load_rtcl (CPUState *env)
-{
-    return cpu_ppc_load_tbl(env) & 0x3FFFFF80;
-}
-
 void cpu_loop(CPUPPCState *env)
 {
     int trapnr;
@@ -173,271 +173,363 @@
 
     for(;;) {
         trapnr = cpu_ppc_exec(env);
-        if (trapnr != EXCP_SYSCALL_USER && trapnr != EXCP_BRANCH &&
-            trapnr != EXCP_TRACE) {
-            if (loglevel > 0) {
-                cpu_dump_state(env, logfile, fprintf, 0);
-            }
-        }
         switch(trapnr) {
-        case EXCP_NONE:
+        case POWERPC_EXCP_NONE:
+            /* Just go on */
             break;
-        case EXCP_SYSCALL_USER:
-            /* system call */
-            if(((int)env->gpr[0]) <= SYS_MAXSYSCALL && ((int)env->gpr[0])>0)
-                ret = do_unix_syscall(env, env->gpr[0]/*, env->gpr[3], env->gpr[4],
-                                      env->gpr[5], env->gpr[6], env->gpr[7],
-                                      env->gpr[8], env->gpr[9], env->gpr[10]*/);
-            else if(((int)env->gpr[0])<0)
-                ret = do_mach_syscall(env, env->gpr[0], env->gpr[3], env->gpr[4],
-                                      env->gpr[5], env->gpr[6], env->gpr[7],
-                                      env->gpr[8], env->gpr[9], env->gpr[10]);
-            else
-                ret = do_thread_syscall(env, env->gpr[0], env->gpr[3], env->gpr[4],
-                                        env->gpr[5], env->gpr[6], env->gpr[7],
-                                        env->gpr[8], env->gpr[9], env->gpr[10]);
-
-            /* Unix syscall error signaling */
-            if(((int)env->gpr[0]) <= SYS_MAXSYSCALL && ((int)env->gpr[0])>0)
-            {
-                if( (int)ret < 0 )
-                    env->nip += 0;
-                else
-                    env->nip += 4;
-            }
-
-            /* Return value */
-            env->gpr[3] = ret;
+        case POWERPC_EXCP_CRITICAL: /* Critical input                        */
+            cpu_abort(env, "Critical interrupt while in user mode. "
+                      "Aborting\n");
             break;
-        case EXCP_RESET:
-            /* Should not happen ! */
-            fprintf(stderr, "RESET asked... Stop emulation\n");
-            if (loglevel)
-                fprintf(logfile, "RESET asked... Stop emulation\n");
-                abort();
-        case EXCP_MACHINE_CHECK:
-            fprintf(stderr, "Machine check exeption...  Stop emulation\n");
-            if (loglevel)
-                fprintf(logfile, "RESET asked... Stop emulation\n");
-                info.si_signo = SIGBUS;
-            info.si_errno = 0;
-            info.si_code = BUS_OBJERR;
-            info.si_addr = (void*)(env->nip - 4);
-            queue_signal(info.si_signo, &info);
-        case EXCP_DSI:
+        case POWERPC_EXCP_MCHECK:   /* Machine check exception               */
+            cpu_abort(env, "Machine check exception while in user mode. "
+                      "Aborting\n");
+            break;
+        case POWERPC_EXCP_DSI:      /* Data storage exception                */
 #ifndef DAR
 /* To deal with multiple qemu header version as host for the darwin-user code */
 # define DAR SPR_DAR
 #endif
-            fprintf(stderr, "Invalid data memory access: 0x%08x\n", env->spr[DAR]);
-            if (loglevel) {
-                fprintf(logfile, "Invalid data memory access: 0x%08x\n",
-                        env->spr[DAR]);
-            }
+            EXCP_DUMP(env, "Invalid data memory access: 0x" ADDRX "\n",
+                      env->spr[SPR_DAR]);
             /* Handle this via the gdb */
             gdb_handlesig (env, SIGSEGV);
 
             info.si_addr = (void*)env->nip;
             queue_signal(info.si_signo, &info);
             break;
-        case EXCP_ISI:
-            fprintf(stderr, "Invalid instruction fetch\n");
-            if (loglevel)
-                fprintf(logfile, "Invalid instruction fetch\n");
+        case POWERPC_EXCP_ISI:      /* Instruction storage exception         */
+            EXCP_DUMP(env, "Invalid instruction fetch: 0x\n" ADDRX "\n",
+                      env->spr[SPR_DAR]);
             /* Handle this via the gdb */
             gdb_handlesig (env, SIGSEGV);
 
             info.si_addr = (void*)(env->nip - 4);
             queue_signal(info.si_signo, &info);
             break;
-        case EXCP_EXTERNAL:
-            /* Should not happen ! */
-            fprintf(stderr, "External interruption... Stop emulation\n");
-            if (loglevel)
-                fprintf(logfile, "External interruption... Stop emulation\n");
-                abort();
-        case EXCP_ALIGN:
-            fprintf(stderr, "Invalid unaligned memory access\n");
-            if (loglevel)
-                fprintf(logfile, "Invalid unaligned memory access\n");
-                info.si_signo = SIGBUS;
+        case POWERPC_EXCP_EXTERNAL: /* External input                        */
+            cpu_abort(env, "External interrupt while in user mode. "
+                      "Aborting\n");
+            break;
+        case POWERPC_EXCP_ALIGN:    /* Alignment exception                   */
+            EXCP_DUMP(env, "Unaligned memory access\n");
             info.si_errno = 0;
             info.si_code = BUS_ADRALN;
             info.si_addr = (void*)(env->nip - 4);
             queue_signal(info.si_signo, &info);
             break;
-        case EXCP_PROGRAM:
+        case POWERPC_EXCP_PROGRAM:  /* Program exception                     */
+            /* XXX: check this */
             switch (env->error_code & ~0xF) {
-                case EXCP_FP:
-                    fprintf(stderr, "Program exception\n");
-                    if (loglevel)
-                        fprintf(logfile, "Program exception\n");
-                        /* Set FX */
-                        env->fpscr[7] |= 0x8;
-                    /* Finally, update FEX */
-                    if ((((env->fpscr[7] & 0x3) << 3) | (env->fpscr[6] >> 1)) &
-                        ((env->fpscr[1] << 1) | (env->fpscr[0] >> 3)))
-                        env->fpscr[7] |= 0x4;
-                        info.si_signo = SIGFPE;
-                    info.si_errno = 0;
-                    switch (env->error_code & 0xF) {
-                        case EXCP_FP_OX:
-                            info.si_code = FPE_FLTOVF;
-                            break;
-                        case EXCP_FP_UX:
-                            info.si_code = FPE_FLTUND;
-                            break;
-                        case EXCP_FP_ZX:
-                        case EXCP_FP_VXZDZ:
-                            info.si_code = FPE_FLTDIV;
-                            break;
-                        case EXCP_FP_XX:
-                            info.si_code = FPE_FLTRES;
-                            break;
-                        case EXCP_FP_VXSOFT:
-                            info.si_code = FPE_FLTINV;
-                            break;
-                        case EXCP_FP_VXNAN:
-                        case EXCP_FP_VXISI:
-                        case EXCP_FP_VXIDI:
-                        case EXCP_FP_VXIMZ:
-                        case EXCP_FP_VXVC:
-                        case EXCP_FP_VXSQRT:
-                        case EXCP_FP_VXCVI:
-                            info.si_code = FPE_FLTSUB;
-                            break;
-                        default:
-                            fprintf(stderr, "Unknown floating point exception "
-                                    "(%02x)\n", env->error_code);
-                            if (loglevel) {
-                                fprintf(logfile, "Unknown floating point exception "
-                                        "(%02x)\n", env->error_code & 0xF);
-                            }
-                    }
-                        break;
-                case EXCP_INVAL:
-                    fprintf(stderr, "Invalid instruction\n");
-                    if (loglevel)
-                        fprintf(logfile, "Invalid instruction\n");
-                        info.si_signo = SIGILL;
-                    info.si_errno = 0;
-                    switch (env->error_code & 0xF) {
-                        case EXCP_INVAL_INVAL:
-                            info.si_code = ILL_ILLOPC;
-                            break;
-                        case EXCP_INVAL_LSWX:
-                            info.si_code = ILL_ILLOPN;
-                            break;
-                        case EXCP_INVAL_SPR:
-                            info.si_code = ILL_PRVREG;
-                            break;
-                        case EXCP_INVAL_FP:
-                            info.si_code = ILL_COPROC;
-                            break;
-                        default:
-                            fprintf(stderr, "Unknown invalid operation (%02x)\n",
-                                    env->error_code & 0xF);
-                            if (loglevel) {
-                                fprintf(logfile, "Unknown invalid operation (%02x)\n",
-                                        env->error_code & 0xF);
-                            }
-                                info.si_code = ILL_ILLADR;
-                            break;
-                    }
-                        /* Handle this via the gdb */
-                        gdb_handlesig (env, SIGSEGV);
+            case POWERPC_EXCP_FP:
+                EXCP_DUMP(env, "Floating point program exception\n");
+                /* Set FX */
+                info.si_signo = SIGFPE;
+                info.si_errno = 0;
+                switch (env->error_code & 0xF) {
+                case POWERPC_EXCP_FP_OX:
+                    info.si_code = FPE_FLTOVF;
                     break;
-                case EXCP_PRIV:
-                    fprintf(stderr, "Privilege violation\n");
-                    if (loglevel)
-                        fprintf(logfile, "Privilege violation\n");
-                        info.si_signo = SIGILL;
-                    info.si_errno = 0;
-                    switch (env->error_code & 0xF) {
-                        case EXCP_PRIV_OPC:
-                            info.si_code = ILL_PRVOPC;
-                            break;
-                        case EXCP_PRIV_REG:
-                            info.si_code = ILL_PRVREG;
-                            break;
-                        default:
-                            fprintf(stderr, "Unknown privilege violation (%02x)\n",
-                                    env->error_code & 0xF);
-                            info.si_code = ILL_PRVOPC;
-                            break;
-                    }
-                        break;
-                case EXCP_TRAP:
-                    fprintf(stderr, "Tried to call a TRAP\n");
-                    if (loglevel)
-                        fprintf(logfile, "Tried to call a TRAP\n");
-                        abort();
+                case POWERPC_EXCP_FP_UX:
+                    info.si_code = FPE_FLTUND;
+                    break;
+                case POWERPC_EXCP_FP_ZX:
+                case POWERPC_EXCP_FP_VXZDZ:
+                    info.si_code = FPE_FLTDIV;
+                    break;
+                case POWERPC_EXCP_FP_XX:
+                    info.si_code = FPE_FLTRES;
+                    break;
+                case POWERPC_EXCP_FP_VXSOFT:
+                    info.si_code = FPE_FLTINV;
+                    break;
+                case POWERPC_EXCP_FP_VXSNAN:
+                case POWERPC_EXCP_FP_VXISI:
+                case POWERPC_EXCP_FP_VXIDI:
+                case POWERPC_EXCP_FP_VXIMZ:
+                case POWERPC_EXCP_FP_VXVC:
+                case POWERPC_EXCP_FP_VXSQRT:
+                case POWERPC_EXCP_FP_VXCVI:
+                    info.si_code = FPE_FLTSUB;
+                    break;
                 default:
-                    /* Should not happen ! */
-                    fprintf(stderr, "Unknown program exception (%02x)\n",
-                            env->error_code);
-                    if (loglevel) {
-                        fprintf(logfile, "Unknwon program exception (%02x)\n",
-                                env->error_code);
-                    }
-                        abort();
+                    EXCP_DUMP(env, "Unknown floating point exception (%02x)\n",
+                              env->error_code);
+                    break;
+                }
+                break;
+            case POWERPC_EXCP_INVAL:
+                EXCP_DUMP(env, "Invalid instruction\n");
+                info.si_signo = SIGILL;
+                info.si_errno = 0;
+                switch (env->error_code & 0xF) {
+                case POWERPC_EXCP_INVAL_INVAL:
+                    info.si_code = ILL_ILLOPC;
+                    break;
+                case POWERPC_EXCP_INVAL_LSWX:
+                    info.si_code = ILL_ILLOPN;
+                    break;
+                case POWERPC_EXCP_INVAL_SPR:
+                    info.si_code = ILL_PRVREG;
+                    break;
+                case POWERPC_EXCP_INVAL_FP:
+                    info.si_code = ILL_COPROC;
+                    break;
+                default:
+                    EXCP_DUMP(env, "Unknown invalid operation (%02x)\n",
+                              env->error_code & 0xF);
+                    info.si_code = ILL_ILLADR;
+                    break;
+                }
+                /* Handle this via the gdb */
+                gdb_handlesig (env, SIGSEGV);
+                break;
+            case POWERPC_EXCP_PRIV:
+                EXCP_DUMP(env, "Privilege violation\n");
+                info.si_signo = SIGILL;
+                info.si_errno = 0;
+                switch (env->error_code & 0xF) {
+                case POWERPC_EXCP_PRIV_OPC:
+                    info.si_code = ILL_PRVOPC;
+                    break;
+                case POWERPC_EXCP_PRIV_REG:
+                    info.si_code = ILL_PRVREG;
+                    break;
+                default:
+                    EXCP_DUMP(env, "Unknown privilege violation (%02x)\n",
+                              env->error_code & 0xF);
+                    info.si_code = ILL_PRVOPC;
+                    break;
+                }
+                break;
+            case POWERPC_EXCP_TRAP:
+                cpu_abort(env, "Tried to call a TRAP\n");
+                break;
+            default:
+                /* Should not happen ! */
+                cpu_abort(env, "Unknown program exception (%02x)\n",
+                          env->error_code);
+                break;
             }
             info.si_addr = (void*)(env->nip - 4);
             queue_signal(info.si_signo, &info);
             break;
-        case EXCP_NO_FP:
-            fprintf(stderr, "No floating point allowed\n");
-            if (loglevel)
-                fprintf(logfile, "No floating point allowed\n");
-                info.si_signo = SIGILL;
+        case POWERPC_EXCP_FPU:      /* Floating-point unavailable exception  */
+            EXCP_DUMP(env, "No floating point allowed\n");
+            info.si_signo = SIGILL;
             info.si_errno = 0;
             info.si_code = ILL_COPROC;
             info.si_addr = (void*)(env->nip - 4);
             queue_signal(info.si_signo, &info);
             break;
-        case EXCP_DECR:
-            /* Should not happen ! */
-            fprintf(stderr, "Decrementer exception\n");
-            if (loglevel)
-                fprintf(logfile, "Decrementer exception\n");
-            abort();
-        case EXCP_TRACE:
-            /* Pass to gdb: we use this to trace execution */
+        case POWERPC_EXCP_SYSCALL:  /* System call exception                 */
+            cpu_abort(env, "Syscall exception while in user mode. "
+                      "Aborting\n");
+            break;
+        case POWERPC_EXCP_APU:      /* Auxiliary processor unavailable       */
+            EXCP_DUMP(env, "No APU instruction allowed\n");
+            info.si_signo = SIGILL;
+            info.si_errno = 0;
+            info.si_code = ILL_COPROC;
+            info.si_addr = (void*)(env->nip - 4);
+            queue_signal(info.si_signo, &info);
+            break;
+        case POWERPC_EXCP_DECR:     /* Decrementer exception                 */
+            cpu_abort(env, "Decrementer interrupt while in user mode. "
+                      "Aborting\n");
+            break;
+        case POWERPC_EXCP_FIT:      /* Fixed-interval timer interrupt        */
+            cpu_abort(env, "Fix interval timer interrupt while in user mode. "
+                      "Aborting\n");
+            break;
+        case POWERPC_EXCP_WDT:      /* Watchdog timer interrupt              */
+            cpu_abort(env, "Watchdog timer interrupt while in user mode. "
+                      "Aborting\n");
+            break;
+        case POWERPC_EXCP_DTLB:     /* Data TLB error                        */
+            cpu_abort(env, "Data TLB exception while in user mode. "
+                      "Aborting\n");
+            break;
+        case POWERPC_EXCP_ITLB:     /* Instruction TLB error                 */
+            cpu_abort(env, "Instruction TLB exception while in user mode. "
+                      "Aborting\n");
+            break;
+        case POWERPC_EXCP_DEBUG:    /* Debug interrupt                       */
             gdb_handlesig (env, SIGTRAP);
             break;
-        case EXCP_FP_ASSIST:
-            /* Should not happen ! */
-            fprintf(stderr, "Floating point assist exception\n");
-            if (loglevel)
-                fprintf(logfile, "Floating point assist exception\n");
-            abort();
-        case EXCP_MTMSR:
-            /* We reloaded the msr, just go on */
-            if (msr_pr == 0) {
-                fprintf(stderr, "Tried to go into supervisor mode !\n");
-                if (loglevel)
-                    fprintf(logfile, "Tried to go into supervisor mode !\n");
-                abort();
+#if defined(TARGET_PPCEMB)
+        case POWERPC_EXCP_SPEU:     /* SPE/embedded floating-point unavail.  */
+            EXCP_DUMP(env, "No SPE/floating-point instruction allowed\n");
+            info.si_signo = SIGILL;
+            info.si_errno = 0;
+            info.si_code = ILL_COPROC;
+            info.si_addr = (void*)(env->nip - 4);
+            queue_signal(info.si_signo, &info);
+            break;
+        case POWERPC_EXCP_EFPDI:    /* Embedded floating-point data IRQ      */
+            cpu_abort(env, "Embedded floating-point data IRQ not handled\n");
+            break;
+        case POWERPC_EXCP_EFPRI:    /* Embedded floating-point round IRQ     */
+            cpu_abort(env, "Embedded floating-point round IRQ not handled\n");
+            break;
+        case POWERPC_EXCP_EPERFM:   /* Embedded performance monitor IRQ      */
+            cpu_abort(env, "Performance monitor exception not handled\n");
+            break;
+        case POWERPC_EXCP_DOORI:    /* Embedded doorbell interrupt           */
+            cpu_abort(env, "Doorbell interrupt while in user mode. "
+                       "Aborting\n");
+            break;
+        case POWERPC_EXCP_DOORCI:   /* Embedded doorbell critical interrupt  */
+            cpu_abort(env, "Doorbell critical interrupt while in user mode. "
+                      "Aborting\n");
+            break;
+#endif /* defined(TARGET_PPCEMB) */
+        case POWERPC_EXCP_RESET:    /* System reset exception                */
+            cpu_abort(env, "Reset interrupt while in user mode. "
+                      "Aborting\n");
+            break;
+#if defined(TARGET_PPC64) /* PowerPC 64 */
+        case POWERPC_EXCP_DSEG:     /* Data segment exception                */
+            cpu_abort(env, "Data segment exception while in user mode. "
+                      "Aborting\n");
+            break;
+        case POWERPC_EXCP_ISEG:     /* Instruction segment exception         */
+            cpu_abort(env, "Instruction segment exception "
+                      "while in user mode. Aborting\n");
+            break;
+#endif /* defined(TARGET_PPC64) */
+#if defined(TARGET_PPC64H) /* PowerPC 64 with hypervisor mode support */
+        case POWERPC_EXCP_HDECR:    /* Hypervisor decrementer exception      */
+            cpu_abort(env, "Hypervisor decrementer interrupt "
+                      "while in user mode. Aborting\n");
+            break;
+#endif /* defined(TARGET_PPC64H) */
+        case POWERPC_EXCP_TRACE:    /* Trace exception                       */
+            /* Nothing to do:
+             * we use this exception to emulate step-by-step execution mode.
+             */
+            break;
+#if defined(TARGET_PPC64H) /* PowerPC 64 with hypervisor mode support */
+        case POWERPC_EXCP_HDSI:     /* Hypervisor data storage exception     */
+            cpu_abort(env, "Hypervisor data storage exception "
+                      "while in user mode. Aborting\n");
+            break;
+        case POWERPC_EXCP_HISI:     /* Hypervisor instruction storage excp   */
+            cpu_abort(env, "Hypervisor instruction storage exception "
+                      "while in user mode. Aborting\n");
+            break;
+        case POWERPC_EXCP_HDSEG:    /* Hypervisor data segment exception     */
+            cpu_abort(env, "Hypervisor data segment exception "
+                      "while in user mode. Aborting\n");
+            break;
+        case POWERPC_EXCP_HISEG:    /* Hypervisor instruction segment excp   */
+            cpu_abort(env, "Hypervisor instruction segment exception "
+                      "while in user mode. Aborting\n");
+            break;
+#endif /* defined(TARGET_PPC64H) */
+        case POWERPC_EXCP_VPU:      /* Vector unavailable exception          */
+            EXCP_DUMP(env, "No Altivec instructions allowed\n");
+            info.si_signo = SIGILL;
+            info.si_errno = 0;
+            info.si_code = ILL_COPROC;
+            info.si_addr = (void*)(env->nip - 4);
+            queue_signal(info.si_signo, &info);
+            break;
+        case POWERPC_EXCP_PIT:      /* Programmable interval timer IRQ       */
+            cpu_abort(env, "Programable interval timer interrupt "
+                      "while in user mode. Aborting\n");
+            break;
+        case POWERPC_EXCP_IO:       /* IO error exception                    */
+            cpu_abort(env, "IO error exception while in user mode. "
+                      "Aborting\n");
+            break;
+        case POWERPC_EXCP_RUNM:     /* Run mode exception                    */
+            cpu_abort(env, "Run mode exception while in user mode. "
+                      "Aborting\n");
+            break;
+        case POWERPC_EXCP_EMUL:     /* Emulation trap exception              */
+            cpu_abort(env, "Emulation trap exception not handled\n");
+            break;
+        case POWERPC_EXCP_IFTLB:    /* Instruction fetch TLB error           */
+            cpu_abort(env, "Instruction fetch TLB exception "
+                      "while in user-mode. Aborting");
+            break;
+        case POWERPC_EXCP_DLTLB:    /* Data load TLB miss                    */
+            cpu_abort(env, "Data load TLB exception while in user-mode. "
+                      "Aborting");
+            break;
+        case POWERPC_EXCP_DSTLB:    /* Data store TLB miss                   */
+            cpu_abort(env, "Data store TLB exception while in user-mode. "
+                      "Aborting");
+            break;
+        case POWERPC_EXCP_FPA:      /* Floating-point assist exception       */
+            cpu_abort(env, "Floating-point assist exception not handled\n");
+            break;
+        case POWERPC_EXCP_IABR:     /* Instruction address breakpoint        */
+            cpu_abort(env, "Instruction address breakpoint exception "
+                      "not handled\n");
+            break;
+        case POWERPC_EXCP_SMI:      /* System management interrupt           */
+            cpu_abort(env, "System management interrupt while in user mode. "
+                      "Aborting\n");
+            break;
+        case POWERPC_EXCP_THERM:    /* Thermal interrupt                     */
+            cpu_abort(env, "Thermal interrupt interrupt while in user mode. "
+                      "Aborting\n");
+            break;
+        case POWERPC_EXCP_PERFM:    /* Embedded performance monitor IRQ      */
+            cpu_abort(env, "Performance monitor exception not handled\n");
+            break;
+        case POWERPC_EXCP_VPUA:     /* Vector assist exception               */
+            cpu_abort(env, "Vector assist exception not handled\n");
+            break;
+        case POWERPC_EXCP_SOFTP:    /* Soft patch exception                  */
+            cpu_abort(env, "Soft patch exception not handled\n");
+            break;
+        case POWERPC_EXCP_MAINT:    /* Maintenance exception                 */
+            cpu_abort(env, "Maintenance exception while in user mode. "
+                      "Aborting\n");
+            break;
+        case POWERPC_EXCP_STOP:     /* stop translation                      */
+            /* We did invalidate the instruction cache. Go on */
+            break;
+        case POWERPC_EXCP_BRANCH:   /* branch instruction:                   */
+            /* We just stopped because of a branch. Go on */
+            break;
+        case POWERPC_EXCP_SYSCALL_USER:
+            /* system call in user-mode emulation */
+            /* system call */
+            if(((int)env->gpr[0]) <= SYS_MAXSYSCALL && ((int)env->gpr[0])>0)
+                ret = do_unix_syscall(env, env->gpr[0]/*, env->gpr[3], env->gpr[4],
+                                      env->gpr[5], env->gpr[6], env->gpr[7],
+                                      env->gpr[8], env->gpr[9], env->gpr[10]*/);
+            else if(((int)env->gpr[0])<0)
+                ret = do_mach_syscall(env, env->gpr[0], env->gpr[3], env->gpr[4],
+                                      env->gpr[5], env->gpr[6], env->gpr[7],
+                                      env->gpr[8], env->gpr[9], env->gpr[10]);
+            else
+                ret = do_thread_syscall(env, env->gpr[0], env->gpr[3], env->gpr[4],
+                                        env->gpr[5], env->gpr[6], env->gpr[7],
+                                        env->gpr[8], env->gpr[9], env->gpr[10]);
+
+            /* Unix syscall error signaling */
+            if(((int)env->gpr[0]) <= SYS_MAXSYSCALL && ((int)env->gpr[0])>0)
+            {
+                if( (int)ret < 0 )
+                    env->nip += 0;
+                else
+                    env->nip += 4;
             }
+
+            /* Return value */
+            env->gpr[3] = ret;
             break;
-        case EXCP_BRANCH:
-            /* We stopped because of a jump... */
-            break;
         case EXCP_INTERRUPT:
-            /* Don't know why this should ever happen... */
-            fprintf(stderr, "EXCP_INTERRUPT\n");
+            /* just indicate that signals should be handled asap */
             break;
-        case EXCP_DEBUG:
-            gdb_handlesig (env, SIGTRAP);
+        default:
+            cpu_abort(env, "Unknown exception 0x%d. Aborting\n", trapnr);
             break;
-        default:
-            fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n",
-                    trapnr);
-            if (loglevel) {
-                fprintf(logfile, "qemu: unhandled CPU exception 0x%02x - "
-                        "0x%02x - aborting\n", trapnr, env->error_code);
-            }
-                abort();
         }
         process_pending_signals(env);
     }

Modified: trunk/src/host/qemu-neo1973/dis-asm.h
===================================================================
--- trunk/src/host/qemu-neo1973/dis-asm.h	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/dis-asm.h	2007-10-29 21:14:04 UTC (rev 3303)
@@ -200,6 +200,10 @@
 #define bfd_mach_m32r          0  /* backwards compatibility */
   bfd_arch_mn10200,    /* Matsushita MN10200 */
   bfd_arch_mn10300,    /* Matsushita MN10300 */
+  bfd_arch_cris,       /* Axis CRIS */
+#define bfd_mach_cris_v0_v10   255
+#define bfd_mach_cris_v32      32
+#define bfd_mach_cris_v10_v32  1032
   bfd_arch_last
   };
 #define bfd_mach_s390_31 31
@@ -382,6 +386,7 @@
 extern int print_insn_ppc		PARAMS ((bfd_vma, disassemble_info*));
 extern int print_insn_alpha             PARAMS ((bfd_vma, disassemble_info*));
 extern int print_insn_s390		PARAMS ((bfd_vma, disassemble_info*));
+extern int print_insn_crisv32           PARAMS ((bfd_vma, disassemble_info*));
 
 #if 0
 /* Fetch the disassembler for a given BFD, if that support is available.  */

Modified: trunk/src/host/qemu-neo1973/disas.c
===================================================================
--- trunk/src/host/qemu-neo1973/disas.c	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/disas.c	2007-10-29 21:14:04 UTC (rev 3303)
@@ -178,13 +178,18 @@
     disasm_info.mach = bfd_mach_sparc_v9b;
 #endif
 #elif defined(TARGET_PPC)
-    if (flags)
+    if (flags >> 16)
         disasm_info.endian = BFD_ENDIAN_LITTLE;
+    if (flags & 0xFFFF) {
+        /* If we have a precise definitions of the instructions set, use it */
+        disasm_info.mach = flags & 0xFFFF;
+    } else {
 #ifdef TARGET_PPC64
-    disasm_info.mach = bfd_mach_ppc64;
+        disasm_info.mach = bfd_mach_ppc64;
 #else
-    disasm_info.mach = bfd_mach_ppc;
+        disasm_info.mach = bfd_mach_ppc;
 #endif
+    }
     print_insn = print_insn_ppc;
 #elif defined(TARGET_M68K)
     print_insn = print_insn_m68k;
@@ -200,6 +205,9 @@
 #elif defined(TARGET_ALPHA)
     disasm_info.mach = bfd_mach_alpha;
     print_insn = print_insn_alpha;
+#elif defined(TARGET_CRIS)
+    disasm_info.mach = bfd_mach_cris_v32;
+    print_insn = print_insn_crisv32;
 #else
     fprintf(out, "0x" TARGET_FMT_lx
 	    ": Asm output not supported on this arch\n", code);

Deleted: trunk/src/host/qemu-neo1973/ecc.h
===================================================================
--- trunk/src/host/qemu-neo1973/ecc.h	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/ecc.h	2007-10-29 21:14:04 UTC (rev 3303)
@@ -1,94 +0,0 @@
-/*
- * Calculate Error-correcting Codes. Used by NAND Flash controllers
- * (not by NAND chips).
- *
- * Copyright (c) 2006 Openedhand Ltd.
- * Written by Andrzej Zaborowski <balrog at zabor.org>
- *
- * This code is licensed under the GNU GPL v2.
- */
-
-struct ecc_state_s {
-    uint8_t cp;		/* Column parity */
-    uint16_t lp[2];	/* Line parity */
-    uint16_t count;
-};
-
-/*
- * Pre-calculated 256-way 1 byte column parity.  Table borrowed from Linux.
- */
-static const uint8_t nand_ecc_precalc_table[] = {
-    0x00, 0x55, 0x56, 0x03, 0x59, 0x0c, 0x0f, 0x5a,
-    0x5a, 0x0f, 0x0c, 0x59, 0x03, 0x56, 0x55, 0x00,
-    0x65, 0x30, 0x33, 0x66, 0x3c, 0x69, 0x6a, 0x3f,
-    0x3f, 0x6a, 0x69, 0x3c, 0x66, 0x33, 0x30, 0x65,
-    0x66, 0x33, 0x30, 0x65, 0x3f, 0x6a, 0x69, 0x3c,
-    0x3c, 0x69, 0x6a, 0x3f, 0x65, 0x30, 0x33, 0x66,
-    0x03, 0x56, 0x55, 0x00, 0x5a, 0x0f, 0x0c, 0x59,
-    0x59, 0x0c, 0x0f, 0x5a, 0x00, 0x55, 0x56, 0x03,
-    0x69, 0x3c, 0x3f, 0x6a, 0x30, 0x65, 0x66, 0x33,
-    0x33, 0x66, 0x65, 0x30, 0x6a, 0x3f, 0x3c, 0x69,
-    0x0c, 0x59, 0x5a, 0x0f, 0x55, 0x00, 0x03, 0x56,
-    0x56, 0x03, 0x00, 0x55, 0x0f, 0x5a, 0x59, 0x0c,
-    0x0f, 0x5a, 0x59, 0x0c, 0x56, 0x03, 0x00, 0x55,
-    0x55, 0x00, 0x03, 0x56, 0x0c, 0x59, 0x5a, 0x0f,
-    0x6a, 0x3f, 0x3c, 0x69, 0x33, 0x66, 0x65, 0x30,
-    0x30, 0x65, 0x66, 0x33, 0x69, 0x3c, 0x3f, 0x6a,
-    0x6a, 0x3f, 0x3c, 0x69, 0x33, 0x66, 0x65, 0x30,
-    0x30, 0x65, 0x66, 0x33, 0x69, 0x3c, 0x3f, 0x6a,
-    0x0f, 0x5a, 0x59, 0x0c, 0x56, 0x03, 0x00, 0x55,
-    0x55, 0x00, 0x03, 0x56, 0x0c, 0x59, 0x5a, 0x0f,
-    0x0c, 0x59, 0x5a, 0x0f, 0x55, 0x00, 0x03, 0x56,
-    0x56, 0x03, 0x00, 0x55, 0x0f, 0x5a, 0x59, 0x0c,
-    0x69, 0x3c, 0x3f, 0x6a, 0x30, 0x65, 0x66, 0x33,
-    0x33, 0x66, 0x65, 0x30, 0x6a, 0x3f, 0x3c, 0x69,
-    0x03, 0x56, 0x55, 0x00, 0x5a, 0x0f, 0x0c, 0x59,
-    0x59, 0x0c, 0x0f, 0x5a, 0x00, 0x55, 0x56, 0x03,
-    0x66, 0x33, 0x30, 0x65, 0x3f, 0x6a, 0x69, 0x3c,
-    0x3c, 0x69, 0x6a, 0x3f, 0x65, 0x30, 0x33, 0x66,
-    0x65, 0x30, 0x33, 0x66, 0x3c, 0x69, 0x6a, 0x3f,
-    0x3f, 0x6a, 0x69, 0x3c, 0x66, 0x33, 0x30, 0x65,
-    0x00, 0x55, 0x56, 0x03, 0x59, 0x0c, 0x0f, 0x5a,
-    0x5a, 0x0f, 0x0c, 0x59, 0x03, 0x56, 0x55, 0x00,
-};
-
-/* Update ECC parity count.  */
-static inline uint8_t ecc_digest(struct ecc_state_s *s, uint8_t sample)
-{
-    uint8_t idx = nand_ecc_precalc_table[sample];
-
-    s->cp ^= idx & 0x3f;
-    if (idx & 0x40) {
-        s->lp[0] ^= ~s->count;
-        s->lp[1] ^= s->count;
-    }
-    s->count ++;
-
-    return sample;
-}
-
-/* Reinitialise the counters.  */
-static inline void ecc_reset(struct ecc_state_s *s)
-{
-    s->lp[0] = 0x0000;
-    s->lp[1] = 0x0000;
-    s->cp = 0x00;
-    s->count = 0;
-}
-
-/* Save/restore */
-static inline void ecc_put(QEMUFile *f, struct ecc_state_s *s)
-{
-    qemu_put_8s(f, &s->cp);
-    qemu_put_be16s(f, &s->lp[0]);
-    qemu_put_be16s(f, &s->lp[1]);
-    qemu_put_be16s(f, &s->count);
-}
-
-static inline void ecc_get(QEMUFile *f, struct ecc_state_s *s)
-{
-    qemu_get_8s(f, &s->cp);
-    qemu_get_be16s(f, &s->lp[0]);
-    qemu_get_be16s(f, &s->lp[1]);
-    qemu_get_be16s(f, &s->count);
-}

Modified: trunk/src/host/qemu-neo1973/elf.h
===================================================================
--- trunk/src/host/qemu-neo1973/elf.h	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/elf.h	2007-10-29 21:14:04 UTC (rev 3303)
@@ -1130,6 +1130,7 @@
 #define elf_note	elf32_note
 #define elf_shdr	elf32_shdr
 #define elf_sym		elf32_sym
+#define elf_addr_t	Elf32_Off
 
 #ifdef ELF_USES_RELOCA
 # define ELF_RELOC      Elf32_Rela
@@ -1144,6 +1145,7 @@
 #define elf_note	elf64_note
 #define elf_shdr	elf64_shdr
 #define elf_sym		elf64_sym
+#define elf_addr_t	Elf64_Off
 
 #ifdef ELF_USES_RELOCA
 # define ELF_RELOC      Elf64_Rela

Modified: trunk/src/host/qemu-neo1973/elf_ops.h
===================================================================
--- trunk/src/host/qemu-neo1973/elf_ops.h	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/elf_ops.h	2007-10-29 21:14:04 UTC (rev 3303)
@@ -145,8 +145,8 @@
     struct elfhdr ehdr;
     struct elf_phdr *phdr = NULL, *ph;
     int size, i, total_size;
-    elf_word low = 0, high = 0;
-    elf_word mem_size, addr;
+    elf_word mem_size;
+    uint64_t addr, low = 0, high = 0;
     uint8_t *data = NULL;
 
     if (read(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr))
@@ -159,7 +159,7 @@
         goto fail;
 
     if (pentry)
-   	*pentry = (uint64_t)ehdr.e_entry;
+   	*pentry = (uint64_t)(elf_sword)ehdr.e_entry;
 
     glue(load_symbols, SZ)(&ehdr, fd, must_swab);
 
@@ -206,9 +206,9 @@
     }
     qemu_free(phdr);
     if (lowaddr)
-        *lowaddr = (uint64_t)low;
+        *lowaddr = (uint64_t)(elf_sword)low;
     if (highaddr)
-        *highaddr = (uint64_t)high;
+        *highaddr = (uint64_t)(elf_sword)high;
     return total_size;
  fail:
     qemu_free(data);

Modified: trunk/src/host/qemu-neo1973/exec-all.h
===================================================================
--- trunk/src/host/qemu-neo1973/exec-all.h	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/exec-all.h	2007-10-29 21:14:04 UTC (rev 3303)
@@ -37,6 +37,14 @@
 #define unlikely(x)   __builtin_expect(!!(x), 0)
 #endif
 
+#ifndef always_inline
+#if (__GNUC__ < 3) || defined(__APPLE__)
+#define always_inline inline
+#else
+#define always_inline __attribute__ (( always_inline )) inline
+#endif
+#endif
+
 #ifdef __i386__
 #define REGPARM(n) __attribute((regparm(n)))
 #else
@@ -109,14 +117,14 @@
 void tlb_flush(CPUState *env, int flush_global);
 int tlb_set_page_exec(CPUState *env, target_ulong vaddr,
                       target_phys_addr_t paddr, int prot,
-                      int is_user, int is_softmmu);
+                      int mmu_idx, int is_softmmu);
 static inline int tlb_set_page(CPUState *env, target_ulong vaddr,
                                target_phys_addr_t paddr, int prot,
-                               int is_user, int is_softmmu)
+                               int mmu_idx, int is_softmmu)
 {
     if (prot & PAGE_READ)
         prot |= PAGE_EXEC;
-    return tlb_set_page_exec(env, vaddr, paddr, prot, is_user, is_softmmu);
+    return tlb_set_page_exec(env, vaddr, paddr, prot, mmu_idx, is_softmmu);
 }
 
 #define CODE_GEN_MAX_SIZE        65536
@@ -171,7 +179,7 @@
 typedef struct TranslationBlock {
     target_ulong pc;   /* simulated PC corresponding to this block (EIP + CS base) */
     target_ulong cs_base; /* CS base for this block */
-    unsigned int flags; /* flags defining in which context the code was generated */
+    uint64_t flags; /* flags defining in which context the code was generated */
     uint16_t size;      /* size of target code for this block (1 <=
                            size <= TARGET_PAGE_SIZE) */
     uint16_t cflags;    /* compile flags */
@@ -554,10 +562,10 @@
 
 #if !defined(CONFIG_USER_ONLY)
 
-void tlb_fill(target_ulong addr, int is_write, int is_user,
+void tlb_fill(target_ulong addr, int is_write, int mmu_idx,
               void *retaddr);
 
-#define ACCESS_TYPE 3
+#define ACCESS_TYPE (NB_MMU_MODES + 1)
 #define MEMSUFFIX _code
 #define env cpu_single_env
 
@@ -590,41 +598,23 @@
    is the offset relative to phys_ram_base */
 static inline target_ulong get_phys_addr_code(CPUState *env, target_ulong addr)
 {
-    int is_user, index, pd;
+    int mmu_idx, index, pd;
 
     index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
-#if defined(TARGET_I386)
-    is_user = ((env->hflags & HF_CPL_MASK) == 3);
-#elif defined (TARGET_PPC)
-    is_user = msr_pr;
-#elif defined (TARGET_MIPS)
-    is_user = ((env->hflags & MIPS_HFLAG_MODE) == MIPS_HFLAG_UM);
-#elif defined (TARGET_SPARC)
-    is_user = (env->psrs == 0);
-#elif defined (TARGET_ARM)
-    is_user = ((env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_USR);
-#elif defined (TARGET_SH4)
-    is_user = ((env->sr & SR_MD) == 0);
-#elif defined (TARGET_ALPHA)
-    is_user = ((env->ps >> 3) & 3);
-#elif defined (TARGET_M68K)
-    is_user = ((env->sr & SR_S) == 0);
-#else
-#error unimplemented CPU
-#endif
-    if (__builtin_expect(env->tlb_table[is_user][index].addr_code !=
+    mmu_idx = cpu_mmu_index(env);
+    if (__builtin_expect(env->tlb_table[mmu_idx][index].addr_code !=
                          (addr & TARGET_PAGE_MASK), 0)) {
         ldub_code(addr);
     }
-    pd = env->tlb_table[is_user][index].addr_code & ~TARGET_PAGE_MASK;
+    pd = env->tlb_table[mmu_idx][index].addr_code & ~TARGET_PAGE_MASK;
     if (pd > IO_MEM_ROM && !(pd & IO_MEM_ROMD)) {
-#ifdef TARGET_SPARC
+#if defined(TARGET_SPARC) || defined(TARGET_MIPS)
         do_unassigned_access(addr, 0, 1, 0);
 #else
         cpu_abort(env, "Trying to execute code outside RAM or ROM at 0x" TARGET_FMT_lx "\n", addr);
 #endif
     }
-    return addr + env->tlb_table[is_user][index].addend - (unsigned long)phys_ram_base;
+    return addr + env->tlb_table[mmu_idx][index].addend - (unsigned long)phys_ram_base;
 }
 #endif
 

Modified: trunk/src/host/qemu-neo1973/exec.c
===================================================================
--- trunk/src/host/qemu-neo1973/exec.c	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/exec.c	2007-10-29 21:14:04 UTC (rev 3303)
@@ -1292,15 +1292,28 @@
     vfprintf(stderr, fmt, ap);
     fprintf(stderr, "\n");
 #ifdef TARGET_I386
+    if(env->intercept & INTERCEPT_SVM_MASK) {
+	/* most probably the virtual machine should not
+	   be shut down but rather caught by the VMM */
+        vmexit(SVM_EXIT_SHUTDOWN, 0);
+    }
     cpu_dump_state(env, stderr, fprintf, X86_DUMP_FPU | X86_DUMP_CCOP);
 #else
     cpu_dump_state(env, stderr, fprintf, 0);
 #endif
-    va_end(ap);
     if (logfile) {
+        fprintf(logfile, "qemu: fatal: ");
+        vfprintf(logfile, fmt, ap);
+        fprintf(logfile, "\n");
+#ifdef TARGET_I386
+        cpu_dump_state(env, logfile, fprintf, X86_DUMP_FPU | X86_DUMP_CCOP);
+#else
+        cpu_dump_state(env, logfile, fprintf, 0);
+#endif
         fflush(logfile);
         fclose(logfile);
     }
+    va_end(ap);
     abort();
 }
 
@@ -1595,7 +1608,7 @@
    conflicting with the host address space). */
 int tlb_set_page_exec(CPUState *env, target_ulong vaddr,
                       target_phys_addr_t paddr, int prot,
-                      int is_user, int is_softmmu)
+                      int mmu_idx, int is_softmmu)
 {
     PhysPageDesc *p;
     unsigned long pd;
@@ -1613,8 +1626,8 @@
         pd = p->phys_offset;
     }
 #if defined(DEBUG_TLB)
-    printf("tlb_set_page: vaddr=" TARGET_FMT_lx " paddr=0x%08x prot=%x u=%d smmu=%d pd=0x%08lx\n",
-           vaddr, (int)paddr, prot, is_user, is_softmmu, pd);
+    printf("tlb_set_page: vaddr=" TARGET_FMT_lx " paddr=0x%08x prot=%x idx=%d smmu=%d pd=0x%08lx\n",
+           vaddr, (int)paddr, prot, mmu_idx, is_softmmu, pd);
 #endif
 
     ret = 0;
@@ -1651,7 +1664,7 @@
 
         index = (vaddr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
         addend -= vaddr;
-        te = &env->tlb_table[is_user][index];
+        te = &env->tlb_table[mmu_idx][index];
         te->addend = addend;
         if (prot & PAGE_READ) {
             te->addr_read = address;
@@ -1777,7 +1790,7 @@
 
 int tlb_set_page_exec(CPUState *env, target_ulong vaddr,
                       target_phys_addr_t paddr, int prot,
-                      int is_user, int is_softmmu)
+                      int mmu_idx, int is_softmmu)
 {
     return 0;
 }
@@ -2053,6 +2066,8 @@
 #endif
 #ifdef TARGET_SPARC
     do_unassigned_access(addr, 0, 0, 0);
+#elif TARGET_CRIS
+    do_unassigned_access(addr, 0, 0, 0);
 #endif
     return 0;
 }
@@ -2064,6 +2079,8 @@
 #endif
 #ifdef TARGET_SPARC
     do_unassigned_access(addr, 1, 0, 0);
+#elif TARGET_CRIS
+    do_unassigned_access(addr, 1, 0, 0);
 #endif
 }
 

Modified: trunk/src/host/qemu-neo1973/gdbstub.c
===================================================================
--- trunk/src/host/qemu-neo1973/gdbstub.c	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/gdbstub.c	2007-10-29 21:14:04 UTC (rev 3303)
@@ -300,7 +300,7 @@
     }
     /* nip, msr, ccr, lnk, ctr, xer, mq */
     registers[96] = tswapl(env->nip);
-    registers[97] = tswapl(do_load_msr(env));
+    registers[97] = tswapl(env->msr);
     tmp = 0;
     for (i = 0; i < 8; i++)
         tmp |= env->crf[i] << (32 - ((i + 1) * 4));
@@ -329,7 +329,7 @@
     }
     /* nip, msr, ccr, lnk, ctr, xer, mq */
     env->nip = tswapl(registers[96]);
-    do_store_msr(env, tswapl(registers[97]));
+    ppc_store_msr(env, tswapl(registers[97]));
     registers[98] = tswapl(registers[98]);
     for (i = 0; i < 8; i++)
         env->crf[i] = (registers[98] >> (32 - ((i + 1) * 4))) & 0xF;
@@ -563,7 +563,7 @@
         ptr += sizeof(target_ulong);
       }
 
-    *(target_ulong *)ptr = tswapl(env->CP0_Status);
+    *(target_ulong *)ptr = (int32_t)tswap32(env->CP0_Status);
     ptr += sizeof(target_ulong);
 
     *(target_ulong *)ptr = tswapl(env->LO[0][env->current_tc]);
@@ -575,7 +575,7 @@
     *(target_ulong *)ptr = tswapl(env->CP0_BadVAddr);
     ptr += sizeof(target_ulong);
 
-    *(target_ulong *)ptr = tswapl(env->CP0_Cause);
+    *(target_ulong *)ptr = (int32_t)tswap32(env->CP0_Cause);
     ptr += sizeof(target_ulong);
 
     *(target_ulong *)ptr = tswapl(env->PC[env->current_tc]);
@@ -585,20 +585,35 @@
       {
         for (i = 0; i < 32; i++)
           {
-            *(target_ulong *)ptr = tswapl(env->fpu->fpr[i].fs[FP_ENDIAN_IDX]);
+            if (env->CP0_Status & (1 << CP0St_FR))
+              *(target_ulong *)ptr = tswapl(env->fpu->fpr[i].d);
+            else
+              *(target_ulong *)ptr = tswap32(env->fpu->fpr[i].w[FP_ENDIAN_IDX]);
             ptr += sizeof(target_ulong);
           }
 
-        *(target_ulong *)ptr = tswapl(env->fpu->fcr31);
+        *(target_ulong *)ptr = (int32_t)tswap32(env->fpu->fcr31);
         ptr += sizeof(target_ulong);
 
-        *(target_ulong *)ptr = tswapl(env->fpu->fcr0);
+        *(target_ulong *)ptr = (int32_t)tswap32(env->fpu->fcr0);
         ptr += sizeof(target_ulong);
       }
 
-    /* 32 FP registers, fsr, fir, fp.  Not yet implemented.  */
-    /* what's 'fp' mean here?  */
+    /* "fp", pseudo frame pointer. Not yet implemented in gdb. */
+    *(target_ulong *)ptr = 0;
+    ptr += sizeof(target_ulong);
 
+    /* Registers for embedded use, we just pad them. */
+    for (i = 0; i < 16; i++)
+      {
+        *(target_ulong *)ptr = 0;
+        ptr += sizeof(target_ulong);
+      }
+
+    /* Processor ID. */
+    *(target_ulong *)ptr = (int32_t)tswap32(env->CP0_PRid);
+    ptr += sizeof(target_ulong);
+
     return ptr - mem_buf;
 }
 
@@ -647,15 +662,17 @@
       {
         for (i = 0; i < 32; i++)
           {
-            env->fpu->fpr[i].fs[FP_ENDIAN_IDX] = tswapl(*(target_ulong *)ptr);
+            if (env->CP0_Status & (1 << CP0St_FR))
+              env->fpu->fpr[i].d = tswapl(*(target_ulong *)ptr);
+            else
+              env->fpu->fpr[i].w[FP_ENDIAN_IDX] = tswapl(*(target_ulong *)ptr);
             ptr += sizeof(target_ulong);
           }
 
-        env->fpu->fcr31 = tswapl(*(target_ulong *)ptr) & 0x0183FFFF;
+        env->fpu->fcr31 = tswapl(*(target_ulong *)ptr) & 0xFF83FFFF;
         ptr += sizeof(target_ulong);
 
-        env->fpu->fcr0 = tswapl(*(target_ulong *)ptr);
-        ptr += sizeof(target_ulong);
+        /* The remaining registers are assumed to be read-only. */
 
         /* set rounding mode */
         RESTORE_ROUNDING_MODE;
@@ -728,6 +745,66 @@
   for (i = 0; i < 8; i++) LOAD(env->gregs[i]);
   for (i = 0; i < 8; i++) LOAD(env->gregs[i + 16]);
 }
+#elif defined (TARGET_CRIS)
+
+static int cris_save_32 (unsigned char *d, uint32_t value)
+{
+	*d++ = (value);
+	*d++ = (value >>= 8);
+	*d++ = (value >>= 8);
+	*d++ = (value >>= 8);
+	return 4;
+}
+static int cris_save_16 (unsigned char *d, uint32_t value)
+{
+	*d++ = (value);
+	*d++ = (value >>= 8);
+	return 2;
+}
+static int cris_save_8 (unsigned char *d, uint32_t value)
+{
+	*d++ = (value);
+	return 1;
+}
+
+/* FIXME: this will bug on archs not supporting unaligned word accesses.  */
+static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf)
+{
+  uint8_t *ptr = mem_buf;
+  uint8_t srs;
+  int i;
+
+  for (i = 0; i < 16; i++)
+	  ptr += cris_save_32 (ptr, env->regs[i]);
+
+  srs = env->pregs[SR_SRS];
+
+  ptr += cris_save_8 (ptr, env->pregs[0]);
+  ptr += cris_save_8 (ptr, env->pregs[1]);
+  ptr += cris_save_32 (ptr, env->pregs[2]);
+  ptr += cris_save_8 (ptr, srs);
+  ptr += cris_save_16 (ptr, env->pregs[4]);
+
+  for (i = 5; i < 16; i++)
+	  ptr += cris_save_32 (ptr, env->pregs[i]);
+
+  ptr += cris_save_32 (ptr, env->pc);
+
+  for (i = 0; i < 16; i++)
+	  ptr += cris_save_32 (ptr, env->sregs[srs][i]);
+
+  return ((uint8_t *)ptr - mem_buf);
+}
+
+static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size)
+{
+  uint32_t *ptr = (uint32_t *)mem_buf;
+  int i;
+
+#define LOAD(x) (x)=*ptr++;
+  for (i = 0; i < 16; i++) LOAD(env->regs[i]);
+  LOAD (env->pc);
+}
 #else
 static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf)
 {
@@ -745,7 +822,7 @@
     const char *p;
     int ch, reg_size, type;
     char buf[4096];
-    uint8_t mem_buf[2000];
+    uint8_t mem_buf[4096];
     uint32_t *registers;
     target_ulong addr, len;
 
@@ -776,6 +853,8 @@
             env->pc = addr;
 #elif defined (TARGET_MIPS)
             env->PC[env->current_tc] = addr;
+#elif defined (TARGET_CRIS)
+            env->pc = addr;
 #endif
         }
 #ifdef CONFIG_USER_ONLY
@@ -800,6 +879,8 @@
             env->pc = addr;
 #elif defined (TARGET_MIPS)
             env->PC[env->current_tc] = addr;
+#elif defined (TARGET_CRIS)
+            env->pc = addr;
 #endif
         }
         cpu_single_step(env, 1);

Modified: trunk/src/host/qemu-neo1973/host-utils.c
===================================================================
--- trunk/src/host/qemu-neo1973/host-utils.c	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/host-utils.c	2007-10-29 21:14:04 UTC (rev 3303)
@@ -1,6 +1,7 @@
 /*
  * Utility compute operations used by translated code.
  *
+ * Copyright (c) 2003 Fabrice Bellard
  * Copyright (c) 2007 Aurelien Jarno
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -24,52 +25,90 @@
 
 #include "vl.h"
 
-/* Signed 64x64 -> 128 multiplication */
+//#define DEBUG_MULDIV
 
-void muls64(int64_t *phigh, int64_t *plow, int64_t a, int64_t b)
+/* Long integer helpers */
+static void add128 (uint64_t *plow, uint64_t *phigh, uint64_t a, uint64_t b)
 {
-#if defined(__x86_64__)
-    __asm__ ("imul %0\n\t"
-             : "=d" (*phigh), "=a" (*plow)
-             : "a" (a), "0" (b)
-             );
-#else
-    int64_t ph;
-    uint64_t pm1, pm2, pl;
+    *plow += a;
+    /* carry test */
+    if (*plow < a)
+        (*phigh)++;
+    *phigh += b;
+}
 
-    pl = (uint64_t)((uint32_t)a) * (uint64_t)((uint32_t)b);
-    pm1 = (a >> 32) * (uint32_t)b;
-    pm2 = (uint32_t)a * (b >> 32);
-    ph = (a >> 32) * (b >> 32);
+static void neg128 (uint64_t *plow, uint64_t *phigh)
+{
+    *plow = ~*plow;
+    *phigh = ~*phigh;
+    add128(plow, phigh, 1, 0);
+}
 
-    ph += (int64_t)pm1 >> 32;
-    pm1 = (uint64_t)((uint32_t)pm1) + pm2 + (pl >> 32);
+static void mul64 (uint64_t *plow, uint64_t *phigh, uint64_t a, uint64_t b)
+{
+    uint32_t a0, a1, b0, b1;
+    uint64_t v;
 
-    *phigh = ph + ((int64_t)pm1 >> 32);
-    *plow = (pm1 << 32) + (uint32_t)pl;
-#endif
+    a0 = a;
+    a1 = a >> 32;
+
+    b0 = b;
+    b1 = b >> 32;
+
+    v = (uint64_t)a0 * (uint64_t)b0;
+    *plow = v;
+    *phigh = 0;
+
+    v = (uint64_t)a0 * (uint64_t)b1;
+    add128(plow, phigh, v << 32, v >> 32);
+
+    v = (uint64_t)a1 * (uint64_t)b0;
+    add128(plow, phigh, v << 32, v >> 32);
+
+    v = (uint64_t)a1 * (uint64_t)b1;
+    *phigh += v;
 }
 
+
 /* Unsigned 64x64 -> 128 multiplication */
-void mulu64(uint64_t *phigh, uint64_t *plow, uint64_t a, uint64_t b)
+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)
-            );
+             : "a" (a), "0" (b));
 #else
-    uint64_t ph, pm1, pm2, pl;
+    mul64(plow, phigh, a, b);
+#endif
+#if defined(DEBUG_MULDIV)
+    printf("mulu64: 0x%016llx * 0x%016llx = 0x%016llx%016llx\n",
+           a, b, *phigh, *plow);
+#endif
+}
 
-    pl = (uint64_t)((uint32_t)a) * (uint64_t)((uint32_t)b);
-    pm1 = (a >> 32) * (uint32_t)b;
-    pm2 = (uint32_t)a * (b >> 32);
-    ph = (a >> 32) * (b >> 32);
+/* 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;
 
-    ph += pm1 >> 32;
-    pm1 = (uint64_t)((uint32_t)pm1) + pm2 + (pl >> 32);
-
-    *phigh = ph + (pm1 >> 32);
-    *plow = (pm1 << 32) + (uint32_t)pl;
+    sa = (a < 0);
+    if (sa)
+        a = -a;
+    sb = (b < 0);
+    if (sb)
+        b = -b;
+    mul64(plow, phigh, a, b);
+    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
 }

Added: trunk/src/host/qemu-neo1973/host-utils.h
===================================================================
--- trunk/src/host/qemu-neo1973/host-utils.h	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/host-utils.h	2007-10-29 21:14:04 UTC (rev 3303)
@@ -0,0 +1,201 @@
+/*
+ * Utility compute operations used by translated code.
+ *
+ * Copyright (c) 2007 Thiemo Seufer
+ * Copyright (c) 2007 Jocelyn Mayer
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+/* 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. */
+
+/* Binary search for leading zeros.  */
+
+static always_inline int clz32(uint32_t val)
+{
+    int cnt = 0;
+
+    if (!(val & 0xFFFF0000U)) {
+        cnt += 16;
+        val <<= 16;
+    }
+    if (!(val & 0xFF000000U)) {
+        cnt += 8;
+        val <<= 8;
+    }
+    if (!(val & 0xF0000000U)) {
+        cnt += 4;
+        val <<= 4;
+    }
+    if (!(val & 0xC0000000U)) {
+        cnt += 2;
+        val <<= 2;
+    }
+    if (!(val & 0x80000000U)) {
+        cnt++;
+        val <<= 1;
+    }
+    if (!(val & 0x80000000U)) {
+        cnt++;
+    }
+    return cnt;
+}
+
+static always_inline int clo32(uint32_t val)
+{
+    return clz32(~val);
+}
+
+static always_inline int clz64(uint64_t val)
+{
+    int cnt = 0;
+
+    if (!(val & 0xFFFFFFFF00000000ULL)) {
+        cnt += 32;
+        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;
+}
+
+static always_inline int clo64(uint64_t val)
+{
+    return clz64(~val);
+}
+
+static always_inline int ctz32 (uint32_t val)
+{
+    int cnt;
+
+    cnt = 0;
+    if (!(val & 0x0000FFFFUL)) {
+         cnt += 16;
+        val >>= 16;
+     }
+    if (!(val & 0x000000FFUL)) {
+         cnt += 8;
+        val >>= 8;
+     }
+    if (!(val & 0x0000000FUL)) {
+         cnt += 4;
+        val >>= 4;
+     }
+    if (!(val & 0x00000003UL)) {
+         cnt += 2;
+        val >>= 2;
+     }
+    if (!(val & 0x00000001UL)) {
+         cnt++;
+        val >>= 1;
+     }
+    if (!(val & 0x00000001UL)) {
+         cnt++;
+     }
+
+     return cnt;
+ }
+ 
+static always_inline int cto32 (uint32_t val)
+ {
+    return ctz32(~val);
+}
+
+static always_inline int ctz64 (uint64_t val)
+{
+    int cnt;
+
+    cnt = 0;
+    if (!((uint32_t)val)) {
+        cnt += 32;
+        val >>= 32;
+    }
+
+    return cnt + ctz32(val);
+}
+
+static always_inline int cto64 (uint64_t val)
+{
+    return ctz64(~val);
+}
+
+static always_inline int ctpop8 (uint8_t val)
+{
+    val = (val & 0x55) + ((val >> 1) & 0x55);
+    val = (val & 0x33) + ((val >> 2) & 0x33);
+    val = (val & 0x0f) + ((val >> 4) & 0x0f);
+
+    return val;
+}
+
+static always_inline int ctpop16 (uint16_t val)
+{
+    val = (val & 0x5555) + ((val >> 1) & 0x5555);
+    val = (val & 0x3333) + ((val >> 2) & 0x3333);
+    val = (val & 0x0f0f) + ((val >> 4) & 0x0f0f);
+    val = (val & 0x00ff) + ((val >> 8) & 0x00ff);
+
+    return val;
+}
+
+static always_inline int ctpop32 (uint32_t val)
+{
+    val = (val & 0x55555555) + ((val >>  1) & 0x55555555);
+    val = (val & 0x33333333) + ((val >>  2) & 0x33333333);
+    val = (val & 0x0f0f0f0f) + ((val >>  4) & 0x0f0f0f0f);
+    val = (val & 0x00ff00ff) + ((val >>  8) & 0x00ff00ff);
+    val = (val & 0x0000ffff) + ((val >> 16) & 0x0000ffff);
+
+    return val;
+}
+
+static always_inline int ctpop64 (uint64_t val)
+{
+    val = (val & 0x5555555555555555ULL) + ((val >>  1) & 0x5555555555555555ULL);
+    val = (val & 0x3333333333333333ULL) + ((val >>  2) & 0x3333333333333333ULL);
+    val = (val & 0x0f0f0f0f0f0f0f0fULL) + ((val >>  4) & 0x0f0f0f0f0f0f0f0fULL);
+    val = (val & 0x00ff00ff00ff00ffULL) + ((val >>  8) & 0x00ff00ff00ff00ffULL);
+    val = (val & 0x0000ffff0000ffffULL) + ((val >> 16) & 0x0000ffff0000ffffULL);
+    val = (val & 0x00000000ffffffffULL) + ((val >> 32) & 0x00000000ffffffffULL);
+
+    return val;
+ }

Modified: trunk/src/host/qemu-neo1973/hw/acpi.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/acpi.c	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/hw/acpi.c	2007-10-29 21:14:04 UTC (rev 3303)
@@ -400,7 +400,7 @@
 
     if (s->dev.config[0x80] & 1) {
         pm_io_base = le32_to_cpu(*(uint32_t *)(s->dev.config + 0x40));
-        pm_io_base &= 0xfffe;
+        pm_io_base &= 0xffc0;
 
         /* XXX: need to improve memory and ioport allocation */
 #if defined(DEBUG)
@@ -474,6 +474,8 @@
     pci_conf[0x01] = 0x80;
     pci_conf[0x02] = 0x13;
     pci_conf[0x03] = 0x71;
+    pci_conf[0x06] = 0x80;
+    pci_conf[0x07] = 0x02;
     pci_conf[0x08] = 0x00; // revision number
     pci_conf[0x09] = 0x00;
     pci_conf[0x0a] = 0x80; // other bridge device

Modified: trunk/src/host/qemu-neo1973/hw/alpha_palcode.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/alpha_palcode.c	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/hw/alpha_palcode.c	2007-10-29 21:14:04 UTC (rev 3303)
@@ -811,12 +811,14 @@
 
 static int get_pte (uint64_t *pfnp, int *zbitsp, int *protp,
                     uint64_t ptebase, int page_bits, uint64_t level,
-                    int is_user, int rw)
+                    int mmu_idx, int rw)
 {
     uint64_t pteaddr, pte, pfn;
     uint8_t gh;
-    int ure, uwe, kre, kwe, foE, foR, foW, v, ret, ar;
+    int ure, uwe, kre, kwe, foE, foR, foW, v, ret, ar, is_user;
 
+    /* XXX: TOFIX */
+    is_user = mmu_idx == MMU_USER_IDX;
     pteaddr = (ptebase << page_bits) + (8 * level);
     pte = ldq_raw(pteaddr);
     /* Decode all interresting PTE fields */
@@ -871,7 +873,7 @@
 
 static int paddr_from_pte (uint64_t *paddr, int *zbitsp, int *prot,
                            uint64_t ptebase, int page_bits,
-                           uint64_t vaddr, int is_user, int rw)
+                           uint64_t vaddr, int mmu_idx, int rw)
 {
     uint64_t pfn, page_mask, lvl_mask, level1, level2, level3;
     int lvl_bits, ret;
@@ -909,7 +911,7 @@
         break;
     }
     /* Level 3 PTE */
-    ret = get_pte(&pfn, zbitsp, prot, pfn, page_bits, level3, is_user, rw);
+    ret = get_pte(&pfn, zbitsp, prot, pfn, page_bits, level3, mmu_idx, rw);
     if (ret & 0x1) {
         /* Translation not valid */
         ret = 1;
@@ -943,7 +945,7 @@
 
 static int virtual_to_physical (CPUState *env, uint64_t *physp,
                                 int *zbitsp, int *protp,
-                                uint64_t virtual, int is_user, int rw)
+                                uint64_t virtual, int mmu_idx, int rw)
 {
     uint64_t sva, ptebase;
     int seg, page_bits, ret;
@@ -961,16 +963,16 @@
     case 0:
         /* seg1: 3 levels of PTE */
         ret = paddr_from_pte(physp, zbitsp, protp, ptebase, page_bits,
-                             virtual, is_user, rw);
+                             virtual, mmu_idx, rw);
         break;
     case 1:
         /* seg1: 2 levels of PTE */
         ret = paddr_from_pte(physp, zbitsp, protp, ptebase, page_bits,
-                             virtual, is_user, rw);
+                             virtual, mmu_idx, rw);
         break;
     case 2:
         /* kernel segment */
-        if (is_user) {
+        if (mmu_idx != 0) {
             ret = 2;
         } else {
             *physp = virtual;
@@ -979,7 +981,7 @@
     case 3:
         /* seg1: TB mapped */
         ret = paddr_from_pte(physp, zbitsp, protp, ptebase, page_bits,
-                             virtual, is_user, rw);
+                             virtual, mmu_idx, rw);
         break;
     default:
         ret = 1;
@@ -991,7 +993,7 @@
 
 /* XXX: code provision */
 int cpu_ppc_handle_mmu_fault (CPUState *env, uint32_t address, int rw,
-                              int is_user, int is_softmmu)
+                              int mmu_idx, int is_softmmu)
 {
     uint64_t physical, page_size, end;
     int prot, zbits, ret;
@@ -1000,7 +1002,7 @@
         ret = 2;
     } else {
         ret = virtual_to_physical(env, &physical, &zbits, &prot,
-                                  address, is_user, rw);
+                                  address, mmu_idx, rw);
     }
     switch (ret) {
     case 0:
@@ -1009,7 +1011,7 @@
         address &= ~(page_size - 1);
         for (end = physical + page_size; physical < end; physical += 0x1000) {
             ret = tlb_set_page(env, address, physical, prot,
-                               is_user, is_softmmu);
+                               mmu_idx, is_softmmu);
             address += 0x1000;
         }
         break;

Modified: trunk/src/host/qemu-neo1973/hw/apb_pci.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/apb_pci.c	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/hw/apb_pci.c	2007-10-29 21:14:04 UTC (rev 3303)
@@ -70,7 +70,7 @@
 };
 
 static void apb_config_writel (void *opaque, target_phys_addr_t addr,
-			       uint32_t val)
+                               uint32_t val)
 {
     //PCIBus *s = opaque;
 
@@ -80,14 +80,14 @@
     case 0x18: // AFAR
     case 0x20: // Diagnostic
     case 0x28: // Target address space
-	// XXX
+        // XXX
     default:
-	break;
+        break;
     }
 }
 
 static uint32_t apb_config_readl (void *opaque,
-				  target_phys_addr_t addr)
+                                  target_phys_addr_t addr)
 {
     //PCIBus *s = opaque;
     uint32_t val;
@@ -98,10 +98,10 @@
     case 0x18: // AFAR
     case 0x20: // Diagnostic
     case 0x28: // Target address space
-	// XXX
+        // XXX
     default:
-	val = 0;
-	break;
+        val = 0;
+        break;
     }
     return val;
 }
@@ -222,7 +222,7 @@
     pci_mem_config = cpu_register_io_memory(0, pci_apb_config_read,
                                             pci_apb_config_write, s);
     apb_config = cpu_register_io_memory(0, apb_config_read,
-					apb_config_write, s);
+                                        apb_config_write, s);
     pci_mem_data = cpu_register_io_memory(0, pci_apb_read,
                                           pci_apb_write, s);
     pci_ioport = cpu_register_io_memory(0, pci_apb_ioread,

Modified: trunk/src/host/qemu-neo1973/hw/apic.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/apic.c	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/hw/apic.c	2007-10-29 21:14:04 UTC (rev 3303)
@@ -484,6 +484,25 @@
     return intno;
 }
 
+int apic_accept_pic_intr(CPUState *env)
+{
+    APICState *s = env->apic_state;
+    uint32_t lvt0;
+
+    if (!s)
+        return -1;
+
+    lvt0 = s->lvt[APIC_LVT_LINT0];
+
+    if (s->id == 0 &&
+        ((s->apicbase & MSR_IA32_APICBASE_ENABLE) == 0 ||
+         ((lvt0 & APIC_LVT_MASKED) == 0 &&
+          ((lvt0 >> 8) & 0x7) == APIC_DM_EXTINT)))
+        return 1;
+
+    return 0;
+}
+
 static uint32_t apic_get_current_count(APICState *s)
 {
     int64_t d;
@@ -790,6 +809,13 @@
 {
     APICState *s = opaque;
     apic_init_ipi(s);
+
+    /*
+     * LINT0 delivery mode is set to ExtInt at initialization time
+     * typically by BIOS, so PIC interrupt can be delivered to the
+     * processor when local APIC is enabled.
+     */
+    s->lvt[APIC_LVT_LINT0] = 0x700;
 }
 
 static CPUReadMemoryFunc *apic_mem_read[3] = {
@@ -821,6 +847,13 @@
     s->apicbase = 0xfee00000 |
         (s->id ? 0 : MSR_IA32_APICBASE_BSP) | MSR_IA32_APICBASE_ENABLE;
 
+    /*
+     * LINT0 delivery mode is set to ExtInt at initialization time
+     * typically by BIOS, so PIC interrupt can be delivered to the
+     * processor when local APIC is enabled.
+     */
+    s->lvt[APIC_LVT_LINT0] = 0x700;
+
     /* XXX: mapping more APICs at the same memory location */
     if (apic_io_memory == 0) {
         /* NOTE: the APIC is directly connected to the CPU - it is not

Modified: trunk/src/host/qemu-neo1973/hw/cs4231.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/cs4231.c	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/hw/cs4231.c	2007-10-29 21:14:04 UTC (rev 3303)
@@ -79,11 +79,11 @@
             break;
         }
         DPRINTF("read dreg[%d]: 0x%8.8x\n", CS_RAP(s), ret);
-	break;
+        break;
     default:
         ret = s->regs[saddr];
         DPRINTF("read reg[%d]: 0x%8.8x\n", saddr, ret);
-	break;
+        break;
     }
     return ret;
 }
@@ -122,7 +122,7 @@
         break;
     default:
         s->regs[saddr] = val;
-	break;
+        break;
     }
 }
 

Modified: trunk/src/host/qemu-neo1973/hw/cuda.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/cuda.c	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/hw/cuda.c	2007-10-29 21:14:04 UTC (rev 3303)
@@ -1,7 +1,8 @@
 /*
- * QEMU CUDA support
+ * QEMU PowerMac CUDA device support
  *
- * Copyright (c) 2004 Fabrice Bellard
+ * Copyright (c) 2004-2007 Fabrice Bellard
+ * Copyright (c) 2007 Jocelyn Mayer
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy
  * of this software and associated documentation files (the "Software"), to deal
@@ -22,6 +23,7 @@
  * THE SOFTWARE.
  */
 #include "vl.h"
+#include "ppc_mac.h"
 
 /* XXX: implement all timer modes */
 
@@ -634,10 +636,9 @@
     &cuda_readl,
 };
 
-int cuda_init(qemu_irq irq)
+void cuda_init (int *cuda_mem_index, qemu_irq irq)
 {
     CUDAState *s = &cuda_state;
-    int cuda_mem_index;
 
     s->irq = irq;
 
@@ -653,6 +654,5 @@
     set_counter(s, &s->timers[1], 0xffff);
 
     s->adb_poll_timer = qemu_new_timer(vm_clock, cuda_adb_poll, s);
-    cuda_mem_index = cpu_register_io_memory(0, cuda_read, cuda_write, s);
-    return cuda_mem_index;
+    *cuda_mem_index = cpu_register_io_memory(0, cuda_read, cuda_write, s);
 }

Added: trunk/src/host/qemu-neo1973/hw/ecc.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/ecc.c	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/hw/ecc.c	2007-10-29 21:14:04 UTC (rev 3303)
@@ -0,0 +1,90 @@
+/*
+ * Calculate Error-correcting Codes. Used by NAND Flash controllers
+ * (not by NAND chips).
+ *
+ * Copyright (c) 2006 Openedhand Ltd.
+ * Written by Andrzej Zaborowski <balrog at zabor.org>
+ *
+ * This code is licensed under the GNU GPL v2.
+ */
+
+#include "vl.h"
+
+/*
+ * Pre-calculated 256-way 1 byte column parity.  Table borrowed from Linux.
+ */
+static const uint8_t nand_ecc_precalc_table[] = {
+    0x00, 0x55, 0x56, 0x03, 0x59, 0x0c, 0x0f, 0x5a,
+    0x5a, 0x0f, 0x0c, 0x59, 0x03, 0x56, 0x55, 0x00,
+    0x65, 0x30, 0x33, 0x66, 0x3c, 0x69, 0x6a, 0x3f,
+    0x3f, 0x6a, 0x69, 0x3c, 0x66, 0x33, 0x30, 0x65,
+    0x66, 0x33, 0x30, 0x65, 0x3f, 0x6a, 0x69, 0x3c,
+    0x3c, 0x69, 0x6a, 0x3f, 0x65, 0x30, 0x33, 0x66,
+    0x03, 0x56, 0x55, 0x00, 0x5a, 0x0f, 0x0c, 0x59,
+    0x59, 0x0c, 0x0f, 0x5a, 0x00, 0x55, 0x56, 0x03,
+    0x69, 0x3c, 0x3f, 0x6a, 0x30, 0x65, 0x66, 0x33,
+    0x33, 0x66, 0x65, 0x30, 0x6a, 0x3f, 0x3c, 0x69,
+    0x0c, 0x59, 0x5a, 0x0f, 0x55, 0x00, 0x03, 0x56,
+    0x56, 0x03, 0x00, 0x55, 0x0f, 0x5a, 0x59, 0x0c,
+    0x0f, 0x5a, 0x59, 0x0c, 0x56, 0x03, 0x00, 0x55,
+    0x55, 0x00, 0x03, 0x56, 0x0c, 0x59, 0x5a, 0x0f,
+    0x6a, 0x3f, 0x3c, 0x69, 0x33, 0x66, 0x65, 0x30,
+    0x30, 0x65, 0x66, 0x33, 0x69, 0x3c, 0x3f, 0x6a,
+    0x6a, 0x3f, 0x3c, 0x69, 0x33, 0x66, 0x65, 0x30,
+    0x30, 0x65, 0x66, 0x33, 0x69, 0x3c, 0x3f, 0x6a,
+    0x0f, 0x5a, 0x59, 0x0c, 0x56, 0x03, 0x00, 0x55,
+    0x55, 0x00, 0x03, 0x56, 0x0c, 0x59, 0x5a, 0x0f,
+    0x0c, 0x59, 0x5a, 0x0f, 0x55, 0x00, 0x03, 0x56,
+    0x56, 0x03, 0x00, 0x55, 0x0f, 0x5a, 0x59, 0x0c,
+    0x69, 0x3c, 0x3f, 0x6a, 0x30, 0x65, 0x66, 0x33,
+    0x33, 0x66, 0x65, 0x30, 0x6a, 0x3f, 0x3c, 0x69,
+    0x03, 0x56, 0x55, 0x00, 0x5a, 0x0f, 0x0c, 0x59,
+    0x59, 0x0c, 0x0f, 0x5a, 0x00, 0x55, 0x56, 0x03,
+    0x66, 0x33, 0x30, 0x65, 0x3f, 0x6a, 0x69, 0x3c,
+    0x3c, 0x69, 0x6a, 0x3f, 0x65, 0x30, 0x33, 0x66,
+    0x65, 0x30, 0x33, 0x66, 0x3c, 0x69, 0x6a, 0x3f,
+    0x3f, 0x6a, 0x69, 0x3c, 0x66, 0x33, 0x30, 0x65,
+    0x00, 0x55, 0x56, 0x03, 0x59, 0x0c, 0x0f, 0x5a,
+    0x5a, 0x0f, 0x0c, 0x59, 0x03, 0x56, 0x55, 0x00,
+};
+
+/* Update ECC parity count.  */
+uint8_t ecc_digest(struct ecc_state_s *s, uint8_t sample)
+{
+    uint8_t idx = nand_ecc_precalc_table[sample];
+
+    s->cp ^= idx & 0x3f;
+    if (idx & 0x40) {
+        s->lp[0] ^= ~s->count;
+        s->lp[1] ^= s->count;
+    }
+    s->count ++;
+
+    return sample;
+}
+
+/* Reinitialise the counters.  */
+void ecc_reset(struct ecc_state_s *s)
+{
+    s->lp[0] = 0x0000;
+    s->lp[1] = 0x0000;
+    s->cp = 0x00;
+    s->count = 0;
+}
+
+/* Save/restore */
+void ecc_put(QEMUFile *f, struct ecc_state_s *s)
+{
+    qemu_put_8s(f, &s->cp);
+    qemu_put_be16s(f, &s->lp[0]);
+    qemu_put_be16s(f, &s->lp[1]);
+    qemu_put_be16s(f, &s->count);
+}
+
+void ecc_get(QEMUFile *f, struct ecc_state_s *s)
+{
+    qemu_get_8s(f, &s->cp);
+    qemu_get_be16s(f, &s->lp[0]);
+    qemu_get_be16s(f, &s->lp[1]);
+    qemu_get_be16s(f, &s->count);
+}

Modified: trunk/src/host/qemu-neo1973/hw/esp.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/esp.c	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/hw/esp.c	2007-10-29 21:14:04 UTC (rev 3303)
@@ -107,9 +107,9 @@
     if (s->dma) {
         espdma_memory_read(s->dma_opaque, buf, dmalen);
     } else {
-	buf[0] = 0;
-	memcpy(&buf[1], s->ti_buf, dmalen);
-	dmalen++;
+        buf[0] = 0;
+        memcpy(&buf[1], s->ti_buf, dmalen);
+        dmalen++;
     }
 
     s->ti_size = 0;
@@ -124,11 +124,11 @@
 
     if (target >= MAX_DISKS || !s->scsi_dev[target]) {
         // No such drive
-	s->rregs[4] = STAT_IN;
-	s->rregs[5] = INTR_DC;
-	s->rregs[6] = SEQ_0;
-	qemu_irq_raise(s->irq);
-	return 0;
+        s->rregs[4] = STAT_IN;
+        s->rregs[5] = INTR_DC;
+        s->rregs[6] = SEQ_0;
+        qemu_irq_raise(s->irq);
+        return 0;
     }
     s->current_dev = s->scsi_dev[target];
     return dmalen;
@@ -190,14 +190,14 @@
     s->ti_buf[1] = 0;
     if (s->dma) {
         espdma_memory_write(s->dma_opaque, s->ti_buf, 2);
-	s->rregs[4] = STAT_IN | STAT_TC | STAT_ST;
-	s->rregs[5] = INTR_BS | INTR_FC;
-	s->rregs[6] = SEQ_CD;
+        s->rregs[4] = STAT_IN | STAT_TC | STAT_ST;
+        s->rregs[5] = INTR_BS | INTR_FC;
+        s->rregs[6] = SEQ_CD;
     } else {
-	s->ti_size = 2;
-	s->ti_rptr = 0;
-	s->ti_wptr = 0;
-	s->rregs[7] = 2;
+        s->ti_size = 2;
+        s->ti_rptr = 0;
+        s->ti_wptr = 0;
+        s->rregs[7] = 2;
     }
     qemu_irq_raise(s->irq);
 }
@@ -359,9 +359,9 @@
     DPRINTF("read reg[%d]: 0x%2.2x\n", saddr, s->rregs[saddr]);
     switch (saddr) {
     case 2:
-	// FIFO
-	if (s->ti_size > 0) {
-	    s->ti_size--;
+        // FIFO
+        if (s->ti_size > 0) {
+            s->ti_size--;
             if ((s->rregs[4] & 6) == 0) {
                 /* Data in/out.  */
                 fprintf(stderr, "esp: PIO data read not implemented\n");
@@ -370,20 +370,20 @@
                 s->rregs[2] = s->ti_buf[s->ti_rptr++];
             }
             qemu_irq_raise(s->irq);
-	}
-	if (s->ti_size == 0) {
+        }
+        if (s->ti_size == 0) {
             s->ti_rptr = 0;
             s->ti_wptr = 0;
         }
-	break;
+        break;
     case 5:
         // interrupt
         // Clear interrupt/error status bits
         s->rregs[4] &= ~(STAT_IN | STAT_GE | STAT_PE);
-	qemu_irq_lower(s->irq);
+        qemu_irq_lower(s->irq);
         break;
     default:
-	break;
+        break;
     }
     return s->rregs[saddr];
 }
@@ -401,7 +401,7 @@
         s->rregs[4] &= ~STAT_TC;
         break;
     case 2:
-	// FIFO
+        // FIFO
         if (s->do_cmd) {
             s->cmdbuf[s->cmdlen++] = val & 0xff;
         } else if ((s->rregs[4] & 6) == 0) {
@@ -413,73 +413,73 @@
             s->ti_size++;
             s->ti_buf[s->ti_wptr++] = val & 0xff;
         }
-	break;
+        break;
     case 3:
         s->rregs[saddr] = val;
-	// Command
-	if (val & 0x80) {
-	    s->dma = 1;
+        // Command
+        if (val & 0x80) {
+            s->dma = 1;
             /* Reload DMA counter.  */
             s->rregs[0] = s->wregs[0];
             s->rregs[1] = s->wregs[1];
-	} else {
-	    s->dma = 0;
-	}
-	switch(val & 0x7f) {
-	case 0:
-	    DPRINTF("NOP (%2.2x)\n", val);
-	    break;
-	case 1:
-	    DPRINTF("Flush FIFO (%2.2x)\n", val);
+        } else {
+            s->dma = 0;
+        }
+        switch(val & 0x7f) {
+        case 0:
+            DPRINTF("NOP (%2.2x)\n", val);
+            break;
+        case 1:
+            DPRINTF("Flush FIFO (%2.2x)\n", val);
             //s->ti_size = 0;
-	    s->rregs[5] = INTR_FC;
-	    s->rregs[6] = 0;
-	    break;
-	case 2:
-	    DPRINTF("Chip reset (%2.2x)\n", val);
-	    esp_reset(s);
-	    break;
-	case 3:
-	    DPRINTF("Bus reset (%2.2x)\n", val);
-	    s->rregs[5] = INTR_RST;
+            s->rregs[5] = INTR_FC;
+            s->rregs[6] = 0;
+            break;
+        case 2:
+            DPRINTF("Chip reset (%2.2x)\n", val);
+            esp_reset(s);
+            break;
+        case 3:
+            DPRINTF("Bus reset (%2.2x)\n", val);
+            s->rregs[5] = INTR_RST;
             if (!(s->wregs[8] & 0x40)) {
                 qemu_irq_raise(s->irq);
             }
-	    break;
-	case 0x10:
-	    handle_ti(s);
-	    break;
-	case 0x11:
-	    DPRINTF("Initiator Command Complete Sequence (%2.2x)\n", val);
-	    write_response(s);
-	    break;
-	case 0x12:
-	    DPRINTF("Message Accepted (%2.2x)\n", val);
-	    write_response(s);
-	    s->rregs[5] = INTR_DC;
-	    s->rregs[6] = 0;
-	    break;
-	case 0x1a:
-	    DPRINTF("Set ATN (%2.2x)\n", val);
-	    break;
-	case 0x42:
-	    DPRINTF("Set ATN (%2.2x)\n", val);
-	    handle_satn(s);
-	    break;
-	case 0x43:
-	    DPRINTF("Set ATN & stop (%2.2x)\n", val);
-	    handle_satn_stop(s);
-	    break;
+            break;
+        case 0x10:
+            handle_ti(s);
+            break;
+        case 0x11:
+            DPRINTF("Initiator Command Complete Sequence (%2.2x)\n", val);
+            write_response(s);
+            break;
+        case 0x12:
+            DPRINTF("Message Accepted (%2.2x)\n", val);
+            write_response(s);
+            s->rregs[5] = INTR_DC;
+            s->rregs[6] = 0;
+            break;
+        case 0x1a:
+            DPRINTF("Set ATN (%2.2x)\n", val);
+            break;
+        case 0x42:
+            DPRINTF("Set ATN (%2.2x)\n", val);
+            handle_satn(s);
+            break;
+        case 0x43:
+            DPRINTF("Set ATN & stop (%2.2x)\n", val);
+            handle_satn_stop(s);
+            break;
         case 0x44:
             DPRINTF("Enable selection (%2.2x)\n", val);
             break;
-	default:
-	    DPRINTF("Unhandled ESP command (%2.2x)\n", val);
-	    break;
-	}
-	break;
+        default:
+            DPRINTF("Unhandled ESP command (%2.2x)\n", val);
+            break;
+        }
+        break;
     case 4 ... 7:
-	break;
+        break;
     case 8:
         s->rregs[saddr] = val;
         break;
@@ -492,7 +492,7 @@
         s->rregs[saddr] = val;
         break;
     default:
-	break;
+        break;
     }
     s->wregs[saddr] = val;
 }

Added: trunk/src/host/qemu-neo1973/hw/etraxfs.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/etraxfs.c	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/hw/etraxfs.c	2007-10-29 21:14:04 UTC (rev 3303)
@@ -0,0 +1,178 @@
+/*
+ * QEMU ETRAX System Emulator
+ *
+ * Copyright (c) 2007 Edgar E. Iglesias, Axis Communications AB.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include <time.h>
+#include <sys/time.h>
+#include "vl.h"
+
+extern FILE *logfile;
+
+static void main_cpu_reset(void *opaque)
+{
+    CPUState *env = opaque;
+    cpu_reset(env);
+}
+
+static uint32_t fs_mmio_readb (void *opaque, target_phys_addr_t addr)
+{
+	CPUState *env = opaque;
+	uint32_t r = 0;
+	printf ("%s %x pc=%x\n", __func__, addr, env->pc);
+	return r;
+}
+static uint32_t fs_mmio_readw (void *opaque, target_phys_addr_t addr)
+{
+	CPUState *env = opaque;
+	uint32_t r = 0;
+	printf ("%s %x pc=%x\n", __func__, addr, env->pc);
+	return r;
+}
+
+static uint32_t fs_mmio_readl (void *opaque, target_phys_addr_t addr)
+{
+	CPUState *env = opaque;
+	uint32_t r = 0;
+	printf ("%s %x p=%x\n", __func__, addr, env->pc);
+	return r;
+}
+
+static void
+fs_mmio_writeb (void *opaque, target_phys_addr_t addr, uint32_t value)
+{
+	CPUState *env = opaque;
+	printf ("%s %x %x pc=%x\n", __func__, addr, value, env->pc);
+}
+static void
+fs_mmio_writew (void *opaque, target_phys_addr_t addr, uint32_t value)
+{
+	CPUState *env = opaque;
+	printf ("%s %x %x pc=%x\n", __func__, addr, value, env->pc);
+}
+static void
+fs_mmio_writel (void *opaque, target_phys_addr_t addr, uint32_t value)
+{
+	CPUState *env = opaque;
+	printf ("%s %x %x pc=%x\n", __func__, addr, value, env->pc);
+}
+
+static CPUReadMemoryFunc *fs_mmio_read[] = {
+    &fs_mmio_readb,
+    &fs_mmio_readw,
+    &fs_mmio_readl,
+};
+
+static CPUWriteMemoryFunc *fs_mmio_write[] = {
+    &fs_mmio_writeb,
+    &fs_mmio_writew,
+    &fs_mmio_writel,
+};
+
+
+/* Init functions for different blocks.  */
+extern void etraxfs_timer_init(CPUState *env, qemu_irq *irqs);
+extern void etraxfs_ser_init(CPUState *env, qemu_irq *irqs);
+
+void etrax_ack_irq(CPUState *env, uint32_t mask)
+{
+	env->pending_interrupts &= ~mask;
+}
+
+static void dummy_cpu_set_irq(void *opaque, int irq, int level)
+{
+	CPUState *env = opaque;
+
+	/* Hmm, should this really be done here?  */
+	env->pending_interrupts |= 1 << irq;
+	cpu_interrupt(env, CPU_INTERRUPT_HARD);
+}
+
+static
+void bareetraxfs_init (int ram_size, int vga_ram_size, int boot_device,
+                       DisplayState *ds, const char **fd_filename, int snapshot,
+                       const char *kernel_filename, const char *kernel_cmdline,
+                       const char *initrd_filename, const char *cpu_model)
+{
+    CPUState *env;
+    qemu_irq *irqs;
+    int kernel_size;
+    int internal_regs;
+
+    /* init CPUs */
+    if (cpu_model == NULL) {
+        cpu_model = "crisv32";
+    }
+    env = cpu_init();
+/*    register_savevm("cpu", 0, 3, cpu_save, cpu_load, env); */
+    qemu_register_reset(main_cpu_reset, env);
+    irqs = qemu_allocate_irqs(dummy_cpu_set_irq, env, 32);
+
+    internal_regs = cpu_register_io_memory(0,
+					   fs_mmio_read, fs_mmio_write, env);
+    /* 0xb0050000 is the last reg.  */
+    cpu_register_physical_memory (0xac000000, 0x4010000, internal_regs);
+    /* allocate RAM */
+    cpu_register_physical_memory(0x40000000, ram_size, IO_MEM_RAM);
+
+    etraxfs_timer_init(env, irqs);
+    etraxfs_ser_init(env, irqs);
+
+    kernel_size = load_image(kernel_filename, phys_ram_base + 0x4000);
+    /* magic for boot.  */
+    env->regs[8] = 0x56902387;
+    env->regs[9] = 0x40004000 + kernel_size;
+    env->pc = 0x40004000;
+
+    {
+       unsigned char *ptr = phys_ram_base + 0x4000;
+       int i;
+       for (i = 0; i < 8; i++)
+       {
+		printf ("%2.2x ", ptr[i]);
+       }
+	printf("\n");
+    }
+
+    printf ("pc =%x\n", env->pc);
+    printf ("ram size =%d\n", ram_size);
+    printf ("kernel name =%s\n", kernel_filename);
+    printf ("kernel size =%d\n", kernel_size);
+    printf ("cpu haltd =%d\n", env->halted);
+}
+
+void DMA_run(void)
+{
+}
+
+void pic_info()
+{
+}
+
+void irq_info()
+{
+}
+
+QEMUMachine bareetraxfs_machine = {
+    "bareetraxfs",
+    "Bare ETRAX FS board",
+    bareetraxfs_init,
+};

Added: trunk/src/host/qemu-neo1973/hw/etraxfs_ser.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/etraxfs_ser.c	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/hw/etraxfs_ser.c	2007-10-29 21:14:04 UTC (rev 3303)
@@ -0,0 +1,122 @@
+/*
+ * QEMU ETRAX System Emulator
+ *
+ * Copyright (c) 2007 Edgar E. Iglesias, Axis Communications AB.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include <stdio.h>
+#include <ctype.h>
+#include "vl.h"
+
+#define RW_TR_DMA_EN 0xb0026004
+#define RW_DOUT 0xb002601c
+#define RW_STAT_DIN 0xb0026020
+#define R_STAT_DIN 0xb0026024
+
+static uint32_t ser_readb (void *opaque, target_phys_addr_t addr)
+{
+	CPUState *env = opaque;
+	uint32_t r = 0;
+	printf ("%s %x pc=%x\n", __func__, addr, env->pc);
+	return r;
+}
+static uint32_t ser_readw (void *opaque, target_phys_addr_t addr)
+{
+	CPUState *env = opaque;
+	uint32_t r = 0;
+	printf ("%s %x pc=%x\n", __func__, addr, env->pc);
+	return r;
+}
+
+static uint32_t ser_readl (void *opaque, target_phys_addr_t addr)
+{
+	CPUState *env = opaque;
+	uint32_t r = 0;
+
+	switch (addr)
+	{
+		case RW_TR_DMA_EN:
+			break;
+		case R_STAT_DIN:
+			r |= 1 << 24; /* set tr_rdy.  */
+			r |= 1 << 22; /* set tr_idle.  */
+			break;
+
+		default:
+			printf ("%s %x p=%x\n", __func__, addr, env->pc);
+			break;
+	}
+	return r;
+}
+
+static void
+ser_writeb (void *opaque, target_phys_addr_t addr, uint32_t value)
+{
+	CPUState *env = opaque;
+	printf ("%s %x %x pc=%x\n", __func__, addr, value, env->pc);
+}
+static void
+ser_writew (void *opaque, target_phys_addr_t addr, uint32_t value)
+{
+	CPUState *env = opaque;
+	printf ("%s %x %x pc=%x\n", __func__, addr, value, env->pc);
+}
+static void
+ser_writel (void *opaque, target_phys_addr_t addr, uint32_t value)
+{
+	CPUState *env = opaque;
+
+	switch (addr)
+	{
+		case RW_TR_DMA_EN:
+			break;
+		case RW_DOUT:
+			if (isprint(value) || isspace(value))
+				putchar(value);
+			else
+				putchar('.');
+			break;
+		default:
+			printf ("%s %x %x pc=%x\n",
+				__func__, addr, value, env->pc);
+			break;
+	}
+}
+
+static CPUReadMemoryFunc *ser_read[] = {
+    &ser_readb,
+    &ser_readw,
+    &ser_readl,
+};
+
+static CPUWriteMemoryFunc *ser_write[] = {
+    &ser_writeb,
+    &ser_writew,
+    &ser_writel,
+};
+
+void etraxfs_ser_init(CPUState *env, qemu_irq *irqs)
+{
+	int ser_regs;
+
+	ser_regs = cpu_register_io_memory(0, ser_read, ser_write, env);
+	cpu_register_physical_memory (0xb0026000, 0x3c, ser_regs);
+}

Added: trunk/src/host/qemu-neo1973/hw/etraxfs_timer.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/etraxfs_timer.c	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/hw/etraxfs_timer.c	2007-10-29 21:14:04 UTC (rev 3303)
@@ -0,0 +1,268 @@
+/*
+ * QEMU ETRAX System Emulator
+ *
+ * Copyright (c) 2007 Edgar E. Iglesias, Axis Communications AB.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include <stdio.h>
+#include <sys/time.h>
+#include "vl.h"
+
+void etrax_ack_irq(CPUState *env, uint32_t mask);
+
+#define R_TIME 0xb001e038
+#define RW_TMR0_DIV 0xb001e000
+#define R_TMR0_DATA 0xb001e004
+#define RW_TMR0_CTRL 0xb001e008
+#define RW_TMR1_DIV 0xb001e010
+#define R_TMR1_DATA 0xb001e014
+#define RW_TMR1_CTRL 0xb001e018
+
+#define RW_INTR_MASK 0xb001e048
+#define RW_ACK_INTR 0xb001e04c
+#define R_INTR 0xb001e050
+#define R_MASKED_INTR 0xb001e054
+
+
+uint32_t rw_intr_mask;
+uint32_t rw_ack_intr;
+uint32_t r_intr;
+
+struct fs_timer_t {
+	QEMUBH *bh;
+	unsigned int limit;
+	int scale;
+	ptimer_state *ptimer;
+	CPUState *env;
+	qemu_irq *irq;
+	uint32_t mask;
+};
+
+static struct fs_timer_t timer0;
+
+/* diff two timevals.  Return a single int in us. */
+int diff_timeval_us(struct timeval *a, struct timeval *b)
+{
+        int diff;
+
+        /* assume these values are signed.  */
+        diff = (a->tv_sec - b->tv_sec) * 1000 * 1000;
+        diff += (a->tv_usec - b->tv_usec);
+        return diff;
+}
+
+static uint32_t timer_readb (void *opaque, target_phys_addr_t addr)
+{
+	CPUState *env = opaque;
+	uint32_t r = 0;
+	printf ("%s %x pc=%x\n", __func__, addr, env->pc);
+	return r;
+}
+static uint32_t timer_readw (void *opaque, target_phys_addr_t addr)
+{
+	CPUState *env = opaque;
+	uint32_t r = 0;
+	printf ("%s %x pc=%x\n", __func__, addr, env->pc);
+	return r;
+}
+
+static uint32_t timer_readl (void *opaque, target_phys_addr_t addr)
+{
+	CPUState *env = opaque;
+	uint32_t r = 0;
+
+	switch (addr) {
+	case R_TMR0_DATA:
+		break;
+	case R_TMR1_DATA:
+		printf ("R_TMR1_DATA\n");
+		break;
+	case R_TIME:
+	{
+		static struct timeval last;
+		struct timeval now;
+		gettimeofday(&now, NULL);
+		if (!(last.tv_sec == 0 && last.tv_usec == 0)) {
+			r = diff_timeval_us(&now, &last);
+			r *= 1000; /* convert to ns.  */
+			r++; /* make sure we increase for each call.  */
+		}
+		last = now;
+		break;
+	}
+
+	case RW_INTR_MASK:
+		r = rw_intr_mask;
+		break;
+	case R_MASKED_INTR:
+		r = r_intr & rw_intr_mask;
+		break;
+	default:
+		printf ("%s %x p=%x\n", __func__, addr, env->pc);
+		break;
+	}
+	return r;
+}
+
+static void
+timer_writeb (void *opaque, target_phys_addr_t addr, uint32_t value)
+{
+	CPUState *env = opaque;
+	printf ("%s %x %x pc=%x\n", __func__, addr, value, env->pc);
+}
+static void
+timer_writew (void *opaque, target_phys_addr_t addr, uint32_t value)
+{
+	CPUState *env = opaque;
+	printf ("%s %x %x pc=%x\n", __func__, addr, value, env->pc);
+}
+
+static void write_ctrl(struct fs_timer_t *t, uint32_t v)
+{
+	int op;
+	int freq;
+	int freq_hz;
+
+	op = v & 3;
+	freq = v >> 2;
+	freq_hz = 32000000;
+
+	switch (freq)
+	{
+	case 0:
+	case 1:
+		printf ("extern or disabled timer clock?\n");
+		break;
+	case 4: freq_hz =  29493000; break;
+	case 5: freq_hz =  32000000; break;
+	case 6: freq_hz =  32768000; break;
+	case 7: freq_hz = 100000000; break;
+	default:
+		abort();
+		break;
+	}
+
+	printf ("freq_hz=%d limit=%d\n", freq_hz, t->limit);
+	t->scale = 0;
+	if (t->limit > 2048)
+	{
+		t->scale = 2048;
+		ptimer_set_period(timer0.ptimer, freq_hz / t->scale);
+	}
+
+	printf ("op=%d\n", op);
+	switch (op)
+	{
+		case 0:
+			printf ("limit=%d %d\n", t->limit, t->limit/t->scale);
+			ptimer_set_limit(t->ptimer, t->limit / t->scale, 1);
+			break;
+		case 1:
+			ptimer_stop(t->ptimer);
+			break;
+		case 2:
+			ptimer_run(t->ptimer, 0);
+			break;
+		default:
+			abort();
+			break;
+	}
+}
+
+static void timer_ack_irq(void)
+{
+	if (!(r_intr & timer0.mask & rw_intr_mask)) {
+		qemu_irq_lower(timer0.irq[0]);
+		etrax_ack_irq(timer0.env, 1 << 0x1b);
+	}
+}
+
+static void
+timer_writel (void *opaque, target_phys_addr_t addr, uint32_t value)
+{
+	CPUState *env = opaque;
+	printf ("%s %x %x pc=%x\n",
+		__func__, addr, value, env->pc);
+	switch (addr)
+	{
+		case RW_TMR0_DIV:
+			printf ("RW_TMR0_DIV=%x\n", value);
+			timer0.limit = value;
+			break;
+		case RW_TMR0_CTRL:
+			printf ("RW_TMR0_CTRL=%x\n", value);
+			write_ctrl(&timer0, value);
+			break;
+		case RW_TMR1_DIV:
+			printf ("RW_TMR1_DIV=%x\n", value);
+			break;
+		case RW_TMR1_CTRL:
+			printf ("RW_TMR1_CTRL=%x\n", value);
+			break;
+		case RW_INTR_MASK:
+			printf ("RW_INTR_MASK=%x\n", value);
+			rw_intr_mask = value;
+			break;
+		case RW_ACK_INTR:
+			r_intr &= ~value;
+			timer_ack_irq();
+			break;
+		default:
+			printf ("%s %x %x pc=%x\n",
+				__func__, addr, value, env->pc);
+			break;
+	}
+}
+
+static CPUReadMemoryFunc *timer_read[] = {
+    &timer_readb,
+    &timer_readw,
+    &timer_readl,
+};
+
+static CPUWriteMemoryFunc *timer_write[] = {
+    &timer_writeb,
+    &timer_writew,
+    &timer_writel,
+};
+
+static void timer_irq(void *opaque)
+{
+	struct fs_timer_t *t = opaque;
+
+	r_intr |= t->mask;
+	if (t->mask & rw_intr_mask) {
+		qemu_irq_raise(t->irq[0]);
+	}
+}
+
+void etraxfs_timer_init(CPUState *env, qemu_irq *irqs)
+{
+	int timer_regs;
+
+	timer0.bh = qemu_bh_new(timer_irq, &timer0);
+	timer0.ptimer = ptimer_init(timer0.bh);
+	timer0.irq = irqs + 0x1b;
+	timer0.mask = 1;
+	timer0.env = env;
+
+	timer_regs = cpu_register_io_memory(0, timer_read, timer_write, env);
+	cpu_register_physical_memory (0xb001e000, 0x5c, timer_regs);
+}

Modified: trunk/src/host/qemu-neo1973/hw/grackle_pci.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/grackle_pci.c	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/hw/grackle_pci.c	2007-10-29 21:14:04 UTC (rev 3303)
@@ -1,7 +1,8 @@
 /*
- * QEMU Grackle (heathrow PPC) PCI host
+ * QEMU Grackle PCI host (heathrow OldWorld PowerMac)
  *
- * Copyright (c) 2006 Fabrice Bellard
+ * Copyright (c) 2006-2007 Fabrice Bellard
+ * Copyright (c) 2007 Jocelyn Mayer
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy
  * of this software and associated documentation files (the "Software"), to deal
@@ -23,6 +24,7 @@
  */
 
 #include "vl.h"
+#include "ppc_mac.h"
 typedef target_phys_addr_t pci_addr_t;
 #include "pci_host.h"
 
@@ -82,7 +84,7 @@
 
 static void pci_grackle_set_irq(qemu_irq *pic, int irq_num, int level)
 {
-    qemu_set_irq(pic[irq_num + 8], level);
+    qemu_set_irq(pic[irq_num + 0x15], level);
 }
 
 PCIBus *pci_grackle_init(uint32_t base, qemu_irq *pic)
@@ -93,7 +95,7 @@
 
     s = qemu_mallocz(sizeof(GrackleState));
     s->bus = pci_register_bus(pci_grackle_set_irq, pci_grackle_map_irq,
-                              pic, 0, 0);
+                              pic, 0, 4);
 
     pci_mem_config = cpu_register_io_memory(0, pci_grackle_config_read,
                                             pci_grackle_config_write, s);

Modified: trunk/src/host/qemu-neo1973/hw/gt64xxx.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/gt64xxx.c	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/hw/gt64xxx.c	2007-10-29 21:14:04 UTC (rev 3303)
@@ -306,9 +306,8 @@
     GT64120State *s = opaque;
     uint32_t saddr;
 
-#ifdef TARGET_WORDS_BIGENDIAN
-    val = bswap32(val);
-#endif
+    if (!(s->regs[GT_PCI0_CMD] & 1))
+        val = bswap32(val);
 
     saddr = (addr & 0xfff) >> 2;
     switch (saddr) {
@@ -528,8 +527,7 @@
         s->pci->config_reg = val & 0x80fffffc;
         break;
     case GT_PCI0_CFGDATA:
-        if (s->pci->config_reg & (1u << 31))
-            pci_host_data_writel(s->pci, 0, val);
+        pci_host_data_writel(s->pci, 0, val);
         break;
 
     /* Interrupts */
@@ -585,9 +583,7 @@
     uint32_t val;
     uint32_t saddr;
 
-    val = 0;
     saddr = (addr & 0xfff) >> 2;
-
     switch (saddr) {
 
     /* CPU Configuration */
@@ -768,10 +764,7 @@
         val = s->pci->config_reg;
         break;
     case GT_PCI0_CFGDATA:
-        if (!(s->pci->config_reg & (1u << 31)))
-            val = 0xffffffff;
-        else
-            val = pci_host_data_readl(s->pci, 0);
+        val = pci_host_data_readl(s->pci, 0);
         break;
 
     case GT_PCI0_CMD:
@@ -844,9 +837,9 @@
         break;
     }
 
-#ifdef TARGET_WORDS_BIGENDIAN
-    val = bswap32(val);
-#endif
+    if (!(s->regs[GT_PCI0_CMD] & 1))
+        val = bswap32(val);
+
     return val;
 }
 
@@ -1083,19 +1076,12 @@
 
 static uint32_t gt64120_read_config(PCIDevice *d, uint32_t address, int len)
 {
-    uint32_t val = pci_default_read_config(d, address, len);
-#ifdef TARGET_WORDS_BIGENDIAN
-    val = bswap32(val);
-#endif
-    return val;
+    return pci_default_read_config(d, address, len);
 }
 
 static void gt64120_write_config(PCIDevice *d, uint32_t address, uint32_t val,
                                  int len)
 {
-#ifdef TARGET_WORDS_BIGENDIAN
-    val = bswap32(val);
-#endif
     pci_default_write_config(d, address, val, len);
 }
 

Modified: trunk/src/host/qemu-neo1973/hw/heathrow_pic.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/heathrow_pic.c	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/hw/heathrow_pic.c	2007-10-29 21:14:04 UTC (rev 3303)
@@ -1,7 +1,8 @@
 /*
- * Heathrow PIC support (standard PowerMac PIC)
+ * Heathrow PIC support (OldWorld PowerMac)
  *
- * Copyright (c) 2005 Fabrice Bellard
+ * Copyright (c) 2005-2007 Fabrice Bellard
+ * Copyright (c) 2007 Jocelyn Mayer
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy
  * of this software and associated documentation files (the "Software"), to deal
@@ -22,6 +23,7 @@
  * THE SOFTWARE.
  */
 #include "vl.h"
+#include "ppc_mac.h"
 
 //#define DEBUG
 
@@ -34,6 +36,7 @@
 
 typedef struct HeathrowPICS {
     HeathrowPIC pics[2];
+    qemu_irq *irqs;
 } HeathrowPICS;
 
 static inline int check_irq(HeathrowPIC *pic)
@@ -45,9 +48,9 @@
 static void heathrow_pic_update(HeathrowPICS *s)
 {
     if (check_irq(&s->pics[0]) || check_irq(&s->pics[1])) {
-        cpu_interrupt(first_cpu, CPU_INTERRUPT_HARD);
+        qemu_irq_raise(s->irqs[0]);
     } else {
-        cpu_reset_interrupt(first_cpu, CPU_INTERRUPT_HARD);
+        qemu_irq_lower(s->irqs[0]);
     }
 }
 
@@ -57,12 +60,13 @@
     HeathrowPIC *pic;
     unsigned int n;
 
+#ifdef TARGET_WORDS_BIGENDIAN
     value = bswap32(value);
+#endif
+    n = ((addr & 0xfff) - 0x10) >> 4;
 #ifdef DEBUG
-    printf("pic_writel: %08x: %08x\n",
-           addr, value);
+    printf("pic_writel: " PADDRX " %u: %08x\n", addr, n, value);
 #endif
-    n = ((addr & 0xfff) - 0x10) >> 4;
     if (n >= 2)
         return;
     pic = &s->pics[n];
@@ -110,10 +114,11 @@
         }
     }
 #ifdef DEBUG
-    printf("pic_readl: %08x: %08x\n",
-           addr, value);
+    printf("pic_readl: " PADDRX " %u: %08x\n", addr, n, value);
 #endif
+#ifdef TARGET_WORDS_BIGENDIAN
     value = bswap32(value);
+#endif
     return value;
 }
 
@@ -156,13 +161,17 @@
     heathrow_pic_update(s);
 }
 
-qemu_irq *heathrow_pic_init(int *pmem_index)
+qemu_irq *heathrow_pic_init(int *pmem_index,
+                            int nb_cpus, qemu_irq **irqs)
 {
     HeathrowPICS *s;
 
     s = qemu_mallocz(sizeof(HeathrowPICS));
     s->pics[0].level_triggered = 0;
     s->pics[1].level_triggered = 0x1ff00000;
+    /* only 1 CPU */
+    s->irqs = irqs[0];
     *pmem_index = cpu_register_io_memory(0, pic_read, pic_write, s);
+
     return qemu_allocate_irqs(heathrow_pic_set_irq, s, 64);
 }

Modified: trunk/src/host/qemu-neo1973/hw/i8259.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/i8259.c	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/hw/i8259.c	2007-10-29 21:14:04 UTC (rev 3303)
@@ -164,7 +164,7 @@
     }
 
 /* all targets should do this rather than acking the IRQ in the cpu */
-#if defined(TARGET_MIPS)
+#if defined(TARGET_MIPS) || defined(TARGET_PPC)
     else {
         qemu_irq_lower(s->parent_irq);
     }

Modified: trunk/src/host/qemu-neo1973/hw/iommu.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/iommu.c	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/hw/iommu.c	2007-10-29 21:14:04 UTC (rev 3303)
@@ -81,7 +81,7 @@
 #define IOMMU_SBCFG_BA16    0x00000004 /* Slave supports 16 byte bursts */
 #define IOMMU_SBCFG_BA8     0x00000002 /* Slave supports 8 byte bursts */
 #define IOMMU_SBCFG_BYPASS  0x00000001 /* Bypass IOMMU, treat all addresses
-       	                                  produced by this device as pure
+                                          produced by this device as pure
                                           physical. */
 #define IOMMU_SBCFG_MASK    0x00010003
 
@@ -98,7 +98,7 @@
 
 #define PAGE_SHIFT      12
 #define PAGE_SIZE       (1 << PAGE_SHIFT)
-#define PAGE_MASK	(PAGE_SIZE - 1)
+#define PAGE_MASK       (PAGE_SIZE - 1)
 
 typedef struct IOMMUState {
     target_phys_addr_t addr;
@@ -114,9 +114,9 @@
     saddr = (addr - s->addr) >> 2;
     switch (saddr) {
     default:
-	DPRINTF("read reg[%d] = %x\n", (int)saddr, s->regs[saddr]);
-	return s->regs[saddr];
-	break;
+        DPRINTF("read reg[%d] = %x\n", (int)saddr, s->regs[saddr]);
+        return s->regs[saddr];
+        break;
     }
     return 0;
 }
@@ -130,61 +130,61 @@
     DPRINTF("write reg[%d] = %x\n", (int)saddr, val);
     switch (saddr) {
     case IOMMU_CTRL:
-	switch (val & IOMMU_CTRL_RNGE) {
-	case IOMMU_RNGE_16MB:
-	    s->iostart = 0xffffffffff000000ULL;
-	    break;
-	case IOMMU_RNGE_32MB:
-	    s->iostart = 0xfffffffffe000000ULL;
-	    break;
-	case IOMMU_RNGE_64MB:
-	    s->iostart = 0xfffffffffc000000ULL;
-	    break;
-	case IOMMU_RNGE_128MB:
-	    s->iostart = 0xfffffffff8000000ULL;
-	    break;
-	case IOMMU_RNGE_256MB:
-	    s->iostart = 0xfffffffff0000000ULL;
-	    break;
-	case IOMMU_RNGE_512MB:
-	    s->iostart = 0xffffffffe0000000ULL;
-	    break;
-	case IOMMU_RNGE_1GB:
-	    s->iostart = 0xffffffffc0000000ULL;
-	    break;
-	default:
-	case IOMMU_RNGE_2GB:
-	    s->iostart = 0xffffffff80000000ULL;
-	    break;
-	}
-	DPRINTF("iostart = " TARGET_FMT_plx "\n", s->iostart);
-	s->regs[saddr] = ((val & IOMMU_CTRL_MASK) | IOMMU_VERSION);
-	break;
+        switch (val & IOMMU_CTRL_RNGE) {
+        case IOMMU_RNGE_16MB:
+            s->iostart = 0xffffffffff000000ULL;
+            break;
+        case IOMMU_RNGE_32MB:
+            s->iostart = 0xfffffffffe000000ULL;
+            break;
+        case IOMMU_RNGE_64MB:
+            s->iostart = 0xfffffffffc000000ULL;
+            break;
+        case IOMMU_RNGE_128MB:
+            s->iostart = 0xfffffffff8000000ULL;
+            break;
+        case IOMMU_RNGE_256MB:
+            s->iostart = 0xfffffffff0000000ULL;
+            break;
+        case IOMMU_RNGE_512MB:
+            s->iostart = 0xffffffffe0000000ULL;
+            break;
+        case IOMMU_RNGE_1GB:
+            s->iostart = 0xffffffffc0000000ULL;
+            break;
+        default:
+        case IOMMU_RNGE_2GB:
+            s->iostart = 0xffffffff80000000ULL;
+            break;
+        }
+        DPRINTF("iostart = " TARGET_FMT_plx "\n", s->iostart);
+        s->regs[saddr] = ((val & IOMMU_CTRL_MASK) | IOMMU_VERSION);
+        break;
     case IOMMU_BASE:
-	s->regs[saddr] = val & IOMMU_BASE_MASK;
-	break;
+        s->regs[saddr] = val & IOMMU_BASE_MASK;
+        break;
     case IOMMU_TLBFLUSH:
-	DPRINTF("tlb flush %x\n", val);
-	s->regs[saddr] = val & IOMMU_TLBFLUSH_MASK;
-	break;
+        DPRINTF("tlb flush %x\n", val);
+        s->regs[saddr] = val & IOMMU_TLBFLUSH_MASK;
+        break;
     case IOMMU_PGFLUSH:
-	DPRINTF("page flush %x\n", val);
-	s->regs[saddr] = val & IOMMU_PGFLUSH_MASK;
-	break;
+        DPRINTF("page flush %x\n", val);
+        s->regs[saddr] = val & IOMMU_PGFLUSH_MASK;
+        break;
     case IOMMU_SBCFG0:
     case IOMMU_SBCFG1:
     case IOMMU_SBCFG2:
     case IOMMU_SBCFG3:
-	s->regs[saddr] = val & IOMMU_SBCFG_MASK;
-	break;
+        s->regs[saddr] = val & IOMMU_SBCFG_MASK;
+        break;
     case IOMMU_ARBEN:
         // XXX implement SBus probing: fault when reading unmapped
         // addresses, fault cause and address stored to MMU/IOMMU
-	s->regs[saddr] = (val & IOMMU_ARBEN_MASK) | IOMMU_MID;
-	break;
+        s->regs[saddr] = (val & IOMMU_ARBEN_MASK) | IOMMU_MID;
+        break;
     default:
-	s->regs[saddr] = val;
-	break;
+        s->regs[saddr] = val;
+        break;
     }
 }
 
@@ -202,7 +202,8 @@
 
 static uint32_t iommu_page_get_flags(IOMMUState *s, target_phys_addr_t addr)
 {
-    uint32_t iopte, ret;
+    uint32_t ret;
+    target_phys_addr_t iopte;
 #ifdef DEBUG_IOMMU
     target_phys_addr_t pa = addr;
 #endif
@@ -210,9 +211,10 @@
     iopte = s->regs[IOMMU_BASE] << 4;
     addr &= ~s->iostart;
     iopte += (addr >> (PAGE_SHIFT - 2)) & ~3;
-    ret = ldl_phys(iopte);
-    DPRINTF("get flags addr " TARGET_FMT_plx " => pte %x, *ptes = %x\n", pa,
-            iopte, ret);
+    cpu_physical_memory_read(iopte, (uint8_t *)&ret, 4);
+    tswap32s(&ret);
+    DPRINTF("get flags addr " TARGET_FMT_plx " => pte " TARGET_FMT_plx
+            ", *pte = %x\n", pa, iopte, ret);
 
     return ret;
 }
@@ -281,7 +283,7 @@
     int i;
 
     for (i = 0; i < IOMMU_NREGS; i++)
-	qemu_put_be32s(f, &s->regs[i]);
+        qemu_put_be32s(f, &s->regs[i]);
     qemu_put_be64s(f, &s->iostart);
 }
 

Modified: trunk/src/host/qemu-neo1973/hw/irq.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/irq.c	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/hw/irq.c	2007-10-29 21:14:04 UTC (rev 3303)
@@ -55,3 +55,14 @@
     return s;
 }
 
+static void qemu_notirq(void *opaque, int line, int level)
+{
+    struct IRQState *irq = opaque;
+
+    irq->handler(irq->opaque, irq->n, !level);
+}
+
+qemu_irq qemu_irq_invert(qemu_irq irq)
+{
+    return qemu_allocate_irqs(qemu_notirq, irq, 1)[0];
+}

Modified: trunk/src/host/qemu-neo1973/hw/irq.h
===================================================================
--- trunk/src/host/qemu-neo1973/hw/irq.h	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/hw/irq.h	2007-10-29 21:14:04 UTC (rev 3303)
@@ -19,3 +19,5 @@
 /* Returns an array of N IRQs.  */
 qemu_irq *qemu_allocate_irqs(qemu_irq_handler handler, void *opaque, int n);
 
+/* Returns a new IRQ with opposite polarity.  */
+qemu_irq qemu_irq_invert(qemu_irq irq);

Modified: trunk/src/host/qemu-neo1973/hw/m48t59.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/m48t59.c	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/hw/m48t59.c	2007-10-29 21:14:04 UTC (rev 3303)
@@ -161,10 +161,9 @@
     NVRAM->alarm = mktime(tm);
     if (NVRAM->alrm_timer != NULL) {
         qemu_del_timer(NVRAM->alrm_timer);
-	NVRAM->alrm_timer = NULL;
+        if (NVRAM->alarm - time(NULL) > 0)
+            qemu_mod_timer(NVRAM->alrm_timer, NVRAM->alarm * 1000);
     }
-    if (NVRAM->alarm - time(NULL) > 0)
-	qemu_mod_timer(NVRAM->alrm_timer, NVRAM->alarm * 1000);
 }
 
 /* Watchdog management */
@@ -188,21 +187,21 @@
 {
     uint64_t interval; /* in 1/16 seconds */
 
+    NVRAM->buffer[0x1FF0] &= ~0x80;
     if (NVRAM->wd_timer != NULL) {
         qemu_del_timer(NVRAM->wd_timer);
-	NVRAM->wd_timer = NULL;
+        if (value != 0) {
+            interval = (1 << (2 * (value & 0x03))) * ((value >> 2) & 0x1F);
+            qemu_mod_timer(NVRAM->wd_timer, ((uint64_t)time(NULL) * 1000) +
+                           ((interval * 1000) >> 4));
+        }
     }
-    NVRAM->buffer[0x1FF0] &= ~0x80;
-    if (value != 0) {
-	interval = (1 << (2 * (value & 0x03))) * ((value >> 2) & 0x1F);
-	qemu_mod_timer(NVRAM->wd_timer, ((uint64_t)time(NULL) * 1000) +
-		       ((interval * 1000) >> 4));
-    }
 }
 
 /* Direct access to NVRAM */
-void m48t59_write (m48t59_t *NVRAM, uint32_t addr, uint32_t val)
+void m48t59_write (void *opaque, uint32_t addr, uint32_t val)
 {
+    m48t59_t *NVRAM = opaque;
     struct tm tm;
     int tmp;
 
@@ -359,8 +358,9 @@
     }
 }
 
-uint32_t m48t59_read (m48t59_t *NVRAM, uint32_t addr)
+uint32_t m48t59_read (void *opaque, uint32_t addr)
 {
+    m48t59_t *NVRAM = opaque;
     struct tm tm;
     uint32_t retval = 0xFF;
 
@@ -453,13 +453,17 @@
     return retval;
 }
 
-void m48t59_set_addr (m48t59_t *NVRAM, uint32_t addr)
+void m48t59_set_addr (void *opaque, uint32_t addr)
 {
+    m48t59_t *NVRAM = opaque;
+
     NVRAM->addr = addr;
 }
 
-void m48t59_toggle_lock (m48t59_t *NVRAM, int lock)
+void m48t59_toggle_lock (void *opaque, int lock)
 {
+    m48t59_t *NVRAM = opaque;
+
     NVRAM->lock ^= 1 << lock;
 }
 

Modified: trunk/src/host/qemu-neo1973/hw/m48t59.h
===================================================================
--- trunk/src/host/qemu-neo1973/hw/m48t59.h	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/hw/m48t59.h	2007-10-29 21:14:04 UTC (rev 3303)
@@ -3,9 +3,9 @@
 
 typedef struct m48t59_t m48t59_t;
 
-void m48t59_write (m48t59_t *NVRAM, uint32_t addr, uint32_t val);
-uint32_t m48t59_read (m48t59_t *NVRAM, uint32_t addr);
-void m48t59_toggle_lock (m48t59_t *NVRAM, int lock);
+void m48t59_write (void *private, uint32_t addr, uint32_t val);
+uint32_t m48t59_read (void *private, uint32_t addr);
+void m48t59_toggle_lock (void *private, int lock);
 m48t59_t *m48t59_init (qemu_irq IRQ, target_phys_addr_t mem_base,
                        uint32_t io_base, uint16_t size,
                        int type);

Added: trunk/src/host/qemu-neo1973/hw/mac_dbdma.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/mac_dbdma.c	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/hw/mac_dbdma.c	2007-10-29 21:14:04 UTC (rev 3303)
@@ -0,0 +1,79 @@
+/*
+ * PowerMac descriptor-based DMA emulation
+ *
+ * Copyright (c) 2005-2007 Fabrice Bellard
+ * Copyright (c) 2007 Jocelyn Mayer
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include "vl.h"
+#include "ppc_mac.h"
+
+/* DBDMA: currently no op - should suffice right now */
+
+static void dbdma_writeb (void *opaque,
+                          target_phys_addr_t addr, uint32_t value)
+{
+    printf("%s: 0x" PADDRX " <= 0x%08x\n", __func__, addr, value);
+}
+
+static void dbdma_writew (void *opaque,
+                          target_phys_addr_t addr, uint32_t value)
+{
+}
+
+static void dbdma_writel (void *opaque,
+                          target_phys_addr_t addr, uint32_t value)
+{
+}
+
+static uint32_t dbdma_readb (void *opaque, target_phys_addr_t addr)
+{
+    printf("%s: 0x" PADDRX " => 0x00000000\n", __func__, addr);
+
+    return 0;
+}
+
+static uint32_t dbdma_readw (void *opaque, target_phys_addr_t addr)
+{
+    return 0;
+}
+
+static uint32_t dbdma_readl (void *opaque, target_phys_addr_t addr)
+{
+    return 0;
+}
+
+static CPUWriteMemoryFunc *dbdma_write[] = {
+    &dbdma_writeb,
+    &dbdma_writew,
+    &dbdma_writel,
+};
+
+static CPUReadMemoryFunc *dbdma_read[] = {
+    &dbdma_readb,
+    &dbdma_readw,
+    &dbdma_readl,
+};
+
+void dbdma_init (int *dbdma_mem_index)
+{
+    *dbdma_mem_index = cpu_register_io_memory(0, dbdma_read, dbdma_write, NULL);
+}
+

Added: trunk/src/host/qemu-neo1973/hw/mac_nvram.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/mac_nvram.c	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/hw/mac_nvram.c	2007-10-29 21:14:04 UTC (rev 3303)
@@ -0,0 +1,123 @@
+/*
+ * PowerMac NVRAM emulation
+ *
+ * Copyright (c) 2005-2007 Fabrice Bellard
+ * Copyright (c) 2007 Jocelyn Mayer
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include "vl.h"
+#include "ppc_mac.h"
+
+struct MacIONVRAMState {
+    uint8_t data[0x2000];
+};
+
+/* Direct access to NVRAM */
+uint32_t macio_nvram_read (void *opaque, uint32_t addr)
+{
+    MacIONVRAMState *s = opaque;
+    uint32_t ret;
+
+    //    printf("%s: %p addr %04x\n", __func__, s, addr);
+    if (addr < 0x2000)
+        ret = s->data[addr];
+    else
+        ret = -1;
+
+    return ret;
+}
+
+void macio_nvram_write (void *opaque, uint32_t addr, uint32_t val)
+{
+    MacIONVRAMState *s = opaque;
+
+    //    printf("%s: %p addr %04x val %02x\n", __func__, s, addr, val);
+    if (addr < 0x2000)
+        s->data[addr] = val;
+}
+
+/* macio style NVRAM device */
+static void macio_nvram_writeb (void *opaque,
+                                target_phys_addr_t addr, uint32_t value)
+{
+    MacIONVRAMState *s = opaque;
+    addr = (addr >> 4) & 0x1fff;
+    s->data[addr] = value;
+    //    printf("macio_nvram_writeb %04x = %02x\n", addr, value);
+}
+
+static uint32_t macio_nvram_readb (void *opaque, target_phys_addr_t addr)
+{
+    MacIONVRAMState *s = opaque;
+    uint32_t value;
+
+    addr = (addr >> 4) & 0x1fff;
+    value = s->data[addr];
+    //    printf("macio_nvram_readb %04x = %02x\n", addr, value);
+
+    return value;
+}
+
+static CPUWriteMemoryFunc *nvram_write[] = {
+    &macio_nvram_writeb,
+    &macio_nvram_writeb,
+    &macio_nvram_writeb,
+};
+
+static CPUReadMemoryFunc *nvram_read[] = {
+    &macio_nvram_readb,
+    &macio_nvram_readb,
+    &macio_nvram_readb,
+};
+
+MacIONVRAMState *macio_nvram_init (int *mem_index)
+{
+    MacIONVRAMState *s;
+    s = qemu_mallocz(sizeof(MacIONVRAMState));
+    if (!s)
+        return NULL;
+    *mem_index = cpu_register_io_memory(0, nvram_read, nvram_write, s);
+
+    return s;
+}
+
+static uint8_t nvram_chksum (const uint8_t *buf, int n)
+{
+    int sum, i;
+    sum = 0;
+    for(i = 0; i < n; i++)
+        sum += buf[i];
+    return (sum & 0xff) + (sum >> 8);
+}
+
+/* set a free Mac OS NVRAM partition */
+void pmac_format_nvram_partition (MacIONVRAMState *nvr, int len)
+{
+    uint8_t *buf;
+    char partition_name[12] = "wwwwwwwwwwww";
+
+    buf = nvr->data;
+    buf[0] = 0x7f; /* free partition magic */
+    buf[1] = 0; /* checksum */
+    buf[2] = len >> 8;
+    buf[3] = len;
+    memcpy(buf + 4, partition_name, 12);
+    buf[1] = nvram_chksum(buf, 16);
+}

Added: trunk/src/host/qemu-neo1973/hw/macio.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/macio.c	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/hw/macio.c	2007-10-29 21:14:04 UTC (rev 3303)
@@ -0,0 +1,116 @@
+/*
+ * PowerMac MacIO device emulation
+ *
+ * Copyright (c) 2005-2007 Fabrice Bellard
+ * Copyright (c) 2007 Jocelyn Mayer
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include "vl.h"
+#include "ppc_mac.h"
+
+typedef struct macio_state_t macio_state_t;
+struct macio_state_t {
+    int is_oldworld;
+    int pic_mem_index;
+    int dbdma_mem_index;
+    int cuda_mem_index;
+    int nvram_mem_index;
+    int nb_ide;
+    int ide_mem_index[4];
+};
+
+static void macio_map (PCIDevice *pci_dev, int region_num,
+                       uint32_t addr, uint32_t size, int type)
+{
+    macio_state_t *macio_state;
+    int i;
+
+    macio_state = (macio_state_t *)(pci_dev + 1);
+    if (macio_state->pic_mem_index >= 0) {
+        if (macio_state->is_oldworld) {
+            /* Heathrow PIC */
+            cpu_register_physical_memory(addr + 0x00000, 0x1000,
+                                         macio_state->pic_mem_index);
+        } else {
+            /* OpenPIC */
+            cpu_register_physical_memory(addr + 0x40000, 0x40000,
+                                         macio_state->pic_mem_index);
+        }
+    }
+    if (macio_state->dbdma_mem_index >= 0) {
+        cpu_register_physical_memory(addr + 0x08000, 0x1000,
+                                     macio_state->dbdma_mem_index);
+    }
+    if (macio_state->cuda_mem_index >= 0) {
+        cpu_register_physical_memory(addr + 0x16000, 0x2000,
+                                     macio_state->cuda_mem_index);
+    }
+    for (i = 0; i < macio_state->nb_ide; i++) {
+        if (macio_state->ide_mem_index[i] >= 0) {
+            cpu_register_physical_memory(addr + 0x1f000 + (i * 0x1000), 0x1000,
+                                         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);
+    }
+}
+
+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 nb_ide, int *ide_mem_index)
+{
+    PCIDevice *d;
+    macio_state_t *macio_state;
+    int i;
+
+    d = pci_register_device(bus, "macio",
+                            sizeof(PCIDevice) + sizeof(macio_state_t),
+                            -1, NULL, NULL);
+    macio_state = (macio_state_t *)(d + 1);
+    macio_state->is_oldworld = is_oldworld;
+    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;
+    if (nb_ide > 4)
+        nb_ide = 4;
+    macio_state->nb_ide = nb_ide;
+    for (i = 0; i < nb_ide; i++)
+        macio_state->ide_mem_index[i] = ide_mem_index[i];
+    for (; i < 4; i++)
+        macio_state->ide_mem_index[i] = -1;
+    /* Note: this code is strongly inspirated from the corresponding code
+       in PearPC */
+    d->config[0x00] = 0x6b; // vendor_id
+    d->config[0x01] = 0x10;
+    d->config[0x02] = device_id;
+    d->config[0x03] = device_id >> 8;
+
+    d->config[0x0a] = 0x00; // class_sub = pci2pci
+    d->config[0x0b] = 0xff; // class_base = bridge
+    d->config[0x0e] = 0x00; // header_type
+
+    d->config[0x3d] = 0x01; // interrupt on pin 1
+
+    pci_register_io_region(d, 0, 0x80000,
+                           PCI_ADDRESS_SPACE_MEM, macio_map);
+}

Modified: trunk/src/host/qemu-neo1973/hw/mips_malta.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/mips_malta.c	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/hw/mips_malta.c	2007-10-29 21:14:04 UTC (rev 3303)
@@ -791,7 +791,9 @@
 
     /* Load a BIOS image unless a kernel image has been specified. */
     if (!kernel_filename) {
-        snprintf(buf, sizeof(buf), "%s/%s", bios_dir, BIOS_FILENAME);
+        if (bios_name == NULL)
+            bios_name = BIOS_FILENAME;
+        snprintf(buf, sizeof(buf), "%s/%s", bios_dir, bios_name);
         ret = load_image(buf, phys_ram_base + bios_offset);
         if (ret < 0 || ret > BIOS_SIZE) {
             fprintf(stderr,

Added: trunk/src/host/qemu-neo1973/hw/mips_mipssim.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/mips_mipssim.c	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/hw/mips_mipssim.c	2007-10-29 21:14:04 UTC (rev 3303)
@@ -0,0 +1,166 @@
+/*
+ * QEMU/mipssim emulation
+ *
+ * Emulates a very simple machine model similiar to the one use by the
+ * proprietary MIPS emulator.
+ */
+#include "vl.h"
+
+#ifdef TARGET_WORDS_BIGENDIAN
+#define BIOS_FILENAME "mips_bios.bin"
+#else
+#define BIOS_FILENAME "mipsel_bios.bin"
+#endif
+
+#ifdef TARGET_MIPS64
+#define PHYS_TO_VIRT(x) ((x) | ~0x7fffffffULL)
+#else
+#define PHYS_TO_VIRT(x) ((x) | ~0x7fffffffU)
+#endif
+
+#define VIRT_TO_PHYS_ADDEND (-((int64_t)(int32_t)0x80000000))
+
+static void load_kernel (CPUState *env)
+{
+    int64_t entry, kernel_low, kernel_high;
+    long kernel_size;
+    long initrd_size;
+    ram_addr_t initrd_offset;
+
+    kernel_size = load_elf(env->kernel_filename, VIRT_TO_PHYS_ADDEND,
+                           &entry, &kernel_low, &kernel_high);
+    if (kernel_size >= 0) {
+        if ((entry & ~0x7fffffffULL) == 0x80000000)
+            entry = (int32_t)entry;
+        env->PC[env->current_tc] = entry;
+    } else {
+        fprintf(stderr, "qemu: could not load kernel '%s'\n",
+                env->kernel_filename);
+        exit(1);
+    }
+
+    /* load initrd */
+    initrd_size = 0;
+    initrd_offset = 0;
+    if (env->initrd_filename) {
+        initrd_size = get_image_size (env->initrd_filename);
+        if (initrd_size > 0) {
+            initrd_offset = (kernel_high + ~TARGET_PAGE_MASK) & TARGET_PAGE_MASK;
+            if (initrd_offset + initrd_size > env->ram_size) {
+                fprintf(stderr,
+                        "qemu: memory too small for initial ram disk '%s'\n",
+                        env->initrd_filename);
+                exit(1);
+            }
+            initrd_size = load_image(env->initrd_filename,
+                                     phys_ram_base + initrd_offset);
+        }
+        if (initrd_size == (target_ulong) -1) {
+            fprintf(stderr, "qemu: could not load initial ram disk '%s'\n",
+                    env->initrd_filename);
+            exit(1);
+        }
+    }
+}
+
+static void main_cpu_reset(void *opaque)
+{
+    CPUState *env = opaque;
+    cpu_reset(env);
+    cpu_mips_register(env, NULL);
+
+    if (env->kernel_filename)
+        load_kernel (env);
+}
+
+static void
+mips_mipssim_init (int ram_size, int vga_ram_size, int boot_device,
+                   DisplayState *ds, const char **fd_filename, int snapshot,
+                   const char *kernel_filename, const char *kernel_cmdline,
+                   const char *initrd_filename, const char *cpu_model)
+{
+    char buf[1024];
+    unsigned long bios_offset;
+    CPUState *env;
+    int bios_size;
+    mips_def_t *def;
+
+    /* Init CPUs. */
+    if (cpu_model == NULL) {
+#ifdef TARGET_MIPS64
+        cpu_model = "5Kf";
+#else
+        cpu_model = "24Kf";
+#endif
+    }
+    if (mips_find_by_name(cpu_model, &def) != 0)
+        def = NULL;
+    env = cpu_init();
+    cpu_mips_register(env, def);
+    register_savevm("cpu", 0, 3, cpu_save, cpu_load, env);
+    qemu_register_reset(main_cpu_reset, env);
+
+    /* Allocate RAM. */
+    cpu_register_physical_memory(0, ram_size, IO_MEM_RAM);
+
+    /* Load a BIOS / boot exception handler image. */
+    bios_offset = ram_size + vga_ram_size;
+    if (bios_name == NULL)
+        bios_name = BIOS_FILENAME;
+    snprintf(buf, sizeof(buf), "%s/%s", bios_dir, bios_name);
+    bios_size = load_image(buf, phys_ram_base + bios_offset);
+    if ((bios_size < 0 || bios_size > BIOS_SIZE) && !kernel_filename) {
+        /* Bail out if we have neither a kernel image nor boot vector code. */
+        fprintf(stderr,
+                "qemu: Could not load MIPS bios '%s', and no -kernel argument was specified\n",
+                buf);
+        exit(1);
+    } else {
+        /* Map the BIOS / boot exception handler. */
+        cpu_register_physical_memory(0x1fc00000LL,
+                                     bios_size, bios_offset | IO_MEM_ROM);
+        /* We have a boot vector start address. */
+        env->PC[env->current_tc] = (target_long)(int32_t)0xbfc00000;
+    }
+
+    if (kernel_filename) {
+        env->ram_size = ram_size;
+        env->kernel_filename = kernel_filename;
+        env->kernel_cmdline = kernel_cmdline;
+        env->initrd_filename = initrd_filename;
+        load_kernel(env);
+    }
+
+    /* Init CPU internal devices. */
+    cpu_mips_irq_init_cpu(env);
+    cpu_mips_clock_init(env);
+    cpu_mips_irqctrl_init();
+
+    /* Register 64 KB of ISA IO space at 0x1fd00000. */
+    isa_mmio_init(0x1fd00000, 0x00010000);
+
+    /* A single 16450 sits at offset 0x3f8. It is attached to
+       MIPS CPU INT2, which is interrupt 4. */
+    if (serial_hds[0])
+        serial_init(0x3f8, env->irq[4], serial_hds[0]);
+
+    if (nd_table[0].vlan) {
+        if (nd_table[0].model == NULL
+            || strcmp(nd_table[0].model, "mipsnet") == 0) {
+            /* MIPSnet uses the MIPS CPU INT0, which is interrupt 2. */
+            mipsnet_init(0x4200, env->irq[2], &nd_table[0]);
+        } else if (strcmp(nd_table[0].model, "?") == 0) {
+            fprintf(stderr, "qemu: Supported NICs: mipsnet\n");
+            exit (1);
+        } else {
+            fprintf(stderr, "qemu: Unsupported NIC: %s\n", nd_table[0].model);
+            exit (1);
+        }
+    }
+}
+
+QEMUMachine mips_mipssim_machine = {
+    "mipssim",
+    "MIPS MIPSsim platform",
+    mips_mipssim_init,
+};

Modified: trunk/src/host/qemu-neo1973/hw/mips_pica61.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/mips_pica61.c	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/hw/mips_pica61.c	2007-10-29 21:14:04 UTC (rev 3303)
@@ -94,7 +94,9 @@
 
     /* load a BIOS image */
     bios_offset = ram_size + vga_ram_size;
-    snprintf(buf, sizeof(buf), "%s/%s", bios_dir, BIOS_FILENAME);
+    if (bios_name == NULL)
+        bios_name = BIOS_FILENAME;
+    snprintf(buf, sizeof(buf), "%s/%s", bios_dir, bios_name);
     bios_size = load_image(buf, phys_ram_base + bios_offset);
     if ((bios_size <= 0) || (bios_size > BIOS_SIZE)) {
         /* fatal */

Modified: trunk/src/host/qemu-neo1973/hw/mips_r4k.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/mips_r4k.c	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/hw/mips_r4k.c	2007-10-29 21:14:04 UTC (rev 3303)
@@ -64,9 +64,10 @@
 
 static int mips_qemu_iomemtype = 0;
 
-void load_kernel (CPUState *env, int ram_size, const char *kernel_filename,
-		  const char *kernel_cmdline,
-		  const char *initrd_filename)
+static void load_kernel (CPUState *env, int ram_size,
+                         const char *kernel_filename,
+                         const char *kernel_cmdline,
+                         const char *initrd_filename)
 {
     int64_t entry, kernel_low, kernel_high;
     long kernel_size, initrd_size;
@@ -179,7 +180,9 @@
        preloaded we also initialize the hardware, since the BIOS wasn't
        run. */
     bios_offset = ram_size + vga_ram_size;
-    snprintf(buf, sizeof(buf), "%s/%s", bios_dir, BIOS_FILENAME);
+    if (bios_name == NULL)
+        bios_name = BIOS_FILENAME;
+    snprintf(buf, sizeof(buf), "%s/%s", bios_dir, bios_name);
     bios_size = load_image(buf, phys_ram_base + bios_offset);
     if ((bios_size > 0) && (bios_size <= BIOS_SIZE)) {
 	cpu_register_physical_memory(0x1fc00000,

Modified: trunk/src/host/qemu-neo1973/hw/mips_timer.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/mips_timer.c	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/hw/mips_timer.c	2007-10-29 21:14:04 UTC (rev 3303)
@@ -17,9 +17,12 @@
 /* MIPS R4K timer */
 uint32_t cpu_mips_get_count (CPUState *env)
 {
-    return env->CP0_Count +
-        (uint32_t)muldiv64(qemu_get_clock(vm_clock),
-                           100 * 1000 * 1000, ticks_per_sec);
+    if (env->CP0_Cause & (1 << CP0Ca_DC))
+        return env->CP0_Count;
+    else
+        return env->CP0_Count +
+            (uint32_t)muldiv64(qemu_get_clock(vm_clock),
+                               100 * 1000 * 1000, ticks_per_sec);
 }
 
 void cpu_mips_store_count (CPUState *env, uint32_t count)
@@ -63,9 +66,21 @@
     cpu_mips_update_count(env, cpu_mips_get_count(env));
     if ((env->CP0_Config0 & (0x7 << CP0C0_AR)) == (1 << CP0C0_AR))
         env->CP0_Cause &= ~(1 << CP0Ca_TI);
-    qemu_irq_lower(env->irq[7]);
+    qemu_irq_lower(env->irq[(env->CP0_IntCtl >> CP0IntCtl_IPTI) & 0x7]);
 }
 
+void cpu_mips_start_count(CPUState *env)
+{
+    cpu_mips_store_count(env, env->CP0_Count);
+}
+
+void cpu_mips_stop_count(CPUState *env)
+{
+    /* Store the current value */
+    env->CP0_Count += (uint32_t)muldiv64(qemu_get_clock(vm_clock),
+                                         100 * 1000 * 1000, ticks_per_sec);
+}
+
 static void mips_timer_cb (void *opaque)
 {
     CPUState *env;
@@ -76,10 +91,14 @@
         fprintf(logfile, "%s\n", __func__);
     }
 #endif
+
+    if (env->CP0_Cause & (1 << CP0Ca_DC))
+        return;
+
     cpu_mips_update_count(env, cpu_mips_get_count(env));
     if ((env->CP0_Config0 & (0x7 << CP0C0_AR)) == (1 << CP0C0_AR))
         env->CP0_Cause |= 1 << CP0Ca_TI;
-    qemu_irq_raise(env->irq[7]);
+    qemu_irq_raise(env->irq[(env->CP0_IntCtl >> CP0IntCtl_IPTI) & 0x7]);
 }
 
 void cpu_mips_clock_init (CPUState *env)

Added: trunk/src/host/qemu-neo1973/hw/mipsnet.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/mipsnet.c	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/hw/mipsnet.c	2007-10-29 21:14:04 UTC (rev 3303)
@@ -0,0 +1,269 @@
+#include "vl.h"
+
+//#define DEBUG_MIPSNET_SEND
+//#define DEBUG_MIPSNET_RECEIVE
+//#define DEBUG_MIPSNET_DATA
+//#define DEBUG_MIPSNET_IRQ
+
+/* MIPSnet register offsets */
+
+#define MIPSNET_DEV_ID		0x00
+# define MIPSNET_DEV_ID_STRING	"MIPSNET0"
+#define MIPSNET_BUSY		0x08
+#define MIPSNET_RX_DATA_COUNT	0x0c
+#define MIPSNET_TX_DATA_COUNT	0x10
+#define MIPSNET_INT_CTL		0x14
+# define MIPSNET_INTCTL_TXDONE		0x00000001
+# define MIPSNET_INTCTL_RXDONE		0x00000002
+# define MIPSNET_INTCTL_TESTBIT		0x80000000
+#define MIPSNET_INTERRUPT_INFO	0x18
+#define MIPSNET_RX_DATA_BUFFER	0x1c
+#define MIPSNET_TX_DATA_BUFFER	0x20
+
+#define MAX_ETH_FRAME_SIZE	1514
+
+typedef struct MIPSnetState {
+    uint32_t busy;
+    uint32_t rx_count;
+    uint32_t rx_read;
+    uint32_t tx_count;
+    uint32_t tx_written;
+    uint32_t intctl;
+    uint8_t rx_buffer[MAX_ETH_FRAME_SIZE];
+    uint8_t tx_buffer[MAX_ETH_FRAME_SIZE];
+    qemu_irq irq;
+    VLANClientState *vc;
+    NICInfo *nd;
+} MIPSnetState;
+
+static void mipsnet_reset(MIPSnetState *s)
+{
+    s->busy = 1;
+    s->rx_count = 0;
+    s->rx_read = 0;
+    s->tx_count = 0;
+    s->tx_written = 0;
+    s->intctl = 0;
+    memset(s->rx_buffer, 0, MAX_ETH_FRAME_SIZE);
+    memset(s->tx_buffer, 0, MAX_ETH_FRAME_SIZE);
+}
+
+static void mipsnet_update_irq(MIPSnetState *s)
+{
+    int isr = !!s->intctl;
+#ifdef DEBUG_MIPSNET_IRQ
+    printf("mipsnet: Set IRQ to %d (%02x)\n", isr, s->intctl);
+#endif
+    qemu_set_irq(s->irq, isr);
+}
+
+static int mipsnet_buffer_full(MIPSnetState *s)
+{
+    if (s->rx_count >= MAX_ETH_FRAME_SIZE)
+        return 1;
+    return 0;
+}
+
+static int mipsnet_can_receive(void *opaque)
+{
+    MIPSnetState *s = opaque;
+
+    if (s->busy)
+        return 0;
+    return !mipsnet_buffer_full(s);
+}
+
+static void mipsnet_receive(void *opaque, const uint8_t *buf, int size)
+{
+    MIPSnetState *s = opaque;
+
+#ifdef DEBUG_MIPSNET_RECEIVE
+    printf("mipsnet: receiving len=%d\n", size);
+#endif
+    if (!mipsnet_can_receive(opaque))
+        return;
+
+    s->busy = 1;
+
+    /* Just accept everything. */
+
+    /* Write packet data. */
+    memcpy(s->rx_buffer, buf, size);
+
+    s->rx_count = size;
+    s->rx_read = 0;
+
+    /* Now we can signal we have received something. */
+    s->intctl |= MIPSNET_INTCTL_RXDONE;
+    mipsnet_update_irq(s);
+}
+
+static uint32_t mipsnet_ioport_read(void *opaque, uint32_t addr)
+{
+    MIPSnetState *s = opaque;
+    int ret = 0;
+    const char *devid = MIPSNET_DEV_ID_STRING;
+
+    addr &= 0x3f;
+    switch (addr) {
+    case MIPSNET_DEV_ID:
+	ret = *((uint32_t *)&devid);
+        break;
+    case MIPSNET_DEV_ID + 4:
+	ret = *((uint32_t *)(&devid + 4));
+        break;
+    case MIPSNET_BUSY:
+	ret = s->busy;
+        break;
+    case MIPSNET_RX_DATA_COUNT:
+	ret = s->rx_count;
+        break;
+    case MIPSNET_TX_DATA_COUNT:
+	ret = s->tx_count;
+        break;
+    case MIPSNET_INT_CTL:
+	ret = s->intctl;
+        s->intctl &= ~MIPSNET_INTCTL_TESTBIT;
+        break;
+    case MIPSNET_INTERRUPT_INFO:
+        /* XXX: This seems to be a per-VPE interrupt number. */
+	ret = 0;
+        break;
+    case MIPSNET_RX_DATA_BUFFER:
+        if (s->rx_count) {
+            s->rx_count--;
+            ret = s->rx_buffer[s->rx_read++];
+        }
+        break;
+    /* Reads as zero. */
+    case MIPSNET_TX_DATA_BUFFER:
+    default:
+        break;
+    }
+#ifdef DEBUG_MIPSNET_DATA
+    printf("mipsnet: read addr=0x%02x val=0x%02x\n", addr, ret);
+#endif
+    return ret;
+}
+
+static void mipsnet_ioport_write(void *opaque, uint32_t addr, uint32_t val)
+{
+    MIPSnetState *s = opaque;
+
+    addr &= 0x3f;
+#ifdef DEBUG_MIPSNET_DATA
+    printf("mipsnet: write addr=0x%02x val=0x%02x\n", addr, val);
+#endif
+    switch (addr) {
+    case MIPSNET_TX_DATA_COUNT:
+	s->tx_count = (val <= MAX_ETH_FRAME_SIZE) ? val : 0;
+        s->tx_written = 0;
+        break;
+    case MIPSNET_INT_CTL:
+        if (val & MIPSNET_INTCTL_TXDONE) {
+            s->intctl &= ~MIPSNET_INTCTL_TXDONE;
+        } else if (val & MIPSNET_INTCTL_RXDONE) {
+            s->intctl &= ~MIPSNET_INTCTL_RXDONE;
+        } else if (val & MIPSNET_INTCTL_TESTBIT) {
+            mipsnet_reset(s);
+            s->intctl |= MIPSNET_INTCTL_TESTBIT;
+        } else if (!val) {
+            /* ACK testbit interrupt, flag was cleared on read. */
+        }
+        s->busy = !!s->intctl;
+        mipsnet_update_irq(s);
+        break;
+    case MIPSNET_TX_DATA_BUFFER:
+        s->tx_buffer[s->tx_written++] = val;
+        if (s->tx_written == s->tx_count) {
+            /* Send buffer. */
+#ifdef DEBUG_MIPSNET_SEND
+            printf("mipsnet: sending len=%d\n", s->tx_count);
+#endif
+            qemu_send_packet(s->vc, s->tx_buffer, s->tx_count);
+            s->tx_count = s->tx_written = 0;
+            s->intctl |= MIPSNET_INTCTL_TXDONE;
+            s->busy = 1;
+            mipsnet_update_irq(s);
+        }
+        break;
+    /* Read-only registers */
+    case MIPSNET_DEV_ID:
+    case MIPSNET_BUSY:
+    case MIPSNET_RX_DATA_COUNT:
+    case MIPSNET_INTERRUPT_INFO:
+    case MIPSNET_RX_DATA_BUFFER:
+    default:
+        break;
+    }
+}
+
+static void mipsnet_save(QEMUFile *f, void *opaque)
+{
+    MIPSnetState *s = opaque;
+
+    qemu_put_be32s(f, &s->busy);
+    qemu_put_be32s(f, &s->rx_count);
+    qemu_put_be32s(f, &s->rx_read);
+    qemu_put_be32s(f, &s->tx_count);
+    qemu_put_be32s(f, &s->tx_written);
+    qemu_put_be32s(f, &s->intctl);
+    qemu_put_buffer(f, s->rx_buffer, MAX_ETH_FRAME_SIZE);
+    qemu_put_buffer(f, s->tx_buffer, MAX_ETH_FRAME_SIZE);
+}
+
+static int mipsnet_load(QEMUFile *f, void *opaque, int version_id)
+{
+    MIPSnetState *s = opaque;
+
+    if (version_id > 0)
+        return -EINVAL;
+
+    qemu_get_be32s(f, &s->busy);
+    qemu_get_be32s(f, &s->rx_count);
+    qemu_get_be32s(f, &s->rx_read);
+    qemu_get_be32s(f, &s->tx_count);
+    qemu_get_be32s(f, &s->tx_written);
+    qemu_get_be32s(f, &s->intctl);
+    qemu_get_buffer(f, s->rx_buffer, MAX_ETH_FRAME_SIZE);
+    qemu_get_buffer(f, s->tx_buffer, MAX_ETH_FRAME_SIZE);
+
+    return 0;
+}
+
+void mipsnet_init (int base, qemu_irq irq, NICInfo *nd)
+{
+    MIPSnetState *s;
+
+    s = qemu_mallocz(sizeof(MIPSnetState));
+    if (!s)
+        return;
+
+    register_ioport_write(base, 36, 1, mipsnet_ioport_write, s);
+    register_ioport_read(base, 36, 1, mipsnet_ioport_read, s);
+    register_ioport_write(base, 36, 2, mipsnet_ioport_write, s);
+    register_ioport_read(base, 36, 2, mipsnet_ioport_read, s);
+    register_ioport_write(base, 36, 4, mipsnet_ioport_write, s);
+    register_ioport_read(base, 36, 4, mipsnet_ioport_read, s);
+
+    s->irq = irq;
+    s->nd = nd;
+    if (nd && nd->vlan) {
+        s->vc = qemu_new_vlan_client(nd->vlan, mipsnet_receive,
+                                     mipsnet_can_receive, s);
+    } else {
+        s->vc = NULL;
+    }
+
+    snprintf(s->vc->info_str, sizeof(s->vc->info_str),
+             "mipsnet macaddr=%02x:%02x:%02x:%02x:%02x:%02x",
+              s->nd->macaddr[0],
+              s->nd->macaddr[1],
+              s->nd->macaddr[2],
+              s->nd->macaddr[3],
+              s->nd->macaddr[4],
+              s->nd->macaddr[5]);
+
+    mipsnet_reset(s);
+    register_savevm("mipsnet", 0, 0, mipsnet_save, mipsnet_load, s);
+}

Modified: trunk/src/host/qemu-neo1973/hw/omap.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/omap.c	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/hw/omap.c	2007-10-29 21:14:04 UTC (rev 3303)
@@ -2787,6 +2787,626 @@
     cpu_register_physical_memory(s->clkm.dsp_base, 0x1000, iomemtype[1]);
 }
 
+/* MPU I/O */
+struct omap_mpuio_s {
+    target_phys_addr_t base;
+    qemu_irq irq;
+    qemu_irq kbd_irq;
+    qemu_irq *in;
+    qemu_irq handler[16];
+    qemu_irq wakeup;
+
+    uint16_t inputs;
+    uint16_t outputs;
+    uint16_t dir;
+    uint16_t edge;
+    uint16_t mask;
+    uint16_t ints;
+
+    uint16_t debounce;
+    uint16_t latch;
+    uint8_t event;
+
+    uint8_t buttons[5];
+    uint8_t row_latch;
+    uint8_t cols;
+    int kbd_mask;
+    int clk;
+};
+
+static void omap_mpuio_set(void *opaque, int line, int level)
+{
+    struct omap_mpuio_s *s = (struct omap_mpuio_s *) opaque;
+    uint16_t prev = s->inputs;
+
+    if (level)
+        s->inputs |= 1 << line;
+    else
+        s->inputs &= ~(1 << line);
+
+    if (((1 << line) & s->dir & ~s->mask) && s->clk) {
+        if ((s->edge & s->inputs & ~prev) | (~s->edge & ~s->inputs & prev)) {
+            s->ints |= 1 << line;
+            qemu_irq_raise(s->irq);
+            /* TODO: wakeup */
+        }
+        if ((s->event & (1 << 0)) &&		/* SET_GPIO_EVENT_MODE */
+                (s->event >> 1) == line)	/* PIN_SELECT */
+            s->latch = s->inputs;
+    }
+}
+
+static void omap_mpuio_kbd_update(struct omap_mpuio_s *s)
+{
+    int i;
+    uint8_t *row, rows = 0, cols = ~s->cols;
+
+    for (row = s->buttons + 4, i = 1 << 4; i; row --, i >>= 1)
+        if (*row & cols)
+            rows |= i;
+
+    qemu_set_irq(s->kbd_irq, rows && ~s->kbd_mask && s->clk);
+    s->row_latch = rows ^ 0x1f;
+}
+
+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;
+    uint16_t ret;
+
+    switch (offset) {
+    case 0x00:	/* INPUT_LATCH */
+        return s->inputs;
+
+    case 0x04:	/* OUTPUT_REG */
+        return s->outputs;
+
+    case 0x08:	/* IO_CNTL */
+        return s->dir;
+
+    case 0x10:	/* KBR_LATCH */
+        return s->row_latch;
+
+    case 0x14:	/* KBC_REG */
+        return s->cols;
+
+    case 0x18:	/* GPIO_EVENT_MODE_REG */
+        return s->event;
+
+    case 0x1c:	/* GPIO_INT_EDGE_REG */
+        return s->edge;
+
+    case 0x20:	/* KBD_INT */
+        return (s->row_latch != 0x1f) && !s->kbd_mask;
+
+    case 0x24:	/* GPIO_INT */
+        ret = s->ints;
+        s->ints &= s->mask;
+        if (ret)
+            qemu_irq_lower(s->irq);
+        return ret;
+
+    case 0x28:	/* KBD_MASKIT */
+        return s->kbd_mask;
+
+    case 0x2c:	/* GPIO_MASKIT */
+        return s->mask;
+
+    case 0x30:	/* GPIO_DEBOUNCING_REG */
+        return s->debounce;
+
+    case 0x34:	/* GPIO_LATCH_REG */
+        return s->latch;
+    }
+
+    OMAP_BAD_REG(addr);
+    return 0;
+}
+
+static void omap_mpuio_write(void *opaque, target_phys_addr_t addr,
+                uint32_t value)
+{
+    struct omap_mpuio_s *s = (struct omap_mpuio_s *) opaque;
+    int offset = addr - s->base;
+    uint16_t diff;
+    int ln;
+
+    switch (offset) {
+    case 0x04:	/* OUTPUT_REG */
+        diff = s->outputs ^ (value & ~s->dir);
+        s->outputs = value;
+	value &= ~s->dir;
+        while ((ln = ffs(diff))) {
+            ln --;
+            if (s->handler[ln])
+                qemu_set_irq(s->handler[ln], (value >> ln) & 1);
+            diff &= ~(1 << ln);
+        }
+        break;
+
+    case 0x08:	/* IO_CNTL */
+        diff = s->outputs & (s->dir ^ value);
+        s->dir = value;
+
+        value = s->outputs & ~s->dir;
+        while ((ln = ffs(diff))) {
+            ln --;
+            if (s->handler[ln])
+                qemu_set_irq(s->handler[ln], (value >> ln) & 1);
+            diff &= ~(1 << ln);
+        }
+        break;
+
+    case 0x14:	/* KBC_REG */
+        s->cols = value;
+        omap_mpuio_kbd_update(s);
+        break;
+
+    case 0x18:	/* GPIO_EVENT_MODE_REG */
+        s->event = value & 0x1f;
+        break;
+
+    case 0x1c:	/* GPIO_INT_EDGE_REG */
+        s->edge = value;
+        break;
+
+    case 0x28:	/* KBD_MASKIT */
+        s->kbd_mask = value & 1;
+        omap_mpuio_kbd_update(s);
+        break;
+
+    case 0x2c:	/* GPIO_MASKIT */
+        s->mask = value;
+        break;
+
+    case 0x30:	/* GPIO_DEBOUNCING_REG */
+        s->debounce = value & 0x1ff;
+        break;
+
+    case 0x00:	/* INPUT_LATCH */
+    case 0x10:	/* KBR_LATCH */
+    case 0x20:	/* KBD_INT */
+    case 0x24:	/* GPIO_INT */
+    case 0x34:	/* GPIO_LATCH_REG */
+        OMAP_RO_REG(addr);
+        return;
+
+    default:
+        OMAP_BAD_REG(addr);
+        return;
+    }
+}
+
+static CPUReadMemoryFunc *omap_mpuio_readfn[] = {
+    omap_badwidth_read16,
+    omap_mpuio_read,
+    omap_badwidth_read16,
+};
+
+static CPUWriteMemoryFunc *omap_mpuio_writefn[] = {
+    omap_badwidth_write16,
+    omap_mpuio_write,
+    omap_badwidth_write16,
+};
+
+void omap_mpuio_reset(struct omap_mpuio_s *s)
+{
+    s->inputs = 0;
+    s->outputs = 0;
+    s->dir = ~0;
+    s->event = 0;
+    s->edge = 0;
+    s->kbd_mask = 0;
+    s->mask = 0;
+    s->debounce = 0;
+    s->latch = 0;
+    s->ints = 0;
+    s->row_latch = 0x1f;
+    s->clk = 1;
+}
+
+static void omap_mpuio_onoff(void *opaque, int line, int on)
+{
+    struct omap_mpuio_s *s = (struct omap_mpuio_s *) opaque;
+
+    s->clk = on;
+    if (on)
+        omap_mpuio_kbd_update(s);
+}
+
+struct omap_mpuio_s *omap_mpuio_init(target_phys_addr_t base,
+                qemu_irq kbd_int, qemu_irq gpio_int, qemu_irq wakeup,
+                omap_clk clk)
+{
+    int iomemtype;
+    struct omap_mpuio_s *s = (struct omap_mpuio_s *)
+            qemu_mallocz(sizeof(struct omap_mpuio_s));
+
+    s->base = base;
+    s->irq = gpio_int;
+    s->kbd_irq = kbd_int;
+    s->wakeup = wakeup;
+    s->in = qemu_allocate_irqs(omap_mpuio_set, s, 16);
+    omap_mpuio_reset(s);
+
+    iomemtype = cpu_register_io_memory(0, omap_mpuio_readfn,
+                    omap_mpuio_writefn, s);
+    cpu_register_physical_memory(s->base, 0x800, iomemtype);
+
+    omap_clk_adduser(clk, qemu_allocate_irqs(omap_mpuio_onoff, s, 1)[0]);
+
+    return s;
+}
+
+qemu_irq *omap_mpuio_in_get(struct omap_mpuio_s *s)
+{
+    return s->in;
+}
+
+void omap_mpuio_out_set(struct omap_mpuio_s *s, int line, qemu_irq handler)
+{
+    if (line >= 16 || line < 0)
+        cpu_abort(cpu_single_env, "%s: No GPIO line %i\n", __FUNCTION__, line);
+    s->handler[line] = handler;
+}
+
+void omap_mpuio_key(struct omap_mpuio_s *s, int row, int col, int down)
+{
+    if (row >= 5 || row < 0)
+        cpu_abort(cpu_single_env, "%s: No key %i-%i\n",
+                        __FUNCTION__, col, row);
+
+    if (down)
+        s->buttons[row] |= 1 << col;
+    else
+        s->buttons[row] &= ~(1 << col);
+
+    omap_mpuio_kbd_update(s);
+}
+
+/* General-Purpose I/O */
+struct omap_gpio_s {
+    target_phys_addr_t base;
+    qemu_irq irq;
+    qemu_irq *in;
+    qemu_irq handler[16];
+
+    uint16_t inputs;
+    uint16_t outputs;
+    uint16_t dir;
+    uint16_t edge;
+    uint16_t mask;
+    uint16_t ints;
+};
+
+static void omap_gpio_set(void *opaque, int line, int level)
+{
+    struct omap_gpio_s *s = (struct omap_gpio_s *) opaque;
+    uint16_t prev = s->inputs;
+
+    if (level)
+        s->inputs |= 1 << line;
+    else
+        s->inputs &= ~(1 << line);
+
+    if (((s->edge & s->inputs & ~prev) | (~s->edge & ~s->inputs & prev)) &
+                    (1 << line) & s->dir & ~s->mask) {
+        s->ints |= 1 << line;
+        qemu_irq_raise(s->irq);
+    }
+}
+
+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;
+
+    switch (offset) {
+    case 0x00:	/* DATA_INPUT */
+        return s->inputs;
+
+    case 0x04:	/* DATA_OUTPUT */
+        return s->outputs;
+
+    case 0x08:	/* DIRECTION_CONTROL */
+        return s->dir;
+
+    case 0x0c:	/* INTERRUPT_CONTROL */
+        return s->edge;
+
+    case 0x10:	/* INTERRUPT_MASK */
+        return s->mask;
+
+    case 0x14:	/* INTERRUPT_STATUS */
+        return s->ints;
+    }
+
+    OMAP_BAD_REG(addr);
+    return 0;
+}
+
+static void omap_gpio_write(void *opaque, target_phys_addr_t addr,
+                uint32_t value)
+{
+    struct omap_gpio_s *s = (struct omap_gpio_s *) opaque;
+    int offset = addr - s->base;
+    uint16_t diff;
+    int ln;
+
+    switch (offset) {
+    case 0x00:	/* DATA_INPUT */
+        OMAP_RO_REG(addr);
+        return;
+
+    case 0x04:	/* DATA_OUTPUT */
+        diff = s->outputs ^ (value & ~s->dir);
+        s->outputs = value;
+	value &= ~s->dir;
+        while ((ln = ffs(diff))) {
+            ln --;
+            if (s->handler[ln])
+                qemu_set_irq(s->handler[ln], (value >> ln) & 1);
+            diff &= ~(1 << ln);
+        }
+        break;
+
+    case 0x08:	/* DIRECTION_CONTROL */
+        diff = s->outputs & (s->dir ^ value);
+        s->dir = value;
+
+        value = s->outputs & ~s->dir;
+        while ((ln = ffs(diff))) {
+            ln --;
+            if (s->handler[ln])
+                qemu_set_irq(s->handler[ln], (value >> ln) & 1);
+            diff &= ~(1 << ln);
+        }
+        break;
+
+    case 0x0c:	/* INTERRUPT_CONTROL */
+        s->edge = value;
+        break;
+
+    case 0x10:	/* INTERRUPT_MASK */
+        s->mask = value;
+        break;
+
+    case 0x14:	/* INTERRUPT_STATUS */
+        s->ints &= ~value;
+        if (!s->ints)
+            qemu_irq_lower(s->irq);
+        break;
+
+    default:
+        OMAP_BAD_REG(addr);
+        return;
+    }
+}
+
+/* *Some* sources say the memory region is 32-bit.  */
+static CPUReadMemoryFunc *omap_gpio_readfn[] = {
+    omap_badwidth_read16,
+    omap_gpio_read,
+    omap_badwidth_read16,
+};
+
+static CPUWriteMemoryFunc *omap_gpio_writefn[] = {
+    omap_badwidth_write16,
+    omap_gpio_write,
+    omap_badwidth_write16,
+};
+
+void omap_gpio_reset(struct omap_gpio_s *s)
+{
+    s->inputs = 0;
+    s->outputs = ~0;
+    s->dir = ~0;
+    s->edge = ~0;
+    s->mask = ~0;
+    s->ints = 0;
+}
+
+struct omap_gpio_s *omap_gpio_init(target_phys_addr_t base,
+                qemu_irq irq, omap_clk clk)
+{
+    int iomemtype;
+    struct omap_gpio_s *s = (struct omap_gpio_s *)
+            qemu_mallocz(sizeof(struct omap_gpio_s));
+
+    s->base = base;
+    s->irq = irq;
+    s->in = qemu_allocate_irqs(omap_gpio_set, s, 16);
+    omap_gpio_reset(s);
+
+    iomemtype = cpu_register_io_memory(0, omap_gpio_readfn,
+                    omap_gpio_writefn, s);
+    cpu_register_physical_memory(s->base, 0x1000, iomemtype);
+
+    return s;
+}
+
+qemu_irq *omap_gpio_in_get(struct omap_gpio_s *s)
+{
+    return s->in;
+}
+
+void omap_gpio_out_set(struct omap_gpio_s *s, int line, qemu_irq handler)
+{
+    if (line >= 16 || line < 0)
+        cpu_abort(cpu_single_env, "%s: No GPIO line %i\n", __FUNCTION__, line);
+    s->handler[line] = handler;
+}
+
+/* MicroWire Interface */
+struct omap_uwire_s {
+    target_phys_addr_t base;
+    qemu_irq txirq;
+    qemu_irq rxirq;
+    qemu_irq txdrq;
+
+    uint16_t txbuf;
+    uint16_t rxbuf;
+    uint16_t control;
+    uint16_t setup[5];
+
+    struct uwire_slave_s *chip[4];
+};
+
+static void omap_uwire_transfer_start(struct omap_uwire_s *s)
+{
+    int chipselect = (s->control >> 10) & 3;		/* INDEX */
+    struct uwire_slave_s *slave = s->chip[chipselect];
+
+    if ((s->control >> 5) & 0x1f) {			/* NB_BITS_WR */
+        if (s->control & (1 << 12))			/* CS_CMD */
+            if (slave && slave->send)
+                slave->send(slave->opaque,
+                                s->txbuf >> (16 - ((s->control >> 5) & 0x1f)));
+        s->control &= ~(1 << 14);			/* CSRB */
+        /* TODO: depending on s->setup[4] bits [1:0] assert an IRQ or
+         * a DRQ.  When is the level IRQ supposed to be reset?  */
+    }
+
+    if ((s->control >> 0) & 0x1f) {			/* NB_BITS_RD */
+        if (s->control & (1 << 12))			/* CS_CMD */
+            if (slave && slave->receive)
+                s->rxbuf = slave->receive(slave->opaque);
+        s->control |= 1 << 15;				/* RDRB */
+        /* TODO: depending on s->setup[4] bits [1:0] assert an IRQ or
+         * a DRQ.  When is the level IRQ supposed to be reset?  */
+    }
+}
+
+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;
+
+    switch (offset) {
+    case 0x00:	/* RDR */
+        s->control &= ~(1 << 15);			/* RDRB */
+        return s->rxbuf;
+
+    case 0x04:	/* CSR */
+        return s->control;
+
+    case 0x08:	/* SR1 */
+        return s->setup[0];
+    case 0x0c:	/* SR2 */
+        return s->setup[1];
+    case 0x10:	/* SR3 */
+        return s->setup[2];
+    case 0x14:	/* SR4 */
+        return s->setup[3];
+    case 0x18:	/* SR5 */
+        return s->setup[4];
+    }
+
+    OMAP_BAD_REG(addr);
+    return 0;
+}
+
+static void omap_uwire_write(void *opaque, target_phys_addr_t addr,
+                uint32_t value)
+{
+    struct omap_uwire_s *s = (struct omap_uwire_s *) opaque;
+    int offset = addr - s->base;
+
+    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 */
+            omap_uwire_transfer_start(s);
+        break;
+
+    case 0x04:	/* CSR */
+        s->control = value & 0x1fff;
+        if (value & (1 << 13))				/* START */
+            omap_uwire_transfer_start(s);
+        break;
+
+    case 0x08:	/* SR1 */
+        s->setup[0] = value & 0x003f;
+        break;
+
+    case 0x0c:	/* SR2 */
+        s->setup[1] = value & 0x0fc0;
+        break;
+
+    case 0x10:	/* SR3 */
+        s->setup[2] = value & 0x0003;
+        break;
+
+    case 0x14:	/* SR4 */
+        s->setup[3] = value & 0x0001;
+        break;
+
+    case 0x18:	/* SR5 */
+        s->setup[4] = value & 0x000f;
+        break;
+
+    default:
+        OMAP_BAD_REG(addr);
+        return;
+    }
+}
+
+static CPUReadMemoryFunc *omap_uwire_readfn[] = {
+    omap_badwidth_read16,
+    omap_uwire_read,
+    omap_badwidth_read16,
+};
+
+static CPUWriteMemoryFunc *omap_uwire_writefn[] = {
+    omap_badwidth_write16,
+    omap_uwire_write,
+    omap_badwidth_write16,
+};
+
+void omap_uwire_reset(struct omap_uwire_s *s)
+{
+    s->control= 0;
+    s->setup[0] = 0;
+    s->setup[1] = 0;
+    s->setup[2] = 0;
+    s->setup[3] = 0;
+    s->setup[4] = 0;
+}
+
+struct omap_uwire_s *omap_uwire_init(target_phys_addr_t base,
+                qemu_irq *irq, qemu_irq dma, omap_clk clk)
+{
+    int iomemtype;
+    struct omap_uwire_s *s = (struct omap_uwire_s *)
+            qemu_mallocz(sizeof(struct omap_uwire_s));
+
+    s->base = base;
+    s->txirq = irq[0];
+    s->rxirq = irq[1];
+    s->txdrq = dma;
+    omap_uwire_reset(s);
+
+    iomemtype = cpu_register_io_memory(0, omap_uwire_readfn,
+                    omap_uwire_writefn, s);
+    cpu_register_physical_memory(s->base, 0x800, iomemtype);
+
+    return s;
+}
+
+void omap_uwire_attach(struct omap_uwire_s *s,
+                struct uwire_slave_s *slave, int chipselect)
+{
+    if (chipselect < 0 || chipselect > 3)
+        cpu_abort(cpu_single_env, "%s: Bad chipselect %i\n", __FUNCTION__,
+                        chipselect);
+
+    s->chip[chipselect] = slave;
+}
+
 /* General chip reset */
 static void omap_mpu_reset(void *opaque)
 {
@@ -2810,10 +3430,13 @@
     omap_dpll_reset(&mpu->dpll[0]);
     omap_dpll_reset(&mpu->dpll[1]);
     omap_dpll_reset(&mpu->dpll[2]);
-    omap_uart_reset(mpu->uart1);
-    omap_uart_reset(mpu->uart2);
-    omap_uart_reset(mpu->uart3);
+    omap_uart_reset(mpu->uart[0]);
+    omap_uart_reset(mpu->uart[1]);
+    omap_uart_reset(mpu->uart[2]);
     omap_mmc_reset(mpu->mmc);
+    omap_mpuio_reset(mpu->mpuio);
+    omap_gpio_reset(mpu->gpio);
+    omap_uwire_reset(mpu->microwire);
     cpu_reset(mpu->env);
 }
 
@@ -2821,7 +3444,8 @@
 {
     struct omap_mpu_state_s *mpu = (struct omap_mpu_state_s *) opaque;
 
-    cpu_interrupt(mpu->env, CPU_INTERRUPT_EXITTB);
+    if (mpu->env->halted)
+        cpu_interrupt(mpu->env, CPU_INTERRUPT_EXITTB);
 }
 
 struct omap_mpu_state_s *omap310_mpu_init(unsigned long sdram_size,
@@ -2839,6 +3463,8 @@
 
     cpu_arm_set_model(s->env, core ?: "ti925t");
 
+    s->wakeup = qemu_allocate_irqs(omap_mpu_wakeup, s, 1)[0];
+
     /* Clocks */
     omap_clk_init(s);
 
@@ -2905,13 +3531,13 @@
 
     omap_tcmi_init(0xfffecc00, s);
 
-    s->uart1 = omap_uart_init(0xfffb0000, s->irq[1][OMAP_INT_UART1],
+    s->uart[0] = omap_uart_init(0xfffb0000, s->irq[1][OMAP_INT_UART1],
                     omap_findclk(s, "uart1_ck"),
                     serial_hds[0]);
-    s->uart2 = omap_uart_init(0xfffb0800, s->irq[1][OMAP_INT_UART2],
+    s->uart[1] = omap_uart_init(0xfffb0800, s->irq[1][OMAP_INT_UART2],
                     omap_findclk(s, "uart2_ck"),
                     serial_hds[0] ? serial_hds[1] : 0);
-    s->uart3 = omap_uart_init(0xe1019800, s->irq[0][OMAP_INT_UART3],
+    s->uart[2] = omap_uart_init(0xe1019800, s->irq[0][OMAP_INT_UART3],
                     omap_findclk(s, "uart3_ck"),
                     serial_hds[0] && serial_hds[1] ? serial_hds[2] : 0);
 
@@ -2922,8 +3548,17 @@
     s->mmc = omap_mmc_init(0xfffb7800, s->irq[1][OMAP_INT_OQN],
                     &s->drq[OMAP_DMA_MMC_TX], omap_findclk(s, "mmc_ck"));
 
+    s->mpuio = omap_mpuio_init(0xfffb5000,
+                    s->irq[1][OMAP_INT_KEYBOARD], s->irq[1][OMAP_INT_MPUIO],
+                    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"));
+
+    s->microwire = omap_uwire_init(0xfffb3000, &s->irq[1][OMAP_INT_uWireTX],
+                    s->drq[OMAP_DMA_UWIRE_TX], omap_findclk(s, "mpuper_ck"));
+
     qemu_register_reset(omap_mpu_reset, s);
-    s->wakeup = qemu_allocate_irqs(omap_mpu_wakeup, s, 1)[0];
 
     return s;
 }

Modified: trunk/src/host/qemu-neo1973/hw/omap.h
===================================================================
--- trunk/src/host/qemu-neo1973/hw/omap.h	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/hw/omap.h	2007-10-29 21:14:04 UTC (rev 3303)
@@ -450,6 +450,31 @@
 struct omap_uart_s *omap_uart_init(target_phys_addr_t base,
                 qemu_irq irq, omap_clk clk, CharDriverState *chr);
 
+struct omap_mpuio_s;
+struct omap_mpuio_s *omap_mpuio_init(target_phys_addr_t base,
+                qemu_irq kbd_int, qemu_irq gpio_int, qemu_irq wakeup,
+                omap_clk clk);
+qemu_irq *omap_mpuio_in_get(struct omap_mpuio_s *s);
+void omap_mpuio_out_set(struct omap_mpuio_s *s, int line, qemu_irq handler);
+void omap_mpuio_key(struct omap_mpuio_s *s, int row, int col, int down);
+
+struct omap_gpio_s;
+struct omap_gpio_s *omap_gpio_init(target_phys_addr_t base,
+                qemu_irq irq, omap_clk clk);
+qemu_irq *omap_gpio_in_get(struct omap_gpio_s *s);
+void omap_gpio_out_set(struct omap_gpio_s *s, int line, qemu_irq handler);
+
+struct uwire_slave_s {
+    uint16_t (*receive)(void *opaque);
+    void (*send)(void *opaque, uint16_t data);
+    void *opaque;
+};
+struct omap_uwire_s;
+struct omap_uwire_s *omap_uwire_init(target_phys_addr_t base,
+                qemu_irq *irq, qemu_irq dma, omap_clk clk);
+void omap_uwire_attach(struct omap_uwire_s *s,
+                struct uwire_slave_s *slave, int chipselect);
+
 /* omap_lcdc.c */
 struct omap_lcd_panel_s;
 void omap_lcdc_reset(struct omap_lcd_panel_s *s);
@@ -462,6 +487,7 @@
 struct omap_mmc_s *omap_mmc_init(target_phys_addr_t base,
                 qemu_irq irq, qemu_irq dma[], omap_clk clk);
 void omap_mmc_reset(struct omap_mmc_s *s);
+void omap_mmc_handlers(struct omap_mmc_s *s, qemu_irq ro, qemu_irq cover);
 
 # define cpu_is_omap310(cpu)		(cpu->mpu_model == omap310)
 # define cpu_is_omap1510(cpu)		(cpu->mpu_model == omap1510)
@@ -495,16 +521,19 @@
     unsigned long sram_size;
 
     /* MPUI-TIPB peripherals */
-    struct omap_uart_s *uart3;
+    struct omap_uart_s *uart[3];
 
+    struct omap_gpio_s *gpio;
+
     /* MPU public TIPB peripherals */
     struct omap_32khz_timer_s *os_timer;
 
-    struct omap_uart_s *uart1;
-    struct omap_uart_s *uart2;
-
     struct omap_mmc_s *mmc;
 
+    struct omap_mpuio_s *mpuio;
+
+    struct omap_uwire_s *microwire;
+
     /* MPU private TIPB peripherals */
     struct omap_intr_handler_s *ih[2];
 

Modified: trunk/src/host/qemu-neo1973/hw/omap_mmc.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/omap_mmc.c	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/hw/omap_mmc.c	2007-10-29 21:14:04 UTC (rev 3303)
@@ -25,6 +25,7 @@
     target_phys_addr_t base;
     qemu_irq irq;
     qemu_irq *dma;
+    qemu_irq handler[2];
     omap_clk clk;
     SDState *card;
     uint16_t last_cmd;
@@ -506,6 +507,22 @@
     host->transfer = 0;
 }
 
+static void omap_mmc_ro_cb(void *opaque, int level)
+{
+    struct omap_mmc_s *s = (struct omap_mmc_s *) opaque;
+
+    if (s->handler[0])
+        qemu_set_irq(s->handler[0], level);
+}
+
+static void omap_mmc_cover_cb(void *opaque, int level)
+{
+    struct omap_mmc_s *s = (struct omap_mmc_s *) opaque;
+
+    if (s->handler[1])
+        qemu_set_irq(s->handler[1], level);
+}
+
 struct omap_mmc_s *omap_mmc_init(target_phys_addr_t base,
                 qemu_irq irq, qemu_irq dma[], omap_clk clk)
 {
@@ -525,7 +542,13 @@
     /* Instantiate the storage */
     s->card = sd_init(sd_bdrv);
 
+    sd_set_cb(s->card, s, omap_mmc_ro_cb, omap_mmc_cover_cb);
+
     return s;
 }
 
-/* TODO: insertion and read-only handlers */
+void omap_mmc_handlers(struct omap_mmc_s *s, qemu_irq ro, qemu_irq cover)
+{
+    s->handler[0] = ro;
+    s->handler[1] = cover;
+}

Modified: trunk/src/host/qemu-neo1973/hw/palm.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/palm.c	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/hw/palm.c	2007-10-29 21:14:04 UTC (rev 3303)
@@ -37,7 +37,8 @@
 }
 
 static void static_write(void *opaque, target_phys_addr_t offset,
-                uint32_t value) {
+                uint32_t value)
+{
 #ifdef SPY
     printf("%s: value %08lx written at " PA_FMT "\n",
                     __FUNCTION__, value, offset);
@@ -57,10 +58,63 @@
 };
 
 /* Palm Tunsgten|E support */
+
+/* Shared GPIOs */
+#define PALMTE_USBDETECT_GPIO	0
+#define PALMTE_USB_OR_DC_GPIO	1
+#define PALMTE_TSC_GPIO		4
+#define PALMTE_PINTDAV_GPIO	6
+#define PALMTE_MMC_WP_GPIO	8
+#define PALMTE_MMC_POWER_GPIO	9
+#define PALMTE_HDQ_GPIO		11
+#define PALMTE_HEADPHONES_GPIO	14
+#define PALMTE_SPEAKER_GPIO	15
+/* MPU private GPIOs */
+#define PALMTE_DC_GPIO		2
+#define PALMTE_MMC_SWITCH_GPIO	4
+#define PALMTE_MMC1_GPIO	6
+#define PALMTE_MMC2_GPIO	7
+#define PALMTE_MMC3_GPIO	11
+
 static void palmte_microwire_setup(struct omap_mpu_state_s *cpu)
 {
+    qemu_irq p_int = omap_gpio_in_get(cpu->gpio)[PALMTE_PINTDAV_GPIO];
+
+    omap_uwire_attach(
+                    cpu->microwire,
+                    tsc2102_init(qemu_irq_invert(p_int)),
+                    0);
 }
 
+static struct {
+    int row;
+    int column;
+} palmte_keymap[0x80] = {
+    [0 ... 0x7f] = { -1, -1 },
+    [0x3b] = { 0, 0 },	/* F1	-> Calendar */
+    [0x3c] = { 1, 0 },	/* F2	-> Contacts */
+    [0x3d] = { 2, 0 },	/* F3	-> Tasks List */
+    [0x3e] = { 3, 0 },	/* F4	-> Note Pad */
+    [0x01] = { 4, 0 },	/* Esc	-> Power */
+    [0x4b] = { 0, 1 },	/* 	   Left */
+    [0x50] = { 1, 1 },	/* 	   Down */
+    [0x48] = { 2, 1 },	/*	   Up */
+    [0x4d] = { 3, 1 },	/*	   Right */
+    [0x4c] = { 4, 1 },	/* 	   Centre */
+    [0x39] = { 4, 1 },	/* Spc	-> Centre */
+};
+
+static void palmte_button_event(void *opaque, int keycode)
+{
+    struct omap_mpu_state_s *cpu = (struct omap_mpu_state_s *) opaque;
+
+    if (palmte_keymap[keycode & 0x7f].row != -1)
+        omap_mpuio_key(cpu->mpuio,
+                        palmte_keymap[keycode & 0x7f].row,
+                        palmte_keymap[keycode & 0x7f].column,
+                        !(keycode & 0x80));
+}
+
 static void palmte_init(int ram_size, int vga_ram_size, int boot_device,
                 DisplayState *ds, const char **fd_filename, int snapshot,
                 const char *kernel_filename, const char *kernel_cmdline,
@@ -101,6 +155,13 @@
 
     palmte_microwire_setup(cpu);
 
+    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]));
+
     /* Setup initial (reset) machine state */
     if (nb_option_roms) {
         rom_size = get_image_size(option_rom[0]);

Modified: trunk/src/host/qemu-neo1973/hw/pc.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/pc.c	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/hw/pc.c	2007-10-29 21:14:04 UTC (rev 3303)
@@ -93,6 +93,9 @@
         return intno;
     }
     /* read the irq from the PIC */
+    if (!apic_accept_pic_intr(env))
+        return -1;
+
     intno = pic_read_irq(isa_pic);
     return intno;
 }
@@ -100,10 +103,8 @@
 static void pic_irq_request(void *opaque, int irq, int level)
 {
     CPUState *env = opaque;
-    if (level)
+    if (level && apic_accept_pic_intr(env))
         cpu_interrupt(env, CPU_INTERRUPT_HARD);
-    else
-        cpu_reset_interrupt(env, CPU_INTERRUPT_HARD);
 }
 
 /* PC cmos mappings */
@@ -706,7 +707,9 @@
     vga_ram_addr = qemu_ram_alloc(vga_ram_size);
 
     /* BIOS load */
-    snprintf(buf, sizeof(buf), "%s/%s", bios_dir, BIOS_FILENAME);
+    if (bios_name == NULL)
+        bios_name = BIOS_FILENAME;
+    snprintf(buf, sizeof(buf), "%s/%s", bios_dir, bios_name);
     bios_size = get_image_size(buf);
     if (bios_size <= 0 ||
         (bios_size % 65536) != 0) {

Modified: trunk/src/host/qemu-neo1973/hw/pckbd.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/pckbd.c	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/hw/pckbd.c	2007-10-29 21:14:04 UTC (rev 3303)
@@ -207,7 +207,7 @@
 #endif
     switch(val) {
     case KBD_CCMD_READ_MODE:
-        kbd_queue(s, s->mode, 0);
+        kbd_queue(s, s->mode, 1);
         break;
     case KBD_CCMD_WRITE_MODE:
     case KBD_CCMD_WRITE_OBUF:

Modified: trunk/src/host/qemu-neo1973/hw/piix_pci.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/piix_pci.c	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/hw/piix_pci.c	2007-10-29 21:14:04 UTC (rev 3303)
@@ -208,6 +208,7 @@
 {
     int i, pic_irq, pic_level;
 
+    piix3_dev->config[0x60 + irq_num] &= ~0x80;   // enable bit
     pci_irq_levels[irq_num] = level;
 
     /* now we change the pic irq level according to the piix irq mappings */

Modified: trunk/src/host/qemu-neo1973/hw/pl110.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/pl110.c	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/hw/pl110.c	2007-10-29 21:14:04 UTC (rev 3303)
@@ -10,6 +10,7 @@
 #include "vl.h"
 
 #define PL110_CR_EN   0x001
+#define PL110_CR_BGR  0x100
 #define PL110_CR_BEBO 0x200
 #define PL110_CR_BEPO 0x400
 #define PL110_CR_PWR  0x800
@@ -114,6 +115,7 @@
     int first, last = 0;
     int dirty, new_dirty;
     int i;
+    int bpp_offset;
 
     if (!pl110_enabled(s))
         return;
@@ -145,12 +147,17 @@
         fprintf(stderr, "pl110: Bad color depth\n");
         exit(1);
     }
+    if (s->cr & PL110_CR_BGR)
+        bpp_offset = 0;
+    else
+        bpp_offset = 18;
+
     if (s->cr & PL110_CR_BEBO)
-      fn = fntable[s->bpp + 6];
+        fn = fntable[s->bpp + 6 + bpp_offset];
     else if (s->cr & PL110_CR_BEPO)
-      fn = fntable[s->bpp + 12];
+        fn = fntable[s->bpp + 12 + bpp_offset];
     else
-      fn = fntable[s->bpp];
+        fn = fntable[s->bpp + bpp_offset];
 
     src_width = s->cols;
     switch (s->bpp) {

Modified: trunk/src/host/qemu-neo1973/hw/pl110_template.h
===================================================================
--- trunk/src/host/qemu-neo1973/hw/pl110_template.h	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/hw/pl110_template.h	2007-10-29 21:14:04 UTC (rev 3303)
@@ -24,35 +24,68 @@
 #error unknown bit depth
 #endif
 
+#undef RGB
+#define BORDER bgr
 #define ORDER 0
 #include "pl110_template.h"
 #define ORDER 1
 #include "pl110_template.h"
 #define ORDER 2
 #include "pl110_template.h"
+#undef BORDER
+#define RGB
+#define BORDER rgb
+#define ORDER 0
+#include "pl110_template.h"
+#define ORDER 1
+#include "pl110_template.h"
+#define ORDER 2
+#include "pl110_template.h"
+#undef BORDER
 
-static drawfn glue(pl110_draw_fn_,BITS)[18] =
+static drawfn glue(pl110_draw_fn_,BITS)[36] =
 {
-    glue(pl110_draw_line1_lblp,BITS),
-    glue(pl110_draw_line2_lblp,BITS),
-    glue(pl110_draw_line4_lblp,BITS),
-    glue(pl110_draw_line8_lblp,BITS),
-    glue(pl110_draw_line16_lblp,BITS),
-    glue(pl110_draw_line32_lblp,BITS),
+    glue(pl110_draw_line1_lblp_bgr,BITS),
+    glue(pl110_draw_line2_lblp_bgr,BITS),
+    glue(pl110_draw_line4_lblp_bgr,BITS),
+    glue(pl110_draw_line8_lblp_bgr,BITS),
+    glue(pl110_draw_line16_lblp_bgr,BITS),
+    glue(pl110_draw_line32_lblp_bgr,BITS),
 
-    glue(pl110_draw_line1_bbbp,BITS),
-    glue(pl110_draw_line2_bbbp,BITS),
-    glue(pl110_draw_line4_bbbp,BITS),
-    glue(pl110_draw_line8_bbbp,BITS),
-    glue(pl110_draw_line16_bbbp,BITS),
-    glue(pl110_draw_line32_bbbp,BITS),
+    glue(pl110_draw_line1_bbbp_bgr,BITS),
+    glue(pl110_draw_line2_bbbp_bgr,BITS),
+    glue(pl110_draw_line4_bbbp_bgr,BITS),
+    glue(pl110_draw_line8_bbbp_bgr,BITS),
+    glue(pl110_draw_line16_bbbp_bgr,BITS),
+    glue(pl110_draw_line32_bbbp_bgr,BITS),
 
-    glue(pl110_draw_line1_lbbp,BITS),
-    glue(pl110_draw_line2_lbbp,BITS),
-    glue(pl110_draw_line4_lbbp,BITS),
-    glue(pl110_draw_line8_lbbp,BITS),
-    glue(pl110_draw_line16_lbbp,BITS),
-    glue(pl110_draw_line32_lbbp,BITS)
+    glue(pl110_draw_line1_lbbp_bgr,BITS),
+    glue(pl110_draw_line2_lbbp_bgr,BITS),
+    glue(pl110_draw_line4_lbbp_bgr,BITS),
+    glue(pl110_draw_line8_lbbp_bgr,BITS),
+    glue(pl110_draw_line16_lbbp_bgr,BITS),
+    glue(pl110_draw_line32_lbbp_bgr,BITS),
+
+    glue(pl110_draw_line1_lblp_rgb,BITS),
+    glue(pl110_draw_line2_lblp_rgb,BITS),
+    glue(pl110_draw_line4_lblp_rgb,BITS),
+    glue(pl110_draw_line8_lblp_rgb,BITS),
+    glue(pl110_draw_line16_lblp_rgb,BITS),
+    glue(pl110_draw_line32_lblp_rgb,BITS),
+
+    glue(pl110_draw_line1_bbbp_rgb,BITS),
+    glue(pl110_draw_line2_bbbp_rgb,BITS),
+    glue(pl110_draw_line4_bbbp_rgb,BITS),
+    glue(pl110_draw_line8_bbbp_rgb,BITS),
+    glue(pl110_draw_line16_bbbp_rgb,BITS),
+    glue(pl110_draw_line32_bbbp_rgb,BITS),
+
+    glue(pl110_draw_line1_lbbp_rgb,BITS),
+    glue(pl110_draw_line2_lbbp_rgb,BITS),
+    glue(pl110_draw_line4_lbbp_rgb,BITS),
+    glue(pl110_draw_line8_lbbp_rgb,BITS),
+    glue(pl110_draw_line16_lbbp_rgb,BITS),
+    glue(pl110_draw_line32_lbbp_rgb,BITS),
 };
 
 #undef BITS
@@ -61,18 +94,18 @@
 #else
 
 #if ORDER == 0
-#define NAME glue(lblp, BITS)
+#define NAME glue(glue(lblp_, BORDER), BITS)
 #ifdef WORDS_BIGENDIAN
 #define SWAP_WORDS 1
 #endif
 #elif ORDER == 1
-#define NAME glue(bbbp, BITS)
+#define NAME glue(glue(bbbp_, BORDER), BITS)
 #ifndef WORDS_BIGENDIAN
 #define SWAP_WORDS 1
 #endif
 #else
 #define SWAP_PIXELS 1
-#define NAME glue(lbbp, BITS)
+#define NAME glue(glue(lbbp_, BORDER), BITS)
 #ifdef WORDS_BIGENDIAN
 #define SWAP_WORDS 1
 #endif
@@ -195,29 +228,38 @@
 #ifdef SWAP_WORDS
         data = bswap32(data);
 #endif
+#ifdef RGB
+#define LSB r
+#define MSB b
+#else
+#define LSB b
+#define MSB r
+#endif
 #if 0
-        r = data & 0x1f;
+        LSB = data & 0x1f;
         data >>= 5;
         g = data & 0x3f;
         data >>= 6;
-        b = data & 0x1f;
+        MSB = data & 0x1f;
         data >>= 5;
 #else
-        r = (data & 0x1f) << 3;
+        LSB = (data & 0x1f) << 3;
         data >>= 5;
         g = (data & 0x3f) << 2;
         data >>= 6;
-        b = (data & 0x1f) << 3;
+        MSB = (data & 0x1f) << 3;
         data >>= 5;
 #endif
         COPY_PIXEL(d, glue(rgb_to_pixel,BITS)(r, g, b));
-        r = (data & 0x1f) << 3;
+        LSB = (data & 0x1f) << 3;
         data >>= 5;
         g = (data & 0x3f) << 2;
         data >>= 6;
-        b = (data & 0x1f) << 3;
+        MSB = (data & 0x1f) << 3;
         data >>= 5;
         COPY_PIXEL(d, glue(rgb_to_pixel,BITS)(r, g, b));
+#undef MSB
+#undef LSB
         width -= 2;
         src += 4;
     }
@@ -229,16 +271,25 @@
     unsigned int r, g, b;
     while (width > 0) {
         data = *(uint32_t *)src;
+#ifdef RGB
+#define LSB r
+#define MSB b
+#else
+#define LSB b
+#define MSB r
+#endif
 #ifdef SWAP_WORDS
-        r = data & 0xff;
+        LSB = data & 0xff;
         g = (data >> 8) & 0xff;
-        b = (data >> 16) & 0xff;
+        MSB = (data >> 16) & 0xff;
 #else
-        r = (data >> 24) & 0xff;
+        LSB = (data >> 24) & 0xff;
         g = (data >> 16) & 0xff;
-        b = (data >> 8) & 0xff;
+        MSB = (data >> 8) & 0xff;
 #endif
         COPY_PIXEL(d, glue(rgb_to_pixel,BITS)(r, g, b));
+#undef MSB
+#undef LSB
         width--;
         src += 4;
     }

Modified: trunk/src/host/qemu-neo1973/hw/ppc.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/ppc.c	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/hw/ppc.c	2007-10-29 21:14:04 UTC (rev 3303)
@@ -22,7 +22,6 @@
  * THE SOFTWARE.
  */
 #include "vl.h"
-#include "m48t59.h"
 
 //#define PPC_DEBUG_IRQ
 //#define PPC_DEBUG_TB
@@ -30,7 +29,10 @@
 extern FILE *logfile;
 extern int loglevel;
 
-void ppc_set_irq (CPUState *env, int n_IRQ, int level)
+static void cpu_ppc_tb_stop (CPUState *env);
+static void cpu_ppc_tb_start (CPUState *env);
+
+static void ppc_set_irq (CPUState *env, int n_IRQ, int level)
 {
     if (level) {
         env->pending_interrupts |= 1 << n_IRQ;
@@ -65,6 +67,19 @@
     /* Don't generate spurious events */
     if ((cur_level == 1 && level == 0) || (cur_level == 0 && level != 0)) {
         switch (pin) {
+        case PPC6xx_INPUT_TBEN:
+            /* Level sensitive - active high */
+#if defined(PPC_DEBUG_IRQ)
+            if (loglevel & CPU_LOG_INT) {
+                fprintf(logfile, "%s: %s the time base\n",
+                        __func__, level ? "start" : "stop");
+            }
+#endif
+            if (level) {
+                cpu_ppc_tb_start(env);
+            } else {
+                cpu_ppc_tb_stop(env);
+            }
         case PPC6xx_INPUT_INT:
             /* Level sensitive - active high */
 #if defined(PPC_DEBUG_IRQ)
@@ -103,6 +118,7 @@
         case PPC6xx_INPUT_CKSTP_IN:
             /* Level sensitive - active low */
             /* XXX: TODO: relay the signal to CKSTP_OUT pin */
+            /* XXX: Note that the only way to restart the CPU is to reset it */
             if (level) {
 #if defined(PPC_DEBUG_IRQ)
                 if (loglevel & CPU_LOG_INT) {
@@ -110,25 +126,22 @@
                 }
 #endif
                 env->halted = 1;
-            } else {
-#if defined(PPC_DEBUG_IRQ)
-                if (loglevel & CPU_LOG_INT) {
-                    fprintf(logfile, "%s: restart the CPU\n", __func__);
-                }
-#endif
-                env->halted = 0;
             }
             break;
         case PPC6xx_INPUT_HRESET:
             /* Level sensitive - active low */
             if (level) {
-#if 0 // XXX: TOFIX
 #if defined(PPC_DEBUG_IRQ)
                 if (loglevel & CPU_LOG_INT) {
                     fprintf(logfile, "%s: reset the CPU\n", __func__);
                 }
 #endif
-                cpu_reset(env);
+                env->interrupt_request |= CPU_INTERRUPT_EXITTB;
+                /* XXX: TOFIX */
+#if 0
+                cpu_ppc_reset(env);
+#else
+                qemu_system_reset_request();
 #endif
             }
             break;
@@ -162,6 +175,7 @@
     env->irq_inputs = (void **)qemu_allocate_irqs(&ppc6xx_set_irq, env, 6);
 }
 
+#if defined(TARGET_PPC64)
 /* PowerPC 970 internal IRQ controller */
 static void ppc970_set_irq (void *opaque, int pin, int level)
 {
@@ -283,9 +297,10 @@
 {
     env->irq_inputs = (void **)qemu_allocate_irqs(&ppc970_set_irq, env, 7);
 }
+#endif /* defined(TARGET_PPC64) */
 
-/* PowerPC 405 internal IRQ controller */
-static void ppc405_set_irq (void *opaque, int pin, int level)
+/* PowerPC 40x internal IRQ controller */
+static void ppc40x_set_irq (void *opaque, int pin, int level)
 {
     CPUState *env = opaque;
     int cur_level;
@@ -300,7 +315,7 @@
     /* Don't generate spurious events */
     if ((cur_level == 1 && level == 0) || (cur_level == 0 && level != 0)) {
         switch (pin) {
-        case PPC405_INPUT_RESET_SYS:
+        case PPC40x_INPUT_RESET_SYS:
             if (level) {
 #if defined(PPC_DEBUG_IRQ)
                 if (loglevel & CPU_LOG_INT) {
@@ -311,7 +326,7 @@
                 ppc40x_system_reset(env);
             }
             break;
-        case PPC405_INPUT_RESET_CHIP:
+        case PPC40x_INPUT_RESET_CHIP:
             if (level) {
 #if defined(PPC_DEBUG_IRQ)
                 if (loglevel & CPU_LOG_INT) {
@@ -321,8 +336,7 @@
                 ppc40x_chip_reset(env);
             }
             break;
-            /* No break here */
-        case PPC405_INPUT_RESET_CORE:
+        case PPC40x_INPUT_RESET_CORE:
             /* XXX: TODO: update DBSR[MRR] */
             if (level) {
 #if defined(PPC_DEBUG_IRQ)
@@ -333,7 +347,7 @@
                 ppc40x_core_reset(env);
             }
             break;
-        case PPC405_INPUT_CINT:
+        case PPC40x_INPUT_CINT:
             /* Level sensitive - active high */
 #if defined(PPC_DEBUG_IRQ)
             if (loglevel & CPU_LOG_INT) {
@@ -341,10 +355,9 @@
                         __func__, level);
             }
 #endif
-            /* XXX: TOFIX */
-            ppc_set_irq(env, PPC_INTERRUPT_RESET, level);
+            ppc_set_irq(env, PPC_INTERRUPT_CEXT, level);
             break;
-        case PPC405_INPUT_INT:
+        case PPC40x_INPUT_INT:
             /* Level sensitive - active high */
 #if defined(PPC_DEBUG_IRQ)
             if (loglevel & CPU_LOG_INT) {
@@ -354,7 +367,7 @@
 #endif
             ppc_set_irq(env, PPC_INTERRUPT_EXT, level);
             break;
-        case PPC405_INPUT_HALT:
+        case PPC40x_INPUT_HALT:
             /* Level sensitive - active low */
             if (level) {
 #if defined(PPC_DEBUG_IRQ)
@@ -372,15 +385,15 @@
                 env->halted = 0;
             }
             break;
-        case PPC405_INPUT_DEBUG:
+        case PPC40x_INPUT_DEBUG:
             /* Level sensitive - active high */
 #if defined(PPC_DEBUG_IRQ)
             if (loglevel & CPU_LOG_INT) {
-                fprintf(logfile, "%s: set the external IRQ state to %d\n",
+                fprintf(logfile, "%s: set the debug pin state to %d\n",
                         __func__, level);
             }
 #endif
-            ppc_set_irq(env, EXCP_40x_DEBUG, level);
+            ppc_set_irq(env, PPC_INTERRUPT_DEBUG, level);
             break;
         default:
             /* Unknown pin - do nothing */
@@ -398,28 +411,38 @@
     }
 }
 
-void ppc405_irq_init (CPUState *env)
+void ppc40x_irq_init (CPUState *env)
 {
-    env->irq_inputs = (void **)qemu_allocate_irqs(&ppc405_set_irq, env, 7);
+    env->irq_inputs = (void **)qemu_allocate_irqs(&ppc40x_set_irq,
+                                                  env, PPC40x_INPUT_NB);
 }
 
 /*****************************************************************************/
 /* PowerPC time base and decrementer emulation */
 struct ppc_tb_t {
     /* Time base management */
-    int64_t  tb_offset;    /* Compensation               */
-    uint32_t tb_freq;      /* TB frequency               */
+    int64_t  tb_offset;    /* Compensation                    */
+    int64_t  atb_offset;   /* Compensation                    */
+    uint32_t tb_freq;      /* TB frequency                    */
     /* Decrementer management */
-    uint64_t decr_next;    /* Tick for next decr interrupt  */
+    uint64_t decr_next;    /* Tick for next decr interrupt    */
+    uint32_t decr_freq;    /* decrementer frequency           */
     struct QEMUTimer *decr_timer;
+#if defined(TARGET_PPC64H)
+    /* Hypervisor decrementer management */
+    uint64_t hdecr_next;    /* Tick for next hdecr interrupt  */
+    struct QEMUTimer *hdecr_timer;
+    uint64_t purr_load;
+    uint64_t purr_start;
+#endif
     void *opaque;
 };
 
-static inline uint64_t cpu_ppc_get_tb (ppc_tb_t *tb_env)
+static always_inline uint64_t cpu_ppc_get_tb (ppc_tb_t *tb_env, uint64_t vmclk,
+                                              int64_t tb_offset)
 {
     /* TB time in tb periods */
-    return muldiv64(qemu_get_clock(vm_clock) + tb_env->tb_offset,
-                    tb_env->tb_freq, ticks_per_sec);
+    return muldiv64(vmclk, tb_env->tb_freq, ticks_per_sec) + tb_offset;
 }
 
 uint32_t cpu_ppc_load_tbl (CPUState *env)
@@ -427,31 +450,22 @@
     ppc_tb_t *tb_env = env->tb_env;
     uint64_t tb;
 
-    tb = cpu_ppc_get_tb(tb_env);
-#ifdef PPC_DEBUG_TB
-    {
-        static int last_time;
-        int now;
-        now = time(NULL);
-        if (last_time != now) {
-            last_time = now;
-            if (loglevel != 0) {
-                fprintf(logfile, "%s: tb=0x%016lx %d %08lx\n",
-                        __func__, tb, now, tb_env->tb_offset);
-            }
-        }
+    tb = cpu_ppc_get_tb(tb_env, qemu_get_clock(vm_clock), tb_env->tb_offset);
+#if defined(PPC_DEBUG_TB)
+    if (loglevel != 0) {
+        fprintf(logfile, "%s: tb=0x%016lx\n", __func__, tb);
     }
 #endif
 
     return tb & 0xFFFFFFFF;
 }
 
-uint32_t cpu_ppc_load_tbu (CPUState *env)
+static always_inline uint32_t _cpu_ppc_load_tbu (CPUState *env)
 {
     ppc_tb_t *tb_env = env->tb_env;
     uint64_t tb;
 
-    tb = cpu_ppc_get_tb(tb_env);
+    tb = cpu_ppc_get_tb(tb_env, qemu_get_clock(vm_clock), tb_env->tb_offset);
 #if defined(PPC_DEBUG_TB)
     if (loglevel != 0) {
         fprintf(logfile, "%s: tb=0x%016lx\n", __func__, tb);
@@ -461,45 +475,158 @@
     return tb >> 32;
 }
 
-static void cpu_ppc_store_tb (ppc_tb_t *tb_env, uint64_t value)
+uint32_t cpu_ppc_load_tbu (CPUState *env)
 {
-    tb_env->tb_offset = muldiv64(value, ticks_per_sec, tb_env->tb_freq)
-        - qemu_get_clock(vm_clock);
+    return _cpu_ppc_load_tbu(env);
+}
+
+static always_inline void cpu_ppc_store_tb (ppc_tb_t *tb_env, uint64_t vmclk,
+                                            int64_t *tb_offsetp,
+                                            uint64_t value)
+{
+    *tb_offsetp = value - muldiv64(vmclk, tb_env->tb_freq, ticks_per_sec);
 #ifdef PPC_DEBUG_TB
     if (loglevel != 0) {
         fprintf(logfile, "%s: tb=0x%016lx offset=%08lx\n", __func__, value,
-                tb_env->tb_offset);
+                *tb_offsetp);
     }
 #endif
 }
 
+void cpu_ppc_store_tbl (CPUState *env, uint32_t value)
+{
+    ppc_tb_t *tb_env = env->tb_env;
+    uint64_t tb;
+
+    tb = cpu_ppc_get_tb(tb_env, qemu_get_clock(vm_clock), tb_env->tb_offset);
+    tb &= 0xFFFFFFFF00000000ULL;
+    cpu_ppc_store_tb(tb_env, qemu_get_clock(vm_clock),
+                     &tb_env->tb_offset, tb | (uint64_t)value);
+}
+
+static always_inline void _cpu_ppc_store_tbu (CPUState *env, uint32_t value)
+{
+    ppc_tb_t *tb_env = env->tb_env;
+    uint64_t tb;
+
+    tb = cpu_ppc_get_tb(tb_env, qemu_get_clock(vm_clock), tb_env->tb_offset);
+    tb &= 0x00000000FFFFFFFFULL;
+    cpu_ppc_store_tb(tb_env, qemu_get_clock(vm_clock),
+                     &tb_env->tb_offset, ((uint64_t)value << 32) | tb);
+}
+
 void cpu_ppc_store_tbu (CPUState *env, uint32_t value)
 {
+    _cpu_ppc_store_tbu(env, value);
+}
+
+uint32_t cpu_ppc_load_atbl (CPUState *env)
+{
     ppc_tb_t *tb_env = env->tb_env;
+    uint64_t tb;
 
-    cpu_ppc_store_tb(tb_env,
-                     ((uint64_t)value << 32) | cpu_ppc_load_tbl(env));
+    tb = cpu_ppc_get_tb(tb_env, qemu_get_clock(vm_clock), tb_env->atb_offset);
+#if defined(PPC_DEBUG_TB)
+    if (loglevel != 0) {
+        fprintf(logfile, "%s: tb=0x%016lx\n", __func__, tb);
+    }
+#endif
+
+    return tb & 0xFFFFFFFF;
 }
 
-void cpu_ppc_store_tbl (CPUState *env, uint32_t value)
+uint32_t cpu_ppc_load_atbu (CPUState *env)
 {
     ppc_tb_t *tb_env = env->tb_env;
+    uint64_t tb;
 
-    cpu_ppc_store_tb(tb_env,
-                     ((uint64_t)cpu_ppc_load_tbu(env) << 32) | value);
+    tb = cpu_ppc_get_tb(tb_env, qemu_get_clock(vm_clock), tb_env->atb_offset);
+#if defined(PPC_DEBUG_TB)
+    if (loglevel != 0) {
+        fprintf(logfile, "%s: tb=0x%016lx\n", __func__, tb);
+    }
+#endif
+
+    return tb >> 32;
 }
 
-uint32_t cpu_ppc_load_decr (CPUState *env)
+void cpu_ppc_store_atbl (CPUState *env, uint32_t value)
 {
     ppc_tb_t *tb_env = env->tb_env;
+    uint64_t tb;
+
+    tb = cpu_ppc_get_tb(tb_env, qemu_get_clock(vm_clock), tb_env->atb_offset);
+    tb &= 0xFFFFFFFF00000000ULL;
+    cpu_ppc_store_tb(tb_env, qemu_get_clock(vm_clock),
+                     &tb_env->atb_offset, tb | (uint64_t)value);
+}
+
+void cpu_ppc_store_atbu (CPUState *env, uint32_t value)
+{
+    ppc_tb_t *tb_env = env->tb_env;
+    uint64_t tb;
+
+    tb = cpu_ppc_get_tb(tb_env, qemu_get_clock(vm_clock), tb_env->atb_offset);
+    tb &= 0x00000000FFFFFFFFULL;
+    cpu_ppc_store_tb(tb_env, qemu_get_clock(vm_clock),
+                     &tb_env->atb_offset, ((uint64_t)value << 32) | tb);
+}
+
+static void cpu_ppc_tb_stop (CPUState *env)
+{
+    ppc_tb_t *tb_env = env->tb_env;
+    uint64_t tb, atb, vmclk;
+
+    /* If the time base is already frozen, do nothing */
+    if (tb_env->tb_freq != 0) {
+        vmclk = qemu_get_clock(vm_clock);
+        /* Get the time base */
+        tb = cpu_ppc_get_tb(tb_env, vmclk, tb_env->tb_offset);
+        /* Get the alternate time base */
+        atb = cpu_ppc_get_tb(tb_env, vmclk, tb_env->atb_offset);
+        /* Store the time base value (ie compute the current offset) */
+        cpu_ppc_store_tb(tb_env, vmclk, &tb_env->tb_offset, tb);
+        /* Store the alternate time base value (compute the current offset) */
+        cpu_ppc_store_tb(tb_env, vmclk, &tb_env->atb_offset, atb);
+        /* Set the time base frequency to zero */
+        tb_env->tb_freq = 0;
+        /* Now, the time bases are frozen to tb_offset / atb_offset value */
+    }
+}
+
+static void cpu_ppc_tb_start (CPUState *env)
+{
+    ppc_tb_t *tb_env = env->tb_env;
+    uint64_t tb, atb, vmclk;
+    
+    /* If the time base is not frozen, do nothing */
+    if (tb_env->tb_freq == 0) {
+        vmclk = qemu_get_clock(vm_clock);
+        /* Get the time base from tb_offset */
+        tb = tb_env->tb_offset;
+        /* Get the alternate time base from atb_offset */
+        atb = tb_env->atb_offset;
+        /* Restore the tb frequency from the decrementer frequency */
+        tb_env->tb_freq = tb_env->decr_freq;
+        /* Store the time base value */
+        cpu_ppc_store_tb(tb_env, vmclk, &tb_env->tb_offset, tb);
+        /* Store the alternate time base value */
+        cpu_ppc_store_tb(tb_env, vmclk, &tb_env->atb_offset, atb);
+    }
+}
+
+static always_inline uint32_t _cpu_ppc_load_decr (CPUState *env,
+                                                  uint64_t *next)
+{
+    ppc_tb_t *tb_env = env->tb_env;
     uint32_t decr;
     int64_t diff;
 
     diff = tb_env->decr_next - qemu_get_clock(vm_clock);
     if (diff >= 0)
-        decr = muldiv64(diff, tb_env->tb_freq, ticks_per_sec);
+        decr = muldiv64(diff, tb_env->decr_freq, ticks_per_sec);
     else
-        decr = -muldiv64(-diff, tb_env->tb_freq, ticks_per_sec);
+        decr = -muldiv64(-diff, tb_env->decr_freq, ticks_per_sec);
 #if defined(PPC_DEBUG_TB)
     if (loglevel != 0) {
         fprintf(logfile, "%s: 0x%08x\n", __func__, decr);
@@ -509,10 +636,36 @@
     return decr;
 }
 
+uint32_t cpu_ppc_load_decr (CPUState *env)
+{
+    ppc_tb_t *tb_env = env->tb_env;
+
+    return _cpu_ppc_load_decr(env, &tb_env->decr_next);
+}
+
+#if defined(TARGET_PPC64H)
+uint32_t cpu_ppc_load_hdecr (CPUState *env)
+{
+    ppc_tb_t *tb_env = env->tb_env;
+
+    return _cpu_ppc_load_decr(env, &tb_env->hdecr_next);
+}
+
+uint64_t cpu_ppc_load_purr (CPUState *env)
+{
+    ppc_tb_t *tb_env = env->tb_env;
+    uint64_t diff;
+
+    diff = qemu_get_clock(vm_clock) - tb_env->purr_start;
+
+    return tb_env->purr_load + muldiv64(diff, tb_env->tb_freq, ticks_per_sec);
+}
+#endif /* defined(TARGET_PPC64H) */
+
 /* When decrementer expires,
  * all we need to do is generate or queue a CPU exception
  */
-static inline void cpu_ppc_decr_excp (CPUState *env)
+static always_inline void cpu_ppc_decr_excp (CPUState *env)
 {
     /* Raise it */
 #ifdef PPC_DEBUG_TB
@@ -523,9 +676,23 @@
     ppc_set_irq(env, PPC_INTERRUPT_DECR, 1);
 }
 
-static void _cpu_ppc_store_decr (CPUState *env, uint32_t decr,
-                                 uint32_t value, int is_excp)
+static always_inline void cpu_ppc_hdecr_excp (CPUState *env)
 {
+    /* Raise it */
+#ifdef PPC_DEBUG_TB
+    if (loglevel != 0) {
+        fprintf(logfile, "raise decrementer exception\n");
+    }
+#endif
+    ppc_set_irq(env, PPC_INTERRUPT_HDECR, 1);
+}
+
+static void __cpu_ppc_store_decr (CPUState *env, uint64_t *nextp,
+                                  struct QEMUTimer *timer,
+                                  void (*raise_excp)(CPUState *),
+                                  uint32_t decr, uint32_t value,
+                                  int is_excp)
+{
     ppc_tb_t *tb_env = env->tb_env;
     uint64_t now, next;
 
@@ -535,21 +702,30 @@
     }
 #endif
     now = qemu_get_clock(vm_clock);
-    next = now + muldiv64(value, ticks_per_sec, tb_env->tb_freq);
+    next = now + muldiv64(value, ticks_per_sec, tb_env->decr_freq);
     if (is_excp)
-        next += tb_env->decr_next - now;
+        next += *nextp - now;
     if (next == now)
         next++;
-    tb_env->decr_next = next;
+    *nextp = next;
     /* Adjust timer */
-    qemu_mod_timer(tb_env->decr_timer, next);
+    qemu_mod_timer(timer, next);
     /* If we set a negative value and the decrementer was positive,
      * raise an exception.
      */
     if ((value & 0x80000000) && !(decr & 0x80000000))
-        cpu_ppc_decr_excp(env);
+        (*raise_excp)(env);
 }
 
+static always_inline void _cpu_ppc_store_decr (CPUState *env, uint32_t decr,
+                                               uint32_t value, int is_excp)
+{
+    ppc_tb_t *tb_env = env->tb_env;
+
+    __cpu_ppc_store_decr(env, &tb_env->decr_next, tb_env->decr_timer,
+                         &cpu_ppc_decr_excp, decr, value, is_excp);
+}
+
 void cpu_ppc_store_decr (CPUState *env, uint32_t value)
 {
     _cpu_ppc_store_decr(env, cpu_ppc_load_decr(env), value, 0);
@@ -560,17 +736,51 @@
     _cpu_ppc_store_decr(opaque, 0x00000000, 0xFFFFFFFF, 1);
 }
 
+#if defined(TARGET_PPC64H)
+static always_inline void _cpu_ppc_store_hdecr (CPUState *env, uint32_t hdecr,
+                                                uint32_t value, int is_excp)
+{
+    ppc_tb_t *tb_env = env->tb_env;
+
+    __cpu_ppc_store_decr(env, &tb_env->hdecr_next, tb_env->hdecr_timer,
+                         &cpu_ppc_hdecr_excp, hdecr, value, is_excp);
+}
+
+void cpu_ppc_store_hdecr (CPUState *env, uint32_t value)
+{
+    _cpu_ppc_store_hdecr(env, cpu_ppc_load_hdecr(env), value, 0);
+}
+
+static void cpu_ppc_hdecr_cb (void *opaque)
+{
+    _cpu_ppc_store_hdecr(opaque, 0x00000000, 0xFFFFFFFF, 1);
+}
+
+void cpu_ppc_store_purr (CPUState *env, uint64_t value)
+{
+    ppc_tb_t *tb_env = env->tb_env;
+
+    tb_env->purr_load = value;
+    tb_env->purr_start = qemu_get_clock(vm_clock);
+}
+#endif /* defined(TARGET_PPC64H) */
+
 static void cpu_ppc_set_tb_clk (void *opaque, uint32_t freq)
 {
     CPUState *env = opaque;
     ppc_tb_t *tb_env = env->tb_env;
 
     tb_env->tb_freq = freq;
+    tb_env->decr_freq = freq;
     /* There is a bug in Linux 2.4 kernels:
      * if a decrementer exception is pending when it enables msr_ee at startup,
      * it's not ready to handle it...
      */
     _cpu_ppc_store_decr(env, 0xFFFFFFFF, 0xFFFFFFFF, 0);
+#if defined(TARGET_PPC64H)
+    _cpu_ppc_store_hdecr(env, 0xFFFFFFFF, 0xFFFFFFFF, 0);
+    cpu_ppc_store_purr(env, 0x0000000000000000ULL);
+#endif /* defined(TARGET_PPC64H) */
 }
 
 /* Set up (once) timebase frequency (in Hz) */
@@ -584,6 +794,9 @@
     env->tb_env = tb_env;
     /* Create new timer */
     tb_env->decr_timer = qemu_new_timer(vm_clock, &cpu_ppc_decr_cb, env);
+#if defined(TARGET_PPC64H)
+    tb_env->hdecr_timer = qemu_new_timer(vm_clock, &cpu_ppc_hdecr_cb, env);
+#endif /* defined(TARGET_PPC64H) */
     cpu_ppc_set_tb_clk(env, freq);
 
     return &cpu_ppc_set_tb_clk;
@@ -596,10 +809,14 @@
 }
 
 void cpu_ppc601_store_rtcu (CPUState *env, uint32_t value)
-__attribute__ (( alias ("cpu_ppc_store_tbu") ));
+{
+    _cpu_ppc_store_tbu(env, value);
+}
 
 uint32_t cpu_ppc601_load_rtcu (CPUState *env)
-__attribute__ (( alias ("cpu_ppc_load_tbu") ));
+{
+    return _cpu_ppc_load_tbu(env);
+}
 
 void cpu_ppc601_store_rtcl (CPUState *env, uint32_t value)
 {
@@ -695,7 +912,7 @@
 #endif
         now = qemu_get_clock(vm_clock);
         next = now + muldiv64(ppcemb_timer->pit_reload,
-                              ticks_per_sec, tb_env->tb_freq);
+                              ticks_per_sec, tb_env->decr_freq);
         if (is_excp)
             next += tb_env->decr_next - now;
         if (next == now)
@@ -759,7 +976,7 @@
         /* Cannot occur, but makes gcc happy */
         return;
     }
-    next = now + muldiv64(next, ticks_per_sec, tb_env->tb_freq);
+    next = now + muldiv64(next, ticks_per_sec, tb_env->decr_freq);
     if (next == now)
         next++;
 #ifdef PPC_DEBUG_TB
@@ -861,6 +1078,7 @@
     }
 #endif
     tb_env->tb_freq = freq;
+    tb_env->decr_freq = freq;
     /* XXX: we should also update all timers */
 }
 
@@ -876,6 +1094,7 @@
     env->tb_env = tb_env;
     ppcemb_timer = qemu_mallocz(sizeof(ppcemb_timer_t));
     tb_env->tb_freq = freq;
+    tb_env->decr_freq = freq;
     tb_env->opaque = ppcemb_timer;
 #ifdef PPC_DEBUG_TB
     if (loglevel != 0) {
@@ -904,6 +1123,9 @@
     void *opaque;
 };
 
+/* XXX: on 460, DCR addresses are 32 bits wide,
+ *      using DCRIPR to get the 22 upper bits of the DCR address
+ */
 #define DCRN_NB 1024
 struct ppc_dcr_t {
     ppc_dcrn_t dcrn[DCRN_NB];
@@ -989,7 +1211,6 @@
     return 0;
 }
 
-
 #if 0
 /*****************************************************************************/
 /* Handle system reset (for now, just stop emulation) */
@@ -1022,63 +1243,75 @@
 
 /*****************************************************************************/
 /* NVRAM helpers */
-void NVRAM_set_byte (m48t59_t *nvram, uint32_t addr, uint8_t value)
+static inline uint32_t nvram_read (nvram_t *nvram, uint32_t addr)
 {
-    m48t59_write(nvram, addr, value);
+    return (*nvram->read_fn)(nvram->opaque, addr);;
 }
 
-uint8_t NVRAM_get_byte (m48t59_t *nvram, uint32_t addr)
+static inline void nvram_write (nvram_t *nvram, uint32_t addr, uint32_t val)
 {
-    return m48t59_read(nvram, addr);
+    (*nvram->write_fn)(nvram->opaque, addr, val);
 }
 
-void NVRAM_set_word (m48t59_t *nvram, uint32_t addr, uint16_t value)
+void NVRAM_set_byte (nvram_t *nvram, uint32_t addr, uint8_t value)
 {
-    m48t59_write(nvram, addr, value >> 8);
-    m48t59_write(nvram, addr + 1, value & 0xFF);
+    nvram_write(nvram, addr, value);
 }
 
-uint16_t NVRAM_get_word (m48t59_t *nvram, uint32_t addr)
+uint8_t NVRAM_get_byte (nvram_t *nvram, uint32_t addr)
 {
+    return nvram_read(nvram, addr);
+}
+
+void NVRAM_set_word (nvram_t *nvram, uint32_t addr, uint16_t value)
+{
+    nvram_write(nvram, addr, value >> 8);
+    nvram_write(nvram, addr + 1, value & 0xFF);
+}
+
+uint16_t NVRAM_get_word (nvram_t *nvram, uint32_t addr)
+{
     uint16_t tmp;
 
-    tmp = m48t59_read(nvram, addr) << 8;
-    tmp |= m48t59_read(nvram, addr + 1);
+    tmp = nvram_read(nvram, addr) << 8;
+    tmp |= nvram_read(nvram, addr + 1);
+
     return tmp;
 }
 
-void NVRAM_set_lword (m48t59_t *nvram, uint32_t addr, uint32_t value)
+void NVRAM_set_lword (nvram_t *nvram, uint32_t addr, uint32_t value)
 {
-    m48t59_write(nvram, addr, value >> 24);
-    m48t59_write(nvram, addr + 1, (value >> 16) & 0xFF);
-    m48t59_write(nvram, addr + 2, (value >> 8) & 0xFF);
-    m48t59_write(nvram, addr + 3, value & 0xFF);
+    nvram_write(nvram, addr, value >> 24);
+    nvram_write(nvram, addr + 1, (value >> 16) & 0xFF);
+    nvram_write(nvram, addr + 2, (value >> 8) & 0xFF);
+    nvram_write(nvram, addr + 3, value & 0xFF);
 }
 
-uint32_t NVRAM_get_lword (m48t59_t *nvram, uint32_t addr)
+uint32_t NVRAM_get_lword (nvram_t *nvram, uint32_t addr)
 {
     uint32_t tmp;
 
-    tmp = m48t59_read(nvram, addr) << 24;
-    tmp |= m48t59_read(nvram, addr + 1) << 16;
-    tmp |= m48t59_read(nvram, addr + 2) << 8;
-    tmp |= m48t59_read(nvram, addr + 3);
+    tmp = nvram_read(nvram, addr) << 24;
+    tmp |= nvram_read(nvram, addr + 1) << 16;
+    tmp |= nvram_read(nvram, addr + 2) << 8;
+    tmp |= nvram_read(nvram, addr + 3);
 
     return tmp;
 }
 
-void NVRAM_set_string (m48t59_t *nvram, uint32_t addr,
+void NVRAM_set_string (nvram_t *nvram, uint32_t addr,
                        const unsigned char *str, uint32_t max)
 {
     int i;
 
     for (i = 0; i < max && str[i] != '\0'; i++) {
-        m48t59_write(nvram, addr + i, str[i]);
+        nvram_write(nvram, addr + i, str[i]);
     }
-    m48t59_write(nvram, addr + max - 1, '\0');
+    nvram_write(nvram, addr + i, str[i]);
+    nvram_write(nvram, addr + max - 1, '\0');
 }
 
-int NVRAM_get_string (m48t59_t *nvram, uint8_t *dst, uint16_t addr, int max)
+int NVRAM_get_string (nvram_t *nvram, uint8_t *dst, uint16_t addr, int max)
 {
     int i;
 
@@ -1107,7 +1340,7 @@
     return tmp;
 }
 
-uint16_t NVRAM_compute_crc (m48t59_t *nvram, uint32_t start, uint32_t count)
+uint16_t NVRAM_compute_crc (nvram_t *nvram, uint32_t start, uint32_t count)
 {
     uint32_t i;
     uint16_t crc = 0xFFFF;
@@ -1127,7 +1360,7 @@
 
 #define CMDLINE_ADDR 0x017ff000
 
-int PPC_NVRAM_set_params (m48t59_t *nvram, uint16_t NVRAM_size,
+int PPC_NVRAM_set_params (nvram_t *nvram, uint16_t NVRAM_size,
                           const unsigned char *arch,
                           uint32_t RAM_size, int boot_device,
                           uint32_t kernel_image, uint32_t kernel_size,
@@ -1164,7 +1397,7 @@
     NVRAM_set_word(nvram,   0x56, height);
     NVRAM_set_word(nvram,   0x58, depth);
     crc = NVRAM_compute_crc(nvram, 0x00, 0xF8);
-    NVRAM_set_word(nvram,  0xFC, crc);
+    NVRAM_set_word(nvram,   0xFC, crc);
 
     return 0;
 }

Modified: trunk/src/host/qemu-neo1973/hw/ppc405.h
===================================================================
--- trunk/src/host/qemu-neo1973/hw/ppc405.h	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/hw/ppc405.h	2007-10-29 21:14:04 UTC (rev 3303)
@@ -25,6 +25,8 @@
 #if !defined(PPC_405_H)
 #define PPC_405_H
 
+#include "ppc4xx.h"
+
 /* Bootinfo as set-up by u-boot */
 typedef struct ppc4xx_bd_info_t ppc4xx_bd_info_t;
 struct ppc4xx_bd_info_t {
@@ -54,18 +56,9 @@
 };
 
 /* PowerPC 405 core */
-CPUState *ppc405_init (const unsigned char *cpu_model,
-                       clk_setup_t *cpu_clk, clk_setup_t *tb_clk,
-                       uint32_t sysclk);
-ram_addr_t ppc405_set_bootinfo (CPUState *env, ppc4xx_bd_info_t *bd);
+ram_addr_t ppc405_set_bootinfo (CPUState *env, ppc4xx_bd_info_t *bd,
+                                uint32_t flags);
 
-/* */
-typedef struct ppc4xx_mmio_t ppc4xx_mmio_t;
-int ppc4xx_mmio_register (CPUState *env, ppc4xx_mmio_t *mmio,
-                          target_phys_addr_t offset, uint32_t len,
-                          CPUReadMemoryFunc **mem_read,
-                          CPUWriteMemoryFunc **mem_write, void *opaque);
-ppc4xx_mmio_t *ppc4xx_mmio_init (CPUState *env, target_phys_addr_t base);
 /* PowerPC 4xx peripheral local bus arbitrer */
 void ppc4xx_plb_init (CPUState *env);
 /* PLB to OPB bridge */
@@ -73,14 +66,6 @@
 /* OPB arbitrer */
 void ppc4xx_opba_init (CPUState *env, ppc4xx_mmio_t *mmio,
                        target_phys_addr_t offset);
-/* PowerPC 4xx universal interrupt controller */
-enum {
-    PPCUIC_OUTPUT_INT = 0,
-    PPCUIC_OUTPUT_CINT = 1,
-    PPCUIC_OUTPUT_NB,
-};
-qemu_irq *ppcuic_init (CPUState *env, qemu_irq *irqs,
-                       uint32_t dcr_base, int has_ssr, int has_vr);
 /* SDRAM controller */
 void ppc405_sdram_init (CPUState *env, qemu_irq irq, int nbanks,
                         target_phys_addr_t *ram_bases,

Modified: trunk/src/host/qemu-neo1973/hw/ppc405_boards.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/ppc405_boards.c	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/hw/ppc405_boards.c	2007-10-29 21:14:04 UTC (rev 3303)
@@ -226,8 +226,8 @@
                fl_idx, bios_size, bios_offset, -bios_size,
                bdrv_get_device_name(pflash_table[fl_idx]), fl_sectors);
 #endif
-        pflash_register(-(bios_size), bios_offset, pflash_table[fl_idx],
-                        65536, fl_sectors, 2,
+        pflash_register((uint32_t)(-bios_size), bios_offset,
+                        pflash_table[fl_idx], 65536, fl_sectors, 2,
                         0x0001, 0x22DA, 0x0000, 0x0000);
         fl_idx++;
     } else
@@ -236,7 +236,9 @@
 #ifdef DEBUG_BOARD_INIT
         printf("Load BIOS from file\n");
 #endif
-        snprintf(buf, sizeof(buf), "%s/%s", bios_dir, BIOS_FILENAME);
+        if (bios_name == NULL)
+            bios_name = BIOS_FILENAME;
+        snprintf(buf, sizeof(buf), "%s/%s", bios_dir, bios_name);
         bios_size = load_image(buf, phys_ram_base + bios_offset);
         if (bios_size < 0 || bios_size > BIOS_SIZE) {
             fprintf(stderr, "qemu: could not load PowerPC bios '%s'\n", buf);
@@ -266,7 +268,7 @@
         memset(&bd, 0, sizeof(bd));
         bd.bi_memstart = 0x00000000;
         bd.bi_memsize = ram_size;
-        bd.bi_flashstart = -(bios_size);
+        bd.bi_flashstart = -bios_size;
         bd.bi_flashsize = -bios_size;
         bd.bi_flashoffset = 0;
         bd.bi_sramstart = 0xFFF00000;
@@ -288,7 +290,7 @@
         bd.bi_plb_busfreq = 33333333;
         bd.bi_pci_busfreq = 33333333;
         bd.bi_opbfreq = 33333333;
-        bdloc = ppc405_set_bootinfo(env, &bd);
+        bdloc = ppc405_set_bootinfo(env, &bd, 0x00000001);
         env->gpr[3] = bdloc;
         kernel_base = KERNEL_LOAD_ADDR;
         /* now we can load the kernel */
@@ -539,8 +541,8 @@
                fl_idx, bios_size, bios_offset, -bios_size,
                bdrv_get_device_name(pflash_table[fl_idx]), fl_sectors);
 #endif
-        pflash_register(-(bios_size), bios_offset, pflash_table[fl_idx],
-                        65536, fl_sectors, 4,
+        pflash_register((uint32_t)(-bios_size), bios_offset,
+                        pflash_table[fl_idx], 65536, fl_sectors, 4,
                         0x0001, 0x22DA, 0x0000, 0x0000);
         fl_idx++;
     } else
@@ -549,7 +551,9 @@
 #ifdef DEBUG_BOARD_INIT
         printf("Load BIOS from file\n");
 #endif
-        snprintf(buf, sizeof(buf), "%s/%s", bios_dir, BIOS_FILENAME);
+        if (bios_name == NULL)
+            bios_name = BIOS_FILENAME;
+        snprintf(buf, sizeof(buf), "%s/%s", bios_dir, bios_name);
         bios_size = load_image(buf, phys_ram_base + bios_offset);
         if (bios_size < 0 || bios_size > BIOS_SIZE) {
             fprintf(stderr, "qemu: could not load PowerPC bios '%s'\n", buf);

Modified: trunk/src/host/qemu-neo1973/hw/ppc405_uc.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/ppc405_uc.c	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/hw/ppc405_uc.c	2007-10-29 21:14:04 UTC (rev 3303)
@@ -27,7 +27,6 @@
 extern int loglevel;
 extern FILE *logfile;
 
-//#define DEBUG_MMIO
 #define DEBUG_OPBA
 #define DEBUG_SDRAM
 #define DEBUG_GPIO
@@ -36,41 +35,12 @@
 //#define DEBUG_I2C
 #define DEBUG_GPT
 #define DEBUG_MAL
-#define DEBUG_UIC
 #define DEBUG_CLOCKS
 //#define DEBUG_UNASSIGNED
 
-/*****************************************************************************/
-/* Generic PowerPC 405 processor instanciation */
-CPUState *ppc405_init (const unsigned char *cpu_model,
-                       clk_setup_t *cpu_clk, clk_setup_t *tb_clk,
-                       uint32_t sysclk)
+ram_addr_t ppc405_set_bootinfo (CPUState *env, ppc4xx_bd_info_t *bd,
+                                uint32_t flags)
 {
-    CPUState *env;
-    ppc_def_t *def;
-
-    /* init CPUs */
-    env = cpu_init();
-    qemu_register_reset(&cpu_ppc_reset, env);
-    register_savevm("cpu", 0, 3, cpu_save, cpu_load, env);
-    ppc_find_by_name(cpu_model, &def);
-    if (def == NULL) {
-        cpu_abort(env, "Unable to find PowerPC %s CPU definition\n",
-                  cpu_model);
-    }
-    cpu_ppc_register(env, def);
-    cpu_clk->cb = NULL; /* We don't care about CPU clock frequency changes */
-    cpu_clk->opaque = env;
-    /* Set time-base frequency to sysclk */
-    tb_clk->cb = ppc_emb_timers_init(env, sysclk);
-    tb_clk->opaque = env;
-    ppc_dcr_init(env, NULL, NULL);
-
-    return env;
-}
-
-ram_addr_t ppc405_set_bootinfo (CPUState *env, ppc4xx_bd_info_t *bd)
-{
     ram_addr_t bdloc;
     int i, n;
 
@@ -103,7 +73,7 @@
     for (i = 0; i < 6; i++)
         stb_raw(phys_ram_base + bdloc + 0x64 + i, bd->bi_pci_enetaddr[i]);
     n = 0x6A;
-    if (env->spr[SPR_PVR] == CPU_PPC_405EP) {
+    if (flags & 0x00000001) {
         for (i = 0; i < 6; i++)
             stb_raw(phys_ram_base + bdloc + n++, bd->bi_pci_enetaddr2[i]);
     }
@@ -121,203 +91,6 @@
 /* Shared peripherals */
 
 /*****************************************************************************/
-/* Fake device used to map multiple devices in a single memory page */
-#define MMIO_AREA_BITS 8
-#define MMIO_AREA_LEN (1 << MMIO_AREA_BITS)
-#define MMIO_AREA_NB (1 << (TARGET_PAGE_BITS - MMIO_AREA_BITS))
-#define MMIO_IDX(addr) (((addr) >> MMIO_AREA_BITS) & (MMIO_AREA_NB - 1))
-struct ppc4xx_mmio_t {
-    target_phys_addr_t base;
-    CPUReadMemoryFunc **mem_read[MMIO_AREA_NB];
-    CPUWriteMemoryFunc **mem_write[MMIO_AREA_NB];
-    void *opaque[MMIO_AREA_NB];
-};
-
-static uint32_t unassigned_mmio_readb (void *opaque, target_phys_addr_t addr)
-{
-#ifdef DEBUG_UNASSIGNED
-    ppc4xx_mmio_t *mmio;
-
-    mmio = opaque;
-    printf("Unassigned mmio read 0x" PADDRX " base " PADDRX "\n",
-           addr, mmio->base);
-#endif
-
-    return 0;
-}
-
-static void unassigned_mmio_writeb (void *opaque,
-                                   target_phys_addr_t addr, uint32_t val)
-{
-#ifdef DEBUG_UNASSIGNED
-    ppc4xx_mmio_t *mmio;
-
-    mmio = opaque;
-    printf("Unassigned mmio write 0x" PADDRX " = 0x%x base " PADDRX "\n",
-           addr, val, mmio->base);
-#endif
-}
-
-static CPUReadMemoryFunc *unassigned_mmio_read[3] = {
-    unassigned_mmio_readb,
-    unassigned_mmio_readb,
-    unassigned_mmio_readb,
-};
-
-static CPUWriteMemoryFunc *unassigned_mmio_write[3] = {
-    unassigned_mmio_writeb,
-    unassigned_mmio_writeb,
-    unassigned_mmio_writeb,
-};
-
-static uint32_t mmio_readlen (ppc4xx_mmio_t *mmio,
-                              target_phys_addr_t addr, int len)
-{
-    CPUReadMemoryFunc **mem_read;
-    uint32_t ret;
-    int idx;
-
-    idx = MMIO_IDX(addr - mmio->base);
-#if defined(DEBUG_MMIO)
-    printf("%s: mmio %p len %d addr " PADDRX " idx %d\n", __func__,
-           mmio, len, addr, idx);
-#endif
-    mem_read = mmio->mem_read[idx];
-    ret = (*mem_read[len])(mmio->opaque[idx], addr - mmio->base);
-
-    return ret;
-}
-
-static void mmio_writelen (ppc4xx_mmio_t *mmio,
-                           target_phys_addr_t addr, uint32_t value, int len)
-{
-    CPUWriteMemoryFunc **mem_write;
-    int idx;
-
-    idx = MMIO_IDX(addr - mmio->base);
-#if defined(DEBUG_MMIO)
-    printf("%s: mmio %p len %d addr " PADDRX " idx %d value %08x\n", __func__,
-           mmio, len, addr, idx, value);
-#endif
-    mem_write = mmio->mem_write[idx];
-    (*mem_write[len])(mmio->opaque[idx], addr - mmio->base, value);
-}
-
-static uint32_t mmio_readb (void *opaque, target_phys_addr_t addr)
-{
-#if defined(DEBUG_MMIO)
-    printf("%s: addr " PADDRX "\n", __func__, addr);
-#endif
-
-    return mmio_readlen(opaque, addr, 0);
-}
-
-static void mmio_writeb (void *opaque,
-                         target_phys_addr_t addr, uint32_t value)
-{
-#if defined(DEBUG_MMIO)
-    printf("%s: addr " PADDRX " val %08x\n", __func__, addr, value);
-#endif
-    mmio_writelen(opaque, addr, value, 0);
-}
-
-static uint32_t mmio_readw (void *opaque, target_phys_addr_t addr)
-{
-#if defined(DEBUG_MMIO)
-    printf("%s: addr " PADDRX "\n", __func__, addr);
-#endif
-
-    return mmio_readlen(opaque, addr, 1);
-}
-
-static void mmio_writew (void *opaque,
-                         target_phys_addr_t addr, uint32_t value)
-{
-#if defined(DEBUG_MMIO)
-    printf("%s: addr " PADDRX " val %08x\n", __func__, addr, value);
-#endif
-    mmio_writelen(opaque, addr, value, 1);
-}
-
-static uint32_t mmio_readl (void *opaque, target_phys_addr_t addr)
-{
-#if defined(DEBUG_MMIO)
-    printf("%s: addr " PADDRX "\n", __func__, addr);
-#endif
-
-    return mmio_readlen(opaque, addr, 2);
-}
-
-static void mmio_writel (void *opaque,
-                         target_phys_addr_t addr, uint32_t value)
-{
-#if defined(DEBUG_MMIO)
-    printf("%s: addr " PADDRX " val %08x\n", __func__, addr, value);
-#endif
-    mmio_writelen(opaque, addr, value, 2);
-}
-
-static CPUReadMemoryFunc *mmio_read[] = {
-    &mmio_readb,
-    &mmio_readw,
-    &mmio_readl,
-};
-
-static CPUWriteMemoryFunc *mmio_write[] = {
-    &mmio_writeb,
-    &mmio_writew,
-    &mmio_writel,
-};
-
-int ppc4xx_mmio_register (CPUState *env, ppc4xx_mmio_t *mmio,
-                          target_phys_addr_t offset, uint32_t len,
-                          CPUReadMemoryFunc **mem_read,
-                          CPUWriteMemoryFunc **mem_write, void *opaque)
-{
-    uint32_t end;
-    int idx, eidx;
-
-    if ((offset + len) > TARGET_PAGE_SIZE)
-        return -1;
-    idx = MMIO_IDX(offset);
-    end = offset + len - 1;
-    eidx = MMIO_IDX(end);
-#if defined(DEBUG_MMIO)
-    printf("%s: offset %08x len %08x %08x %d %d\n", __func__, offset, len,
-           end, idx, eidx);
-#endif
-    for (; idx <= eidx; idx++) {
-        mmio->mem_read[idx] = mem_read;
-        mmio->mem_write[idx] = mem_write;
-        mmio->opaque[idx] = opaque;
-    }
-
-    return 0;
-}
-
-ppc4xx_mmio_t *ppc4xx_mmio_init (CPUState *env, target_phys_addr_t base)
-{
-    ppc4xx_mmio_t *mmio;
-    int mmio_memory;
-
-    mmio = qemu_mallocz(sizeof(ppc4xx_mmio_t));
-    if (mmio != NULL) {
-        mmio->base = base;
-        mmio_memory = cpu_register_io_memory(0, mmio_read, mmio_write, mmio);
-#if defined(DEBUG_MMIO)
-        printf("%s: %p base %08x len %08x %d\n", __func__,
-               mmio, base, TARGET_PAGE_SIZE, mmio_memory);
-#endif
-        cpu_register_physical_memory(base, TARGET_PAGE_SIZE, mmio_memory);
-        ppc4xx_mmio_register(env, mmio, 0, TARGET_PAGE_SIZE,
-                             unassigned_mmio_read, unassigned_mmio_write,
-                             mmio);
-    }
-
-    return mmio;
-}
-
-/*****************************************************************************/
 /* Peripheral local bus arbitrer */
 enum {
     PLB0_BESR = 0x084,
@@ -622,281 +395,6 @@
 }
 
 /*****************************************************************************/
-/* "Universal" Interrupt controller */
-enum {
-    DCR_UICSR  = 0x000,
-    DCR_UICSRS = 0x001,
-    DCR_UICER  = 0x002,
-    DCR_UICCR  = 0x003,
-    DCR_UICPR  = 0x004,
-    DCR_UICTR  = 0x005,
-    DCR_UICMSR = 0x006,
-    DCR_UICVR  = 0x007,
-    DCR_UICVCR = 0x008,
-    DCR_UICMAX = 0x009,
-};
-
-#define UIC_MAX_IRQ 32
-typedef struct ppcuic_t ppcuic_t;
-struct ppcuic_t {
-    uint32_t dcr_base;
-    int use_vectors;
-    uint32_t uicsr;  /* Status register */
-    uint32_t uicer;  /* Enable register */
-    uint32_t uiccr;  /* Critical register */
-    uint32_t uicpr;  /* Polarity register */
-    uint32_t uictr;  /* Triggering register */
-    uint32_t uicvcr; /* Vector configuration register */
-    uint32_t uicvr;
-    qemu_irq *irqs;
-};
-
-static void ppcuic_trigger_irq (ppcuic_t *uic)
-{
-    uint32_t ir, cr;
-    int start, end, inc, i;
-
-    /* Trigger interrupt if any is pending */
-    ir = uic->uicsr & uic->uicer & (~uic->uiccr);
-    cr = uic->uicsr & uic->uicer & uic->uiccr;
-#ifdef DEBUG_UIC
-    if (loglevel & CPU_LOG_INT) {
-        fprintf(logfile, "%s: uicsr %08x uicer %08x uiccr %08x\n"
-                "   %08x ir %08x cr %08x\n", __func__,
-                uic->uicsr, uic->uicer, uic->uiccr,
-                uic->uicsr & uic->uicer, ir, cr);
-    }
-#endif
-    if (ir != 0x0000000) {
-#ifdef DEBUG_UIC
-        if (loglevel & CPU_LOG_INT) {
-            fprintf(logfile, "Raise UIC interrupt\n");
-        }
-#endif
-        qemu_irq_raise(uic->irqs[PPCUIC_OUTPUT_INT]);
-    } else {
-#ifdef DEBUG_UIC
-        if (loglevel & CPU_LOG_INT) {
-            fprintf(logfile, "Lower UIC interrupt\n");
-        }
-#endif
-        qemu_irq_lower(uic->irqs[PPCUIC_OUTPUT_INT]);
-    }
-    /* Trigger critical interrupt if any is pending and update vector */
-    if (cr != 0x0000000) {
-        qemu_irq_raise(uic->irqs[PPCUIC_OUTPUT_CINT]);
-        if (uic->use_vectors) {
-            /* Compute critical IRQ vector */
-            if (uic->uicvcr & 1) {
-                start = 31;
-                end = 0;
-                inc = -1;
-            } else {
-                start = 0;
-                end = 31;
-                inc = 1;
-            }
-            uic->uicvr = uic->uicvcr & 0xFFFFFFFC;
-            for (i = start; i <= end; i += inc) {
-                if (cr & (1 << i)) {
-                    uic->uicvr += (i - start) * 512 * inc;
-                    break;
-                }
-            }
-        }
-#ifdef DEBUG_UIC
-        if (loglevel & CPU_LOG_INT) {
-            fprintf(logfile, "Raise UIC critical interrupt - vector %08x\n",
-                    uic->uicvr);
-        }
-#endif
-    } else {
-#ifdef DEBUG_UIC
-        if (loglevel & CPU_LOG_INT) {
-            fprintf(logfile, "Lower UIC critical interrupt\n");
-        }
-#endif
-        qemu_irq_lower(uic->irqs[PPCUIC_OUTPUT_CINT]);
-        uic->uicvr = 0x00000000;
-    }
-}
-
-static void ppcuic_set_irq (void *opaque, int irq_num, int level)
-{
-    ppcuic_t *uic;
-    uint32_t mask, sr;
-
-    uic = opaque;
-    mask = 1 << irq_num;
-#ifdef DEBUG_UIC
-    if (loglevel & CPU_LOG_INT) {
-        fprintf(logfile, "%s: irq %d level %d uicsr %08x mask %08x => %08x "
-                "%08x\n", __func__, irq_num, level,
-                uic->uicsr, mask, uic->uicsr & mask, level << irq_num);
-    }
-#endif
-    if (irq_num < 0 || irq_num > 31)
-        return;
-    sr = uic->uicsr;
-    if (!(uic->uicpr & mask)) {
-        /* Negatively asserted IRQ */
-        level = level == 0 ? 1 : 0;
-    }
-    /* Update status register */
-    if (uic->uictr & mask) {
-        /* Edge sensitive interrupt */
-        if (level == 1)
-            uic->uicsr |= mask;
-    } else {
-        /* Level sensitive interrupt */
-        if (level == 1)
-            uic->uicsr |= mask;
-        else
-            uic->uicsr &= ~mask;
-    }
-#ifdef DEBUG_UIC
-    if (loglevel & CPU_LOG_INT) {
-        fprintf(logfile, "%s: irq %d level %d sr %08x => %08x\n", __func__,
-                irq_num, level, uic->uicsr, sr);
-    }
-#endif
-    if (sr != uic->uicsr)
-        ppcuic_trigger_irq(uic);
-}
-
-static target_ulong dcr_read_uic (void *opaque, int dcrn)
-{
-    ppcuic_t *uic;
-    target_ulong ret;
-
-    uic = opaque;
-    dcrn -= uic->dcr_base;
-    switch (dcrn) {
-    case DCR_UICSR:
-    case DCR_UICSRS:
-        ret = uic->uicsr;
-        break;
-    case DCR_UICER:
-        ret = uic->uicer;
-        break;
-    case DCR_UICCR:
-        ret = uic->uiccr;
-        break;
-    case DCR_UICPR:
-        ret = uic->uicpr;
-        break;
-    case DCR_UICTR:
-        ret = uic->uictr;
-        break;
-    case DCR_UICMSR:
-        ret = uic->uicsr & uic->uicer;
-        break;
-    case DCR_UICVR:
-        if (!uic->use_vectors)
-            goto no_read;
-        ret = uic->uicvr;
-        break;
-    case DCR_UICVCR:
-        if (!uic->use_vectors)
-            goto no_read;
-        ret = uic->uicvcr;
-        break;
-    default:
-    no_read:
-        ret = 0x00000000;
-        break;
-    }
-
-    return ret;
-}
-
-static void dcr_write_uic (void *opaque, int dcrn, target_ulong val)
-{
-    ppcuic_t *uic;
-
-    uic = opaque;
-    dcrn -= uic->dcr_base;
-#ifdef DEBUG_UIC
-    if (loglevel & CPU_LOG_INT) {
-        fprintf(logfile, "%s: dcr %d val " ADDRX "\n", __func__, dcrn, val);
-    }
-#endif
-    switch (dcrn) {
-    case DCR_UICSR:
-        uic->uicsr &= ~val;
-        ppcuic_trigger_irq(uic);
-        break;
-    case DCR_UICSRS:
-        uic->uicsr |= val;
-        ppcuic_trigger_irq(uic);
-        break;
-    case DCR_UICER:
-        uic->uicer = val;
-        ppcuic_trigger_irq(uic);
-        break;
-    case DCR_UICCR:
-        uic->uiccr = val;
-        ppcuic_trigger_irq(uic);
-        break;
-    case DCR_UICPR:
-        uic->uicpr = val;
-        ppcuic_trigger_irq(uic);
-        break;
-    case DCR_UICTR:
-        uic->uictr = val;
-        ppcuic_trigger_irq(uic);
-        break;
-    case DCR_UICMSR:
-        break;
-    case DCR_UICVR:
-        break;
-    case DCR_UICVCR:
-        uic->uicvcr = val & 0xFFFFFFFD;
-        ppcuic_trigger_irq(uic);
-        break;
-    }
-}
-
-static void ppcuic_reset (void *opaque)
-{
-    ppcuic_t *uic;
-
-    uic = opaque;
-    uic->uiccr = 0x00000000;
-    uic->uicer = 0x00000000;
-    uic->uicpr = 0x00000000;
-    uic->uicsr = 0x00000000;
-    uic->uictr = 0x00000000;
-    if (uic->use_vectors) {
-        uic->uicvcr = 0x00000000;
-        uic->uicvr = 0x0000000;
-    }
-}
-
-qemu_irq *ppcuic_init (CPUState *env, qemu_irq *irqs,
-                       uint32_t dcr_base, int has_ssr, int has_vr)
-{
-    ppcuic_t *uic;
-    int i;
-
-    uic = qemu_mallocz(sizeof(ppcuic_t));
-    if (uic != NULL) {
-        uic->dcr_base = dcr_base;
-        uic->irqs = irqs;
-        if (has_vr)
-            uic->use_vectors = 1;
-        for (i = 0; i < DCR_UICMAX; i++) {
-            ppc_dcr_register(env, dcr_base + i, uic,
-                             &dcr_read_uic, &dcr_write_uic);
-        }
-        qemu_register_reset(ppcuic_reset, uic);
-        ppcuic_reset(uic);
-    }
-
-    return qemu_allocate_irqs(&ppcuic_set_irq, uic, UIC_MAX_IRQ);
-}
-
-/*****************************************************************************/
 /* Code decompression controller */
 /* XXX: TODO */
 
@@ -965,7 +463,7 @@
     return bcr;
 }
 
-static inline target_phys_addr_t sdram_base (uint32_t bcr)
+static always_inline target_phys_addr_t sdram_base (uint32_t bcr)
 {
     return bcr & 0xFF800000;
 }
@@ -2691,12 +2189,17 @@
     target_ulong dbsr;
 
     printf("Reset PowerPC core\n");
+    env->interrupt_request |= CPU_INTERRUPT_EXITTB;
+    /* XXX: TOFIX */
+#if 0
     cpu_ppc_reset(env);
+#else
+    qemu_system_reset_request();
+#endif
     dbsr = env->spr[SPR_40x_DBSR];
     dbsr &= ~0x00000300;
     dbsr |= 0x00000100;
     env->spr[SPR_40x_DBSR] = dbsr;
-    cpu_loop_exit();
 }
 
 void ppc40x_chip_reset (CPUState *env)
@@ -2704,13 +2207,18 @@
     target_ulong dbsr;
 
     printf("Reset PowerPC chip\n");
+    env->interrupt_request |= CPU_INTERRUPT_EXITTB;
+    /* XXX: TOFIX */
+#if 0
     cpu_ppc_reset(env);
+#else
+    qemu_system_reset_request();
+#endif
     /* XXX: TODO reset all internal peripherals */
     dbsr = env->spr[SPR_40x_DBSR];
     dbsr &= ~0x00000300;
     dbsr |= 0x00000200;
     env->spr[SPR_40x_DBSR] = dbsr;
-    cpu_loop_exit();
 }
 
 void ppc40x_system_reset (CPUState *env)
@@ -3037,7 +2545,7 @@
     int i;
 
     memset(clk_setup, 0, sizeof(clk_setup));
-    env = ppc405_init("405cr", &clk_setup[PPC405CR_CPU_CLK],
+    env = ppc4xx_init("405cr", &clk_setup[PPC405CR_CPU_CLK],
                       &clk_setup[PPC405CR_TMR_CLK], sysclk);
     /* Memory mapped devices registers */
     mmio = ppc4xx_mmio_init(env, 0xEF600000);
@@ -3050,9 +2558,9 @@
     /* Universal interrupt controller */
     irqs = qemu_mallocz(sizeof(qemu_irq) * PPCUIC_OUTPUT_NB);
     irqs[PPCUIC_OUTPUT_INT] =
-        ((qemu_irq *)env->irq_inputs)[PPC405_INPUT_INT];
+        ((qemu_irq *)env->irq_inputs)[PPC40x_INPUT_INT];
     irqs[PPCUIC_OUTPUT_CINT] =
-        ((qemu_irq *)env->irq_inputs)[PPC405_INPUT_CINT];
+        ((qemu_irq *)env->irq_inputs)[PPC40x_INPUT_CINT];
     pic = ppcuic_init(env, irqs, 0x0C0, 0, 1);
     *picp = pic;
     /* SDRAM controller */
@@ -3387,7 +2895,7 @@
 
     memset(clk_setup, 0, sizeof(clk_setup));
     /* init CPUs */
-    env = ppc405_init("405ep", &clk_setup[PPC405EP_CPU_CLK],
+    env = ppc4xx_init("405ep", &clk_setup[PPC405EP_CPU_CLK],
                       &tlb_clk_setup, sysclk);
     clk_setup[PPC405EP_CPU_CLK].cb = tlb_clk_setup.cb;
     clk_setup[PPC405EP_CPU_CLK].opaque = tlb_clk_setup.opaque;
@@ -3403,9 +2911,9 @@
     /* Universal interrupt controller */
     irqs = qemu_mallocz(sizeof(qemu_irq) * PPCUIC_OUTPUT_NB);
     irqs[PPCUIC_OUTPUT_INT] =
-        ((qemu_irq *)env->irq_inputs)[PPC405_INPUT_INT];
+        ((qemu_irq *)env->irq_inputs)[PPC40x_INPUT_INT];
     irqs[PPCUIC_OUTPUT_CINT] =
-        ((qemu_irq *)env->irq_inputs)[PPC405_INPUT_CINT];
+        ((qemu_irq *)env->irq_inputs)[PPC40x_INPUT_CINT];
     pic = ppcuic_init(env, irqs, 0x0C0, 0, 1);
     *picp = pic;
     /* SDRAM controller */

Added: trunk/src/host/qemu-neo1973/hw/ppc4xx.h
===================================================================
--- trunk/src/host/qemu-neo1973/hw/ppc4xx.h	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/hw/ppc4xx.h	2007-10-29 21:14:04 UTC (rev 3303)
@@ -0,0 +1,49 @@
+/*
+ * QEMU PowerPC 4xx emulation shared definitions
+ *
+ * Copyright (c) 2007 Jocelyn Mayer
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#if !defined(PPC_4XX_H)
+#define PPC_4XX_H
+
+/* PowerPC 4xx core initialization */
+CPUState *ppc4xx_init (const unsigned char *cpu_model,
+                       clk_setup_t *cpu_clk, clk_setup_t *tb_clk,
+                       uint32_t sysclk);
+
+typedef struct ppc4xx_mmio_t ppc4xx_mmio_t;
+int ppc4xx_mmio_register (CPUState *env, ppc4xx_mmio_t *mmio,
+                          target_phys_addr_t offset, uint32_t len,
+                          CPUReadMemoryFunc **mem_read,
+                          CPUWriteMemoryFunc **mem_write, void *opaque);
+ppc4xx_mmio_t *ppc4xx_mmio_init (CPUState *env, target_phys_addr_t base);
+
+/* PowerPC 4xx universal interrupt controller */
+enum {
+    PPCUIC_OUTPUT_INT = 0,
+    PPCUIC_OUTPUT_CINT = 1,
+    PPCUIC_OUTPUT_NB,
+};
+qemu_irq *ppcuic_init (CPUState *env, qemu_irq *irqs,
+                       uint32_t dcr_base, int has_ssr, int has_vr);
+
+#endif /* !defined(PPC_4XX_H) */

Added: trunk/src/host/qemu-neo1973/hw/ppc4xx_devs.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/ppc4xx_devs.c	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/hw/ppc4xx_devs.c	2007-10-29 21:14:04 UTC (rev 3303)
@@ -0,0 +1,534 @@
+/*
+ * QEMU PowerPC 4xx embedded processors shared devices emulation
+ *
+ * Copyright (c) 2007 Jocelyn Mayer
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include "vl.h"
+#include "ppc4xx.h"
+
+extern int loglevel;
+extern FILE *logfile;
+
+//#define DEBUG_MMIO
+#define DEBUG_UIC
+
+/*****************************************************************************/
+/* Generic PowerPC 4xx processor instanciation */
+CPUState *ppc4xx_init (const unsigned char *cpu_model,
+                       clk_setup_t *cpu_clk, clk_setup_t *tb_clk,
+                       uint32_t sysclk)
+{
+    CPUState *env;
+    ppc_def_t *def;
+
+    /* init CPUs */
+    env = cpu_init();
+    ppc_find_by_name(cpu_model, &def);
+    if (def == NULL) {
+        cpu_abort(env, "Unable to find PowerPC %s CPU definition\n",
+                  cpu_model);
+    }
+    cpu_ppc_register(env, def);
+    cpu_ppc_reset(env);
+    cpu_clk->cb = NULL; /* We don't care about CPU clock frequency changes */
+    cpu_clk->opaque = env;
+    /* Set time-base frequency to sysclk */
+    tb_clk->cb = ppc_emb_timers_init(env, sysclk);
+    tb_clk->opaque = env;
+    ppc_dcr_init(env, NULL, NULL);
+    /* Register qemu callbacks */
+    qemu_register_reset(&cpu_ppc_reset, env);
+    register_savevm("cpu", 0, 3, cpu_save, cpu_load, env);
+
+    return env;
+}
+
+/*****************************************************************************/
+/* Fake device used to map multiple devices in a single memory page */
+#define MMIO_AREA_BITS 8
+#define MMIO_AREA_LEN (1 << MMIO_AREA_BITS)
+#define MMIO_AREA_NB (1 << (TARGET_PAGE_BITS - MMIO_AREA_BITS))
+#define MMIO_IDX(addr) (((addr) >> MMIO_AREA_BITS) & (MMIO_AREA_NB - 1))
+struct ppc4xx_mmio_t {
+    target_phys_addr_t base;
+    CPUReadMemoryFunc **mem_read[MMIO_AREA_NB];
+    CPUWriteMemoryFunc **mem_write[MMIO_AREA_NB];
+    void *opaque[MMIO_AREA_NB];
+};
+
+static uint32_t unassigned_mmio_readb (void *opaque, target_phys_addr_t addr)
+{
+#ifdef DEBUG_UNASSIGNED
+    ppc4xx_mmio_t *mmio;
+
+    mmio = opaque;
+    printf("Unassigned mmio read 0x" PADDRX " base " PADDRX "\n",
+           addr, mmio->base);
+#endif
+
+    return 0;
+}
+
+static void unassigned_mmio_writeb (void *opaque,
+                                    target_phys_addr_t addr, uint32_t val)
+{
+#ifdef DEBUG_UNASSIGNED
+    ppc4xx_mmio_t *mmio;
+
+    mmio = opaque;
+    printf("Unassigned mmio write 0x" PADDRX " = 0x%x base " PADDRX "\n",
+           addr, val, mmio->base);
+#endif
+}
+
+static CPUReadMemoryFunc *unassigned_mmio_read[3] = {
+    unassigned_mmio_readb,
+    unassigned_mmio_readb,
+    unassigned_mmio_readb,
+};
+
+static CPUWriteMemoryFunc *unassigned_mmio_write[3] = {
+    unassigned_mmio_writeb,
+    unassigned_mmio_writeb,
+    unassigned_mmio_writeb,
+};
+
+static uint32_t mmio_readlen (ppc4xx_mmio_t *mmio,
+                              target_phys_addr_t addr, int len)
+{
+    CPUReadMemoryFunc **mem_read;
+    uint32_t ret;
+    int idx;
+
+    idx = MMIO_IDX(addr - mmio->base);
+#if defined(DEBUG_MMIO)
+    printf("%s: mmio %p len %d addr " PADDRX " idx %d\n", __func__,
+           mmio, len, addr, idx);
+#endif
+    mem_read = mmio->mem_read[idx];
+    ret = (*mem_read[len])(mmio->opaque[idx], addr - mmio->base);
+
+    return ret;
+}
+
+static void mmio_writelen (ppc4xx_mmio_t *mmio,
+                           target_phys_addr_t addr, uint32_t value, int len)
+{
+    CPUWriteMemoryFunc **mem_write;
+    int idx;
+
+    idx = MMIO_IDX(addr - mmio->base);
+#if defined(DEBUG_MMIO)
+    printf("%s: mmio %p len %d addr " PADDRX " idx %d value %08x\n", __func__,
+           mmio, len, addr, idx, value);
+#endif
+    mem_write = mmio->mem_write[idx];
+    (*mem_write[len])(mmio->opaque[idx], addr - mmio->base, value);
+}
+
+static uint32_t mmio_readb (void *opaque, target_phys_addr_t addr)
+{
+#if defined(DEBUG_MMIO)
+    printf("%s: addr " PADDRX "\n", __func__, addr);
+#endif
+
+    return mmio_readlen(opaque, addr, 0);
+}
+
+static void mmio_writeb (void *opaque,
+                         target_phys_addr_t addr, uint32_t value)
+{
+#if defined(DEBUG_MMIO)
+    printf("%s: addr " PADDRX " val %08x\n", __func__, addr, value);
+#endif
+    mmio_writelen(opaque, addr, value, 0);
+}
+
+static uint32_t mmio_readw (void *opaque, target_phys_addr_t addr)
+{
+#if defined(DEBUG_MMIO)
+    printf("%s: addr " PADDRX "\n", __func__, addr);
+#endif
+
+    return mmio_readlen(opaque, addr, 1);
+}
+
+static void mmio_writew (void *opaque,
+                         target_phys_addr_t addr, uint32_t value)
+{
+#if defined(DEBUG_MMIO)
+    printf("%s: addr " PADDRX " val %08x\n", __func__, addr, value);
+#endif
+    mmio_writelen(opaque, addr, value, 1);
+}
+
+static uint32_t mmio_readl (void *opaque, target_phys_addr_t addr)
+{
+#if defined(DEBUG_MMIO)
+    printf("%s: addr " PADDRX "\n", __func__, addr);
+#endif
+
+    return mmio_readlen(opaque, addr, 2);
+}
+
+static void mmio_writel (void *opaque,
+                         target_phys_addr_t addr, uint32_t value)
+{
+#if defined(DEBUG_MMIO)
+    printf("%s: addr " PADDRX " val %08x\n", __func__, addr, value);
+#endif
+    mmio_writelen(opaque, addr, value, 2);
+}
+
+static CPUReadMemoryFunc *mmio_read[] = {
+    &mmio_readb,
+    &mmio_readw,
+    &mmio_readl,
+};
+
+static CPUWriteMemoryFunc *mmio_write[] = {
+    &mmio_writeb,
+    &mmio_writew,
+    &mmio_writel,
+};
+
+int ppc4xx_mmio_register (CPUState *env, ppc4xx_mmio_t *mmio,
+                          target_phys_addr_t offset, uint32_t len,
+                          CPUReadMemoryFunc **mem_read,
+                          CPUWriteMemoryFunc **mem_write, void *opaque)
+{
+    uint32_t end;
+    int idx, eidx;
+
+    if ((offset + len) > TARGET_PAGE_SIZE)
+        return -1;
+    idx = MMIO_IDX(offset);
+    end = offset + len - 1;
+    eidx = MMIO_IDX(end);
+#if defined(DEBUG_MMIO)
+    printf("%s: offset %08x len %08x %08x %d %d\n", __func__, offset, len,
+           end, idx, eidx);
+#endif
+    for (; idx <= eidx; idx++) {
+        mmio->mem_read[idx] = mem_read;
+        mmio->mem_write[idx] = mem_write;
+        mmio->opaque[idx] = opaque;
+    }
+
+    return 0;
+}
+
+ppc4xx_mmio_t *ppc4xx_mmio_init (CPUState *env, target_phys_addr_t base)
+{
+    ppc4xx_mmio_t *mmio;
+    int mmio_memory;
+
+    mmio = qemu_mallocz(sizeof(ppc4xx_mmio_t));
+    if (mmio != NULL) {
+        mmio->base = base;
+        mmio_memory = cpu_register_io_memory(0, mmio_read, mmio_write, mmio);
+#if defined(DEBUG_MMIO)
+        printf("%s: %p base %08x len %08x %d\n", __func__,
+               mmio, base, TARGET_PAGE_SIZE, mmio_memory);
+#endif
+        cpu_register_physical_memory(base, TARGET_PAGE_SIZE, mmio_memory);
+        ppc4xx_mmio_register(env, mmio, 0, TARGET_PAGE_SIZE,
+                             unassigned_mmio_read, unassigned_mmio_write,
+                             mmio);
+    }
+
+    return mmio;
+}
+
+/*****************************************************************************/
+/* "Universal" Interrupt controller */
+enum {
+    DCR_UICSR  = 0x000,
+    DCR_UICSRS = 0x001,
+    DCR_UICER  = 0x002,
+    DCR_UICCR  = 0x003,
+    DCR_UICPR  = 0x004,
+    DCR_UICTR  = 0x005,
+    DCR_UICMSR = 0x006,
+    DCR_UICVR  = 0x007,
+    DCR_UICVCR = 0x008,
+    DCR_UICMAX = 0x009,
+};
+
+#define UIC_MAX_IRQ 32
+typedef struct ppcuic_t ppcuic_t;
+struct ppcuic_t {
+    uint32_t dcr_base;
+    int use_vectors;
+    uint32_t uicsr;  /* Status register */
+    uint32_t uicer;  /* Enable register */
+    uint32_t uiccr;  /* Critical register */
+    uint32_t uicpr;  /* Polarity register */
+    uint32_t uictr;  /* Triggering register */
+    uint32_t uicvcr; /* Vector configuration register */
+    uint32_t uicvr;
+    qemu_irq *irqs;
+};
+
+static void ppcuic_trigger_irq (ppcuic_t *uic)
+{
+    uint32_t ir, cr;
+    int start, end, inc, i;
+
+    /* Trigger interrupt if any is pending */
+    ir = uic->uicsr & uic->uicer & (~uic->uiccr);
+    cr = uic->uicsr & uic->uicer & uic->uiccr;
+#ifdef DEBUG_UIC
+    if (loglevel & CPU_LOG_INT) {
+        fprintf(logfile, "%s: uicsr %08x uicer %08x uiccr %08x\n"
+                "   %08x ir %08x cr %08x\n", __func__,
+                uic->uicsr, uic->uicer, uic->uiccr,
+                uic->uicsr & uic->uicer, ir, cr);
+    }
+#endif
+    if (ir != 0x0000000) {
+#ifdef DEBUG_UIC
+        if (loglevel & CPU_LOG_INT) {
+            fprintf(logfile, "Raise UIC interrupt\n");
+        }
+#endif
+        qemu_irq_raise(uic->irqs[PPCUIC_OUTPUT_INT]);
+    } else {
+#ifdef DEBUG_UIC
+        if (loglevel & CPU_LOG_INT) {
+            fprintf(logfile, "Lower UIC interrupt\n");
+        }
+#endif
+        qemu_irq_lower(uic->irqs[PPCUIC_OUTPUT_INT]);
+    }
+    /* Trigger critical interrupt if any is pending and update vector */
+    if (cr != 0x0000000) {
+        qemu_irq_raise(uic->irqs[PPCUIC_OUTPUT_CINT]);
+        if (uic->use_vectors) {
+            /* Compute critical IRQ vector */
+            if (uic->uicvcr & 1) {
+                start = 31;
+                end = 0;
+                inc = -1;
+            } else {
+                start = 0;
+                end = 31;
+                inc = 1;
+            }
+            uic->uicvr = uic->uicvcr & 0xFFFFFFFC;
+            for (i = start; i <= end; i += inc) {
+                if (cr & (1 << i)) {
+                    uic->uicvr += (i - start) * 512 * inc;
+                    break;
+                }
+            }
+        }
+#ifdef DEBUG_UIC
+        if (loglevel & CPU_LOG_INT) {
+            fprintf(logfile, "Raise UIC critical interrupt - vector %08x\n",
+                    uic->uicvr);
+        }
+#endif
+    } else {
+#ifdef DEBUG_UIC
+        if (loglevel & CPU_LOG_INT) {
+            fprintf(logfile, "Lower UIC critical interrupt\n");
+        }
+#endif
+        qemu_irq_lower(uic->irqs[PPCUIC_OUTPUT_CINT]);
+        uic->uicvr = 0x00000000;
+    }
+}
+
+static void ppcuic_set_irq (void *opaque, int irq_num, int level)
+{
+    ppcuic_t *uic;
+    uint32_t mask, sr;
+
+    uic = opaque;
+    mask = 1 << irq_num;
+#ifdef DEBUG_UIC
+    if (loglevel & CPU_LOG_INT) {
+        fprintf(logfile, "%s: irq %d level %d uicsr %08x mask %08x => %08x "
+                "%08x\n", __func__, irq_num, level,
+                uic->uicsr, mask, uic->uicsr & mask, level << irq_num);
+    }
+#endif
+    if (irq_num < 0 || irq_num > 31)
+        return;
+    sr = uic->uicsr;
+    if (!(uic->uicpr & mask)) {
+        /* Negatively asserted IRQ */
+        level = level == 0 ? 1 : 0;
+    }
+    /* Update status register */
+    if (uic->uictr & mask) {
+        /* Edge sensitive interrupt */
+        if (level == 1)
+            uic->uicsr |= mask;
+    } else {
+        /* Level sensitive interrupt */
+        if (level == 1)
+            uic->uicsr |= mask;
+        else
+            uic->uicsr &= ~mask;
+    }
+#ifdef DEBUG_UIC
+    if (loglevel & CPU_LOG_INT) {
+        fprintf(logfile, "%s: irq %d level %d sr %08x => %08x\n", __func__,
+                irq_num, level, uic->uicsr, sr);
+    }
+#endif
+    if (sr != uic->uicsr)
+        ppcuic_trigger_irq(uic);
+}
+
+static target_ulong dcr_read_uic (void *opaque, int dcrn)
+{
+    ppcuic_t *uic;
+    target_ulong ret;
+
+    uic = opaque;
+    dcrn -= uic->dcr_base;
+    switch (dcrn) {
+    case DCR_UICSR:
+    case DCR_UICSRS:
+        ret = uic->uicsr;
+        break;
+    case DCR_UICER:
+        ret = uic->uicer;
+        break;
+    case DCR_UICCR:
+        ret = uic->uiccr;
+        break;
+    case DCR_UICPR:
+        ret = uic->uicpr;
+        break;
+    case DCR_UICTR:
+        ret = uic->uictr;
+        break;
+    case DCR_UICMSR:
+        ret = uic->uicsr & uic->uicer;
+        break;
+    case DCR_UICVR:
+        if (!uic->use_vectors)
+            goto no_read;
+        ret = uic->uicvr;
+        break;
+    case DCR_UICVCR:
+        if (!uic->use_vectors)
+            goto no_read;
+        ret = uic->uicvcr;
+        break;
+    default:
+    no_read:
+        ret = 0x00000000;
+        break;
+    }
+
+    return ret;
+}
+
+static void dcr_write_uic (void *opaque, int dcrn, target_ulong val)
+{
+    ppcuic_t *uic;
+
+    uic = opaque;
+    dcrn -= uic->dcr_base;
+#ifdef DEBUG_UIC
+    if (loglevel & CPU_LOG_INT) {
+        fprintf(logfile, "%s: dcr %d val " ADDRX "\n", __func__, dcrn, val);
+    }
+#endif
+    switch (dcrn) {
+    case DCR_UICSR:
+        uic->uicsr &= ~val;
+        ppcuic_trigger_irq(uic);
+        break;
+    case DCR_UICSRS:
+        uic->uicsr |= val;
+        ppcuic_trigger_irq(uic);
+        break;
+    case DCR_UICER:
+        uic->uicer = val;
+        ppcuic_trigger_irq(uic);
+        break;
+    case DCR_UICCR:
+        uic->uiccr = val;
+        ppcuic_trigger_irq(uic);
+        break;
+    case DCR_UICPR:
+        uic->uicpr = val;
+        ppcuic_trigger_irq(uic);
+        break;
+    case DCR_UICTR:
+        uic->uictr = val;
+        ppcuic_trigger_irq(uic);
+        break;
+    case DCR_UICMSR:
+        break;
+    case DCR_UICVR:
+        break;
+    case DCR_UICVCR:
+        uic->uicvcr = val & 0xFFFFFFFD;
+        ppcuic_trigger_irq(uic);
+        break;
+    }
+}
+
+static void ppcuic_reset (void *opaque)
+{
+    ppcuic_t *uic;
+
+    uic = opaque;
+    uic->uiccr = 0x00000000;
+    uic->uicer = 0x00000000;
+    uic->uicpr = 0x00000000;
+    uic->uicsr = 0x00000000;
+    uic->uictr = 0x00000000;
+    if (uic->use_vectors) {
+        uic->uicvcr = 0x00000000;
+        uic->uicvr = 0x0000000;
+    }
+}
+
+qemu_irq *ppcuic_init (CPUState *env, qemu_irq *irqs,
+                       uint32_t dcr_base, int has_ssr, int has_vr)
+{
+    ppcuic_t *uic;
+    int i;
+
+    uic = qemu_mallocz(sizeof(ppcuic_t));
+    if (uic != NULL) {
+        uic->dcr_base = dcr_base;
+        uic->irqs = irqs;
+        if (has_vr)
+            uic->use_vectors = 1;
+        for (i = 0; i < DCR_UICMAX; i++) {
+            ppc_dcr_register(env, dcr_base + i, uic,
+                             &dcr_read_uic, &dcr_write_uic);
+        }
+        qemu_register_reset(ppcuic_reset, uic);
+        ppcuic_reset(uic);
+    }
+
+    return qemu_allocate_irqs(&ppcuic_set_irq, uic, UIC_MAX_IRQ);
+}

Modified: trunk/src/host/qemu-neo1973/hw/ppc_chrp.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/ppc_chrp.c	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/hw/ppc_chrp.c	2007-10-29 21:14:04 UTC (rev 3303)
@@ -1,7 +1,8 @@
 /*
- * QEMU PPC CHRP/PMAC hardware System Emulator
+ * QEMU PowerPC CHRP (currently NewWorld PowerMac) hardware System Emulator
  *
  * Copyright (c) 2004-2007 Fabrice Bellard
+ * Copyright (c) 2007 Jocelyn Mayer
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy
  * of this software and associated documentation files (the "Software"), to deal
@@ -22,172 +23,8 @@
  * THE SOFTWARE.
  */
 #include "vl.h"
+#include "ppc_mac.h"
 
-/* SMP is not enabled, for now */
-#define MAX_CPUS 1
-
-#define BIOS_FILENAME "ppc_rom.bin"
-#define VGABIOS_FILENAME "video.x"
-#define NVRAM_SIZE        0x2000
-
-#define KERNEL_LOAD_ADDR 0x01000000
-#define INITRD_LOAD_ADDR 0x01800000
-
-/* MacIO devices (mapped inside the MacIO address space): CUDA, DBDMA,
-   NVRAM */
-
-static int dbdma_mem_index;
-static int cuda_mem_index;
-static int ide0_mem_index = -1;
-static int ide1_mem_index = -1;
-static int openpic_mem_index = -1;
-static int heathrow_pic_mem_index = -1;
-static int macio_nvram_mem_index = -1;
-
-/* DBDMA: currently no op - should suffice right now */
-
-static void dbdma_writeb (void *opaque,
-                          target_phys_addr_t addr, uint32_t value)
-{
-    printf("%s: 0x" PADDRX " <= 0x%08x\n", __func__, addr, value);
-}
-
-static void dbdma_writew (void *opaque,
-                          target_phys_addr_t addr, uint32_t value)
-{
-}
-
-static void dbdma_writel (void *opaque,
-                          target_phys_addr_t addr, uint32_t value)
-{
-}
-
-static uint32_t dbdma_readb (void *opaque, target_phys_addr_t addr)
-{
-    printf("%s: 0x" PADDRX " => 0x00000000\n", __func__, addr);
-
-    return 0;
-}
-
-static uint32_t dbdma_readw (void *opaque, target_phys_addr_t addr)
-{
-    return 0;
-}
-
-static uint32_t dbdma_readl (void *opaque, target_phys_addr_t addr)
-{
-    return 0;
-}
-
-static CPUWriteMemoryFunc *dbdma_write[] = {
-    &dbdma_writeb,
-    &dbdma_writew,
-    &dbdma_writel,
-};
-
-static CPUReadMemoryFunc *dbdma_read[] = {
-    &dbdma_readb,
-    &dbdma_readw,
-    &dbdma_readl,
-};
-
-/* macio style NVRAM device */
-typedef struct MacIONVRAMState {
-    uint8_t data[0x2000];
-} MacIONVRAMState;
-
-static void macio_nvram_writeb (void *opaque,
-                                target_phys_addr_t addr, uint32_t value)
-{
-    MacIONVRAMState *s = opaque;
-    addr = (addr >> 4) & 0x1fff;
-    s->data[addr] = value;
-    //    printf("macio_nvram_writeb %04x = %02x\n", addr, value);
-}
-
-static uint32_t macio_nvram_readb (void *opaque, target_phys_addr_t addr)
-{
-    MacIONVRAMState *s = opaque;
-    uint32_t value;
-
-    addr = (addr >> 4) & 0x1fff;
-    value = s->data[addr];
-    //    printf("macio_nvram_readb %04x = %02x\n", addr, value);
-
-    return value;
-}
-
-static CPUWriteMemoryFunc *macio_nvram_write[] = {
-    &macio_nvram_writeb,
-    &macio_nvram_writeb,
-    &macio_nvram_writeb,
-};
-
-static CPUReadMemoryFunc *macio_nvram_read[] = {
-    &macio_nvram_readb,
-    &macio_nvram_readb,
-    &macio_nvram_readb,
-};
-
-static MacIONVRAMState *macio_nvram_init (void)
-{
-    MacIONVRAMState *s;
-    s = qemu_mallocz(sizeof(MacIONVRAMState));
-    if (!s)
-        return NULL;
-    macio_nvram_mem_index = cpu_register_io_memory(0, macio_nvram_read,
-                                                   macio_nvram_write, s);
-
-    return s;
-}
-
-static void macio_map (PCIDevice *pci_dev, int region_num,
-                       uint32_t addr, uint32_t size, int type)
-{
-    if (heathrow_pic_mem_index >= 0) {
-        cpu_register_physical_memory(addr + 0x00000, 0x1000,
-                                     heathrow_pic_mem_index);
-    }
-    cpu_register_physical_memory(addr + 0x08000, 0x1000, dbdma_mem_index);
-    cpu_register_physical_memory(addr + 0x16000, 0x2000, cuda_mem_index);
-    if (ide0_mem_index >= 0)
-        cpu_register_physical_memory(addr + 0x1f000, 0x1000, ide0_mem_index);
-    if (ide1_mem_index >= 0)
-        cpu_register_physical_memory(addr + 0x20000, 0x1000, ide1_mem_index);
-    if (openpic_mem_index >= 0) {
-        cpu_register_physical_memory(addr + 0x40000, 0x40000,
-                                     openpic_mem_index);
-    }
-    if (macio_nvram_mem_index >= 0)
-        cpu_register_physical_memory(addr + 0x60000, 0x20000,
-                                     macio_nvram_mem_index);
-}
-
-static void macio_init (PCIBus *bus, int device_id)
-{
-    PCIDevice *d;
-
-    d = pci_register_device(bus, "macio", sizeof(PCIDevice),
-                            -1, NULL, NULL);
-    /* Note: this code is strongly inspirated from the corresponding code
-       in PearPC */
-    d->config[0x00] = 0x6b; // vendor_id
-    d->config[0x01] = 0x10;
-    d->config[0x02] = device_id;
-    d->config[0x03] = device_id >> 8;
-
-    d->config[0x0a] = 0x00; // class_sub = pci2pci
-    d->config[0x0b] = 0xff; // class_base = bridge
-    d->config[0x0e] = 0x00; // header_type
-
-    d->config[0x3d] = 0x01; // interrupt on pin 1
-
-    dbdma_mem_index = cpu_register_io_memory(0, dbdma_read, dbdma_write, NULL);
-
-    pci_register_io_region(d, 0, 0x80000,
-                           PCI_ADDRESS_SPACE_MEM, macio_map);
-}
-
 /* UniN device */
 static void unin_writel (void *opaque, target_phys_addr_t addr, uint32_t value)
 {
@@ -210,159 +47,83 @@
     &unin_readl,
 };
 
-/* temporary frame buffer OSI calls for the video.x driver. The right
-   solution is to modify the driver to use VGA PCI I/Os */
-/* XXX: to be removed. This is no way related to emulation */
-static int vga_osi_call (CPUState *env)
+/* PowerPC Mac99 hardware initialisation */
+static void ppc_core99_init (int ram_size, int vga_ram_size, int boot_device,
+                             DisplayState *ds, const char **fd_filename,
+                             int snapshot,
+                             const char *kernel_filename,
+                             const char *kernel_cmdline,
+                             const char *initrd_filename,
+                             const char *cpu_model)
 {
-    static int vga_vbl_enabled;
-    int linesize;
-
-    //    printf("osi_call R5=%d\n", env->gpr[5]);
-
-    /* same handler as PearPC, coming from the original MOL video
-       driver. */
-    switch(env->gpr[5]) {
-    case 4:
-        break;
-    case 28: /* set_vmode */
-        if (env->gpr[6] != 1 || env->gpr[7] != 0)
-            env->gpr[3] = 1;
-        else
-            env->gpr[3] = 0;
-        break;
-    case 29: /* get_vmode_info */
-        if (env->gpr[6] != 0) {
-            if (env->gpr[6] != 1 || env->gpr[7] != 0) {
-                env->gpr[3] = 1;
-                break;
-            }
-        }
-        env->gpr[3] = 0;
-        env->gpr[4] = (1 << 16) | 1; /* num_vmodes, cur_vmode */
-        env->gpr[5] = (1 << 16) | 0; /* num_depths, cur_depth_mode */
-        env->gpr[6] = (graphic_width << 16) | graphic_height; /* w, h */
-        env->gpr[7] = 85 << 16; /* refresh rate */
-        env->gpr[8] = (graphic_depth + 7) & ~7; /* depth (round to byte) */
-        linesize = ((graphic_depth + 7) >> 3) * graphic_width;
-        linesize = (linesize + 3) & ~3;
-        env->gpr[9] = (linesize << 16) | 0; /* row_bytes, offset */
-        break;
-    case 31: /* set_video power */
-        env->gpr[3] = 0;
-        break;
-    case 39: /* video_ctrl */
-        if (env->gpr[6] == 0 || env->gpr[6] == 1)
-            vga_vbl_enabled = env->gpr[6];
-        env->gpr[3] = 0;
-        break;
-    case 47:
-        break;
-    case 59: /* set_color */
-        /* R6 = index, R7 = RGB */
-        env->gpr[3] = 0;
-        break;
-    case 64: /* get color */
-        /* R6 = index */
-        env->gpr[3] = 0;
-        break;
-    case 116: /* set hwcursor */
-        /* R6 = x, R7 = y, R8 = visible, R9 = data */
-        break;
-    default:
-        fprintf(stderr, "unsupported OSI call R5=" REGX "\n", env->gpr[5]);
-        break;
-    }
-
-    return 1; /* osi_call handled */
-}
-
-static uint8_t nvram_chksum (const uint8_t *buf, int n)
-{
-    int sum, i;
-    sum = 0;
-    for(i = 0; i < n; i++)
-        sum += buf[i];
-    return (sum & 0xff) + (sum >> 8);
-}
-
-/* set a free Mac OS NVRAM partition */
-void pmac_format_nvram_partition (uint8_t *buf, int len)
-{
-    char partition_name[12] = "wwwwwwwwwwww";
-
-    buf[0] = 0x7f; /* free partition magic */
-    buf[1] = 0; /* checksum */
-    buf[2] = len >> 8;
-    buf[3] = len;
-    memcpy(buf + 4, partition_name, 12);
-    buf[1] = nvram_chksum(buf, 16);
-}
-
-/* PowerPC CHRP hardware initialisation */
-static void ppc_chrp_init (int ram_size, int vga_ram_size, int boot_device,
-                           DisplayState *ds, const char **fd_filename,
-                           int snapshot,
-                           const char *kernel_filename,
-                           const char *kernel_cmdline,
-                           const char *initrd_filename,
-                           const char *cpu_model,
-                           int is_heathrow)
-{
     CPUState *env, *envs[MAX_CPUS];
     char buf[1024];
     qemu_irq *pic, **openpic_irqs;
-    m48t59_t *nvram;
     int unin_memory;
     int linux_boot, i;
     unsigned long bios_offset, vga_bios_offset;
     uint32_t kernel_base, kernel_size, initrd_base, initrd_size;
     ppc_def_t *def;
     PCIBus *pci_bus;
-    const char *arch_name;
+    nvram_t nvram;
+#if 0
+    MacIONVRAMState *nvr;
+    int nvram_mem_index;
+#endif
+    m48t59_t *m48t59;
     int vga_bios_size, bios_size;
     qemu_irq *dummy_irq;
+    int pic_mem_index, dbdma_mem_index, cuda_mem_index;
+    int ide_mem_index[2];
 
     linux_boot = (kernel_filename != NULL);
 
     /* init CPUs */
     env = cpu_init();
-    qemu_register_reset(&cpu_ppc_reset, env);
-    register_savevm("cpu", 0, 3, cpu_save, cpu_load, env);
-
-    /* Default CPU is a generic 74x/75x */
     if (cpu_model == NULL)
-        cpu_model = "750";
-    /* XXX: CPU model (or PVR) should be provided on command line */
-    //    ppc_find_by_name("750gx", &def); // Linux boot OK
-    //    ppc_find_by_name("750fx", &def); // Linux boot OK
-    /* Linux does not boot on 750cxe (and probably other 750cx based)
-     * because it assumes it has 8 IBAT & DBAT pairs as it only have 4.
-     */
+        cpu_model = "default";
     ppc_find_by_name(cpu_model, &def);
     if (def == NULL) {
         cpu_abort(env, "Unable to find PowerPC CPU definition\n");
     }
     for (i = 0; i < smp_cpus; i++) {
         cpu_ppc_register(env, def);
+        cpu_ppc_reset(env);
         /* Set time-base frequency to 100 Mhz */
         cpu_ppc_tb_init(env, 100UL * 1000UL * 1000UL);
+#if 0
         env->osi_call = vga_osi_call;
+#endif
+        qemu_register_reset(&cpu_ppc_reset, env);
+        register_savevm("cpu", 0, 3, cpu_save, cpu_load, env);
         envs[i] = env;
     }
+    if (env->nip < 0xFFF80000) {
+        /* Special test for PowerPC 601:
+         * the boot vector is at 0xFFF00100, then we need a 1MB BIOS.
+         * But the NVRAM is located at 0xFFF04000...
+         */
+        cpu_abort(env, "Mac99 hardware can not handle 1 MB BIOS\n");
+    }
 
     /* allocate RAM */
     cpu_register_physical_memory(0, ram_size, IO_MEM_RAM);
 
     /* allocate and load BIOS */
     bios_offset = ram_size + vga_ram_size;
-    snprintf(buf, sizeof(buf), "%s/%s", bios_dir, BIOS_FILENAME);
+    if (bios_name == NULL)
+        bios_name = BIOS_FILENAME;
+    snprintf(buf, sizeof(buf), "%s/%s", bios_dir, bios_name);
     bios_size = load_image(buf, phys_ram_base + bios_offset);
     if (bios_size < 0 || bios_size > BIOS_SIZE) {
         cpu_abort(env, "qemu: could not load PowerPC bios '%s'\n", buf);
         exit(1);
     }
     bios_size = (bios_size + 0xfff) & ~0xfff;
+    if (bios_size > 0x00080000) {
+        /* As the NVRAM is located at 0xFFF04000, we cannot use 1 MB BIOSes */
+        cpu_abort(env, "Mac99 hardware can not handle 1 MB BIOS\n");
+    }
     cpu_register_physical_memory((uint32_t)(-bios_size),
                                  bios_size, bios_offset | IO_MEM_ROM);
 
@@ -418,150 +179,113 @@
         initrd_size = 0;
     }
 
-    if (is_heathrow) {
-        isa_mem_base = 0x80000000;
+    isa_mem_base = 0x80000000;
 
-        /* Register 2 MB of ISA IO space */
-        isa_mmio_init(0xfe000000, 0x00200000);
+    /* Register 8 MB of ISA IO space */
+    isa_mmio_init(0xf2000000, 0x00800000);
 
-        /* init basic PC hardware */
-        if (PPC_INPUT(env) != PPC_FLAGS_INPUT_6xx) {
-            cpu_abort(env, "Only 6xx bus is supported on heathrow machine\n");
+    /* UniN init */
+    unin_memory = cpu_register_io_memory(0, unin_read, unin_write, NULL);
+    cpu_register_physical_memory(0xf8000000, 0x00001000, unin_memory);
+
+    openpic_irqs = qemu_mallocz(smp_cpus * sizeof(qemu_irq *));
+    openpic_irqs[0] =
+        qemu_mallocz(smp_cpus * sizeof(qemu_irq) * OPENPIC_OUTPUT_NB);
+    for (i = 0; i < smp_cpus; i++) {
+        /* Mac99 IRQ connection between OpenPIC outputs pins
+         * and PowerPC input pins
+         */
+        switch (PPC_INPUT(env)) {
+        case PPC_FLAGS_INPUT_6xx:
+            openpic_irqs[i] = openpic_irqs[0] + (i * OPENPIC_OUTPUT_NB);
+            openpic_irqs[i][OPENPIC_OUTPUT_INT] =
+                ((qemu_irq *)env->irq_inputs)[PPC6xx_INPUT_INT];
+            openpic_irqs[i][OPENPIC_OUTPUT_CINT] =
+                ((qemu_irq *)env->irq_inputs)[PPC6xx_INPUT_INT];
+            openpic_irqs[i][OPENPIC_OUTPUT_MCK] =
+                ((qemu_irq *)env->irq_inputs)[PPC6xx_INPUT_MCP];
+            /* Not connected ? */
+            openpic_irqs[i][OPENPIC_OUTPUT_DEBUG] = NULL;
+            /* Check this */
+            openpic_irqs[i][OPENPIC_OUTPUT_RESET] =
+                ((qemu_irq *)env->irq_inputs)[PPC6xx_INPUT_HRESET];
+            break;
+#if defined(TARGET_PPC64)
+        case PPC_FLAGS_INPUT_970:
+            openpic_irqs[i] = openpic_irqs[0] + (i * OPENPIC_OUTPUT_NB);
+            openpic_irqs[i][OPENPIC_OUTPUT_INT] =
+                ((qemu_irq *)env->irq_inputs)[PPC970_INPUT_INT];
+            openpic_irqs[i][OPENPIC_OUTPUT_CINT] =
+                ((qemu_irq *)env->irq_inputs)[PPC970_INPUT_INT];
+            openpic_irqs[i][OPENPIC_OUTPUT_MCK] =
+                ((qemu_irq *)env->irq_inputs)[PPC970_INPUT_MCP];
+            /* Not connected ? */
+            openpic_irqs[i][OPENPIC_OUTPUT_DEBUG] = NULL;
+            /* Check this */
+            openpic_irqs[i][OPENPIC_OUTPUT_RESET] =
+                ((qemu_irq *)env->irq_inputs)[PPC970_INPUT_HRESET];
+            break;
+#endif /* defined(TARGET_PPC64) */
+        default:
+            cpu_abort(env, "Bus model not supported on mac99 machine\n");
             exit(1);
         }
-        pic = heathrow_pic_init(&heathrow_pic_mem_index);
-        pci_bus = pci_grackle_init(0xfec00000, pic);
-        pci_vga_init(pci_bus, ds, phys_ram_base + ram_size,
-                     ram_size, vga_ram_size,
-                     vga_bios_offset, vga_bios_size);
+    }
+    pic = openpic_init(NULL, &pic_mem_index, smp_cpus, openpic_irqs, NULL);
+    pci_bus = pci_pmac_init(pic);
+    /* init basic PC hardware */
+    pci_vga_init(pci_bus, ds, phys_ram_base + ram_size,
+                 ram_size, vga_ram_size,
+                 vga_bios_offset, vga_bios_size);
+    
+    /* XXX: suppress that */
+    dummy_irq = i8259_init(NULL);
 
-        /* XXX: suppress that */
-        dummy_irq = i8259_init(NULL);
-
-        /* XXX: use Mac Serial port */
-        serial_init(0x3f8, dummy_irq[4], serial_hds[0]);
-
-        for(i = 0; i < nb_nics; i++) {
-            if (!nd_table[i].model)
-                nd_table[i].model = "ne2k_pci";
-            pci_nic_init(pci_bus, &nd_table[i], -1);
-        }
-
-        pci_cmd646_ide_init(pci_bus, &bs_table[0], 0);
-
-        /* cuda also initialize ADB */
-        cuda_mem_index = cuda_init(pic[0x12]);
-
-        adb_kbd_init(&adb_bus);
-        adb_mouse_init(&adb_bus);
-
-        {
-            MacIONVRAMState *nvr;
-            nvr = macio_nvram_init();
-            pmac_format_nvram_partition(nvr->data, 0x2000);
-        }
-
-        macio_init(pci_bus, 0x0017);
-
-        nvram = m48t59_init(dummy_irq[8], 0xFFF04000, 0x0074, NVRAM_SIZE, 59);
-
-        arch_name = "HEATHROW";
-    } else {
-        isa_mem_base = 0x80000000;
-
-        /* Register 8 MB of ISA IO space */
-        isa_mmio_init(0xf2000000, 0x00800000);
-
-        /* UniN init */
-        unin_memory = cpu_register_io_memory(0, unin_read, unin_write, NULL);
-        cpu_register_physical_memory(0xf8000000, 0x00001000, unin_memory);
-
-        openpic_irqs = qemu_mallocz(smp_cpus * sizeof(qemu_irq *));
-        openpic_irqs[0] =
-            qemu_mallocz(smp_cpus * sizeof(qemu_irq) * OPENPIC_OUTPUT_NB);
-        for (i = 0; i < smp_cpus; i++) {
-            /* Mac99 IRQ connection between OpenPIC outputs pins
-             * and PowerPC input pins
-             */
-            switch (PPC_INPUT(env)) {
-            case PPC_FLAGS_INPUT_6xx:
-                openpic_irqs[i] = openpic_irqs[0] + (i * OPENPIC_OUTPUT_NB);
-                openpic_irqs[i][OPENPIC_OUTPUT_INT] =
-                    ((qemu_irq *)env->irq_inputs)[PPC6xx_INPUT_INT];
-                openpic_irqs[i][OPENPIC_OUTPUT_CINT] =
-                    ((qemu_irq *)env->irq_inputs)[PPC6xx_INPUT_INT];
-                openpic_irqs[i][OPENPIC_OUTPUT_MCK] =
-                    ((qemu_irq *)env->irq_inputs)[PPC6xx_INPUT_MCP];
-                /* Not connected ? */
-                openpic_irqs[i][OPENPIC_OUTPUT_DEBUG] = NULL;
-                /* Check this */
-                openpic_irqs[i][OPENPIC_OUTPUT_RESET] =
-                    ((qemu_irq *)env->irq_inputs)[PPC6xx_INPUT_HRESET];
-                break;
-            case PPC_FLAGS_INPUT_970:
-                openpic_irqs[i] = openpic_irqs[0] + (i * OPENPIC_OUTPUT_NB);
-                openpic_irqs[i][OPENPIC_OUTPUT_INT] =
-                    ((qemu_irq *)env->irq_inputs)[PPC970_INPUT_INT];
-                openpic_irqs[i][OPENPIC_OUTPUT_CINT] =
-                    ((qemu_irq *)env->irq_inputs)[PPC970_INPUT_INT];
-                openpic_irqs[i][OPENPIC_OUTPUT_MCK] =
-                    ((qemu_irq *)env->irq_inputs)[PPC970_INPUT_MCP];
-                /* Not connected ? */
-                openpic_irqs[i][OPENPIC_OUTPUT_DEBUG] = NULL;
-                /* Check this */
-                openpic_irqs[i][OPENPIC_OUTPUT_RESET] =
-                    ((qemu_irq *)env->irq_inputs)[PPC970_INPUT_HRESET];
-                break;
-            default:
-                cpu_abort(env, "Bus model not supported on mac99 machine\n");
-                exit(1);
-            }
-        }
-        pic = openpic_init(NULL, &openpic_mem_index, smp_cpus,
-                           openpic_irqs, NULL);
-        pci_bus = pci_pmac_init(pic);
-        /* init basic PC hardware */
-        pci_vga_init(pci_bus, ds, phys_ram_base + ram_size,
-                     ram_size, vga_ram_size,
-                     vga_bios_offset, vga_bios_size);
-
-        /* XXX: suppress that */
-        dummy_irq = i8259_init(NULL);
-
-        /* XXX: use Mac Serial port */
-        serial_init(0x3f8, dummy_irq[4], serial_hds[0]);
-        for(i = 0; i < nb_nics; i++) {
-            if (!nd_table[i].model)
-                nd_table[i].model = "ne2k_pci";
-            pci_nic_init(pci_bus, &nd_table[i], -1);
-        }
+    /* XXX: use Mac Serial port */
+    serial_init(0x3f8, dummy_irq[4], serial_hds[0]);
+    for(i = 0; i < nb_nics; i++) {
+        if (!nd_table[i].model)
+            nd_table[i].model = "ne2k_pci";
+        pci_nic_init(pci_bus, &nd_table[i], -1);
+    }
 #if 1
-        ide0_mem_index = pmac_ide_init(&bs_table[0], pic[0x13]);
-        ide1_mem_index = pmac_ide_init(&bs_table[2], pic[0x14]);
+    ide_mem_index[0] = pmac_ide_init(&bs_table[0], pic[0x13]);
+    ide_mem_index[1] = pmac_ide_init(&bs_table[2], pic[0x14]);
 #else
-        pci_cmd646_ide_init(pci_bus, &bs_table[0], 0);
+    pci_cmd646_ide_init(pci_bus, &bs_table[0], 0);
 #endif
-        /* cuda also initialize ADB */
-        cuda_mem_index = cuda_init(pic[0x19]);
+    /* cuda also initialize ADB */
+    cuda_init(&cuda_mem_index, pic[0x19]);
+    
+    adb_kbd_init(&adb_bus);
+    adb_mouse_init(&adb_bus);
 
-        adb_kbd_init(&adb_bus);
-        adb_mouse_init(&adb_bus);
+    dbdma_init(&dbdma_mem_index);
 
-        macio_init(pci_bus, 0x0022);
+    macio_init(pci_bus, 0x0022, 0, pic_mem_index, dbdma_mem_index,
+               cuda_mem_index, -1, 2, ide_mem_index);
 
-        nvram = m48t59_init(dummy_irq[8], 0xFFF04000, 0x0074, NVRAM_SIZE, 59);
-
-        arch_name = "MAC99";
-    }
-
     if (usb_enabled) {
         usb_ohci_init_pci(pci_bus, 3, -1);
     }
 
     if (graphic_depth != 15 && graphic_depth != 32 && graphic_depth != 8)
         graphic_depth = 15;
-
-    PPC_NVRAM_set_params(nvram, NVRAM_SIZE, arch_name, ram_size, boot_device,
+#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);
+    pmac_format_nvram_partition(nvr, 0x2000);
+    cpu_register_physical_memory(0xFFF04000, 0x20000, nvram_mem_index);
+    nvram.opaque = nvr;
+    nvram.read_fn = &macio_nvram_read;
+    nvram.write_fn = &macio_nvram_write;
+#else
+    m48t59 = m48t59_init(dummy_irq[8], 0xFFF04000, 0x0074, NVRAM_SIZE, 59);
+    nvram.opaque = m48t59;
+    nvram.read_fn = &m48t59_read;
+    nvram.write_fn = &m48t59_write;
+#endif
+    PPC_NVRAM_set_params(&nvram, NVRAM_SIZE, "MAC99", ram_size, boot_device,
                          kernel_base, kernel_size,
                          kernel_cmdline,
                          initrd_base, initrd_size,
@@ -572,44 +296,10 @@
 
     /* Special port to get debug messages from Open-Firmware */
     register_ioport_write(0x0F00, 4, 1, &PPC_debug_write, NULL);
-}
+ }
 
-static void ppc_core99_init (int ram_size, int vga_ram_size, int boot_device,
-                             DisplayState *ds, const char **fd_filename,
-                             int snapshot,
-                             const char *kernel_filename,
-                             const char *kernel_cmdline,
-                             const char *initrd_filename,
-                             const char *cpu_model)
-{
-    ppc_chrp_init(ram_size, vga_ram_size, boot_device,
-                  ds, fd_filename, snapshot,
-                  kernel_filename, kernel_cmdline,
-                  initrd_filename, cpu_model, 0);
-}
-
-static void ppc_heathrow_init (int ram_size, int vga_ram_size, int boot_device,
-                               DisplayState *ds, const char **fd_filename,
-                               int snapshot,
-                               const char *kernel_filename,
-                               const char *kernel_cmdline,
-                               const char *initrd_filename,
-                               const char *cpu_model)
-{
-    ppc_chrp_init(ram_size, vga_ram_size, boot_device,
-                  ds, fd_filename, snapshot,
-                  kernel_filename, kernel_cmdline,
-                  initrd_filename, cpu_model, 1);
-}
-
 QEMUMachine core99_machine = {
     "mac99",
     "Mac99 based PowerMAC",
     ppc_core99_init,
 };
-
-QEMUMachine heathrow_machine = {
-    "g3bw",
-    "Heathrow based PowerMAC",
-    ppc_heathrow_init,
-};

Added: trunk/src/host/qemu-neo1973/hw/ppc_mac.h
===================================================================
--- trunk/src/host/qemu-neo1973/hw/ppc_mac.h	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/hw/ppc_mac.h	2007-10-29 21:14:04 UTC (rev 3303)
@@ -0,0 +1,70 @@
+/*
+ * QEMU PowerMac emulation shared definitions and prototypes
+ *
+ * Copyright (c) 2004-2007 Fabrice Bellard
+ * Copyright (c) 2007 Jocelyn Mayer
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#if !defined(__PPC_MAC_H__)
+#define __PPC_MAC_H__
+
+/* SMP is not enabled, for now */
+#define MAX_CPUS 1
+
+#define BIOS_FILENAME "ppc_rom.bin"
+#define VGABIOS_FILENAME "video.x"
+#define NVRAM_SIZE        0x2000
+
+#define KERNEL_LOAD_ADDR 0x01000000
+#define INITRD_LOAD_ADDR 0x01800000
+
+/* DBDMA */
+void dbdma_init (int *dbdma_mem_index);
+
+/* Cuda */
+void cuda_init (int *cuda_mem_index, qemu_irq irq);
+
+/* 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 nb_ide, int *ide_mem_index);
+
+/* NewWorld PowerMac IDE */
+int pmac_ide_init (BlockDriverState **hd_table, qemu_irq irq);
+
+/* Heathrow PIC */
+qemu_irq *heathrow_pic_init(int *pmem_index,
+                            int nb_cpus, qemu_irq **irqs);
+
+/* Grackle PCI */
+PCIBus *pci_grackle_init(uint32_t base, qemu_irq *pic);
+
+/* UniNorth PCI */
+PCIBus *pci_pmac_init(qemu_irq *pic);
+
+/* Mac NVRAM */
+typedef struct MacIONVRAMState MacIONVRAMState;
+
+MacIONVRAMState *macio_nvram_init (int *mem_index);
+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);
+
+#endif /* !defined(__PPC_MAC_H__) */

Added: trunk/src/host/qemu-neo1973/hw/ppc_oldworld.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/ppc_oldworld.c	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/hw/ppc_oldworld.c	2007-10-29 21:14:04 UTC (rev 3303)
@@ -0,0 +1,309 @@
+/*
+ * QEMU OldWorld PowerMac (currently ~G3 B&W) hardware System Emulator
+ *
+ * Copyright (c) 2004-2007 Fabrice Bellard
+ * Copyright (c) 2007 Jocelyn Mayer
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include "vl.h"
+#include "ppc_mac.h"
+
+/* temporary frame buffer OSI calls for the video.x driver. The right
+   solution is to modify the driver to use VGA PCI I/Os */
+/* XXX: to be removed. This is no way related to emulation */
+static int vga_osi_call (CPUState *env)
+{
+    static int vga_vbl_enabled;
+    int linesize;
+
+    //    printf("osi_call R5=%d\n", env->gpr[5]);
+
+    /* same handler as PearPC, coming from the original MOL video
+       driver. */
+    switch(env->gpr[5]) {
+    case 4:
+        break;
+    case 28: /* set_vmode */
+        if (env->gpr[6] != 1 || env->gpr[7] != 0)
+            env->gpr[3] = 1;
+        else
+            env->gpr[3] = 0;
+        break;
+    case 29: /* get_vmode_info */
+        if (env->gpr[6] != 0) {
+            if (env->gpr[6] != 1 || env->gpr[7] != 0) {
+                env->gpr[3] = 1;
+                break;
+            }
+        }
+        env->gpr[3] = 0;
+        env->gpr[4] = (1 << 16) | 1; /* num_vmodes, cur_vmode */
+        env->gpr[5] = (1 << 16) | 0; /* num_depths, cur_depth_mode */
+        env->gpr[6] = (graphic_width << 16) | graphic_height; /* w, h */
+        env->gpr[7] = 85 << 16; /* refresh rate */
+        env->gpr[8] = (graphic_depth + 7) & ~7; /* depth (round to byte) */
+        linesize = ((graphic_depth + 7) >> 3) * graphic_width;
+        linesize = (linesize + 3) & ~3;
+        env->gpr[9] = (linesize << 16) | 0; /* row_bytes, offset */
+        break;
+    case 31: /* set_video power */
+        env->gpr[3] = 0;
+        break;
+    case 39: /* video_ctrl */
+        if (env->gpr[6] == 0 || env->gpr[6] == 1)
+            vga_vbl_enabled = env->gpr[6];
+        env->gpr[3] = 0;
+        break;
+    case 47:
+        break;
+    case 59: /* set_color */
+        /* R6 = index, R7 = RGB */
+        env->gpr[3] = 0;
+        break;
+    case 64: /* get color */
+        /* R6 = index */
+        env->gpr[3] = 0;
+        break;
+    case 116: /* set hwcursor */
+        /* R6 = x, R7 = y, R8 = visible, R9 = data */
+        break;
+    default:
+        fprintf(stderr, "unsupported OSI call R5=" REGX "\n", env->gpr[5]);
+        break;
+    }
+
+    return 1; /* osi_call handled */
+}
+
+static void ppc_heathrow_init (int ram_size, int vga_ram_size, int boot_device,
+                               DisplayState *ds, const char **fd_filename,
+                               int snapshot,
+                               const char *kernel_filename,
+                               const char *kernel_cmdline,
+                               const char *initrd_filename,
+                               const char *cpu_model)
+{
+    CPUState *env, *envs[MAX_CPUS];
+    char buf[1024];
+    qemu_irq *pic, **heathrow_irqs;
+    nvram_t nvram;
+    m48t59_t *m48t59;
+    int linux_boot, i;
+    unsigned long bios_offset, vga_bios_offset;
+    uint32_t kernel_base, kernel_size, initrd_base, initrd_size;
+    ppc_def_t *def;
+    PCIBus *pci_bus;
+    MacIONVRAMState *nvr;
+    int vga_bios_size, bios_size;
+    qemu_irq *dummy_irq;
+    int pic_mem_index, nvram_mem_index, dbdma_mem_index, cuda_mem_index;
+
+    linux_boot = (kernel_filename != NULL);
+
+    /* init CPUs */
+    env = cpu_init();
+    if (cpu_model == NULL)
+        cpu_model = "default";
+    ppc_find_by_name(cpu_model, &def);
+    if (def == NULL) {
+        cpu_abort(env, "Unable to find PowerPC CPU definition\n");
+    }
+    for (i = 0; i < smp_cpus; i++) {
+        cpu_ppc_register(env, def);
+        cpu_ppc_reset(env);
+        /* Set time-base frequency to 100 Mhz */
+        cpu_ppc_tb_init(env, 100UL * 1000UL * 1000UL);
+        env->osi_call = vga_osi_call;
+        qemu_register_reset(&cpu_ppc_reset, env);
+        register_savevm("cpu", 0, 3, cpu_save, cpu_load, env);
+        envs[i] = env;
+    }
+    if (env->nip < 0xFFF80000) {
+        /* Special test for PowerPC 601:
+         * the boot vector is at 0xFFF00100, then we need a 1MB BIOS.
+         * But the NVRAM is located at 0xFFF04000...
+         */
+        cpu_abort(env, "G3BW Mac hardware can not handle 1 MB BIOS\n");
+    }
+
+    /* allocate RAM */
+    cpu_register_physical_memory(0, ram_size, IO_MEM_RAM);
+
+    /* allocate and load BIOS */
+    bios_offset = ram_size + vga_ram_size;
+    if (bios_name == NULL)
+        bios_name = BIOS_FILENAME;
+    snprintf(buf, sizeof(buf), "%s/%s", bios_dir, bios_name);
+    bios_size = load_image(buf, phys_ram_base + bios_offset);
+    if (bios_size < 0 || bios_size > BIOS_SIZE) {
+        cpu_abort(env, "qemu: could not load PowerPC bios '%s'\n", buf);
+        exit(1);
+    }
+    bios_size = (bios_size + 0xfff) & ~0xfff;
+    if (bios_size > 0x00080000) {
+        /* As the NVRAM is located at 0xFFF04000, we cannot use 1 MB BIOSes */
+        cpu_abort(env, "G3BW Mac hardware can not handle 1 MB BIOS\n");
+    }
+    cpu_register_physical_memory((uint32_t)(-bios_size),
+                                 bios_size, bios_offset | IO_MEM_ROM);
+
+    /* allocate and load VGA BIOS */
+    vga_bios_offset = bios_offset + bios_size;
+    snprintf(buf, sizeof(buf), "%s/%s", bios_dir, VGABIOS_FILENAME);
+    vga_bios_size = load_image(buf, phys_ram_base + vga_bios_offset + 8);
+    if (vga_bios_size < 0) {
+        /* if no bios is present, we can still work */
+        fprintf(stderr, "qemu: warning: could not load VGA bios '%s'\n", buf);
+        vga_bios_size = 0;
+    } else {
+        /* set a specific header (XXX: find real Apple format for NDRV
+           drivers) */
+        phys_ram_base[vga_bios_offset] = 'N';
+        phys_ram_base[vga_bios_offset + 1] = 'D';
+        phys_ram_base[vga_bios_offset + 2] = 'R';
+        phys_ram_base[vga_bios_offset + 3] = 'V';
+        cpu_to_be32w((uint32_t *)(phys_ram_base + vga_bios_offset + 4),
+                     vga_bios_size);
+        vga_bios_size += 8;
+    }
+    vga_bios_size = (vga_bios_size + 0xfff) & ~0xfff;
+
+    if (linux_boot) {
+        kernel_base = KERNEL_LOAD_ADDR;
+        /* now we can load the kernel */
+        kernel_size = load_image(kernel_filename, phys_ram_base + kernel_base);
+        if (kernel_size < 0) {
+            cpu_abort(env, "qemu: could not load kernel '%s'\n",
+                      kernel_filename);
+            exit(1);
+        }
+        /* load initrd */
+        if (initrd_filename) {
+            initrd_base = INITRD_LOAD_ADDR;
+            initrd_size = load_image(initrd_filename,
+                                     phys_ram_base + initrd_base);
+            if (initrd_size < 0) {
+                cpu_abort(env, "qemu: could not load initial ram disk '%s'\n",
+                          initrd_filename);
+                exit(1);
+            }
+        } else {
+            initrd_base = 0;
+            initrd_size = 0;
+        }
+        boot_device = 'm';
+    } else {
+        kernel_base = 0;
+        kernel_size = 0;
+        initrd_base = 0;
+        initrd_size = 0;
+    }
+
+    isa_mem_base = 0x80000000;
+    
+    /* Register 2 MB of ISA IO space */
+    isa_mmio_init(0xfe000000, 0x00200000);
+
+    /* XXX: we register only 1 output pin for heathrow PIC */
+    heathrow_irqs = qemu_mallocz(smp_cpus * sizeof(qemu_irq *));
+    heathrow_irqs[0] =
+        qemu_mallocz(smp_cpus * sizeof(qemu_irq) * 1);
+    /* Connect the heathrow PIC outputs to the 6xx bus */
+    for (i = 0; i < smp_cpus; i++) {
+        switch (PPC_INPUT(env)) {
+        case PPC_FLAGS_INPUT_6xx:
+            heathrow_irqs[i] = heathrow_irqs[0] + (i * 1);
+            heathrow_irqs[i][0] =
+                ((qemu_irq *)env->irq_inputs)[PPC6xx_INPUT_INT];
+            break;
+        default:
+            cpu_abort(env, "Bus model not supported on OldWorld Mac machine\n");
+            exit(1);
+        }
+    }
+
+    /* init basic PC hardware */
+    if (PPC_INPUT(env) != PPC_FLAGS_INPUT_6xx) {
+        cpu_abort(env, "Only 6xx bus is supported on heathrow machine\n");
+        exit(1);
+    }
+    pic = heathrow_pic_init(&pic_mem_index, 1, heathrow_irqs);
+    pci_bus = pci_grackle_init(0xfec00000, pic);
+    pci_vga_init(pci_bus, ds, phys_ram_base + ram_size,
+                 ram_size, vga_ram_size,
+                 vga_bios_offset, vga_bios_size);
+    
+    /* XXX: suppress that */
+    dummy_irq = i8259_init(NULL);
+
+    /* XXX: use Mac Serial port */
+    serial_init(0x3f8, dummy_irq[4], serial_hds[0]);
+    
+    for(i = 0; i < nb_nics; i++) {
+        if (!nd_table[i].model)
+            nd_table[i].model = "ne2k_pci";
+        pci_nic_init(pci_bus, &nd_table[i], -1);
+    }
+    
+    pci_cmd646_ide_init(pci_bus, &bs_table[0], 0);
+
+    /* cuda also initialize ADB */
+    cuda_init(&cuda_mem_index, pic[0x12]);
+
+    adb_kbd_init(&adb_bus);
+    adb_mouse_init(&adb_bus);
+    
+    nvr = macio_nvram_init(&nvram_mem_index);
+    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);
+
+    if (usb_enabled) {
+        usb_ohci_init_pci(pci_bus, 3, -1);
+    }
+
+    if (graphic_depth != 15 && graphic_depth != 32 && graphic_depth != 8)
+        graphic_depth = 15;
+
+    m48t59 = m48t59_init(dummy_irq[8], 0xFFF04000, 0x0074, NVRAM_SIZE, 59);
+    nvram.opaque = m48t59;
+    nvram.read_fn = &m48t59_read;
+    nvram.write_fn = &m48t59_write;
+    PPC_NVRAM_set_params(&nvram, NVRAM_SIZE, "HEATHROW", ram_size, boot_device,
+                         kernel_base, kernel_size,
+                         kernel_cmdline,
+                         initrd_base, initrd_size,
+                         /* XXX: need an option to load a NVRAM image */
+                         0,
+                         graphic_width, graphic_height, graphic_depth);
+    /* No PCI init: the BIOS will do it */
+
+    /* Special port to get debug messages from Open-Firmware */
+    register_ioport_write(0x0F00, 4, 1, &PPC_debug_write, NULL);
+}
+
+QEMUMachine heathrow_machine = {
+    "g3bw",
+    "Heathrow based PowerMAC",
+    ppc_heathrow_init,
+};

Modified: trunk/src/host/qemu-neo1973/hw/ppc_prep.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/ppc_prep.c	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/hw/ppc_prep.c	2007-10-29 21:14:04 UTC (rev 3303)
@@ -26,6 +26,9 @@
 //#define HARD_DEBUG_PPC_IO
 //#define DEBUG_PPC_IO
 
+/* SMP is not enabled, for now */
+#define MAX_CPUS 1
+
 #define BIOS_FILENAME "ppc_rom.bin"
 #define KERNEL_LOAD_ADDR 0x01000000
 #define INITRD_LOAD_ADDR 0x01800000
@@ -104,7 +107,7 @@
     //    printf("%s: 0x%08x => 0x%08x\n", __func__, addr, value);
 }
 
-static inline uint32_t _PPC_intack_read (target_phys_addr_t addr)
+static always_inline uint32_t _PPC_intack_read (target_phys_addr_t addr)
 {
     uint32_t retval = 0;
 
@@ -249,6 +252,7 @@
 
 /* Fake super-io ports for PREP platform (Intel 82378ZB) */
 typedef struct sysctrl_t {
+    qemu_irq reset_irq;
     m48t59_t *nvram;
     uint8_t state;
     uint8_t syscontrol;
@@ -290,7 +294,9 @@
         /* Special port 92 */
         /* Check soft reset asked */
         if (val & 0x01) {
-            //            cpu_interrupt(first_cpu, PPC_INTERRUPT_RESET);
+            qemu_irq_raise(sysctrl->reset_irq);
+        } else {
+            qemu_irq_lower(sysctrl->reset_irq);
         }
         /* Check LE mode */
         if (val & 0x02) {
@@ -409,8 +415,9 @@
     return retval;
 }
 
-static inline target_phys_addr_t prep_IO_address (sysctrl_t *sysctrl,
-                                                  target_phys_addr_t addr)
+static always_inline target_phys_addr_t prep_IO_address (sysctrl_t *sysctrl,
+                                                         target_phys_addr_t
+                                                         addr)
 {
     if (sysctrl->contiguous_map == 0) {
         /* 64 KB contiguous space for IOs */
@@ -521,9 +528,10 @@
                            const char *initrd_filename,
                            const char *cpu_model)
 {
-    CPUState *env;
+    CPUState *env, *envs[MAX_CPUS];
     char buf[1024];
-    m48t59_t *nvram;
+    nvram_t nvram;
+    m48t59_t *m48t59;
     int PPC_io_memory;
     int linux_boot, i, nb_nics1, bios_size;
     unsigned long bios_offset;
@@ -539,33 +547,39 @@
     linux_boot = (kernel_filename != NULL);
 
     /* init CPUs */
-
     env = cpu_init();
-    qemu_register_reset(&cpu_ppc_reset, env);
-    register_savevm("cpu", 0, 3, cpu_save, cpu_load, env);
-
-    /* Default CPU is a 604 */
     if (cpu_model == NULL)
-        cpu_model = "604";
+        cpu_model = "default";
     ppc_find_by_name(cpu_model, &def);
     if (def == NULL) {
         cpu_abort(env, "Unable to find PowerPC CPU definition\n");
     }
-    cpu_ppc_register(env, def);
-    /* Set time-base frequency to 100 Mhz */
-    cpu_ppc_tb_init(env, 100UL * 1000UL * 1000UL);
+    for (i = 0; i < smp_cpus; i++) {
+        cpu_ppc_register(env, def);
+        cpu_ppc_reset(env);
+        /* Set time-base frequency to 100 Mhz */
+        cpu_ppc_tb_init(env, 100UL * 1000UL * 1000UL);
+        qemu_register_reset(&cpu_ppc_reset, env);
+        register_savevm("cpu", 0, 3, cpu_save, cpu_load, env);
+        envs[i] = env;
+    }
 
     /* allocate RAM */
     cpu_register_physical_memory(0, ram_size, IO_MEM_RAM);
 
     /* allocate and load BIOS */
     bios_offset = ram_size + vga_ram_size;
-    snprintf(buf, sizeof(buf), "%s/%s", bios_dir, BIOS_FILENAME);
+    if (bios_name == NULL)
+        bios_name = BIOS_FILENAME;
+    snprintf(buf, sizeof(buf), "%s/%s", bios_dir, bios_name);
     bios_size = load_image(buf, phys_ram_base + bios_offset);
     if (bios_size < 0 || bios_size > BIOS_SIZE) {
         cpu_abort(env, "qemu: could not load PPC PREP bios '%s'\n", buf);
         exit(1);
     }
+    if (env->nip < 0xFFF80000 && bios_size < 0x00100000) {
+        cpu_abort(env, "PowerPC 601 / 620 / 970 need a 1MB BIOS\n");
+    }
     bios_size = (bios_size + 0xfff) & ~0xfff;
     cpu_register_physical_memory((uint32_t)(-bios_size),
                                  bios_size, bios_offset | IO_MEM_ROM);
@@ -626,16 +640,11 @@
     if (nb_nics1 > NE2000_NB_MAX)
         nb_nics1 = NE2000_NB_MAX;
     for(i = 0; i < nb_nics1; i++) {
-        if (nd_table[0].model == NULL
-            || strcmp(nd_table[0].model, "ne2k_isa") == 0) {
+        if (nd_table[i].model == NULL
+            || strcmp(nd_table[i].model, "ne2k_isa") == 0) {
             isa_ne2000_init(ne2000_io[i], i8259[ne2000_irq[i]], &nd_table[i]);
-        } else if (strcmp(nd_table[0].model, "?") == 0) {
-            fprintf(stderr, "qemu: Supported NICs: ne2k_isa\n");
-            exit (1);
         } else {
-            /* Why ? */
-            cpu_abort(env, "qemu: Unsupported NIC: %s\n", nd_table[0].model);
-            exit (1);
+            pci_nic_init(pci_bus, &nd_table[i], -1);
         }
     }
 
@@ -654,6 +663,7 @@
     register_ioport_read(0x61, 1, 1, speaker_ioport_read, NULL);
     register_ioport_write(0x61, 1, 1, speaker_ioport_write, NULL);
     /* Register fake IO ports for PREP */
+    sysctrl->reset_irq = first_cpu->irq_inputs[PPC6xx_INPUT_HRESET];
     register_ioport_read(0x398, 2, 1, &PREP_io_read, sysctrl);
     register_ioport_write(0x398, 2, 1, &PREP_io_write, sysctrl);
     /* System control ports */
@@ -676,13 +686,16 @@
         usb_ohci_init_pci(pci_bus, 3, -1);
     }
 
-    nvram = m48t59_init(i8259[8], 0, 0x0074, NVRAM_SIZE, 59);
-    if (nvram == NULL)
+    m48t59 = m48t59_init(i8259[8], 0, 0x0074, NVRAM_SIZE, 59);
+    if (m48t59 == NULL)
         return;
-    sysctrl->nvram = nvram;
+    sysctrl->nvram = m48t59;
 
     /* Initialise NVRAM */
-    PPC_NVRAM_set_params(nvram, NVRAM_SIZE, "PREP", ram_size, boot_device,
+    nvram.opaque = m48t59;
+    nvram.read_fn = &m48t59_read;
+    nvram.write_fn = &m48t59_write;
+    PPC_NVRAM_set_params(&nvram, NVRAM_SIZE, "PREP", ram_size, boot_device,
                          kernel_base, kernel_size,
                          kernel_cmdline,
                          initrd_base, initrd_size,

Modified: trunk/src/host/qemu-neo1973/hw/prep_pci.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/prep_pci.c	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/hw/prep_pci.c	2007-10-29 21:14:04 UTC (rev 3303)
@@ -117,7 +117,6 @@
     &PPC_PCIIO_readl,
 };
 
-/* Don't know if this matches real hardware, but it agrees with OHW.  */
 static int prep_map_irq(PCIDevice *pci_dev, int irq_num)
 {
     return (irq_num + (pci_dev->devfn >> 3)) & 1;
@@ -125,7 +124,7 @@
 
 static void prep_set_irq(qemu_irq *pic, int irq_num, int level)
 {
-    qemu_set_irq(pic[irq_num ? 11 : 9], level);
+    qemu_set_irq(pic[(irq_num & 1) ? 11 : 9] , level);
 }
 
 PCIBus *pci_prep_init(qemu_irq *pic)
@@ -135,7 +134,7 @@
     int PPC_io_memory;
 
     s = qemu_mallocz(sizeof(PREPPCIState));
-    s->bus = pci_register_bus(prep_set_irq, prep_map_irq, pic, 0, 2);
+    s->bus = pci_register_bus(prep_set_irq, prep_map_irq, pic, 0, 4);
 
     register_ioport_write(0xcf8, 4, 4, pci_prep_addr_writel, s);
     register_ioport_read(0xcf8, 4, 4, pci_prep_addr_readl, s);

Modified: trunk/src/host/qemu-neo1973/hw/pxa.h
===================================================================
--- trunk/src/host/qemu-neo1973/hw/pxa.h	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/hw/pxa.h	2007-10-29 21:14:04 UTC (rev 3303)
@@ -4,7 +4,7 @@
  * Copyright (c) 2006 Openedhand Ltd.
  * Written by Andrzej Zaborowski <balrog at zabor.org>
  *
- * This code is licenced under the GPL.
+ * This code is licenced under the GNU GPL v2.
  */
 #ifndef PXA_H
 # define PXA_H			"pxa.h"

Modified: trunk/src/host/qemu-neo1973/hw/pxa2xx_gpio.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/pxa2xx_gpio.c	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/hw/pxa2xx_gpio.c	2007-10-29 21:14:04 UTC (rev 3303)
@@ -24,6 +24,7 @@
     uint32_t rising[PXA2XX_GPIO_BANKS];
     uint32_t falling[PXA2XX_GPIO_BANKS];
     uint32_t status[PXA2XX_GPIO_BANKS];
+    uint32_t gpsr[PXA2XX_GPIO_BANKS];
     uint32_t gafr[PXA2XX_GPIO_BANKS * 2];
 
     uint32_t prev_level[PXA2XX_GPIO_BANKS];
@@ -152,6 +153,11 @@
     case GPDR:		/* GPIO Pin-Direction registers */
         return s->dir[bank];
 
+    case GPSR:		/* GPIO Pin-Output Set registers */
+        printf("%s: Read from a write-only register " REG_FMT "\n",
+                        __FUNCTION__, offset);
+        return s->gpsr[bank];	/* Return last written value.  */
+
     case GRER:		/* GPIO Rising-Edge Detect Enable registers */
         return s->rising[bank];
 
@@ -201,6 +207,7 @@
     case GPSR:		/* GPIO Pin-Output Set registers */
         s->olevel[bank] |= value;
         pxa2xx_gpio_handler_update(s);
+        s->gpsr[bank] = value;
         break;
 
     case GPCR:		/* GPIO Pin-Output Clear registers */

Added: trunk/src/host/qemu-neo1973/hw/r2d.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/r2d.c	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/hw/r2d.c	2007-10-29 21:14:04 UTC (rev 3303)
@@ -0,0 +1,63 @@
+/*
+ * Renesas SH7751R R2D-PLUS emulation
+ *
+ * Copyright (c) 2007 Magnus Damm
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "vl.h"
+
+#define SDRAM_BASE 0x0c000000 /* Physical location of SDRAM: Area 3 */
+#define SDRAM_SIZE 0x04000000
+
+void r2d_init(int ram_size, int vga_ram_size, int boot_device,
+	      DisplayState * ds, const char **fd_filename, int snapshot,
+	      const char *kernel_filename, const char *kernel_cmdline,
+	      const char *initrd_filename, const char *cpu_model)
+{
+    CPUState *env;
+    struct SH7750State *s;
+
+    env = cpu_init();
+
+    /* Allocate memory space */
+    cpu_register_physical_memory(SDRAM_BASE, SDRAM_SIZE, 0);
+    /* Register peripherals */
+    s = sh7750_init(env);
+    /* Todo: register on board registers */
+    {
+      int kernel_size;
+
+      kernel_size = load_image(kernel_filename, phys_ram_base);
+
+      if (kernel_size < 0) {
+        fprintf(stderr, "qemu: could not load kernel '%s'\n", kernel_filename);
+        exit(1);
+      }
+
+      env->pc = SDRAM_BASE | 0xa0000000; /* Start from P2 area */
+    }
+}
+
+QEMUMachine r2d_machine = {
+    "r2d",
+    "r2d-plus board",
+    r2d_init
+};

Modified: trunk/src/host/qemu-neo1973/hw/sh7750.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/sh7750.c	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/hw/sh7750.c	2007-10-29 21:14:04 UTC (rev 3303)
@@ -1,6 +1,7 @@
 /*
  * SH7750 device
  *
+ * Copyright (c) 2007 Magnus Damm
  * Copyright (c) 2005 Samuel Tardieu
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -26,14 +27,8 @@
 #include "vl.h"
 #include "sh7750_regs.h"
 #include "sh7750_regnames.h"
+#include "sh_intc.h"
 
-typedef struct {
-    uint8_t data[16];
-    uint8_t length;		/* Number of characters in the FIFO */
-    uint8_t write_idx;		/* Index of first character to write */
-    uint8_t read_idx;		/* Index of first character to read */
-} fifo;
-
 #define NB_DEVICES 4
 
 typedef struct SH7750State {
@@ -43,34 +38,6 @@
     uint32_t periph_freq;
     /* SDRAM controller */
     uint16_t rfcr;
-    /* First serial port */
-    CharDriverState *serial1;
-    uint8_t scscr1;
-    uint8_t scsmr1;
-    uint8_t scbrr1;
-    uint8_t scssr1;
-    uint8_t scssr1_read;
-    uint8_t sctsr1;
-    uint8_t sctsr1_loaded;
-    uint8_t sctdr1;
-    uint8_t scrdr1;
-    /* Second serial port */
-    CharDriverState *serial2;
-    uint16_t sclsr2;
-    uint16_t scscr2;
-    uint16_t scfcr2;
-    uint16_t scfsr2;
-    uint16_t scsmr2;
-    uint8_t scbrr2;
-    fifo serial2_receive_fifo;
-    fifo serial2_transmit_fifo;
-    /* Timers */
-    uint8_t tstr;
-    /* Timer 0 */
-    QEMUTimer *timer0;
-    uint16_t tcr0;
-    uint32_t tcor0;
-    uint32_t tcnt0;
     /* IO ports */
     uint16_t gpioic;
     uint32_t pctra;
@@ -86,345 +53,16 @@
     uint16_t periph_pdtrb;	/* Imposed by the peripherals */
     uint16_t periph_portdirb;	/* Direction seen from the peripherals */
     sh7750_io_device *devices[NB_DEVICES];	/* External peripherals */
+
+    uint16_t icr;
     /* Cache */
     uint32_t ccr;
+
+    struct intc_desc intc;
 } SH7750State;
 
-/**********************************************************************
- Timers
-**********************************************************************/
 
-/* XXXXX At this time, timer0 works in underflow only mode, that is
-   the value of tcnt0 is read at alarm computation time and cannot
-   be read back by the guest OS */
-
-static void start_timer0(SH7750State * s)
-{
-    uint64_t now, next, prescaler;
-
-    if ((s->tcr0 & 6) == 6) {
-	fprintf(stderr, "rtc clock for timer 0 not supported\n");
-	assert(0);
-    }
-
-    if ((s->tcr0 & 7) == 5) {
-	fprintf(stderr, "timer 0 configuration not supported\n");
-	assert(0);
-    }
-
-    if ((s->tcr0 & 4) == 4)
-	prescaler = 1024;
-    else
-	prescaler = 4 << (s->tcr0 & 3);
-
-    now = qemu_get_clock(vm_clock);
-    /* XXXXX */
-    next =
-	now + muldiv64(prescaler * s->tcnt0, ticks_per_sec,
-		       s->periph_freq);
-    if (next == now)
-	next = now + 1;
-    fprintf(stderr, "now=%016" PRIx64 ", next=%016" PRIx64 "\n", now, next);
-    fprintf(stderr, "timer will underflow in %f seconds\n",
-	    (float) (next - now) / (float) ticks_per_sec);
-
-    qemu_mod_timer(s->timer0, next);
-}
-
-static void timer_start_changed(SH7750State * s)
-{
-    if (s->tstr & SH7750_TSTR_STR0) {
-	start_timer0(s);
-    } else {
-	fprintf(stderr, "timer 0 is stopped\n");
-	qemu_del_timer(s->timer0);
-    }
-}
-
-static void timer0_cb(void *opaque)
-{
-    SH7750State *s = opaque;
-
-    s->tcnt0 = (uint32_t) 0;	/* XXXXX */
-    if (--s->tcnt0 == (uint32_t) - 1) {
-	fprintf(stderr, "timer 0 underflow\n");
-	s->tcnt0 = s->tcor0;
-	s->tcr0 |= SH7750_TCR_UNF;
-	if (s->tcr0 & SH7750_TCR_UNIE) {
-	    fprintf(stderr,
-		    "interrupt generation for timer 0 not supported\n");
-	    assert(0);
-	}
-    }
-    start_timer0(s);
-}
-
-static void init_timers(SH7750State * s)
-{
-    s->tcor0 = 0xffffffff;
-    s->tcnt0 = 0xffffffff;
-    s->timer0 = qemu_new_timer(vm_clock, &timer0_cb, s);
-}
-
 /**********************************************************************
- First serial port
-**********************************************************************/
-
-static int serial1_can_receive(void *opaque)
-{
-    SH7750State *s = opaque;
-
-    return s->scscr1 & SH7750_SCSCR_RE;
-}
-
-static void serial1_receive_char(SH7750State * s, uint8_t c)
-{
-    if (s->scssr1 & SH7750_SCSSR1_RDRF) {
-	s->scssr1 |= SH7750_SCSSR1_ORER;
-	return;
-    }
-
-    s->scrdr1 = c;
-    s->scssr1 |= SH7750_SCSSR1_RDRF;
-}
-
-static void serial1_receive(void *opaque, const uint8_t * buf, int size)
-{
-    SH7750State *s = opaque;
-    int i;
-
-    for (i = 0; i < size; i++) {
-	serial1_receive_char(s, buf[i]);
-    }
-}
-
-static void serial1_event(void *opaque, int event)
-{
-    assert(0);
-}
-
-static void serial1_maybe_send(SH7750State * s)
-{
-    uint8_t c;
-
-    if (s->scssr1 & SH7750_SCSSR1_TDRE)
-	return;
-    c = s->sctdr1;
-    s->scssr1 |= SH7750_SCSSR1_TDRE | SH7750_SCSSR1_TEND;
-    if (s->scscr1 & SH7750_SCSCR_TIE) {
-	fprintf(stderr, "interrupts for serial port 1 not implemented\n");
-	assert(0);
-    }
-    /* XXXXX Check for errors in write */
-    qemu_chr_write(s->serial1, &c, 1);
-}
-
-static void serial1_change_scssr1(SH7750State * s, uint8_t mem_value)
-{
-    uint8_t new_flags;
-
-    /* If transmit disable, TDRE and TEND stays up */
-    if ((s->scscr1 & SH7750_SCSCR_TE) == 0) {
-	mem_value |= SH7750_SCSSR1_TDRE | SH7750_SCSSR1_TEND;
-    }
-
-    /* Only clear bits which have been read before and do not set any bit
-       in the flags */
-    new_flags = s->scssr1 & ~s->scssr1_read;	/* Preserve unread flags */
-    new_flags &= mem_value | ~s->scssr1_read;	/* Clear read flags */
-
-    s->scssr1 = (new_flags & 0xf8) | (mem_value & 1);
-    s->scssr1_read &= mem_value;
-
-    /* If TDRE has been cleared, TEND will also be cleared */
-    if ((s->scssr1 & SH7750_SCSSR1_TDRE) == 0) {
-	s->scssr1 &= ~SH7750_SCSSR1_TEND;
-    }
-
-    /* Check for transmission to start */
-    serial1_maybe_send(s);
-}
-
-static void serial1_update_parameters(SH7750State * s)
-{
-    QEMUSerialSetParams ssp;
-
-    if (s->scsmr1 & SH7750_SCSMR_CHR_7)
-	ssp.data_bits = 7;
-    else
-	ssp.data_bits = 8;
-    if (s->scsmr1 & SH7750_SCSMR_PE) {
-	if (s->scsmr1 & SH7750_SCSMR_PM_ODD)
-	    ssp.parity = 'O';
-	else
-	    ssp.parity = 'E';
-    } else
-	ssp.parity = 'N';
-    if (s->scsmr1 & SH7750_SCSMR_STOP_2)
-	ssp.stop_bits = 2;
-    else
-	ssp.stop_bits = 1;
-    fprintf(stderr, "SCSMR1=%04x SCBRR1=%02x\n", s->scsmr1, s->scbrr1);
-    ssp.speed = s->periph_freq /
-	(32 * s->scbrr1 * (1 << (2 * (s->scsmr1 & 3)))) - 1;
-    fprintf(stderr, "data bits=%d, stop bits=%d, parity=%c, speed=%d\n",
-	    ssp.data_bits, ssp.stop_bits, ssp.parity, ssp.speed);
-    qemu_chr_ioctl(s->serial1, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp);
-}
-
-static void scscr1_changed(SH7750State * s)
-{
-    if (s->scscr1 & (SH7750_SCSCR_TE | SH7750_SCSCR_RE)) {
-	if (!s->serial1) {
-	    fprintf(stderr, "serial port 1 not bound to anything\n");
-	    assert(0);
-	}
-	serial1_update_parameters(s);
-    }
-    if ((s->scscr1 & SH7750_SCSCR_RE) == 0) {
-	s->scssr1 |= SH7750_SCSSR1_TDRE;
-    }
-}
-
-static void init_serial1(SH7750State * s, int serial_nb)
-{
-    CharDriverState *chr;
-
-    s->scssr1 = 0x84;
-    chr = serial_hds[serial_nb];
-    if (!chr) {
-	fprintf(stderr,
-		"no serial port associated to SH7750 first serial port\n");
-	return;
-    }
-
-    s->serial1 = chr;
-    qemu_chr_add_handlers(chr, serial1_can_receive,
-			  serial1_receive, serial1_event, s);
-}
-
-/**********************************************************************
- Second serial port
-**********************************************************************/
-
-static int serial2_can_receive(void *opaque)
-{
-    SH7750State *s = opaque;
-    static uint8_t max_fifo_size[] = { 15, 1, 4, 6, 8, 10, 12, 14 };
-
-    return s->serial2_receive_fifo.length <
-	max_fifo_size[(s->scfcr2 >> 9) & 7];
-}
-
-static void serial2_adjust_receive_flags(SH7750State * s)
-{
-    static uint8_t max_fifo_size[] = { 1, 4, 8, 14 };
-
-    /* XXXXX Add interrupt generation */
-    if (s->serial2_receive_fifo.length >=
-	max_fifo_size[(s->scfcr2 >> 7) & 3]) {
-	s->scfsr2 |= SH7750_SCFSR2_RDF;
-	s->scfsr2 &= ~SH7750_SCFSR2_DR;
-    } else {
-	s->scfsr2 &= ~SH7750_SCFSR2_RDF;
-	if (s->serial2_receive_fifo.length > 0)
-	    s->scfsr2 |= SH7750_SCFSR2_DR;
-	else
-	    s->scfsr2 &= ~SH7750_SCFSR2_DR;
-    }
-}
-
-static void serial2_append_char(SH7750State * s, uint8_t c)
-{
-    if (s->serial2_receive_fifo.length == 16) {
-	/* Overflow */
-	s->sclsr2 |= SH7750_SCLSR2_ORER;
-	return;
-    }
-
-    s->serial2_receive_fifo.data[s->serial2_receive_fifo.write_idx++] = c;
-    s->serial2_receive_fifo.length++;
-    serial2_adjust_receive_flags(s);
-}
-
-static void serial2_receive(void *opaque, const uint8_t * buf, int size)
-{
-    SH7750State *s = opaque;
-    int i;
-
-    for (i = 0; i < size; i++)
-	serial2_append_char(s, buf[i]);
-}
-
-static void serial2_event(void *opaque, int event)
-{
-    /* XXXXX */
-    assert(0);
-}
-
-static void serial2_update_parameters(SH7750State * s)
-{
-    QEMUSerialSetParams ssp;
-
-    if (s->scsmr2 & SH7750_SCSMR_CHR_7)
-	ssp.data_bits = 7;
-    else
-	ssp.data_bits = 8;
-    if (s->scsmr2 & SH7750_SCSMR_PE) {
-	if (s->scsmr2 & SH7750_SCSMR_PM_ODD)
-	    ssp.parity = 'O';
-	else
-	    ssp.parity = 'E';
-    } else
-	ssp.parity = 'N';
-    if (s->scsmr2 & SH7750_SCSMR_STOP_2)
-	ssp.stop_bits = 2;
-    else
-	ssp.stop_bits = 1;
-    fprintf(stderr, "SCSMR2=%04x SCBRR2=%02x\n", s->scsmr2, s->scbrr2);
-    ssp.speed = s->periph_freq /
-	(32 * s->scbrr2 * (1 << (2 * (s->scsmr2 & 3)))) - 1;
-    fprintf(stderr, "data bits=%d, stop bits=%d, parity=%c, speed=%d\n",
-	    ssp.data_bits, ssp.stop_bits, ssp.parity, ssp.speed);
-    qemu_chr_ioctl(s->serial2, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp);
-}
-
-static void scscr2_changed(SH7750State * s)
-{
-    if (s->scscr2 & (SH7750_SCSCR_TE | SH7750_SCSCR_RE)) {
-	if (!s->serial2) {
-	    fprintf(stderr, "serial port 2 not bound to anything\n");
-	    assert(0);
-	}
-	serial2_update_parameters(s);
-    }
-}
-
-static void init_serial2(SH7750State * s, int serial_nb)
-{
-    CharDriverState *chr;
-
-    s->scfsr2 = 0x0060;
-
-    chr = serial_hds[serial_nb];
-    if (!chr) {
-	fprintf(stderr,
-		"no serial port associated to SH7750 second serial port\n");
-	return;
-    }
-
-    s->serial2 = chr;
-    qemu_chr_add_handlers(chr, serial2_can_receive,
-			  serial2_receive, serial1_event, s);
-}
-
-static void init_serial_ports(SH7750State * s)
-{
-    init_serial1(s, 0);
-    init_serial2(s, 1);
-}
-
-/**********************************************************************
  I/O ports
 **********************************************************************/
 
@@ -554,17 +192,7 @@
 
 static uint32_t sh7750_mem_readb(void *opaque, target_phys_addr_t addr)
 {
-    SH7750State *s = opaque;
-    uint8_t r;
-
     switch (addr) {
-    case SH7750_SCSSR1_A7:
-	r = s->scssr1;
-	s->scssr1_read |= r;
-	return s->scssr1;
-    case SH7750_SCRDR1_A7:
-	s->scssr1 &= ~SH7750_SCSSR1_RDRF;
-	return s->scrdr1;
     default:
 	error_access("byte read", addr);
 	assert(0);
@@ -574,26 +202,20 @@
 static uint32_t sh7750_mem_readw(void *opaque, target_phys_addr_t addr)
 {
     SH7750State *s = opaque;
-    uint16_t r;
 
     switch (addr) {
+    case SH7750_FRQCR_A7:
+	return 0;
     case SH7750_RFCR_A7:
 	fprintf(stderr,
 		"Read access to refresh count register, incrementing\n");
 	return s->rfcr++;
-    case SH7750_TCR0_A7:
-	return s->tcr0;
-    case SH7750_SCLSR2_A7:
-	/* Read and clear overflow bit */
-	r = s->sclsr2;
-	s->sclsr2 = 0;
-	return r;
-    case SH7750_SCSFR2_A7:
-	return s->scfsr2;
     case SH7750_PDTRA_A7:
 	return porta_lines(s);
     case SH7750_PDTRB_A7:
 	return portb_lines(s);
+    case 0x1fd00000:
+        return s->icr;
     default:
 	error_access("word read", addr);
 	assert(0);
@@ -638,38 +260,12 @@
 static void sh7750_mem_writeb(void *opaque, target_phys_addr_t addr,
 			      uint32_t mem_value)
 {
-    SH7750State *s = opaque;
-
     switch (addr) {
 	/* PRECHARGE ? XXXXX */
     case SH7750_PRECHARGE0_A7:
     case SH7750_PRECHARGE1_A7:
 	ignore_access("byte write", addr);
 	return;
-    case SH7750_SCBRR2_A7:
-	s->scbrr2 = mem_value;
-	return;
-    case SH7750_TSTR_A7:
-	s->tstr = mem_value;
-	timer_start_changed(s);
-	return;
-    case SH7750_SCSCR1_A7:
-	s->scscr1 = mem_value;
-	scscr1_changed(s);
-	return;
-    case SH7750_SCSMR1_A7:
-	s->scsmr1 = mem_value;
-	return;
-    case SH7750_SCBRR1_A7:
-	s->scbrr1 = mem_value;
-	return;
-    case SH7750_SCTDR1_A7:
-	s->scssr1 &= ~SH7750_SCSSR1_TEND;
-	s->sctdr1 = mem_value;
-	return;
-    case SH7750_SCSSR1_A7:
-	serial1_change_scssr1(s, mem_value);
-	return;
     default:
 	error_access("byte write", addr);
 	assert(0);
@@ -684,8 +280,6 @@
 
     switch (addr) {
 	/* SDRAM controller */
-    case SH7750_SCBRR1_A7:
-    case SH7750_SCBRR2_A7:
     case SH7750_BCR2_A7:
     case SH7750_BCR3_A7:
     case SH7750_RTCOR_A7:
@@ -708,22 +302,6 @@
 	fprintf(stderr, "Write access to refresh count register\n");
 	s->rfcr = mem_value;
 	return;
-    case SH7750_SCLSR2_A7:
-	s->sclsr2 = mem_value;
-	return;
-    case SH7750_SCSCR2_A7:
-	s->scscr2 = mem_value;
-	scscr2_changed(s);
-	return;
-    case SH7750_SCFCR2_A7:
-	s->scfcr2 = mem_value;
-	return;
-    case SH7750_SCSMR2_A7:
-	s->scsmr2 = mem_value;
-	return;
-    case SH7750_TCR0_A7:
-	s->tcr0 = mem_value;
-	return;
     case SH7750_GPIOIC_A7:
 	s->gpioic = mem_value;
 	if (mem_value != 0) {
@@ -731,6 +309,9 @@
 	    assert(0);
 	}
 	return;
+    case 0x1fd00000:
+        s->icr = mem_value;
+	return;
     default:
 	error_access("word write", addr);
 	assert(0);
@@ -768,9 +349,6 @@
 	s->portpullupb = portpullup(mem_value);
 	portb_changed(s, temp);
 	return;
-    case SH7750_TCNT0_A7:
-	s->tcnt0 = mem_value & 0xf;
-	return;
     case SH7750_MMUCR_A7:
 	s->cpu->mmucr = mem_value;
 	return;
@@ -816,10 +394,144 @@
     sh7750_mem_writel
 };
 
+/* sh775x interrupt controller tables for sh_intc.c
+ * stolen from linux/arch/sh/kernel/cpu/sh4/setup-sh7750.c
+ */
+
+enum {
+	UNUSED = 0,
+
+	/* interrupt sources */
+	IRL0, IRL1, IRL2, IRL3, /* only IRLM mode supported */
+	HUDI, GPIOI,
+	DMAC_DMTE0, DMAC_DMTE1, DMAC_DMTE2, DMAC_DMTE3,
+	DMAC_DMTE4, DMAC_DMTE5, DMAC_DMTE6, DMAC_DMTE7,
+	DMAC_DMAE,
+	PCIC0_PCISERR, PCIC1_PCIERR, PCIC1_PCIPWDWN, PCIC1_PCIPWON,
+	PCIC1_PCIDMA0, PCIC1_PCIDMA1, PCIC1_PCIDMA2, PCIC1_PCIDMA3,
+	TMU3, TMU4, TMU0, TMU1, TMU2_TUNI, TMU2_TICPI,
+	RTC_ATI, RTC_PRI, RTC_CUI,
+	SCI1_ERI, SCI1_RXI, SCI1_TXI, SCI1_TEI,
+	SCIF_ERI, SCIF_RXI, SCIF_BRI, SCIF_TXI,
+	WDT,
+	REF_RCMI, REF_ROVI,
+
+	/* interrupt groups */
+	DMAC, PCIC1, TMU2, RTC, SCI1, SCIF, REF,
+
+	NR_SOURCES,
+};
+
+static struct intc_vect vectors[] = {
+	INTC_VECT(HUDI, 0x600), INTC_VECT(GPIOI, 0x620),
+	INTC_VECT(TMU0, 0x400), INTC_VECT(TMU1, 0x420),
+	INTC_VECT(TMU2_TUNI, 0x440), INTC_VECT(TMU2_TICPI, 0x460),
+	INTC_VECT(RTC_ATI, 0x480), INTC_VECT(RTC_PRI, 0x4a0),
+	INTC_VECT(RTC_CUI, 0x4c0),
+	INTC_VECT(SCI1_ERI, 0x4e0), INTC_VECT(SCI1_RXI, 0x500),
+	INTC_VECT(SCI1_TXI, 0x520), INTC_VECT(SCI1_TEI, 0x540),
+	INTC_VECT(SCIF_ERI, 0x700), INTC_VECT(SCIF_RXI, 0x720),
+	INTC_VECT(SCIF_BRI, 0x740), INTC_VECT(SCIF_TXI, 0x760),
+	INTC_VECT(WDT, 0x560),
+	INTC_VECT(REF_RCMI, 0x580), INTC_VECT(REF_ROVI, 0x5a0),
+};
+
+static struct intc_group groups[] = {
+	INTC_GROUP(TMU2, TMU2_TUNI, TMU2_TICPI),
+	INTC_GROUP(RTC, RTC_ATI, RTC_PRI, RTC_CUI),
+	INTC_GROUP(SCI1, SCI1_ERI, SCI1_RXI, SCI1_TXI, SCI1_TEI),
+	INTC_GROUP(SCIF, SCIF_ERI, SCIF_RXI, SCIF_BRI, SCIF_TXI),
+	INTC_GROUP(REF, REF_RCMI, REF_ROVI),
+};
+
+static struct intc_prio_reg prio_registers[] = {
+	{ 0xffd00004, 0, 16, 4, /* IPRA */ { TMU0, TMU1, TMU2, RTC } },
+	{ 0xffd00008, 0, 16, 4, /* IPRB */ { WDT, REF, SCI1, 0 } },
+	{ 0xffd0000c, 0, 16, 4, /* IPRC */ { GPIOI, DMAC, SCIF, HUDI } },
+	{ 0xffd00010, 0, 16, 4, /* IPRD */ { IRL0, IRL1, IRL2, IRL3 } },
+	{ 0xfe080000, 0, 32, 4, /* INTPRI00 */ { 0, 0, 0, 0,
+						 TMU4, TMU3,
+						 PCIC1, PCIC0_PCISERR } },
+};
+
+/* SH7750, SH7750S, SH7751 and SH7091 all have 4-channel DMA controllers */
+
+static struct intc_vect vectors_dma4[] = {
+	INTC_VECT(DMAC_DMTE0, 0x640), INTC_VECT(DMAC_DMTE1, 0x660),
+	INTC_VECT(DMAC_DMTE2, 0x680), INTC_VECT(DMAC_DMTE3, 0x6a0),
+	INTC_VECT(DMAC_DMAE, 0x6c0),
+};
+
+static struct intc_group groups_dma4[] = {
+	INTC_GROUP(DMAC, DMAC_DMTE0, DMAC_DMTE1, DMAC_DMTE2,
+		   DMAC_DMTE3, DMAC_DMAE),
+};
+
+/* SH7750R and SH7751R both have 8-channel DMA controllers */
+
+static struct intc_vect vectors_dma8[] = {
+	INTC_VECT(DMAC_DMTE0, 0x640), INTC_VECT(DMAC_DMTE1, 0x660),
+	INTC_VECT(DMAC_DMTE2, 0x680), INTC_VECT(DMAC_DMTE3, 0x6a0),
+	INTC_VECT(DMAC_DMTE4, 0x780), INTC_VECT(DMAC_DMTE5, 0x7a0),
+	INTC_VECT(DMAC_DMTE6, 0x7c0), INTC_VECT(DMAC_DMTE7, 0x7e0),
+	INTC_VECT(DMAC_DMAE, 0x6c0),
+};
+
+static struct intc_group groups_dma8[] = {
+	INTC_GROUP(DMAC, DMAC_DMTE0, DMAC_DMTE1, DMAC_DMTE2,
+		   DMAC_DMTE3, DMAC_DMTE4, DMAC_DMTE5,
+		   DMAC_DMTE6, DMAC_DMTE7, DMAC_DMAE),
+};
+
+/* SH7750R, SH7751 and SH7751R all have two extra timer channels */
+
+static struct intc_vect vectors_tmu34[] = {
+	INTC_VECT(TMU3, 0xb00), INTC_VECT(TMU4, 0xb80),
+};
+
+static struct intc_mask_reg mask_registers[] = {
+	{ 0xfe080040, 0xfe080060, 32, /* INTMSK00 / INTMSKCLR00 */
+	  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	    0, 0, 0, 0, 0, 0, TMU4, TMU3,
+	    PCIC1_PCIERR, PCIC1_PCIPWDWN, PCIC1_PCIPWON,
+	    PCIC1_PCIDMA0, PCIC1_PCIDMA1, PCIC1_PCIDMA2,
+	    PCIC1_PCIDMA3, PCIC0_PCISERR } },
+};
+
+/* SH7750S, SH7750R, SH7751 and SH7751R all have IRLM priority registers */
+
+static struct intc_vect vectors_irlm[] = {
+	INTC_VECT(IRL0, 0x240), INTC_VECT(IRL1, 0x2a0),
+	INTC_VECT(IRL2, 0x300), INTC_VECT(IRL3, 0x360),
+};
+
+/* SH7751 and SH7751R both have PCI */
+
+static struct intc_vect vectors_pci[] = {
+	INTC_VECT(PCIC0_PCISERR, 0xa00), INTC_VECT(PCIC1_PCIERR, 0xae0),
+	INTC_VECT(PCIC1_PCIPWDWN, 0xac0), INTC_VECT(PCIC1_PCIPWON, 0xaa0),
+	INTC_VECT(PCIC1_PCIDMA0, 0xa80), INTC_VECT(PCIC1_PCIDMA1, 0xa60),
+	INTC_VECT(PCIC1_PCIDMA2, 0xa40), INTC_VECT(PCIC1_PCIDMA3, 0xa20),
+};
+
+static struct intc_group groups_pci[] = {
+	INTC_GROUP(PCIC1, PCIC1_PCIERR, PCIC1_PCIPWDWN, PCIC1_PCIPWON,
+		   PCIC1_PCIDMA0, PCIC1_PCIDMA1, PCIC1_PCIDMA2, PCIC1_PCIDMA3),
+};
+
+#define SH_CPU_SH7750  (1 << 0)
+#define SH_CPU_SH7750S (1 << 1)
+#define SH_CPU_SH7750R (1 << 2)
+#define SH_CPU_SH7751  (1 << 3)
+#define SH_CPU_SH7751R (1 << 4)
+#define SH_CPU_SH7750_ALL (SH_CPU_SH7750 | SH_CPU_SH7750S | SH_CPU_SH7750R)
+#define SH_CPU_SH7751_ALL (SH_CPU_SH7751 | SH_CPU_SH7751R)
+
 SH7750State *sh7750_init(CPUSH4State * cpu)
 {
     SH7750State *s;
     int sh7750_io_memory;
+    int cpu_model = SH_CPU_SH7751R; /* for now */
 
     s = qemu_mallocz(sizeof(SH7750State));
     s->cpu = cpu;
@@ -828,7 +540,54 @@
 					      sh7750_mem_read,
 					      sh7750_mem_write, s);
     cpu_register_physical_memory(0x1c000000, 0x04000000, sh7750_io_memory);
-    init_timers(s);
-    init_serial_ports(s);
+
+    sh_intc_init(&s->intc, NR_SOURCES,
+		 _INTC_ARRAY(mask_registers),
+		 _INTC_ARRAY(prio_registers));
+
+    sh_intc_register_sources(&s->intc, 
+			     _INTC_ARRAY(vectors),
+			     _INTC_ARRAY(groups));
+
+    sh_serial_init(0x1fe00000, 0, s->periph_freq, serial_hds[0]);
+    sh_serial_init(0x1fe80000, SH_SERIAL_FEAT_SCIF,
+		   s->periph_freq, serial_hds[1]);
+
+    tmu012_init(0x1fd80000,
+		TMU012_FEAT_TOCR | TMU012_FEAT_3CHAN | TMU012_FEAT_EXTCLK,
+		s->periph_freq);
+
+
+    if (cpu_model & (SH_CPU_SH7750 | SH_CPU_SH7750S | SH_CPU_SH7751)) {
+        sh_intc_register_sources(&s->intc, 
+				 _INTC_ARRAY(vectors_dma4),
+				 _INTC_ARRAY(groups_dma4));
+    }
+
+    if (cpu_model & (SH_CPU_SH7750R | SH_CPU_SH7751R)) {
+        sh_intc_register_sources(&s->intc, 
+				 _INTC_ARRAY(vectors_dma8),
+				 _INTC_ARRAY(groups_dma8));
+    }
+
+    if (cpu_model & (SH_CPU_SH7750R | SH_CPU_SH7751 | SH_CPU_SH7751R)) {
+        sh_intc_register_sources(&s->intc, 
+				 _INTC_ARRAY(vectors_tmu34),
+				 _INTC_ARRAY(NULL));
+        tmu012_init(0x1e100000, 0, s->periph_freq);
+    }
+
+    if (cpu_model & (SH_CPU_SH7751_ALL)) {
+        sh_intc_register_sources(&s->intc, 
+				 _INTC_ARRAY(vectors_pci),
+				 _INTC_ARRAY(groups_pci));
+    }
+
+    if (cpu_model & (SH_CPU_SH7750S | SH_CPU_SH7750R | SH_CPU_SH7751_ALL)) {
+        sh_intc_register_sources(&s->intc, 
+				 _INTC_ARRAY(vectors_irlm),
+				 _INTC_ARRAY(NULL));
+    }
+
     return s;
 }

Modified: trunk/src/host/qemu-neo1973/hw/sh7750_regnames.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/sh7750_regnames.c	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/hw/sh7750_regnames.c	2007-10-29 21:14:04 UTC (rev 3303)
@@ -42,18 +42,6 @@
 	REGNAME(SH7750_RMONAR_A7)
 	REGNAME(SH7750_RCR1_A7)
 	REGNAME(SH7750_RCR2_A7)
-	REGNAME(SH7750_TOCR_A7)
-	REGNAME(SH7750_TSTR_A7)
-	REGNAME(SH7750_TCOR0_A7)
-	REGNAME(SH7750_TCOR1_A7)
-	REGNAME(SH7750_TCOR2_A7)
-	REGNAME(SH7750_TCNT0_A7)
-	REGNAME(SH7750_TCNT1_A7)
-	REGNAME(SH7750_TCNT2_A7)
-	REGNAME(SH7750_TCR0_A7)
-	REGNAME(SH7750_TCR1_A7)
-	REGNAME(SH7750_TCR2_A7)
-	REGNAME(SH7750_TCPR2_A7)
 	REGNAME(SH7750_BCR1_A7)
 	REGNAME(SH7750_BCR2_A7)
 	REGNAME(SH7750_WCR1_A7)
@@ -82,33 +70,12 @@
 	REGNAME(SH7750_CHCR2_A7)
 	REGNAME(SH7750_CHCR3_A7)
 	REGNAME(SH7750_DMAOR_A7)
-	REGNAME(SH7750_SCRDR1_A7)
-	REGNAME(SH7750_SCRDR2_A7)
-	REGNAME(SH7750_SCTDR1_A7)
-	REGNAME(SH7750_SCTDR2_A7)
-	REGNAME(SH7750_SCSMR1_A7)
-	REGNAME(SH7750_SCSMR2_A7)
-	REGNAME(SH7750_SCSCR1_A7)
-	REGNAME(SH7750_SCSCR2_A7)
-	REGNAME(SH7750_SCSSR1_A7)
-	REGNAME(SH7750_SCSFR2_A7)
-	REGNAME(SH7750_SCSPTR1_A7)
-	REGNAME(SH7750_SCSPTR2_A7)
-	REGNAME(SH7750_SCBRR1_A7)
-	REGNAME(SH7750_SCBRR2_A7)
-	REGNAME(SH7750_SCFCR2_A7)
-	REGNAME(SH7750_SCFDR2_A7)
-	REGNAME(SH7750_SCLSR2_A7)
-	REGNAME(SH7750_SCSCMR1_A7)
 	REGNAME(SH7750_PCTRA_A7)
 	REGNAME(SH7750_PDTRA_A7)
 	REGNAME(SH7750_PCTRB_A7)
 	REGNAME(SH7750_PDTRB_A7)
 	REGNAME(SH7750_GPIOIC_A7)
 	REGNAME(SH7750_ICR_A7)
-	REGNAME(SH7750_IPRA_A7)
-	REGNAME(SH7750_IPRB_A7)
-	REGNAME(SH7750_IPRC_A7)
 	REGNAME(SH7750_BCR3_A7)
 	REGNAME(SH7750_BCR4_A7)
 	REGNAME(SH7750_PRECHARGE0_A7)

Modified: trunk/src/host/qemu-neo1973/hw/sh7750_regs.h
===================================================================
--- trunk/src/host/qemu-neo1973/hw/sh7750_regs.h	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/hw/sh7750_regs.h	2007-10-29 21:14:04 UTC (rev 3303)
@@ -524,95 +524,7 @@
 					   year counters are stopped
 					   1 - sec, min, hr, day-of-week, month,
 					   year counters operate normally */
-
-
 /*
- * Timer Unit (TMU)
- */
-/* Timer Output Control Register (byte) - TOCR */
-#define SH7750_TOCR_REGOFS    0xD80000	/* offset */
-#define SH7750_TOCR           SH7750_P4_REG32(SH7750_TOCR_REGOFS)
-#define SH7750_TOCR_A7        SH7750_A7_REG32(SH7750_TOCR_REGOFS)
-#define SH7750_TOCR_TCOE      0x01	/* Timer Clock Pin Control:
-					   0 - TCLK is used as external clock
-					   input or input capture control
-					   1 - TCLK is used as on-chip RTC
-					   output clock pin */
-
-/* Timer Start Register (byte) - TSTR */
-#define SH7750_TSTR_REGOFS    0xD80004	/* offset */
-#define SH7750_TSTR           SH7750_P4_REG32(SH7750_TSTR_REGOFS)
-#define SH7750_TSTR_A7        SH7750_A7_REG32(SH7750_TSTR_REGOFS)
-#define SH7750_TSTR_STR2      0x04	/* TCNT2 performs count operations */
-#define SH7750_TSTR_STR1      0x02	/* TCNT1 performs count operations */
-#define SH7750_TSTR_STR0      0x01	/* TCNT0 performs count operations */
-#define SH7750_TSTR_STR(n)    (1 << (n))
-
-/* Timer Constant Register - TCOR0, TCOR1, TCOR2 */
-#define SH7750_TCOR_REGOFS(n) (0xD80008 + ((n)*12))	/* offset */
-#define SH7750_TCOR(n)        SH7750_P4_REG32(SH7750_TCOR_REGOFS(n))
-#define SH7750_TCOR_A7(n)     SH7750_A7_REG32(SH7750_TCOR_REGOFS(n))
-#define SH7750_TCOR0          SH7750_TCOR(0)
-#define SH7750_TCOR1          SH7750_TCOR(1)
-#define SH7750_TCOR2          SH7750_TCOR(2)
-#define SH7750_TCOR0_A7       SH7750_TCOR_A7(0)
-#define SH7750_TCOR1_A7       SH7750_TCOR_A7(1)
-#define SH7750_TCOR2_A7       SH7750_TCOR_A7(2)
-
-/* Timer Counter Register - TCNT0, TCNT1, TCNT2 */
-#define SH7750_TCNT_REGOFS(n) (0xD8000C + ((n)*12))	/* offset */
-#define SH7750_TCNT(n)        SH7750_P4_REG32(SH7750_TCNT_REGOFS(n))
-#define SH7750_TCNT_A7(n)     SH7750_A7_REG32(SH7750_TCNT_REGOFS(n))
-#define SH7750_TCNT0          SH7750_TCNT(0)
-#define SH7750_TCNT1          SH7750_TCNT(1)
-#define SH7750_TCNT2          SH7750_TCNT(2)
-#define SH7750_TCNT0_A7       SH7750_TCNT_A7(0)
-#define SH7750_TCNT1_A7       SH7750_TCNT_A7(1)
-#define SH7750_TCNT2_A7       SH7750_TCNT_A7(2)
-
-/* Timer Control Register (half) - TCR0, TCR1, TCR2 */
-#define SH7750_TCR_REGOFS(n)  (0xD80010 + ((n)*12))	/* offset */
-#define SH7750_TCR(n)         SH7750_P4_REG32(SH7750_TCR_REGOFS(n))
-#define SH7750_TCR_A7(n)      SH7750_A7_REG32(SH7750_TCR_REGOFS(n))
-#define SH7750_TCR0           SH7750_TCR(0)
-#define SH7750_TCR1           SH7750_TCR(1)
-#define SH7750_TCR2           SH7750_TCR(2)
-#define SH7750_TCR0_A7        SH7750_TCR_A7(0)
-#define SH7750_TCR1_A7        SH7750_TCR_A7(1)
-#define SH7750_TCR2_A7        SH7750_TCR_A7(2)
-
-#define SH7750_TCR2_ICPF       0x200	/* Input Capture Interrupt Flag
-					   (1 - input capture has occured) */
-#define SH7750_TCR_UNF         0x100	/* Underflow flag */
-#define SH7750_TCR2_ICPE       0x0C0	/* Input Capture Control: */
-#define SH7750_TCR2_ICPE_DIS   0x000	/*   Input Capture function is not used */
-#define SH7750_TCR2_ICPE_NOINT 0x080	/*   Input Capture function is used, but
-					   input capture interrupt is not
-					   enabled */
-#define SH7750_TCR2_ICPE_INT   0x0C0	/*   Input Capture function is used,
-					   input capture interrupt enabled */
-#define SH7750_TCR_UNIE        0x020	/* Underflow Interrupt Control
-					   (1 - underflow interrupt enabled) */
-#define SH7750_TCR_CKEG        0x018	/* Clock Edge selection: */
-#define SH7750_TCR_CKEG_RAISE  0x000	/*   Count/capture on rising edge */
-#define SH7750_TCR_CKEG_FALL   0x008	/*   Count/capture on falling edge */
-#define SH7750_TCR_CKEG_BOTH   0x018	/*   Count/capture on both rising and
-					   falling edges */
-#define SH7750_TCR_TPSC         0x007	/* Timer prescaler */
-#define SH7750_TCR_TPSC_DIV4    0x000	/*   Counts on peripheral clock/4 */
-#define SH7750_TCR_TPSC_DIV16   0x001	/*   Counts on peripheral clock/16 */
-#define SH7750_TCR_TPSC_DIV64   0x002	/*   Counts on peripheral clock/64 */
-#define SH7750_TCR_TPSC_DIV256  0x003	/*   Counts on peripheral clock/256 */
-#define SH7750_TCR_TPSC_DIV1024 0x004	/*   Counts on peripheral clock/1024 */
-#define SH7750_TCR_TPSC_RTC     0x006	/*   Counts on on-chip RTC output clk */
-#define SH7750_TCR_TPSC_EXT     0x007	/*   Counts on external clock */
-
-/* Input Capture Register (read-only) - TCPR2 */
-#define SH7750_TCPR2_REGOFS   0xD8002C	/* offset */
-#define SH7750_TCPR2          SH7750_P4_REG32(SH7750_TCPR2_REGOFS)
-#define SH7750_TCPR2_A7       SH7750_A7_REG32(SH7750_TCPR2_REGOFS)
-
-/*
  * Bus State Controller - BSC
  */
 /* Bus Control Register 1 - BCR1 */
@@ -1257,231 +1169,6 @@
 #define SH7750_DMAOR_DME      0x00000001	/* DMAC Master Enable */
 
 /*
- * Serial Communication Interface - SCI
- * Serial Communication Interface with FIFO - SCIF
- */
-/* SCI Receive Data Register (byte, read-only) - SCRDR1, SCFRDR2 */
-#define SH7750_SCRDR_REGOFS(n) ((n) == 1 ? 0xE00014 : 0xE80014)	/* offset */
-#define SH7750_SCRDR(n)       SH7750_P4_REG32(SH7750_SCRDR_REGOFS(n))
-#define SH7750_SCRDR1         SH7750_SCRDR(1)
-#define SH7750_SCRDR2         SH7750_SCRDR(2)
-#define SH7750_SCRDR_A7(n)    SH7750_A7_REG32(SH7750_SCRDR_REGOFS(n))
-#define SH7750_SCRDR1_A7      SH7750_SCRDR_A7(1)
-#define SH7750_SCRDR2_A7      SH7750_SCRDR_A7(2)
-
-/* SCI Transmit Data Register (byte) - SCTDR1, SCFTDR2 */
-#define SH7750_SCTDR_REGOFS(n) ((n) == 1 ? 0xE0000C : 0xE8000C)	/* offset */
-#define SH7750_SCTDR(n)       SH7750_P4_REG32(SH7750_SCTDR_REGOFS(n))
-#define SH7750_SCTDR1         SH7750_SCTDR(1)
-#define SH7750_SCTDR2         SH7750_SCTDR(2)
-#define SH7750_SCTDR_A7(n)    SH7750_A7_REG32(SH7750_SCTDR_REGOFS(n))
-#define SH7750_SCTDR1_A7      SH7750_SCTDR_A7(1)
-#define SH7750_SCTDR2_A7      SH7750_SCTDR_A7(2)
-
-/* SCI Serial Mode Register - SCSMR1(byte), SCSMR2(half) */
-#define SH7750_SCSMR_REGOFS(n) ((n) == 1 ? 0xE00000 : 0xE80000)	/* offset */
-#define SH7750_SCSMR(n)       SH7750_P4_REG32(SH7750_SCSMR_REGOFS(n))
-#define SH7750_SCSMR1         SH7750_SCSMR(1)
-#define SH7750_SCSMR2         SH7750_SCSMR(2)
-#define SH7750_SCSMR_A7(n)    SH7750_A7_REG32(SH7750_SCSMR_REGOFS(n))
-#define SH7750_SCSMR1_A7      SH7750_SCSMR_A7(1)
-#define SH7750_SCSMR2_A7      SH7750_SCSMR_A7(2)
-
-#define SH7750_SCSMR1_CA       0x80	/* Communication Mode (C/A\): */
-#define SH7750_SCSMR1_CA_ASYNC 0x00	/*     Asynchronous Mode */
-#define SH7750_SCSMR1_CA_SYNC  0x80	/*     Synchronous Mode */
-#define SH7750_SCSMR_CHR       0x40	/* Character Length: */
-#define SH7750_SCSMR_CHR_8     0x00	/*     8-bit data */
-#define SH7750_SCSMR_CHR_7     0x40	/*     7-bit data */
-#define SH7750_SCSMR_PE        0x20	/* Parity Enable */
-#define SH7750_SCSMR_PM        0x10	/* Parity Mode: */
-#define SH7750_SCSMR_PM_EVEN   0x00	/*     Even Parity */
-#define SH7750_SCSMR_PM_ODD    0x10	/*     Odd Parity */
-#define SH7750_SCSMR_STOP      0x08	/* Stop Bit Length: */
-#define SH7750_SCSMR_STOP_1    0x00	/*     1 stop bit */
-#define SH7750_SCSMR_STOP_2    0x08	/*     2 stop bit */
-#define SH7750_SCSMR1_MP       0x04	/* Multiprocessor Mode */
-#define SH7750_SCSMR_CKS       0x03	/* Clock Select */
-#define SH7750_SCSMR_CKS_S     0
-#define SH7750_SCSMR_CKS_DIV1  0x00	/*     Periph clock */
-#define SH7750_SCSMR_CKS_DIV4  0x01	/*     Periph clock / 4 */
-#define SH7750_SCSMR_CKS_DIV16 0x02	/*     Periph clock / 16 */
-#define SH7750_SCSMR_CKS_DIV64 0x03	/*     Periph clock / 64 */
-
-/* SCI Serial Control Register - SCSCR1(byte), SCSCR2(half) */
-#define SH7750_SCSCR_REGOFS(n) ((n) == 1 ? 0xE00008 : 0xE80008)	/* offset */
-#define SH7750_SCSCR(n)       SH7750_P4_REG32(SH7750_SCSCR_REGOFS(n))
-#define SH7750_SCSCR1         SH7750_SCSCR(1)
-#define SH7750_SCSCR2         SH7750_SCSCR(2)
-#define SH7750_SCSCR_A7(n)    SH7750_A7_REG32(SH7750_SCSCR_REGOFS(n))
-#define SH7750_SCSCR1_A7      SH7750_SCSCR_A7(1)
-#define SH7750_SCSCR2_A7      SH7750_SCSCR_A7(2)
-
-#define SH7750_SCSCR_TIE      0x80	/* Transmit Interrupt Enable */
-#define SH7750_SCSCR_RIE      0x40	/* Receive Interrupt Enable */
-#define SH7750_SCSCR_TE       0x20	/* Transmit Enable */
-#define SH7750_SCSCR_RE       0x10	/* Receive Enable */
-#define SH7750_SCSCR1_MPIE    0x08	/* Multiprocessor Interrupt Enable */
-#define SH7750_SCSCR2_REIE    0x08	/* Receive Error Interrupt Enable */
-#define SH7750_SCSCR1_TEIE    0x04	/* Transmit End Interrupt Enable */
-#define SH7750_SCSCR1_CKE     0x03	/* Clock Enable: */
-#define SH7750_SCSCR_CKE_INTCLK            0x00	/* Use Internal Clock */
-#define SH7750_SCSCR_CKE_EXTCLK            0x02	/* Use External Clock from SCK */
-#define SH7750_SCSCR1_CKE_ASYNC_SCK_CLKOUT 0x01	/* Use SCK as a clock output
-						   in asynchronous mode */
-
-/* SCI Serial Status Register - SCSSR1(byte), SCSFR2(half) */
-#define SH7750_SCSSR_REGOFS(n) ((n) == 1 ? 0xE00010 : 0xE80010)	/* offset */
-#define SH7750_SCSSR(n)       SH7750_P4_REG32(SH7750_SCSSR_REGOFS(n))
-#define SH7750_SCSSR1         SH7750_SCSSR(1)
-#define SH7750_SCSFR2         SH7750_SCSSR(2)
-#define SH7750_SCSSR_A7(n)    SH7750_A7_REG32(SH7750_SCSSR_REGOFS(n))
-#define SH7750_SCSSR1_A7      SH7750_SCSSR_A7(1)
-#define SH7750_SCSFR2_A7      SH7750_SCSSR_A7(2)
-
-#define SH7750_SCSSR1_TDRE    0x80	/* Transmit Data Register Empty */
-#define SH7750_SCSSR1_RDRF    0x40	/* Receive Data Register Full */
-#define SH7750_SCSSR1_ORER    0x20	/* Overrun Error */
-#define SH7750_SCSSR1_FER     0x10	/* Framing Error */
-#define SH7750_SCSSR1_PER     0x08	/* Parity Error */
-#define SH7750_SCSSR1_TEND    0x04	/* Transmit End */
-#define SH7750_SCSSR1_MPB     0x02	/* Multiprocessor Bit */
-#define SH7750_SCSSR1_MPBT    0x01	/* Multiprocessor Bit Transfer */
-
-#define SH7750_SCFSR2_PERN    0xF000	/* Number of Parity Errors */
-#define SH7750_SCFSR2_PERN_S  12
-#define SH7750_SCFSR2_FERN    0x0F00	/* Number of Framing Errors */
-#define SH7750_SCFSR2_FERN_S  8
-#define SH7750_SCFSR2_ER      0x0080	/* Receive Error */
-#define SH7750_SCFSR2_TEND    0x0040	/* Transmit End */
-#define SH7750_SCFSR2_TDFE    0x0020	/* Transmit FIFO Data Empty */
-#define SH7750_SCFSR2_BRK     0x0010	/* Break Detect */
-#define SH7750_SCFSR2_FER     0x0008	/* Framing Error */
-#define SH7750_SCFSR2_PER     0x0004	/* Parity Error */
-#define SH7750_SCFSR2_RDF     0x0002	/* Receive FIFO Data Full */
-#define SH7750_SCFSR2_DR      0x0001	/* Receive Data Ready */
-
-/* SCI Serial Port Register - SCSPTR1(byte) */
-#define SH7750_SCSPTR1_REGOFS 0xE0001C	/* offset */
-#define SH7750_SCSPTR1        SH7750_P4_REG32(SH7750_SCSPTR1_REGOFS)
-#define SH7750_SCSPTR1_A7     SH7750_A7_REG32(SH7750_SCSPTR1_REGOFS)
-
-#define SH7750_SCSPTR1_EIO    0x80	/* Error Interrupt Only */
-#define SH7750_SCSPTR1_SPB1IO 0x08	/* 1: Output SPB1DT bit to SCK pin */
-#define SH7750_SCSPTR1_SPB1DT 0x04	/* Serial Port Clock Port Data */
-#define SH7750_SCSPTR1_SPB0IO 0x02	/* 1: Output SPB0DT bit to TxD pin */
-#define SH7750_SCSPTR1_SPB0DT 0x01	/* Serial Port Break Data */
-
-/* SCIF Serial Port Register - SCSPTR2(half) */
-#define SH7750_SCSPTR2_REGOFS 0xE80020	/* offset */
-#define SH7750_SCSPTR2        SH7750_P4_REG32(SH7750_SCSPTR2_REGOFS)
-#define SH7750_SCSPTR2_A7     SH7750_A7_REG32(SH7750_SCSPTR2_REGOFS)
-
-#define SH7750_SCSPTR2_RTSIO  0x80	/* 1: Output RTSDT bit to RTS2\ pin */
-#define SH7750_SCSPTR2_RTSDT  0x40	/* RTS Port Data */
-#define SH7750_SCSPTR2_CTSIO  0x20	/* 1: Output CTSDT bit to CTS2\ pin */
-#define SH7750_SCSPTR2_CTSDT  0x10	/* CTS Port Data */
-#define SH7750_SCSPTR2_SPB2IO 0x02	/* 1: Output SPBDT bit to TxD2 pin */
-#define SH7750_SCSPTR2_SPB2DT 0x01	/* Serial Port Break Data */
-
-/* SCI Bit Rate Register - SCBRR1(byte), SCBRR2(byte) */
-#define SH7750_SCBRR_REGOFS(n) ((n) == 1 ? 0xE00004 : 0xE80004)	/* offset */
-#define SH7750_SCBRR(n)       SH7750_P4_REG32(SH7750_SCBRR_REGOFS(n))
-#define SH7750_SCBRR1         SH7750_SCBRR_P4(1)
-#define SH7750_SCBRR2         SH7750_SCBRR_P4(2)
-#define SH7750_SCBRR_A7(n)    SH7750_A7_REG32(SH7750_SCBRR_REGOFS(n))
-#define SH7750_SCBRR1_A7      SH7750_SCBRR_A7(1)
-#define SH7750_SCBRR2_A7      SH7750_SCBRR_A7(2)
-
-/* SCIF FIFO Control Register - SCFCR2(half) */
-#define SH7750_SCFCR2_REGOFS  0xE80018	/* offset */
-#define SH7750_SCFCR2         SH7750_P4_REG32(SH7750_SCFCR2_REGOFS)
-#define SH7750_SCFCR2_A7      SH7750_A7_REG32(SH7750_SCFCR2_REGOFS)
-
-#define SH7750_SCFCR2_RSTRG   0x700	/* RTS2\ Output Active Trigger; RTS2\
-					   signal goes to high level when the
-					   number of received data stored in
-					   FIFO exceeds the trigger number */
-#define SH7750_SCFCR2_RSTRG_15 0x000	/* 15 bytes */
-#define SH7750_SCFCR2_RSTRG_1  0x000	/* 1 byte */
-#define SH7750_SCFCR2_RSTRG_4  0x000	/* 4 bytes */
-#define SH7750_SCFCR2_RSTRG_6  0x000	/* 6 bytes */
-#define SH7750_SCFCR2_RSTRG_8  0x000	/* 8 bytes */
-#define SH7750_SCFCR2_RSTRG_10 0x000	/* 10 bytes */
-#define SH7750_SCFCR2_RSTRG_14 0x000	/* 14 bytes */
-
-#define SH7750_SCFCR2_RTRG    0x0C0	/* Receive FIFO Data Number Trigger,
-					   Receive Data Full (RDF) Flag sets
-					   when number of receive data bytes is
-					   equal or greater than the trigger
-					   number */
-#define SH7750_SCFCR2_RTRG_1  0x000	/* 1 byte */
-#define SH7750_SCFCR2_RTRG_4  0x040	/* 4 bytes */
-#define SH7750_SCFCR2_RTRG_8  0x080	/* 8 bytes */
-#define SH7750_SCFCR2_RTRG_14 0x0C0	/* 14 bytes */
-
-#define SH7750_SCFCR2_TTRG    0x030	/* Transmit FIFO Data Number Trigger,
-					   Transmit FIFO Data Register Empty (TDFE)
-					   flag sets when the number of remaining
-					   transmit data bytes is equal or less
-					   than the trigger number */
-#define SH7750_SCFCR2_TTRG_8  0x000	/* 8 bytes */
-#define SH7750_SCFCR2_TTRG_4  0x010	/* 4 bytes */
-#define SH7750_SCFCR2_TTRG_2  0x020	/* 2 bytes */
-#define SH7750_SCFCR2_TTRG_1  0x030	/* 1 byte */
-
-#define SH7750_SCFCR2_MCE     0x008	/* Modem Control Enable */
-#define SH7750_SCFCR2_TFRST   0x004	/* Transmit FIFO Data Register Reset,
-					   invalidates the transmit data in the
-					   transmit FIFO */
-#define SH7750_SCFCR2_RFRST   0x002	/* Receive FIFO Data Register Reset,
-					   invalidates the receive data in the
-					   receive FIFO data register and resets
-					   it to the empty state */
-#define SH7750_SCFCR2_LOOP    0x001	/* Loopback Test */
-
-/* SCIF FIFO Data Count Register - SCFDR2(half, read-only) */
-#define SH7750_SCFDR2_REGOFS  0xE8001C	/* offset */
-#define SH7750_SCFDR2         SH7750_P4_REG32(SH7750_SCFDR2_REGOFS)
-#define SH7750_SCFDR2_A7      SH7750_A7_REG32(SH7750_SCFDR2_REGOFS)
-
-#define SH7750_SCFDR2_T       0x1F00	/* Number of untransmitted data bytes
-					   in transmit FIFO */
-#define SH7750_SCFDR2_T_S     8
-#define SH7750_SCFDR2_R       0x001F	/* Number of received data bytes in
-					   receive FIFO */
-#define SH7750_SCFDR2_R_S     0
-
-/* SCIF Line Status Register - SCLSR2(half, read-only) */
-#define SH7750_SCLSR2_REGOFS  0xE80024	/* offset */
-#define SH7750_SCLSR2         SH7750_P4_REG32(SH7750_SCLSR2_REGOFS)
-#define SH7750_SCLSR2_A7      SH7750_A7_REG32(SH7750_SCLSR2_REGOFS)
-
-#define SH7750_SCLSR2_ORER    0x0001	/* Overrun Error */
-
-/*
- * SCI-based Smart Card Interface
- */
-/* Smart Card Mode Register - SCSCMR1(byte) */
-#define SH7750_SCSCMR1_REGOFS 0xE00018	/* offset */
-#define SH7750_SCSCMR1        SH7750_P4_REG32(SH7750_SCSCMR1_REGOFS)
-#define SH7750_SCSCMR1_A7     SH7750_A7_REG32(SH7750_SCSCMR1_REGOFS)
-
-#define SH7750_SCSCMR1_SDIR   0x08	/* Smart Card Data Transfer Direction: */
-#define SH7750_SCSCMR1_SDIR_LSBF 0x00	/* LSB-first */
-#define SH7750_SCSCMR1_SDIR_MSBF 0x08	/* MSB-first */
-
-#define SH7750_SCSCMR1_SINV   0x04	/* Smart Card Data Inversion */
-#define SH7750_SCSCMR1_SMIF   0x01	/* Smart Card Interface Mode Select */
-
-/* Smart-card specific bits in other registers */
-/* SCSMR1: */
-#define SH7750_SCSMR1_GSM     0x80	/* GSM mode select */
-
-/* SCSSR1: */
-#define SH7750_SCSSR1_ERS     0x10	/* Error Signal Status */
-
-/*
  * I/O Ports
  */
 /* Port Control Register A - PCTRA */
@@ -1554,48 +1241,6 @@
 #define SH7750_ICR_IRLM_RAW   0x0080	/*   IRL\ pins used as a four independent
 					   interrupt requests */
 
-/* Interrupt Priority Register A - IPRA (half) */
-#define SH7750_IPRA_REGOFS    0xD00004	/* offset */
-#define SH7750_IPRA           SH7750_P4_REG32(SH7750_IPRA_REGOFS)
-#define SH7750_IPRA_A7        SH7750_A7_REG32(SH7750_IPRA_REGOFS)
-
-#define SH7750_IPRA_TMU0      0xF000	/* TMU0 interrupt priority */
-#define SH7750_IPRA_TMU0_S    12
-#define SH7750_IPRA_TMU1      0x0F00	/* TMU1 interrupt priority */
-#define SH7750_IPRA_TMU1_S    8
-#define SH7750_IPRA_TMU2      0x00F0	/* TMU2 interrupt priority */
-#define SH7750_IPRA_TMU2_S    4
-#define SH7750_IPRA_RTC       0x000F	/* RTC interrupt priority */
-#define SH7750_IPRA_RTC_S     0
-
-/* Interrupt Priority Register B - IPRB (half) */
-#define SH7750_IPRB_REGOFS    0xD00008	/* offset */
-#define SH7750_IPRB           SH7750_P4_REG32(SH7750_IPRB_REGOFS)
-#define SH7750_IPRB_A7        SH7750_A7_REG32(SH7750_IPRB_REGOFS)
-
-#define SH7750_IPRB_WDT       0xF000	/* WDT interrupt priority */
-#define SH7750_IPRB_WDT_S     12
-#define SH7750_IPRB_REF       0x0F00	/* Memory Refresh unit interrupt
-					   priority */
-#define SH7750_IPRB_REF_S     8
-#define SH7750_IPRB_SCI1      0x00F0	/* SCI1 interrupt priority */
-#define SH7750_IPRB_SCI1_S    4
-
-/* Interrupt Priority Register ó - IPRó (half) */
-#define SH7750_IPRC_REGOFS    0xD00004	/* offset */
-#define SH7750_IPRC           SH7750_P4_REG32(SH7750_IPRC_REGOFS)
-#define SH7750_IPRC_A7        SH7750_A7_REG32(SH7750_IPRC_REGOFS)
-
-#define SH7750_IPRC_GPIO      0xF000	/* GPIO interrupt priority */
-#define SH7750_IPRC_GPIO_S    12
-#define SH7750_IPRC_DMAC      0x0F00	/* DMAC interrupt priority */
-#define SH7750_IPRC_DMAC_S    8
-#define SH7750_IPRC_SCIF      0x00F0	/* SCIF interrupt priority */
-#define SH7750_IPRC_SCIF_S    4
-#define SH7750_IPRC_HUDI      0x000F	/* H-UDI interrupt priority */
-#define SH7750_IPRC_HUDI_S    0
-
-
 /*
  * User Break Controller registers
  */

Added: trunk/src/host/qemu-neo1973/hw/sh_intc.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/sh_intc.c	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/hw/sh_intc.c	2007-10-29 21:14:04 UTC (rev 3303)
@@ -0,0 +1,383 @@
+/*
+ * SuperH interrupt controller module
+ *
+ * Copyright (c) 2007 Magnus Damm
+ * Based on sh_timer.c and arm_timer.c by Paul Brook
+ * Copyright (c) 2005-2006 CodeSourcery.
+ *
+ * This code is licenced under the GPL.
+ */
+
+#include <assert.h>
+#include "sh_intc.h"
+#include "vl.h"
+
+//#define DEBUG_INTC
+
+#define INTC_A7(x) ((x) & 0x1fffffff)
+#define INTC_ARRAY(x) (sizeof(x) / sizeof(x[0]))
+
+#define INTC_MODE_NONE       0
+#define INTC_MODE_DUAL_SET   1
+#define INTC_MODE_DUAL_CLR   2
+#define INTC_MODE_ENABLE_REG 3
+#define INTC_MODE_MASK_REG   4
+#define INTC_MODE_IS_PRIO    8
+
+static unsigned int sh_intc_mode(unsigned long address,
+				 unsigned long set_reg, unsigned long clr_reg)
+{
+    if ((address != INTC_A7(set_reg)) &&
+	(address != INTC_A7(clr_reg)))
+        return INTC_MODE_NONE;
+
+    if (set_reg && clr_reg) {
+        if (address == INTC_A7(set_reg))
+            return INTC_MODE_DUAL_SET;
+	else
+            return INTC_MODE_DUAL_CLR;
+    }
+
+    if (set_reg)
+        return INTC_MODE_ENABLE_REG;
+    else
+        return INTC_MODE_MASK_REG;
+}
+
+static void sh_intc_locate(struct intc_desc *desc,
+			   unsigned long address,
+			   unsigned long **datap,
+			   intc_enum **enums,
+			   unsigned int *first,
+			   unsigned int *width,
+			   unsigned int *modep)
+{
+    unsigned int i, mode;
+
+    /* this is slow but works for now */
+
+    if (desc->mask_regs) {
+        for (i = 0; i < desc->nr_mask_regs; i++) {
+	    struct intc_mask_reg *mr = desc->mask_regs + i;
+
+	    mode = sh_intc_mode(address, mr->set_reg, mr->clr_reg);
+	    if (mode == INTC_MODE_NONE)
+                continue;
+
+	    *modep = mode;
+	    *datap = &mr->value;
+	    *enums = mr->enum_ids;
+	    *first = mr->reg_width - 1;
+	    *width = 1;
+	    return;
+	}
+    }
+
+    if (desc->prio_regs) {
+        for (i = 0; i < desc->nr_prio_regs; i++) {
+	    struct intc_prio_reg *pr = desc->prio_regs + i;
+
+	    mode = sh_intc_mode(address, pr->set_reg, pr->clr_reg);
+	    if (mode == INTC_MODE_NONE)
+                continue;
+
+	    *modep = mode | INTC_MODE_IS_PRIO;
+	    *datap = &pr->value;
+	    *enums = pr->enum_ids;
+	    *first = (pr->reg_width / pr->field_width) - 1;
+	    *width = pr->field_width;
+	    return;
+	}
+    }
+
+    assert(0);
+}
+
+static void sh_intc_toggle(struct intc_desc *desc, intc_enum id,
+			   int enable, int is_group)
+{
+    struct intc_source *source = desc->sources + id;
+    int old = source->enable_count;
+
+    if (!id)
+	return;
+
+    if (!source->next_enum_id && (!source->enable_max || !source->vect)) {
+#ifdef DEBUG_INTC
+        printf("sh_intc: reserved interrupt source %d modified\n", id);
+#endif
+	return;
+    }
+
+    if (source->vect) {
+        if (enable)
+            source->enable_count++;
+	else 
+            source->enable_count--;
+
+        if (source->enable_count == source->enable_max) {
+#ifdef DEBUG_INTC
+            printf("sh_intc: enabling interrupt source %d -> 0x%04x\n",
+		   id, source->vect);
+#endif
+	}
+
+        if (old == source->enable_max) {
+#ifdef DEBUG_INTC
+            printf("sh_intc: disabling interrupt source %d -> 0x%04x\n",
+		   id, source->vect);
+#endif
+	}
+    }
+#ifdef DEBUG_INTC
+    else {
+        printf("setting interrupt group %d to %d\n", id, !!enable);
+    }
+#endif
+
+    if ((is_group || !source->vect) && source->next_enum_id) {
+        sh_intc_toggle(desc, source->next_enum_id, enable, 1);
+    }
+
+#ifdef DEBUG_INTC
+    if (!source->vect) {
+        printf("setting interrupt group %d to %d - done\n", id, !!enable);
+    }
+#endif
+}
+
+static uint32_t sh_intc_read(void *opaque, target_phys_addr_t offset)
+{
+    struct intc_desc *desc = opaque;
+    intc_enum *enum_ids = NULL;
+    unsigned int first = 0;
+    unsigned int width = 0;
+    unsigned int mode = 0;
+    unsigned long *valuep;
+
+#ifdef DEBUG_INTC
+    printf("sh_intc_read 0x%lx\n", (unsigned long) offset);
+#endif
+
+    sh_intc_locate(desc, (unsigned long)offset, &valuep, 
+		   &enum_ids, &first, &width, &mode);
+    return *valuep;
+}
+
+static void sh_intc_write(void *opaque, target_phys_addr_t offset,
+			  uint32_t value)
+{
+    struct intc_desc *desc = opaque;
+    intc_enum *enum_ids = NULL;
+    unsigned int first = 0;
+    unsigned int width = 0;
+    unsigned int mode = 0;
+    unsigned int k;
+    unsigned long *valuep;
+    unsigned long mask;
+
+#ifdef DEBUG_INTC
+    printf("sh_intc_write 0x%lx 0x%08x\n", (unsigned long) offset, value);
+#endif
+
+    sh_intc_locate(desc, (unsigned long)offset, &valuep, 
+		   &enum_ids, &first, &width, &mode);
+
+    switch (mode) {
+    case INTC_MODE_ENABLE_REG | INTC_MODE_IS_PRIO: break;
+    case INTC_MODE_DUAL_SET: value |= *valuep; break;
+    case INTC_MODE_DUAL_CLR: value = *valuep & ~value; break;
+    default: assert(0);
+    }
+
+    for (k = 0; k <= first; k++) {
+        mask = ((1 << width) - 1) << ((first - k) * width);
+
+	if ((*valuep & mask) == (value & mask))
+            continue;
+#if 0
+	printf("k = %d, first = %d, enum = %d, mask = 0x%08x\n", 
+	       k, first, enum_ids[k], (unsigned int)mask);
+#endif
+        sh_intc_toggle(desc, enum_ids[k], value & mask, 0);
+    }
+
+    *valuep = value;
+
+#ifdef DEBUG_INTC
+    printf("sh_intc_write 0x%lx -> 0x%08x\n", (unsigned long) offset, value);
+#endif
+}
+
+static CPUReadMemoryFunc *sh_intc_readfn[] = {
+    sh_intc_read,
+    sh_intc_read,
+    sh_intc_read
+};
+
+static CPUWriteMemoryFunc *sh_intc_writefn[] = {
+    sh_intc_write,
+    sh_intc_write,
+    sh_intc_write
+};
+
+struct intc_source *sh_intc_source(struct intc_desc *desc, intc_enum id)
+{
+    if (id)
+        return desc->sources + id;
+
+    return NULL;
+}
+
+static void sh_intc_register(struct intc_desc *desc, 
+			     unsigned long address)
+{
+    if (address)
+        cpu_register_physical_memory(INTC_A7(address), 4, desc->iomemtype);
+}
+
+static void sh_intc_register_source(struct intc_desc *desc,
+				    intc_enum source,
+				    struct intc_group *groups,
+				    int nr_groups)
+{
+    unsigned int i, k;
+    struct intc_source *s;
+
+    if (desc->mask_regs) {
+        for (i = 0; i < desc->nr_mask_regs; i++) {
+	    struct intc_mask_reg *mr = desc->mask_regs + i;
+
+	    for (k = 0; k < INTC_ARRAY(mr->enum_ids); k++) {
+                if (mr->enum_ids[k] != source)
+                    continue;
+
+		s = sh_intc_source(desc, mr->enum_ids[k]);
+		if (s)
+                    s->enable_max++;
+	    }
+	}
+    }
+
+    if (desc->prio_regs) {
+        for (i = 0; i < desc->nr_prio_regs; i++) {
+	    struct intc_prio_reg *pr = desc->prio_regs + i;
+
+	    for (k = 0; k < INTC_ARRAY(pr->enum_ids); k++) {
+                if (pr->enum_ids[k] != source)
+                    continue;
+
+		s = sh_intc_source(desc, pr->enum_ids[k]);
+		if (s)
+                    s->enable_max++;
+	    }
+	}
+    }
+
+    if (groups) {
+        for (i = 0; i < nr_groups; i++) {
+	    struct intc_group *gr = groups + i;
+
+	    for (k = 0; k < INTC_ARRAY(gr->enum_ids); k++) {
+                if (gr->enum_ids[k] != source)
+                    continue;
+
+		s = sh_intc_source(desc, gr->enum_ids[k]);
+		if (s)
+                    s->enable_max++;
+	    }
+	}
+    }
+
+}
+
+void sh_intc_register_sources(struct intc_desc *desc,
+			      struct intc_vect *vectors,
+			      int nr_vectors,
+			      struct intc_group *groups,
+			      int nr_groups)
+{
+    unsigned int i, k;
+    struct intc_source *s;
+
+    for (i = 0; i < nr_vectors; i++) {
+	struct intc_vect *vect = vectors + i;
+
+	sh_intc_register_source(desc, vect->enum_id, groups, nr_groups);
+	s = sh_intc_source(desc, vect->enum_id);
+	if (s)
+	    s->vect = vect->vect;
+
+#ifdef DEBUG_INTC
+	printf("sh_intc: registered source %d -> 0x%04x (%d/%d)\n",
+	       vect->enum_id, s->vect, s->enable_count, s->enable_max);
+#endif
+    }
+
+    if (groups) {
+        for (i = 0; i < nr_groups; i++) {
+	    struct intc_group *gr = groups + i;
+
+	    s = sh_intc_source(desc, gr->enum_id);
+	    s->next_enum_id = gr->enum_ids[0];
+
+	    for (k = 1; k < INTC_ARRAY(gr->enum_ids); k++) {
+                if (!gr->enum_ids[k])
+                    continue;
+
+		s = sh_intc_source(desc, gr->enum_ids[k - 1]);
+		s->next_enum_id = gr->enum_ids[k];
+	    }
+
+#ifdef DEBUG_INTC
+	    printf("sh_intc: registered group %d (%d/%d)\n",
+		   gr->enum_id, s->enable_count, s->enable_max);
+#endif
+	}
+    }
+}
+
+int sh_intc_init(struct intc_desc *desc,
+		 int nr_sources,
+		 struct intc_mask_reg *mask_regs,
+		 int nr_mask_regs,
+		 struct intc_prio_reg *prio_regs,
+		 int nr_prio_regs)
+{
+    unsigned int i;
+
+    desc->nr_sources = nr_sources;
+    desc->mask_regs = mask_regs;
+    desc->nr_mask_regs = nr_mask_regs;
+    desc->prio_regs = prio_regs;
+    desc->nr_prio_regs = nr_prio_regs;
+
+    i = sizeof(struct intc_source) * nr_sources;
+    desc->sources = malloc(i);
+    if (!desc->sources)
+        return -1;
+
+    memset(desc->sources, 0, i);
+ 
+    desc->iomemtype = cpu_register_io_memory(0, sh_intc_readfn,
+					     sh_intc_writefn, desc);
+    if (desc->mask_regs) {
+        for (i = 0; i < desc->nr_mask_regs; i++) {
+	    struct intc_mask_reg *mr = desc->mask_regs + i;
+
+	    sh_intc_register(desc, mr->set_reg);
+	    sh_intc_register(desc, mr->clr_reg);
+	}
+    }
+
+    if (desc->prio_regs) {
+        for (i = 0; i < desc->nr_prio_regs; i++) {
+	    struct intc_prio_reg *pr = desc->prio_regs + i;
+
+	    sh_intc_register(desc, pr->set_reg);
+	    sh_intc_register(desc, pr->clr_reg);
+	}
+    }
+
+    return 0;
+}

Added: trunk/src/host/qemu-neo1973/hw/sh_intc.h
===================================================================
--- trunk/src/host/qemu-neo1973/hw/sh_intc.h	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/hw/sh_intc.h	2007-10-29 21:14:04 UTC (rev 3303)
@@ -0,0 +1,69 @@
+#ifndef __SH_INTC_H__
+#define __SH_INTC_H__
+
+typedef unsigned char intc_enum;
+
+struct intc_vect {
+    intc_enum enum_id;
+    unsigned short vect;
+};
+
+#define INTC_VECT(enum_id, vect) { enum_id, vect }
+
+struct intc_group {
+    intc_enum enum_id;
+    intc_enum enum_ids[32];
+};
+
+#define INTC_GROUP(enum_id, ids...) { enum_id, { ids } }
+
+struct intc_mask_reg {
+    unsigned long set_reg, clr_reg, reg_width;
+    intc_enum enum_ids[32];
+    unsigned long value;
+};
+
+struct intc_prio_reg {
+    unsigned long set_reg, clr_reg, reg_width, field_width;
+    intc_enum enum_ids[16];
+    unsigned long value;
+};
+
+#define _INTC_ARRAY(a) a, sizeof(a)/sizeof(*a)
+
+struct intc_source {
+    unsigned short vect;
+    intc_enum next_enum_id;
+
+    int asserted;
+    int enable_count;
+    int enable_max;
+};
+
+struct intc_desc {
+    struct intc_source *sources;
+    int nr_sources;
+    struct intc_mask_reg *mask_regs;
+    int nr_mask_regs;
+    struct intc_prio_reg *prio_regs;
+    int nr_prio_regs;
+
+    int iomemtype;
+};
+
+struct intc_source *sh_intc_source(struct intc_desc *desc, intc_enum id);
+
+void sh_intc_register_sources(struct intc_desc *desc,
+			      struct intc_vect *vectors,
+			      int nr_vectors,
+			      struct intc_group *groups,
+			      int nr_groups);
+
+int sh_intc_init(struct intc_desc *desc,
+		 int nr_sources,
+		 struct intc_mask_reg *mask_regs,
+		 int nr_mask_regs,
+		 struct intc_prio_reg *prio_regs,
+		 int nr_prio_regs);
+
+#endif /* __SH_INTC_H__ */

Added: trunk/src/host/qemu-neo1973/hw/sh_serial.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/sh_serial.c	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/hw/sh_serial.c	2007-10-29 21:14:04 UTC (rev 3303)
@@ -0,0 +1,315 @@
+/*
+ * QEMU SCI/SCIF serial port emulation
+ *
+ * Copyright (c) 2007 Magnus Damm
+ *
+ * Based on serial.c - QEMU 16450 UART emulation
+ * Copyright (c) 2003-2004 Fabrice Bellard
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include "vl.h"
+#include <assert.h>
+
+//#define DEBUG_SERIAL
+
+#define SH_SERIAL_FLAG_TEND (1 << 0)
+#define SH_SERIAL_FLAG_TDE  (1 << 1)
+#define SH_SERIAL_FLAG_RDF  (1 << 2)
+#define SH_SERIAL_FLAG_BRK  (1 << 3)
+#define SH_SERIAL_FLAG_DR   (1 << 4)
+
+typedef struct {
+    uint8_t smr;
+    uint8_t brr;
+    uint8_t scr;
+    uint8_t dr; /* ftdr / tdr */
+    uint8_t sr; /* fsr / ssr */
+    uint16_t fcr;
+    uint8_t sptr;
+
+    uint8_t rx_fifo[16]; /* frdr / rdr */
+    uint8_t rx_cnt;
+
+    target_phys_addr_t base;
+    int freq;
+    int feat;
+    int flags;
+
+    CharDriverState *chr;
+} sh_serial_state;
+
+static void sh_serial_ioport_write(void *opaque, uint32_t offs, uint32_t val)
+{
+    sh_serial_state *s = opaque;
+    unsigned char ch;
+
+#ifdef DEBUG_SERIAL
+    printf("sh_serial: write base=0x%08lx offs=0x%02x val=0x%02x\n",
+	   (unsigned long) s->base, offs, val);
+#endif
+    switch(offs) {
+    case 0x00: /* SMR */
+        s->smr = val & ((s->feat & SH_SERIAL_FEAT_SCIF) ? 0x7b : 0xff);
+        return;
+    case 0x04: /* BRR */
+        s->brr = val;
+	return;
+    case 0x08: /* SCR */
+        s->scr = val & ((s->feat & SH_SERIAL_FEAT_SCIF) ? 0xfb : 0xff);
+        if (!(val & (1 << 5)))
+            s->flags |= SH_SERIAL_FLAG_TEND;
+        return;
+    case 0x0c: /* FTDR / TDR */
+        if (s->chr) {
+            ch = val;
+            qemu_chr_write(s->chr, &ch, 1);
+	}
+	s->dr = val;
+	s->flags &= ~SH_SERIAL_FLAG_TDE;
+        return;
+#if 0
+    case 0x14: /* FRDR / RDR */
+        ret = 0;
+        break;
+#endif
+    }
+    if (s->feat & SH_SERIAL_FEAT_SCIF) {
+        switch(offs) {
+        case 0x10: /* FSR */
+            if (!(val & (1 << 6)))
+                s->flags &= ~SH_SERIAL_FLAG_TEND;
+            if (!(val & (1 << 5)))
+                s->flags &= ~SH_SERIAL_FLAG_TDE;
+            if (!(val & (1 << 4)))
+                s->flags &= ~SH_SERIAL_FLAG_BRK;
+            if (!(val & (1 << 1)))
+                s->flags &= ~SH_SERIAL_FLAG_RDF;
+            if (!(val & (1 << 0)))
+                s->flags &= ~SH_SERIAL_FLAG_DR;
+            return;
+        case 0x18: /* FCR */
+            s->fcr = val;
+            return;
+        case 0x20: /* SPTR */
+            s->sptr = val;
+            return;
+        case 0x24: /* LSR */
+            return;
+        }
+    }
+    else {
+#if 0
+        switch(offs) {
+        case 0x0c:
+            ret = s->dr;
+            break;
+        case 0x10:
+            ret = 0;
+            break;
+        case 0x1c:
+            ret = s->sptr;
+            break;
+        }
+#endif
+    }
+
+    fprintf(stderr, "sh_serial: unsupported write to 0x%02x\n", offs);
+    assert(0);
+}
+
+static uint32_t sh_serial_ioport_read(void *opaque, uint32_t offs)
+{
+    sh_serial_state *s = opaque;
+    uint32_t ret = ~0;
+
+#if 0
+    switch(offs) {
+    case 0x00:
+        ret = s->smr;
+        break;
+    case 0x04:
+        ret = s->brr;
+	break;
+    case 0x08:
+        ret = s->scr;
+        break;
+    case 0x14:
+        ret = 0;
+        break;
+    }
+#endif
+    if (s->feat & SH_SERIAL_FEAT_SCIF) {
+        switch(offs) {
+        case 0x10: /* FSR */
+            ret = 0;
+            if (s->flags & SH_SERIAL_FLAG_TEND)
+                ret |= (1 << 6);
+            if (s->flags & SH_SERIAL_FLAG_TDE)
+                ret |= (1 << 5);
+            if (s->flags & SH_SERIAL_FLAG_BRK)
+                ret |= (1 << 4);
+            if (s->flags & SH_SERIAL_FLAG_RDF)
+                ret |= (1 << 1);
+            if (s->flags & SH_SERIAL_FLAG_DR)
+                ret |= (1 << 0);
+
+	    if (s->scr & (1 << 5))
+                s->flags |= SH_SERIAL_FLAG_TDE | SH_SERIAL_FLAG_TEND;
+
+            break;
+#if 0
+        case 0x18:
+            ret = s->fcr;
+            break;
+#endif
+        case 0x1c:
+            ret = s->rx_cnt;
+            break;
+        case 0x20:
+            ret = s->sptr;
+            break;
+        case 0x24:
+            ret = 0;
+            break;
+        }
+    }
+    else {
+#if 0
+        switch(offs) {
+        case 0x0c:
+            ret = s->dr;
+            break;
+        case 0x10:
+            ret = 0;
+            break;
+        case 0x1c:
+            ret = s->sptr;
+            break;
+        }
+#endif
+    }
+#ifdef DEBUG_SERIAL
+    printf("sh_serial: read base=0x%08lx offs=0x%02x val=0x%x\n",
+	   (unsigned long) s->base, offs, ret);
+#endif
+
+    if (ret & ~((1 << 16) - 1)) {
+        fprintf(stderr, "sh_serial: unsupported read from 0x%02x\n", offs);
+	assert(0);
+    }
+
+    return ret;
+}
+
+static int sh_serial_can_receive(sh_serial_state *s)
+{
+    return 0;
+}
+
+static void sh_serial_receive_byte(sh_serial_state *s, int ch)
+{
+}
+
+static void sh_serial_receive_break(sh_serial_state *s)
+{
+}
+
+static int sh_serial_can_receive1(void *opaque)
+{
+    sh_serial_state *s = opaque;
+    return sh_serial_can_receive(s);
+}
+
+static void sh_serial_receive1(void *opaque, const uint8_t *buf, int size)
+{
+    sh_serial_state *s = opaque;
+    sh_serial_receive_byte(s, buf[0]);
+}
+
+static void sh_serial_event(void *opaque, int event)
+{
+    sh_serial_state *s = opaque;
+    if (event == CHR_EVENT_BREAK)
+        sh_serial_receive_break(s);
+}
+
+uint32_t sh_serial_read (void *opaque, target_phys_addr_t addr)
+{
+    sh_serial_state *s = opaque;
+    return sh_serial_ioport_read(s, addr - s->base);
+}
+
+void sh_serial_write (void *opaque,
+		      target_phys_addr_t addr, uint32_t value)
+{
+    sh_serial_state *s = opaque;
+    sh_serial_ioport_write(s, addr - s->base, value);
+}
+
+static CPUReadMemoryFunc *sh_serial_readfn[] = {
+    &sh_serial_read,
+    &sh_serial_read,
+    &sh_serial_read,
+};
+
+static CPUWriteMemoryFunc *sh_serial_writefn[] = {
+    &sh_serial_write,
+    &sh_serial_write,
+    &sh_serial_write,
+};
+
+void sh_serial_init (target_phys_addr_t base, int feat,
+		     uint32_t freq, CharDriverState *chr)
+{
+    sh_serial_state *s;
+    int s_io_memory;
+
+    s = qemu_mallocz(sizeof(sh_serial_state));
+    if (!s)
+        return;
+
+    s->base = base;
+    s->feat = feat;
+    s->flags = SH_SERIAL_FLAG_TEND | SH_SERIAL_FLAG_TDE;
+
+    s->smr = 0;
+    s->brr = 0xff;
+    s->scr = 0;
+    s->sptr = 0;
+
+    if (feat & SH_SERIAL_FEAT_SCIF) {
+        s->fcr = 0;
+    }
+    else {
+        s->dr = 0xff;
+    }
+
+    s->rx_cnt = 0;
+
+    s_io_memory = cpu_register_io_memory(0, sh_serial_readfn,
+					 sh_serial_writefn, s);
+    cpu_register_physical_memory(base, 0x28, s_io_memory);
+
+    s->chr = chr;
+
+    if (chr)
+        qemu_chr_add_handlers(chr, sh_serial_can_receive1, sh_serial_receive1,
+			      sh_serial_event, s);
+}

Added: trunk/src/host/qemu-neo1973/hw/sh_timer.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/sh_timer.c	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/hw/sh_timer.c	2007-10-29 21:14:04 UTC (rev 3303)
@@ -0,0 +1,323 @@
+/*
+ * SuperH Timer modules.
+ *
+ * Copyright (c) 2007 Magnus Damm
+ * Based on arm_timer.c by Paul Brook
+ * Copyright (c) 2005-2006 CodeSourcery.
+ *
+ * This code is licenced under the GPL.
+ */
+
+#include "vl.h"
+
+//#define DEBUG_TIMER
+
+#define TIMER_TCR_TPSC          (7 << 0)
+#define TIMER_TCR_CKEG          (3 << 3)
+#define TIMER_TCR_UNIE          (1 << 5)
+#define TIMER_TCR_ICPE          (3 << 6)
+#define TIMER_TCR_UNF           (1 << 8)
+#define TIMER_TCR_ICPF          (1 << 9)
+#define TIMER_TCR_RESERVED      (0x3f << 10)
+
+#define TIMER_FEAT_CAPT   (1 << 0)
+#define TIMER_FEAT_EXTCLK (1 << 1)
+
+typedef struct {
+    ptimer_state *timer;
+    uint32_t tcnt;
+    uint32_t tcor;
+    uint32_t tcr;
+    uint32_t tcpr;
+    int freq;
+    int int_level;
+    int feat;
+    int enabled;
+    qemu_irq irq;
+} sh_timer_state;
+
+/* Check all active timers, and schedule the next timer interrupt. */
+
+static void sh_timer_update(sh_timer_state *s)
+{
+#if 0 /* not yet */
+    /* Update interrupts.  */
+    if (s->int_level && (s->tcr & TIMER_TCR_UNIE)) {
+        qemu_irq_raise(s->irq);
+    } else {
+        qemu_irq_lower(s->irq);
+    }
+#endif
+}
+
+uint32_t sh_timer_read(void *opaque, target_phys_addr_t offset)
+{
+    sh_timer_state *s = (sh_timer_state *)opaque;
+
+    switch (offset >> 2) {
+    case 0:
+        return s->tcor;
+    case 1:
+        return ptimer_get_count(s->timer);
+    case 2:
+        return s->tcr | (s->int_level ? TIMER_TCR_UNF : 0);
+    case 3:
+        if (s->feat & TIMER_FEAT_CAPT)
+            return s->tcpr;
+    default:
+        cpu_abort (cpu_single_env, "sh_timer_read: Bad offset %x\n",
+                   (int)offset);
+        return 0;
+    }
+}
+
+static void sh_timer_write(void *opaque, target_phys_addr_t offset,
+                            uint32_t value)
+{
+    sh_timer_state *s = (sh_timer_state *)opaque;
+    int freq;
+
+    switch (offset >> 2) {
+    case 0:
+        s->tcor = value;
+        ptimer_set_limit(s->timer, s->tcor, 0);
+        break;
+    case 1:
+        s->tcnt = value;
+        ptimer_set_count(s->timer, s->tcnt);
+        break;
+    case 2:
+        if (s->enabled) {
+            /* Pause the timer if it is running.  This may cause some
+               inaccuracy dure to rounding, but avoids a whole lot of other
+               messyness.  */
+            ptimer_stop(s->timer);
+        }
+        freq = s->freq;
+        /* ??? Need to recalculate expiry time after changing divisor.  */
+        switch (value & TIMER_TCR_TPSC) {
+        case 0: freq >>= 2; break;
+        case 1: freq >>= 4; break;
+        case 2: freq >>= 6; break;
+        case 3: freq >>= 8; break;
+        case 4: freq >>= 10; break;
+	case 6:
+	case 7: if (s->feat & TIMER_FEAT_EXTCLK) break;
+	default: cpu_abort (cpu_single_env,
+			   "sh_timer_write: Reserved TPSC value\n"); break;
+        }
+        switch ((value & TIMER_TCR_CKEG) >> 3) {
+	case 0: break;
+        case 1:
+        case 2:
+        case 3: if (s->feat & TIMER_FEAT_EXTCLK) break;
+	default: cpu_abort (cpu_single_env,
+			   "sh_timer_write: Reserved CKEG value\n"); break;
+        }
+        switch ((value & TIMER_TCR_ICPE) >> 6) {
+	case 0: break;
+        case 2:
+        case 3: if (s->feat & TIMER_FEAT_CAPT) break;
+	default: cpu_abort (cpu_single_env,
+			   "sh_timer_write: Reserved ICPE value\n"); break;
+        }
+	if ((value & TIMER_TCR_UNF) == 0)
+            s->int_level = 0;
+
+	value &= ~TIMER_TCR_UNF;
+
+	if ((value & TIMER_TCR_ICPF) && (!(s->feat & TIMER_FEAT_CAPT)))
+            cpu_abort (cpu_single_env,
+		       "sh_timer_write: Reserved ICPF value\n");
+
+	value &= ~TIMER_TCR_ICPF; /* capture not supported */
+
+	if (value & TIMER_TCR_RESERVED)
+            cpu_abort (cpu_single_env,
+		       "sh_timer_write: Reserved TCR bits set\n");
+        s->tcr = value;
+        ptimer_set_limit(s->timer, s->tcor, 0);
+        ptimer_set_freq(s->timer, freq);
+        if (s->enabled) {
+            /* Restart the timer if still enabled.  */
+            ptimer_run(s->timer, 0);
+        }
+        break;
+    case 3:
+        if (s->feat & TIMER_FEAT_CAPT) {
+            s->tcpr = value;
+	    break;
+	}
+    default:
+        cpu_abort (cpu_single_env, "sh_timer_write: Bad offset %x\n",
+                   (int)offset);
+    }
+    sh_timer_update(s);
+}
+
+static void sh_timer_start_stop(void *opaque, int enable)
+{
+    sh_timer_state *s = (sh_timer_state *)opaque;
+
+#ifdef DEBUG_TIMER
+    printf("sh_timer_start_stop %d (%d)\n", enable, s->enabled);
+#endif
+
+    if (s->enabled && !enable) {
+        ptimer_stop(s->timer);
+    }
+    if (!s->enabled && enable) {
+        ptimer_run(s->timer, 0);
+    }
+    s->enabled = !!enable;
+
+#ifdef DEBUG_TIMER
+    printf("sh_timer_start_stop done %d\n", s->enabled);
+#endif
+}
+
+static void sh_timer_tick(void *opaque)
+{
+    sh_timer_state *s = (sh_timer_state *)opaque;
+    s->int_level = s->enabled;
+    sh_timer_update(s);
+}
+
+static void *sh_timer_init(uint32_t freq, int feat)
+{
+    sh_timer_state *s;
+    QEMUBH *bh;
+
+    s = (sh_timer_state *)qemu_mallocz(sizeof(sh_timer_state));
+    s->freq = freq;
+    s->feat = feat;
+    s->tcor = 0xffffffff;
+    s->tcnt = 0xffffffff;
+    s->tcpr = 0xdeadbeef;
+    s->tcor = 0;
+    s->enabled = 0;
+
+    bh = qemu_bh_new(sh_timer_tick, s);
+    s->timer = ptimer_init(bh);
+    /* ??? Save/restore.  */
+    return s;
+}
+
+typedef struct {
+    void *timer[3];
+    int level[3];
+    uint32_t tocr;
+    uint32_t tstr;
+    target_phys_addr_t base;
+    int feat;
+} tmu012_state;
+
+static uint32_t tmu012_read(void *opaque, target_phys_addr_t offset)
+{
+    tmu012_state *s = (tmu012_state *)opaque;
+
+#ifdef DEBUG_TIMER
+    printf("tmu012_read 0x%lx\n", (unsigned long) offset);
+#endif
+    offset -= s->base;
+
+    if (offset >= 0x20) {
+        if (!(s->feat & TMU012_FEAT_3CHAN))
+	    cpu_abort (cpu_single_env, "tmu012_write: Bad channel offset %x\n",
+		       (int)offset);
+        return sh_timer_read(s->timer[2], offset - 0x20);
+    }
+
+    if (offset >= 0x14)
+        return sh_timer_read(s->timer[1], offset - 0x14);
+
+    if (offset >= 0x08)
+        return sh_timer_read(s->timer[0], offset - 0x08);
+
+    if (offset == 4)
+        return s->tstr;
+
+    if ((s->feat & TMU012_FEAT_TOCR) && offset == 0)
+        return s->tocr;
+
+    cpu_abort (cpu_single_env, "tmu012_write: Bad offset %x\n",
+	       (int)offset);
+    return 0;
+}
+
+static void tmu012_write(void *opaque, target_phys_addr_t offset,
+                        uint32_t value)
+{
+    tmu012_state *s = (tmu012_state *)opaque;
+
+#ifdef DEBUG_TIMER
+    printf("tmu012_write 0x%lx 0x%08x\n", (unsigned long) offset, value);
+#endif
+    offset -= s->base;
+
+    if (offset >= 0x20) {
+        if (!(s->feat & TMU012_FEAT_3CHAN))
+	    cpu_abort (cpu_single_env, "tmu012_write: Bad channel offset %x\n",
+		       (int)offset);
+        sh_timer_write(s->timer[2], offset - 0x20, value);
+	return;
+    }
+
+    if (offset >= 0x14) {
+        sh_timer_write(s->timer[1], offset - 0x14, value);
+	return;
+    }
+
+    if (offset >= 0x08) {
+        sh_timer_write(s->timer[0], offset - 0x08, value);
+	return;
+    }
+
+    if (offset == 4) {
+        sh_timer_start_stop(s->timer[0], value & (1 << 0));
+        sh_timer_start_stop(s->timer[1], value & (1 << 1));
+        if (s->feat & TMU012_FEAT_3CHAN)
+            sh_timer_start_stop(s->timer[2], value & (1 << 2));
+	else
+            if (value & (1 << 2))
+                cpu_abort (cpu_single_env, "tmu012_write: Bad channel\n");
+
+	s->tstr = value;
+	return;
+    }
+
+    if ((s->feat & TMU012_FEAT_TOCR) && offset == 0) {
+        s->tocr = value & (1 << 0);
+    }
+}
+
+static CPUReadMemoryFunc *tmu012_readfn[] = {
+    tmu012_read,
+    tmu012_read,
+    tmu012_read
+};
+
+static CPUWriteMemoryFunc *tmu012_writefn[] = {
+    tmu012_write,
+    tmu012_write,
+    tmu012_write
+};
+
+void tmu012_init(uint32_t base, int feat, uint32_t freq)
+{
+    int iomemtype;
+    tmu012_state *s;
+    int timer_feat = (feat & TMU012_FEAT_EXTCLK) ? TIMER_FEAT_EXTCLK : 0;
+
+    s = (tmu012_state *)qemu_mallocz(sizeof(tmu012_state));
+    s->base = base;
+    s->feat = feat;
+    s->timer[0] = sh_timer_init(freq, timer_feat);
+    s->timer[1] = sh_timer_init(freq, timer_feat);
+    if (feat & TMU012_FEAT_3CHAN)
+        s->timer[2] = sh_timer_init(freq, timer_feat | TIMER_FEAT_CAPT);
+    iomemtype = cpu_register_io_memory(0, tmu012_readfn,
+                                       tmu012_writefn, s);
+    cpu_register_physical_memory(base, 0x00001000, iomemtype);
+    /* ??? Save/restore.  */
+}

Modified: trunk/src/host/qemu-neo1973/hw/shix.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/shix.c	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/hw/shix.c	2007-10-29 21:14:04 UTC (rev 3303)
@@ -83,12 +83,14 @@
     cpu_register_physical_memory(0x0c000000, 0x01000000, 0x01004000);
 
     /* Load BIOS in 0 (and access it through P2, 0xA0000000) */
-    printf("%s: load BIOS '%s'\n", __func__, BIOS_FILENAME);
-    ret = load_image(BIOS_FILENAME, phys_ram_base);
+    if (bios_name == NULL)
+        bios_name = BIOS_FILENAME;
+    printf("%s: load BIOS '%s'\n", __func__, bios_name);
+    ret = load_image(bios_name, phys_ram_base);
     if (ret < 0) {		/* Check bios size */
 	fprintf(stderr, "ret=%d\n", ret);
 	fprintf(stderr, "qemu: could not load SHIX bios '%s'\n",
-		BIOS_FILENAME);
+		bios_name);
 	exit(1);
     }
 

Modified: trunk/src/host/qemu-neo1973/hw/slavio_intctl.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/slavio_intctl.c	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/hw/slavio_intctl.c	2007-10-29 21:14:04 UTC (rev 3303)
@@ -100,21 +100,21 @@
     DPRINTF("write cpu %d reg 0x" TARGET_FMT_plx " = %x\n", cpu, addr, val);
     switch (saddr) {
     case 1: // clear pending softints
-	if (val & 0x4000)
-	    val |= 80000000;
-	val &= 0xfffe0000;
-	s->intreg_pending[cpu] &= ~val;
+        if (val & 0x4000)
+            val |= 80000000;
+        val &= 0xfffe0000;
+        s->intreg_pending[cpu] &= ~val;
         slavio_check_interrupts(s);
-	DPRINTF("Cleared cpu %d irq mask %x, curmask %x\n", cpu, val, s->intreg_pending[cpu]);
-	break;
+        DPRINTF("Cleared cpu %d irq mask %x, curmask %x\n", cpu, val, s->intreg_pending[cpu]);
+        break;
     case 2: // set softint
-	val &= 0xfffe0000;
-	s->intreg_pending[cpu] |= val;
+        val &= 0xfffe0000;
+        s->intreg_pending[cpu] |= val;
         slavio_check_interrupts(s);
-	DPRINTF("Set cpu %d irq mask %x, curmask %x\n", cpu, val, s->intreg_pending[cpu]);
-	break;
+        DPRINTF("Set cpu %d irq mask %x, curmask %x\n", cpu, val, s->intreg_pending[cpu]);
+        break;
     default:
-	break;
+        break;
     }
 }
 
@@ -165,27 +165,27 @@
     DPRINTF("write system reg 0x" TARGET_FMT_plx " = %x\n", addr, val);
     switch (saddr) {
     case 2: // clear (enable)
-	// Force clear unused bits
-	val &= ~0x4fb2007f;
-	s->intregm_disabled &= ~val;
-	DPRINTF("Enabled master irq mask %x, curmask %x\n", val, s->intregm_disabled);
-	slavio_check_interrupts(s);
-	break;
+        // Force clear unused bits
+        val &= ~0x4fb2007f;
+        s->intregm_disabled &= ~val;
+        DPRINTF("Enabled master irq mask %x, curmask %x\n", val, s->intregm_disabled);
+        slavio_check_interrupts(s);
+        break;
     case 3: // set (disable, clear pending)
-	// Force clear unused bits
-	val &= ~0x4fb2007f;
-	s->intregm_disabled |= val;
-	s->intregm_pending &= ~val;
+        // Force clear unused bits
+        val &= ~0x4fb2007f;
+        s->intregm_disabled |= val;
+        s->intregm_pending &= ~val;
         slavio_check_interrupts(s);
-	DPRINTF("Disabled master irq mask %x, curmask %x\n", val, s->intregm_disabled);
-	break;
+        DPRINTF("Disabled master irq mask %x, curmask %x\n", val, s->intregm_disabled);
+        break;
     case 4:
-	s->target_cpu = val & (MAX_CPUS - 1);
+        s->target_cpu = val & (MAX_CPUS - 1);
         slavio_check_interrupts(s);
-	DPRINTF("Set master irq cpu %d\n", s->target_cpu);
-	break;
+        DPRINTF("Set master irq cpu %d\n", s->target_cpu);
+        break;
     default:
-	break;
+        break;
     }
 }
 
@@ -207,7 +207,7 @@
     int i;
 
     for (i = 0; i < MAX_CPUS; i++) {
-	term_printf("per-cpu %d: pending 0x%08x\n", i, s->intreg_pending[i]);
+        term_printf("per-cpu %d: pending 0x%08x\n", i, s->intreg_pending[i]);
     }
     term_printf("master: pending 0x%08x, disabled 0x%08x\n", s->intregm_pending, s->intregm_disabled);
 }
@@ -310,7 +310,7 @@
     int i;
 
     for (i = 0; i < MAX_CPUS; i++) {
-	qemu_put_be32s(f, &s->intreg_pending[i]);
+        qemu_put_be32s(f, &s->intreg_pending[i]);
     }
     qemu_put_be32s(f, &s->intregm_pending);
     qemu_put_be32s(f, &s->intregm_disabled);
@@ -326,7 +326,7 @@
         return -EINVAL;
 
     for (i = 0; i < MAX_CPUS; i++) {
-	qemu_get_be32s(f, &s->intreg_pending[i]);
+        qemu_get_be32s(f, &s->intreg_pending[i]);
     }
     qemu_get_be32s(f, &s->intregm_pending);
     qemu_get_be32s(f, &s->intregm_disabled);
@@ -341,7 +341,7 @@
     int i;
 
     for (i = 0; i < MAX_CPUS; i++) {
-	s->intreg_pending[i] = 0;
+        s->intreg_pending[i] = 0;
     }
     s->intregm_disabled = ~0xffb2007f;
     s->intregm_pending = 0;
@@ -363,8 +363,8 @@
 
     s->intbit_to_level = intbit_to_level;
     for (i = 0; i < MAX_CPUS; i++) {
-	slavio_intctl_io_memory = cpu_register_io_memory(0, slavio_intctl_mem_read, slavio_intctl_mem_write, s);
-	cpu_register_physical_memory(addr + i * TARGET_PAGE_SIZE, INTCTL_SIZE,
+        slavio_intctl_io_memory = cpu_register_io_memory(0, slavio_intctl_mem_read, slavio_intctl_mem_write, s);
+        cpu_register_physical_memory(addr + i * TARGET_PAGE_SIZE, INTCTL_SIZE,
                                      slavio_intctl_io_memory);
         s->cpu_irqs[i] = parent_irq[i];
     }

Modified: trunk/src/host/qemu-neo1973/hw/slavio_misc.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/slavio_misc.c	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/hw/slavio_misc.c	2007-10-29 21:14:04 UTC (rev 3303)
@@ -76,9 +76,9 @@
 
     MISC_DPRINTF("Power fail: %d, config: %d\n", power_failing, s->config);
     if (power_failing && (s->config & 0x8)) {
-	s->aux2 |= 0x4;
+        s->aux2 |= 0x4;
     } else {
-	s->aux2 &= ~0x4;
+        s->aux2 &= ~0x4;
     }
     slavio_misc_update_irq(s);
 }
@@ -89,44 +89,44 @@
 
     switch (addr & 0xfff0000) {
     case 0x1800000:
-	MISC_DPRINTF("Write config %2.2x\n", val & 0xff);
-	s->config = val & 0xff;
-	slavio_misc_update_irq(s);
-	break;
+        MISC_DPRINTF("Write config %2.2x\n", val & 0xff);
+        s->config = val & 0xff;
+        slavio_misc_update_irq(s);
+        break;
     case 0x1900000:
-	MISC_DPRINTF("Write aux1 %2.2x\n", val & 0xff);
-	s->aux1 = val & 0xff;
-	break;
+        MISC_DPRINTF("Write aux1 %2.2x\n", val & 0xff);
+        s->aux1 = val & 0xff;
+        break;
     case 0x1910000:
-	val &= 0x3;
-	MISC_DPRINTF("Write aux2 %2.2x\n", val);
-	val |= s->aux2 & 0x4;
-	if (val & 0x2) // Clear Power Fail int
-	    val &= 0x1;
-	s->aux2 = val;
-	if (val & 1)
-	    qemu_system_shutdown_request();
-	slavio_misc_update_irq(s);
-	break;
+        val &= 0x3;
+        MISC_DPRINTF("Write aux2 %2.2x\n", val);
+        val |= s->aux2 & 0x4;
+        if (val & 0x2) // Clear Power Fail int
+            val &= 0x1;
+        s->aux2 = val;
+        if (val & 1)
+            qemu_system_shutdown_request();
+        slavio_misc_update_irq(s);
+        break;
     case 0x1a00000:
-	MISC_DPRINTF("Write diag %2.2x\n", val & 0xff);
-	s->diag = val & 0xff;
-	break;
+        MISC_DPRINTF("Write diag %2.2x\n", val & 0xff);
+        s->diag = val & 0xff;
+        break;
     case 0x1b00000:
-	MISC_DPRINTF("Write modem control %2.2x\n", val & 0xff);
-	s->mctrl = val & 0xff;
-	break;
+        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;
+        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);
+        MISC_DPRINTF("Write power management %2.2x\n", val & 0xff);
         cpu_interrupt(cpu_single_env, CPU_INTERRUPT_HALT);
-	break;
+        break;
     }
 }
 
@@ -137,32 +137,32 @@
 
     switch (addr & 0xfff0000) {
     case 0x1800000:
-	ret = s->config;
-	MISC_DPRINTF("Read config %2.2x\n", ret);
-	break;
+        ret = s->config;
+        MISC_DPRINTF("Read config %2.2x\n", ret);
+        break;
     case 0x1900000:
-	ret = s->aux1;
-	MISC_DPRINTF("Read aux1 %2.2x\n", ret);
-	break;
+        ret = s->aux1;
+        MISC_DPRINTF("Read aux1 %2.2x\n", ret);
+        break;
     case 0x1910000:
-	ret = s->aux2;
-	MISC_DPRINTF("Read aux2 %2.2x\n", ret);
-	break;
+        ret = s->aux2;
+        MISC_DPRINTF("Read aux2 %2.2x\n", ret);
+        break;
     case 0x1a00000:
-	ret = s->diag;
-	MISC_DPRINTF("Read diag %2.2x\n", ret);
-	break;
+        ret = s->diag;
+        MISC_DPRINTF("Read diag %2.2x\n", ret);
+        break;
     case 0x1b00000:
-	ret = s->mctrl;
-	MISC_DPRINTF("Read modem control %2.2x\n", ret);
-	break;
+        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;
+        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;
+        MISC_DPRINTF("Read power management %2.2x\n", ret);
+        break;
     }
     return ret;
 }

Modified: trunk/src/host/qemu-neo1973/hw/slavio_serial.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/slavio_serial.c	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/hw/slavio_serial.c	2007-10-29 21:14:04 UTC (rev 3303)
@@ -95,6 +95,7 @@
     uint8_t rx, tx, wregs[16], rregs[16];
     SERIOQueue queue;
     CharDriverState *chr;
+    int e0_mode, led_mode, caps_lock_mode, num_lock_mode;
 } ChannelState;
 
 struct SerialState {
@@ -138,7 +139,7 @@
     int val;
 
     if (q->count == 0) {
-	return 0;
+        return 0;
     } else {
         val = q->data[q->rptr];
         if (++q->rptr == SERIO_QUEUE_SIZE)
@@ -147,17 +148,17 @@
     }
     SER_DPRINTF("channel %c get 0x%02x\n", CHN_C(s), val);
     if (q->count > 0)
-	serial_receive_byte(s, 0);
+        serial_receive_byte(s, 0);
     return val;
 }
 
 static int slavio_serial_update_irq_chn(ChannelState *s)
 {
     if ((s->wregs[1] & 1) && // interrupts enabled
-	(((s->wregs[1] & 2) && s->txint == 1) || // tx ints enabled, pending
-	 ((((s->wregs[1] & 0x18) == 8) || ((s->wregs[1] & 0x18) == 0x10)) &&
-	  s->rxint == 1) || // rx ints enabled, pending
-	 ((s->wregs[15] & 0x80) && (s->rregs[0] & 0x80)))) { // break int e&p
+        (((s->wregs[1] & 2) && s->txint == 1) || // tx ints enabled, pending
+         ((((s->wregs[1] & 0x18) == 8) || ((s->wregs[1] & 0x18) == 0x10)) &&
+          s->rxint == 1) || // rx ints enabled, pending
+         ((s->wregs[15] & 0x80) && (s->rregs[0] & 0x80)))) { // break int e&p
         return 1;
     }
     return 0;
@@ -180,8 +181,8 @@
 
     s->reg = 0;
     for (i = 0; i < SERIAL_SIZE; i++) {
-	s->rregs[i] = 0;
-	s->wregs[i] = 0;
+        s->rregs[i] = 0;
+        s->wregs[i] = 0;
     }
     s->wregs[4] = 4;
     s->wregs[9] = 0xc0;
@@ -194,6 +195,7 @@
     s->rx = s->tx = 0;
     s->rxint = s->txint = 0;
     s->rxint_under_svc = s->txint_under_svc = 0;
+    s->e0_mode = s->led_mode = s->caps_lock_mode = s->num_lock_mode = 0;
     clear_queue(s);
 }
 
@@ -365,82 +367,82 @@
     s = &serial->chn[channel];
     switch (saddr) {
     case 0:
-	SER_DPRINTF("Write channel %c, reg[%d] = %2.2x\n", CHN_C(s), s->reg, val & 0xff);
-	newreg = 0;
-	switch (s->reg) {
-	case 0:
-	    newreg = val & 7;
-	    val &= 0x38;
-	    switch (val) {
-	    case 8:
-		newreg |= 0x8;
-		break;
-	    case 0x28:
+        SER_DPRINTF("Write channel %c, reg[%d] = %2.2x\n", CHN_C(s), s->reg, val & 0xff);
+        newreg = 0;
+        switch (s->reg) {
+        case 0:
+            newreg = val & 7;
+            val &= 0x38;
+            switch (val) {
+            case 8:
+                newreg |= 0x8;
+                break;
+            case 0x28:
                 clr_txint(s);
-		break;
-	    case 0x38:
+                break;
+            case 0x38:
                 if (s->rxint_under_svc)
                     clr_rxint(s);
                 else if (s->txint_under_svc)
                     clr_txint(s);
-		break;
-	    default:
-		break;
-	    }
-	    break;
+                break;
+            default:
+                break;
+            }
+            break;
         case 1 ... 3:
         case 6 ... 8:
         case 10 ... 11:
         case 14 ... 15:
-	    s->wregs[s->reg] = val;
-	    break;
+            s->wregs[s->reg] = val;
+            break;
         case 4:
         case 5:
         case 12:
         case 13:
-	    s->wregs[s->reg] = val;
+            s->wregs[s->reg] = val;
             slavio_serial_update_parameters(s);
-	    break;
-	case 9:
-	    switch (val & 0xc0) {
-	    case 0:
-	    default:
-		break;
-	    case 0x40:
-		slavio_serial_reset_chn(&serial->chn[1]);
-		return;
-	    case 0x80:
-		slavio_serial_reset_chn(&serial->chn[0]);
-		return;
-	    case 0xc0:
-		slavio_serial_reset(serial);
-		return;
-	    }
-	    break;
-	default:
-	    break;
-	}
-	if (s->reg == 0)
-	    s->reg = newreg;
-	else
-	    s->reg = 0;
-	break;
+            break;
+        case 9:
+            switch (val & 0xc0) {
+            case 0:
+            default:
+                break;
+            case 0x40:
+                slavio_serial_reset_chn(&serial->chn[1]);
+                return;
+            case 0x80:
+                slavio_serial_reset_chn(&serial->chn[0]);
+                return;
+            case 0xc0:
+                slavio_serial_reset(serial);
+                return;
+            }
+            break;
+        default:
+            break;
+        }
+        if (s->reg == 0)
+            s->reg = newreg;
+        else
+            s->reg = 0;
+        break;
     case 1:
-	SER_DPRINTF("Write channel %c, ch %d\n", CHN_C(s), val);
+        SER_DPRINTF("Write channel %c, ch %d\n", CHN_C(s), val);
         s->tx = val;
-	if (s->wregs[5] & 8) { // tx enabled
-	    if (s->chr)
-		qemu_chr_write(s->chr, &s->tx, 1);
-	    else if (s->type == kbd) {
-		handle_kbd_command(s, val);
-	    }
-	}
+        if (s->wregs[5] & 8) { // tx enabled
+            if (s->chr)
+                qemu_chr_write(s->chr, &s->tx, 1);
+            else if (s->type == kbd) {
+                handle_kbd_command(s, val);
+            }
+        }
         s->rregs[0] |= 4; // Tx buffer empty
         s->rregs[1] |= 1; // All sent
         set_txint(s);
-	break;
+        break;
     default:
-	break;
+        break;
     }
 }
 
@@ -457,21 +459,21 @@
     s = &serial->chn[channel];
     switch (saddr) {
     case 0:
-	SER_DPRINTF("Read channel %c, reg[%d] = %2.2x\n", CHN_C(s), s->reg, s->rregs[s->reg]);
-	ret = s->rregs[s->reg];
-	s->reg = 0;
-	return ret;
+        SER_DPRINTF("Read channel %c, reg[%d] = %2.2x\n", CHN_C(s), s->reg, s->rregs[s->reg]);
+        ret = s->rregs[s->reg];
+        s->reg = 0;
+        return ret;
     case 1:
-	s->rregs[0] &= ~1;
+        s->rregs[0] &= ~1;
         clr_rxint(s);
-	if (s->type == kbd || s->type == mouse)
-	    ret = get_queue(s);
-	else
-	    ret = s->rx;
-	SER_DPRINTF("Read channel %c, ch %d\n", CHN_C(s), ret);
-	return ret;
+        if (s->type == kbd || s->type == mouse)
+            ret = get_queue(s);
+        else
+            ret = s->rx;
+        SER_DPRINTF("Read channel %c, ch %d\n", CHN_C(s), ret);
+        return ret;
     default:
-	break;
+        break;
     }
     return 0;
 }
@@ -482,10 +484,10 @@
     int ret;
 
     if (((s->wregs[3] & 1) == 0) // Rx not enabled
-	|| ((s->rregs[0] & 1) == 1)) // char already available
-	ret = 0;
+        || ((s->rregs[0] & 1) == 1)) // char already available
+        ret = 0;
     else
-	ret = 1;
+        ret = 1;
     //SER_DPRINTF("channel %c can receive %d\n", CHN_C(s), ret);
     return ret;
 }
@@ -582,7 +584,7 @@
 
     ret = slavio_serial_load_chn(f, &s->chn[0], version_id);
     if (ret != 0)
-	return ret;
+        return ret;
     ret = slavio_serial_load_chn(f, &s->chn[1], version_id);
     return ret;
 
@@ -605,13 +607,13 @@
     s->chn[1].chr = chr2;
 
     for (i = 0; i < 2; i++) {
-	s->chn[i].irq = irq;
-	s->chn[i].chn = 1 - i;
-	s->chn[i].type = ser;
-	if (s->chn[i].chr) {
-	    qemu_chr_add_handlers(s->chn[i].chr, serial_can_receive,
+        s->chn[i].irq = irq;
+        s->chn[i].chn = 1 - i;
+        s->chn[i].type = ser;
+        if (s->chn[i].chr) {
+            qemu_chr_add_handlers(s->chn[i].chr, serial_can_receive,
                                   serial_receive1, serial_event, &s->chn[i]);
-	}
+        }
     }
     s->chn[0].otherchn = &s->chn[1];
     s->chn[1].otherchn = &s->chn[0];
@@ -632,33 +634,85 @@
     0, 45, 2, 4, 48, 0, 0, 21, 0, 0, 0, 0, 0, 120, 122, 67,
 };
 
+static const uint8_t e0_keycodes[128] = {
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 90, 76, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 109, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 68, 69, 70, 0, 91, 0, 93, 0, 112,
+    113, 114, 94, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
 static void sunkbd_event(void *opaque, int ch)
 {
     ChannelState *s = opaque;
     int release = ch & 0x80;
 
-    ch = keycodes[ch & 0x7f];
-    KBD_DPRINTF("Keycode %d (%s)\n", ch, release? "release" : "press");
+    KBD_DPRINTF("Untranslated keycode %2.2x (%s)\n", ch, release? "release" : "press");
+    switch (ch) {
+    case 58: // Caps lock press
+        s->caps_lock_mode ^= 1;
+        if (s->caps_lock_mode == 2)
+            return; // Drop second press
+        break;
+    case 69: // Num lock press
+        s->num_lock_mode ^= 1;
+        if (s->num_lock_mode == 2)
+            return; // Drop second press
+        break;
+    case 186: // Caps lock release
+        s->caps_lock_mode ^= 2;
+        if (s->caps_lock_mode == 3)
+            return; // Drop first release
+        break;
+    case 197: // Num lock release
+        s->num_lock_mode ^= 2;
+        if (s->num_lock_mode == 3)
+            return; // Drop first release
+        break;
+    case 0xe0:
+        s->e0_mode = 1;
+        return;
+    default:
+        break;
+    }
+    if (s->e0_mode) {
+        s->e0_mode = 0;
+        ch = e0_keycodes[ch & 0x7f];
+    } else {
+        ch = keycodes[ch & 0x7f];
+    }
+    KBD_DPRINTF("Translated keycode %2.2x\n", ch);
     put_queue(s, ch | release);
 }
 
 static void handle_kbd_command(ChannelState *s, int val)
 {
     KBD_DPRINTF("Command %d\n", val);
+    if (s->led_mode) { // Ignore led byte
+        s->led_mode = 0;
+        return;
+    }
     switch (val) {
     case 1: // Reset, return type code
         clear_queue(s);
-	put_queue(s, 0xff);
-	put_queue(s, 4); // Type 4
-	break;
+        put_queue(s, 0xff);
+        put_queue(s, 4); // Type 4
+        put_queue(s, 0x7f);
+        break;
+    case 0xe: // Set leds
+        s->led_mode = 1;
+        break;
     case 7: // Query layout
     case 0xf:
         clear_queue(s);
-	put_queue(s, 0xfe);
-	put_queue(s, 19); // XXX, layout?
-	break;
+        put_queue(s, 0xfe);
+        put_queue(s, 0); // XXX, layout?
+        break;
     default:
-	break;
+        break;
     }
 }
 
@@ -714,9 +768,9 @@
     if (!s)
         return;
     for (i = 0; i < 2; i++) {
-	s->chn[i].irq = irq;
-	s->chn[i].chn = 1 - i;
-	s->chn[i].chr = NULL;
+        s->chn[i].irq = irq;
+        s->chn[i].chn = 1 - i;
+        s->chn[i].chr = NULL;
     }
     s->chn[0].otherchn = &s->chn[1];
     s->chn[1].otherchn = &s->chn[0];

Modified: trunk/src/host/qemu-neo1973/hw/slavio_timer.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/slavio_timer.c	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/hw/slavio_timer.c	2007-10-29 21:14:04 UTC (rev 3303)
@@ -47,18 +47,31 @@
  *
  */
 
+#define MAX_CPUS 16
+
 typedef struct SLAVIO_TIMERState {
     qemu_irq irq;
     ptimer_state *timer;
     uint32_t count, counthigh, reached;
     uint64_t limit;
-    int stopped;
-    int mode; // 0 = processor, 1 = user, 2 = system
+    // processor only
+    int running;
+    struct SLAVIO_TIMERState *master;
+    int slave_index;
+    // system only
+    struct SLAVIO_TIMERState *slave[MAX_CPUS];
+    uint32_t slave_mode;
 } SLAVIO_TIMERState;
 
 #define TIMER_MAXADDR 0x1f
-#define TIMER_SIZE (TIMER_MAXADDR + 1)
+#define SYS_TIMER_SIZE 0x14
+#define CPU_TIMER_SIZE 0x10
 
+static int slavio_timer_is_user(SLAVIO_TIMERState *s)
+{
+    return s->master && (s->master->slave_mode & (1 << s->slave_index));
+}
+
 // Update count, set irq, update expire_time
 // Convert from ptimer countdown units
 static void slavio_timer_get_out(SLAVIO_TIMERState *s)
@@ -79,9 +92,10 @@
 
     slavio_timer_get_out(s);
     DPRINTF("callback: count %x%08x\n", s->counthigh, s->count);
-    s->reached = 0x80000000;
-    if (s->mode != 1)
-	qemu_irq_raise(s->irq);
+    if (!slavio_timer_is_user(s)) {
+        s->reached = 0x80000000;
+        qemu_irq_raise(s->irq);
+    }
 }
 
 static uint32_t slavio_timer_mem_readl(void *opaque, target_phys_addr_t addr)
@@ -92,37 +106,41 @@
     saddr = (addr & TIMER_MAXADDR) >> 2;
     switch (saddr) {
     case 0:
-	// read limit (system counter mode) or read most signifying
-	// part of counter (user mode)
-	if (s->mode != 1) {
-	    // clear irq
+        // read limit (system counter mode) or read most signifying
+        // part of counter (user mode)
+        if (slavio_timer_is_user(s)) {
+            // read user timer MSW
+            slavio_timer_get_out(s);
+            ret = s->counthigh;
+        } else {
+            // read limit
+            // clear irq
             qemu_irq_lower(s->irq);
-	    s->reached = 0;
+            s->reached = 0;
             ret = s->limit & 0x7fffffff;
-	}
-	else {
-	    slavio_timer_get_out(s);
-            ret = s->counthigh & 0x7fffffff;
-	}
+        }
         break;
     case 1:
-	// read counter and reached bit (system mode) or read lsbits
-	// of counter (user mode)
-	slavio_timer_get_out(s);
-	if (s->mode != 1)
-            ret = (s->count & 0x7fffffff) | s->reached;
-	else
-            ret = s->count;
+        // read counter and reached bit (system mode) or read lsbits
+        // of counter (user mode)
+        slavio_timer_get_out(s);
+        if (slavio_timer_is_user(s)) // read user timer LSW
+            ret = s->count & 0xffffffe00;
+        else // read limit
+            ret = (s->count & 0x7ffffe00) | s->reached;
         break;
     case 3:
-	// read start/stop status
-        ret = s->stopped;
+        // only available in processor counter/timer
+        // read start/stop status
+        ret = s->running;
         break;
     case 4:
-	// read user/system mode
-        ret = s->mode & 1;
+        // only available in system counter
+        // read user/system mode
+        ret = s->slave_mode;
         break;
     default:
+        DPRINTF("invalid read address " TARGET_FMT_plx "\n", addr);
         ret = 0;
         break;
     }
@@ -141,42 +159,75 @@
     saddr = (addr & TIMER_MAXADDR) >> 2;
     switch (saddr) {
     case 0:
-	// set limit, reset counter
-        reload = 1;
-	qemu_irq_lower(s->irq);
-	// fall through
+        if (slavio_timer_is_user(s)) {
+            // set user counter MSW, reset counter
+            qemu_irq_lower(s->irq);
+            s->limit = 0x7ffffffffffffe00ULL;
+            DPRINTF("processor %d user timer reset\n", s->slave_index);
+            ptimer_set_limit(s->timer, s->limit >> 9, 1);
+        } else {
+            // set limit, reset counter
+            qemu_irq_lower(s->irq);
+            s->limit = val & 0x7ffffe00ULL;
+            if (!s->limit)
+                s->limit = 0x7ffffe00ULL;
+            ptimer_set_limit(s->timer, s->limit >> 9, 1);
+        }
+        break;
+    case 1:
+        if (slavio_timer_is_user(s)) {
+            // set user counter LSW, reset counter
+            qemu_irq_lower(s->irq);
+            s->limit = 0x7ffffffffffffe00ULL;
+            DPRINTF("processor %d user timer reset\n", s->slave_index);
+            ptimer_set_limit(s->timer, s->limit >> 9, 1);
+        } else
+            DPRINTF("not user timer\n");
+        break;
     case 2:
-	// set limit without resetting counter
+        // set limit without resetting counter
         s->limit = val & 0x7ffffe00ULL;
         if (!s->limit)
             s->limit = 0x7ffffe00ULL;
         ptimer_set_limit(s->timer, s->limit >> 9, reload);
-	break;
+        break;
     case 3:
-	// start/stop user counter
-	if (s->mode == 1) {
-	    if (val & 1) {
+        if (slavio_timer_is_user(s)) {
+            // start/stop user counter
+            if ((val & 1) && !s->running) {
+                DPRINTF("processor %d user timer started\n", s->slave_index);
+                ptimer_run(s->timer, 0);
+                s->running = 1;
+            } else if (!(val & 1) && s->running) {
+                DPRINTF("processor %d user timer stopped\n", s->slave_index);
                 ptimer_stop(s->timer);
-		s->stopped = 1;
-	    }
-	    else {
-                ptimer_run(s->timer, 0);
-		s->stopped = 0;
-	    }
-	}
-	break;
+                s->running = 0;
+            }
+        }
+        break;
     case 4:
-	// bit 0: user (1) or system (0) counter mode
-	if (s->mode == 0 || s->mode == 1)
-	    s->mode = val & 1;
-        if (s->mode == 1) {
-            qemu_irq_lower(s->irq);
-            s->limit = -1ULL;
-        }
-        ptimer_set_limit(s->timer, s->limit >> 9, 1);
-	break;
+        if (s->master == NULL) {
+            unsigned int i;
+
+            for (i = 0; i < MAX_CPUS; i++) {
+                if (val & (1 << i)) {
+                    qemu_irq_lower(s->slave[i]->irq);
+                    s->slave[i]->limit = -1ULL;
+                }
+                if ((val & (1 << i)) != (s->slave_mode & (1 << i))) {
+                    ptimer_stop(s->slave[i]->timer);
+                    ptimer_set_limit(s->slave[i]->timer, s->slave[i]->limit >> 9, 1);
+                    DPRINTF("processor %d timer changed\n", s->slave[i]->slave_index);
+                    ptimer_run(s->slave[i]->timer, 0);
+                }
+            }
+            s->slave_mode = val & ((1 << MAX_CPUS) - 1);
+        } else
+            DPRINTF("not system timer\n");
+        break;
     default:
-	break;
+        DPRINTF("invalid write address " TARGET_FMT_plx "\n", addr);
+        break;
     }
 }
 
@@ -201,8 +252,8 @@
     qemu_put_be32s(f, &s->counthigh);
     qemu_put_be32(f, 0); // Was irq
     qemu_put_be32s(f, &s->reached);
-    qemu_put_be32s(f, &s->stopped);
-    qemu_put_be32s(f, &s->mode);
+    qemu_put_be32s(f, &s->running);
+    qemu_put_be32s(f, 0); // Was mode
     qemu_put_ptimer(f, s->timer);
 }
 
@@ -219,8 +270,8 @@
     qemu_get_be32s(f, &s->counthigh);
     qemu_get_be32s(f, &tmp); // Was irq
     qemu_get_be32s(f, &s->reached);
-    qemu_get_be32s(f, &s->stopped);
-    qemu_get_be32s(f, &s->mode);
+    qemu_get_be32s(f, &s->running);
+    qemu_get_be32s(f, &tmp); // Was mode
     qemu_get_ptimer(f, s->timer);
 
     return 0;
@@ -230,17 +281,22 @@
 {
     SLAVIO_TIMERState *s = opaque;
 
-    s->limit = 0x7ffffe00ULL;
+    if (slavio_timer_is_user(s))
+        s->limit = 0x7ffffffffffffe00ULL;
+    else
+        s->limit = 0x7ffffe00ULL;
     s->count = 0;
     s->reached = 0;
-    s->mode &= 2;
     ptimer_set_limit(s->timer, s->limit >> 9, 1);
     ptimer_run(s->timer, 0);
-    s->stopped = 1;
+    s->running = 1;
     qemu_irq_lower(s->irq);
 }
 
-void slavio_timer_init(target_phys_addr_t addr, qemu_irq irq, int mode)
+static SLAVIO_TIMERState *slavio_timer_init(target_phys_addr_t addr,
+                                            qemu_irq irq,
+                                            SLAVIO_TIMERState *master,
+                                            int slave_index)
 {
     int slavio_timer_io_memory;
     SLAVIO_TIMERState *s;
@@ -248,17 +304,38 @@
 
     s = qemu_mallocz(sizeof(SLAVIO_TIMERState));
     if (!s)
-        return;
+        return s;
     s->irq = irq;
-    s->mode = mode;
+    s->master = master;
+    s->slave_index = slave_index;
     bh = qemu_bh_new(slavio_timer_irq, s);
     s->timer = ptimer_init(bh);
     ptimer_set_period(s->timer, 500ULL);
 
     slavio_timer_io_memory = cpu_register_io_memory(0, slavio_timer_mem_read,
-						    slavio_timer_mem_write, s);
-    cpu_register_physical_memory(addr, TIMER_SIZE, slavio_timer_io_memory);
+                                                    slavio_timer_mem_write, s);
+    if (master)
+        cpu_register_physical_memory(addr, CPU_TIMER_SIZE, slavio_timer_io_memory);
+    else
+        cpu_register_physical_memory(addr, SYS_TIMER_SIZE, slavio_timer_io_memory);
     register_savevm("slavio_timer", addr, 2, slavio_timer_save, slavio_timer_load, s);
     qemu_register_reset(slavio_timer_reset, s);
     slavio_timer_reset(s);
+
+    return s;
 }
+
+void slavio_timer_init_all(target_phys_addr_t base, qemu_irq master_irq,
+                           qemu_irq *cpu_irqs)
+{
+    SLAVIO_TIMERState *master;
+    unsigned int i;
+
+    master = slavio_timer_init(base + 0x10000ULL, master_irq, NULL, 0);
+
+    for (i = 0; i < MAX_CPUS; i++) {
+        master->slave[i] = slavio_timer_init(base + (target_phys_addr_t)
+                                             (i * TARGET_PAGE_SIZE),
+                                             cpu_irqs[i], master, i);
+    }
+}

Modified: trunk/src/host/qemu-neo1973/hw/spitz.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/spitz.c	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/hw/spitz.c	2007-10-29 21:14:04 UTC (rev 3303)
@@ -194,8 +194,8 @@
     { 0x0f, 0x10, 0x12, 0x14, 0x22, 0x16, 0x24, 0x25,  -1 ,  -1 ,  -1  },
     { 0x3c, 0x11, 0x1f, 0x21, 0x2f, 0x23, 0x32, 0x26,  -1 , 0x36,  -1  },
     { 0x3b, 0x1e, 0x20, 0x2e, 0x30, 0x31, 0x34,  -1 , 0x1c, 0x2a,  -1  },
-    { 0x44, 0x2c, 0x2d, 0x0c, 0x39, 0x33,  -1 , 0x48,  -1 ,  -1 , 0x3d },
-    { 0x37, 0x38,  -1 , 0x45, 0x57, 0x58, 0x4b, 0x50, 0x4d,  -1 ,  -1  },
+    { 0x44, 0x2c, 0x2d, 0x0c, 0x39, 0x33,  -1 , 0x48,  -1 ,  -1 , 0x38 },
+    { 0x37, 0x3d,  -1 , 0x45, 0x57, 0x58, 0x4b, 0x50, 0x4d,  -1 ,  -1  },
     { 0x52, 0x43, 0x01, 0x47, 0x49,  -1 ,  -1 ,  -1 ,  -1 ,  -1 ,  -1  },
 };
 
@@ -415,13 +415,17 @@
     s->pre_map[0x0d | SHIFT	] = 0x13 | FN;		/* plus */
     s->pre_map[0x1a		] = 0x14 | FN;		/* bracketleft */
     s->pre_map[0x1b		] = 0x15 | FN;		/* bracketright */
+    s->pre_map[0x1a | SHIFT	] = 0x16 | FN;		/* braceleft */
+    s->pre_map[0x1b | SHIFT	] = 0x17 | FN;		/* braceright */
     s->pre_map[0x27		] = 0x22 | FN;		/* semicolon */
     s->pre_map[0x27 | SHIFT	] = 0x23 | FN;		/* colon */
     s->pre_map[0x09 | SHIFT	] = 0x24 | FN;		/* asterisk */
     s->pre_map[0x2b		] = 0x25 | FN;		/* backslash */
     s->pre_map[0x2b | SHIFT	] = 0x26 | FN;		/* bar */
     s->pre_map[0x0c | SHIFT	] = 0x30 | FN;		/* underscore */
+    s->pre_map[0x33 | SHIFT	] = 0x33 | FN;		/* less */
     s->pre_map[0x35		] = 0x33 | SHIFT;	/* slash */
+    s->pre_map[0x34 | SHIFT	] = 0x34 | FN;		/* greater */
     s->pre_map[0x35 | SHIFT	] = 0x34 | SHIFT;	/* question */
     s->pre_map[0x49		] = 0x48 | FN;		/* Page_Up */
     s->pre_map[0x51		] = 0x50 | FN;		/* Page_Down */

Modified: trunk/src/host/qemu-neo1973/hw/sun4m.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/sun4m.c	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/hw/sun4m.c	2007-10-29 21:14:04 UTC (rev 3303)
@@ -49,9 +49,10 @@
 #define KERNEL_LOAD_ADDR     0x00004000
 #define CMDLINE_ADDR         0x007ff000
 #define INITRD_LOAD_ADDR     0x00800000
-#define PROM_SIZE_MAX        (256 * 1024)
-#define PROM_ADDR	     0xffd00000
-#define PROM_FILENAME	     "openbios-sparc32"
+#define PROM_SIZE_MAX        (512 * 1024)
+#define PROM_PADDR           0xff0000000ULL
+#define PROM_VADDR           0xffd00000
+#define PROM_FILENAME        "openbios-sparc32"
 
 #define MAX_CPUS 16
 #define MAX_PILS 16
@@ -157,9 +158,9 @@
 extern int nographic;
 
 static void nvram_init(m48t59_t *nvram, uint8_t *macaddr, const char *cmdline,
-		       int boot_device, uint32_t RAM_size,
-		       uint32_t kernel_size,
-		       int width, int height, int depth,
+                       int boot_device, uint32_t RAM_size,
+                       uint32_t kernel_size,
+                       int width, int height, int depth,
                        int machine_id)
 {
     unsigned char tmp = 0;
@@ -178,8 +179,8 @@
     nvram_set_lword(nvram,  0x38, KERNEL_LOAD_ADDR);
     nvram_set_lword(nvram,  0x3C, kernel_size);
     if (cmdline) {
-	strcpy(phys_ram_base + CMDLINE_ADDR, cmdline);
-	nvram_set_lword(nvram,  0x40, CMDLINE_ADDR);
+        strcpy(phys_ram_base + CMDLINE_ADDR, cmdline);
+        nvram_set_lword(nvram,  0x40, CMDLINE_ADDR);
         nvram_set_lword(nvram,  0x44, strlen(cmdline));
     }
     // initrd_image, initrd_size passed differently
@@ -326,7 +327,7 @@
 
     for(i = 0; i < smp_cpus; i++) {
         env = cpu_init();
-        cpu_sparc_register(env, def);
+        cpu_sparc_register(env, def, i);
         envs[i] = env;
         if (i == 0) {
             qemu_register_reset(main_cpu_reset, env);
@@ -379,13 +380,10 @@
 
     nvram = m48t59_init(slavio_irq[0], hwdef->nvram_base, 0,
                         hwdef->nvram_size, 8);
-    for (i = 0; i < MAX_CPUS; i++) {
-        slavio_timer_init(hwdef->counter_base +
-                          (target_phys_addr_t)(i * TARGET_PAGE_SIZE),
-                           slavio_cpu_irq[i], 0);
-    }
-    slavio_timer_init(hwdef->counter_base + 0x10000ULL,
-                      slavio_irq[hwdef->clock1_irq], 2);
+
+    slavio_timer_init_all(hwdef->counter_base, slavio_irq[hwdef->clock1_irq],
+                          slavio_cpu_irq);
+
     slavio_serial_ms_kbd_init(hwdef->ms_kb_base, slavio_irq[hwdef->ms_kb_irq]);
     // Slavio TTYA (base+4, Linux ttyS0) is the first Qemu serial device
     // Slavio TTYB (base+0, Linux ttyS1) is the second Qemu serial device
@@ -425,29 +423,34 @@
     linux_boot = (kernel_filename != NULL);
 
     prom_offset = RAM_size + vram_size;
-    cpu_register_physical_memory(PROM_ADDR,
+    cpu_register_physical_memory(PROM_PADDR,
                                  (PROM_SIZE_MAX + TARGET_PAGE_SIZE - 1) & TARGET_PAGE_MASK,
                                  prom_offset | IO_MEM_ROM);
 
-    snprintf(buf, sizeof(buf), "%s/%s", bios_dir, PROM_FILENAME);
-    ret = load_elf(buf, 0, NULL, NULL, NULL);
-    if (ret < 0) {
-	fprintf(stderr, "qemu: could not load prom '%s'\n",
-		buf);
-	exit(1);
+    if (bios_name == NULL)
+        bios_name = PROM_FILENAME;
+    snprintf(buf, sizeof(buf), "%s/%s", bios_dir, bios_name);
+    ret = load_elf(buf, PROM_PADDR - PROM_VADDR, NULL, NULL, NULL);
+    if (ret < 0 || ret > PROM_SIZE_MAX)
+        ret = load_image(buf, phys_ram_base + prom_offset);
+    if (ret < 0 || ret > PROM_SIZE_MAX) {
+        fprintf(stderr, "qemu: could not load prom '%s'\n",
+                buf);
+        exit(1);
     }
 
     kernel_size = 0;
     if (linux_boot) {
-        kernel_size = load_elf(kernel_filename, -0xf0000000, NULL, NULL, NULL);
+        kernel_size = load_elf(kernel_filename, -0xf0000000ULL, NULL, NULL,
+                               NULL);
         if (kernel_size < 0)
-	    kernel_size = load_aout(kernel_filename, phys_ram_base + KERNEL_LOAD_ADDR);
-	if (kernel_size < 0)
-	    kernel_size = load_image(kernel_filename, phys_ram_base + KERNEL_LOAD_ADDR);
+            kernel_size = load_aout(kernel_filename, phys_ram_base + KERNEL_LOAD_ADDR);
+        if (kernel_size < 0)
+            kernel_size = load_image(kernel_filename, phys_ram_base + KERNEL_LOAD_ADDR);
         if (kernel_size < 0) {
             fprintf(stderr, "qemu: could not load kernel '%s'\n",
                     kernel_filename);
-	    exit(1);
+            exit(1);
         }
 
         /* load initrd */
@@ -461,14 +464,14 @@
             }
         }
         if (initrd_size > 0) {
-	    for (i = 0; i < 64 * TARGET_PAGE_SIZE; i += TARGET_PAGE_SIZE) {
-		if (ldl_raw(phys_ram_base + KERNEL_LOAD_ADDR + i)
-		    == 0x48647253) { // HdrS
-		    stl_raw(phys_ram_base + KERNEL_LOAD_ADDR + i + 16, INITRD_LOAD_ADDR);
-		    stl_raw(phys_ram_base + KERNEL_LOAD_ADDR + i + 20, initrd_size);
-		    break;
-		}
-	    }
+            for (i = 0; i < 64 * TARGET_PAGE_SIZE; i += TARGET_PAGE_SIZE) {
+                if (ldl_raw(phys_ram_base + KERNEL_LOAD_ADDR + i)
+                    == 0x48647253) { // HdrS
+                    stl_raw(phys_ram_base + KERNEL_LOAD_ADDR + i + 16, INITRD_LOAD_ADDR);
+                    stl_raw(phys_ram_base + KERNEL_LOAD_ADDR + i + 20, initrd_size);
+                    break;
+                }
+            }
         }
     }
     nvram_init(nvram, (uint8_t *)&nd_table[0].macaddr, kernel_cmdline,
@@ -506,8 +509,8 @@
         .cs_irq = 5,
         .machine_id = 0x80,
         .intbit_to_level = {
-            2, 3, 5, 7, 9, 11, 0, 14,	3, 5, 7, 9, 11, 13, 12, 12,
-            6, 0, 4, 10, 8, 0, 11, 0,	0, 0, 0, 0, 15, 0, 15, 0,
+            2, 3, 5, 7, 9, 11, 0, 14,   3, 5, 7, 9, 11, 13, 12, 12,
+            6, 0, 4, 10, 8, 0, 11, 0,   0, 0, 0, 0, 15, 0, 15, 0,
         },
     },
     /* SS-10 */
@@ -539,8 +542,8 @@
         .cs_irq = -1,
         .machine_id = 0x72,
         .intbit_to_level = {
-            2, 3, 5, 7, 9, 11, 0, 14,	3, 5, 7, 9, 11, 13, 12, 12,
-            6, 0, 4, 10, 8, 0, 11, 0,	0, 0, 0, 0, 15, 0, 15, 0,
+            2, 3, 5, 7, 9, 11, 0, 14,   3, 5, 7, 9, 11, 13, 12, 12,
+            6, 0, 4, 10, 8, 0, 11, 0,   0, 0, 0, 0, 15, 0, 15, 0,
         },
     },
 };
@@ -588,7 +591,7 @@
         cpu_model = "TI SuperSparc II";
     sun4m_common_init(RAM_size, boot_device, ds, kernel_filename,
                       kernel_cmdline, initrd_filename, cpu_model,
-                      1, PROM_ADDR); // XXX prom overlap, actually first 4GB ok
+                      1, 0xffffffff); // XXX actually first 62GB ok
 }
 
 QEMUMachine ss5_machine = {

Modified: trunk/src/host/qemu-neo1973/hw/sun4u.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/sun4u.c	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/hw/sun4u.c	2007-10-29 21:14:04 UTC (rev 3303)
@@ -28,12 +28,12 @@
 #define CMDLINE_ADDR         0x003ff000
 #define INITRD_LOAD_ADDR     0x00300000
 #define PROM_SIZE_MAX        (512 * 1024)
-#define PROM_ADDR	     0x1fff0000000ULL
-#define PROM_VADDR	     0x000ffd00000ULL
+#define PROM_ADDR            0x1fff0000000ULL
+#define PROM_VADDR           0x000ffd00000ULL
 #define APB_SPECIAL_BASE     0x1fe00000000ULL
-#define APB_MEM_BASE	     0x1ff00000000ULL
-#define VGA_BASE	     (APB_MEM_BASE + 0x400000ULL)
-#define PROM_FILENAME	     "openbios-sparc64"
+#define APB_MEM_BASE         0x1ff00000000ULL
+#define VGA_BASE             (APB_MEM_BASE + 0x400000ULL)
+#define PROM_FILENAME        "openbios-sparc64"
 #define NVRAM_SIZE           0x2000
 
 /* TSC handling */
@@ -162,10 +162,10 @@
     odd = count & 1;
     count &= ~1;
     for (i = 0; i != count; i++) {
-	crc = NVRAM_crc_update(crc, NVRAM_get_word(nvram, start + i));
+        crc = NVRAM_crc_update(crc, NVRAM_get_word(nvram, start + i));
     }
     if (odd) {
-	crc = NVRAM_crc_update(crc, NVRAM_get_byte(nvram, start + i) << 8);
+        crc = NVRAM_crc_update(crc, NVRAM_get_byte(nvram, start + i) << 8);
     }
 
     return crc;
@@ -358,7 +358,7 @@
         exit(1);
     }
     env = cpu_init();
-    cpu_sparc_register(env, def);
+    cpu_sparc_register(env, def, 0);
     bh = qemu_bh_new(tick_irq, env);
     env->tick = ptimer_init(bh);
     ptimer_set_period(env->tick, 1ULL);
@@ -382,12 +382,14 @@
                                  (PROM_SIZE_MAX + TARGET_PAGE_SIZE) & TARGET_PAGE_MASK,
                                  prom_offset | IO_MEM_ROM);
 
-    snprintf(buf, sizeof(buf), "%s/%s", bios_dir, PROM_FILENAME);
+    if (bios_name == NULL)
+        bios_name = PROM_FILENAME;
+    snprintf(buf, sizeof(buf), "%s/%s", bios_dir, bios_name);
     ret = load_elf(buf, PROM_ADDR - PROM_VADDR, NULL, NULL, NULL);
     if (ret < 0) {
-	fprintf(stderr, "qemu: could not load prom '%s'\n",
-		buf);
-	exit(1);
+        fprintf(stderr, "qemu: could not load prom '%s'\n",
+                buf);
+        exit(1);
     }
 
     kernel_size = 0;
@@ -396,13 +398,13 @@
         /* XXX: put correct offset */
         kernel_size = load_elf(kernel_filename, 0, NULL, NULL, NULL);
         if (kernel_size < 0)
-	    kernel_size = load_aout(kernel_filename, phys_ram_base + KERNEL_LOAD_ADDR);
-	if (kernel_size < 0)
-	    kernel_size = load_image(kernel_filename, phys_ram_base + KERNEL_LOAD_ADDR);
+            kernel_size = load_aout(kernel_filename, phys_ram_base + KERNEL_LOAD_ADDR);
+        if (kernel_size < 0)
+            kernel_size = load_image(kernel_filename, phys_ram_base + KERNEL_LOAD_ADDR);
         if (kernel_size < 0) {
             fprintf(stderr, "qemu: could not load kernel '%s'\n",
                     kernel_filename);
-	    exit(1);
+            exit(1);
         }
 
         /* load initrd */
@@ -415,14 +417,14 @@
             }
         }
         if (initrd_size > 0) {
-	    for (i = 0; i < 64 * TARGET_PAGE_SIZE; i += TARGET_PAGE_SIZE) {
-		if (ldl_raw(phys_ram_base + KERNEL_LOAD_ADDR + i)
-		    == 0x48647253) { // HdrS
-		    stl_raw(phys_ram_base + KERNEL_LOAD_ADDR + i + 16, INITRD_LOAD_ADDR);
-		    stl_raw(phys_ram_base + KERNEL_LOAD_ADDR + i + 20, initrd_size);
-		    break;
-		}
-	    }
+            for (i = 0; i < 64 * TARGET_PAGE_SIZE; i += TARGET_PAGE_SIZE) {
+                if (ldl_raw(phys_ram_base + KERNEL_LOAD_ADDR + i)
+                    == 0x48647253) { // HdrS
+                    stl_raw(phys_ram_base + KERNEL_LOAD_ADDR + i + 16, INITRD_LOAD_ADDR);
+                    stl_raw(phys_ram_base + KERNEL_LOAD_ADDR + i + 20, initrd_size);
+                    break;
+                }
+            }
         }
     }
     pci_bus = pci_apb_init(APB_SPECIAL_BASE, APB_MEM_BASE, NULL);
@@ -444,7 +446,7 @@
     for(i = 0; i < nb_nics; i++) {
         if (!nd_table[i].model)
             nd_table[i].model = "ne2k_pci";
-	pci_nic_init(pci_bus, &nd_table[i], -1);
+        pci_nic_init(pci_bus, &nd_table[i], -1);
     }
 
     irq = qemu_allocate_irqs(dummy_cpu_set_irq, NULL, 32);

Modified: trunk/src/host/qemu-neo1973/hw/tcx.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/tcx.c	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/hw/tcx.c	2007-10-29 21:14:04 UTC (rev 3303)
@@ -84,39 +84,39 @@
 }
 
 static void tcx_draw_line32(TCXState *s1, uint8_t *d,
-			    const uint8_t *s, int width)
+                            const uint8_t *s, int width)
 {
     int x;
     uint8_t val;
     uint32_t *p = (uint32_t *)d;
 
     for(x = 0; x < width; x++) {
-	val = *s++;
+        val = *s++;
         *p++ = s1->palette[val];
     }
 }
 
 static void tcx_draw_line16(TCXState *s1, uint8_t *d,
-			    const uint8_t *s, int width)
+                            const uint8_t *s, int width)
 {
     int x;
     uint8_t val;
     uint16_t *p = (uint16_t *)d;
 
     for(x = 0; x < width; x++) {
-	val = *s++;
+        val = *s++;
         *p++ = s1->palette[val];
     }
 }
 
 static void tcx_draw_line8(TCXState *s1, uint8_t *d,
-			   const uint8_t *s, int width)
+                           const uint8_t *s, int width)
 {
     int x;
     uint8_t val;
 
     for(x = 0; x < width; x++) {
-	val = *s++;
+        val = *s++;
         *d++ = s1->palette[val];
     }
 }
@@ -183,7 +183,7 @@
     void (*f)(TCXState *s1, uint8_t *dst, const uint8_t *src, int width);
 
     if (ts->ds->depth == 0)
-	return;
+        return;
     page = ts->vram_offset;
     y_start = -1;
     page_min = 0xffffffff;
@@ -195,55 +195,55 @@
 
     switch (ts->ds->depth) {
     case 32:
-	f = tcx_draw_line32;
-	break;
+        f = tcx_draw_line32;
+        break;
     case 15:
     case 16:
-	f = tcx_draw_line16;
-	break;
+        f = tcx_draw_line16;
+        break;
     default:
     case 8:
-	f = tcx_draw_line8;
-	break;
+        f = tcx_draw_line8;
+        break;
     case 0:
-	return;
+        return;
     }
 
     for(y = 0; y < ts->height; y += 4, page += TARGET_PAGE_SIZE) {
-	if (cpu_physical_memory_get_dirty(page, VGA_DIRTY_FLAG)) {
-	    if (y_start < 0)
+        if (cpu_physical_memory_get_dirty(page, VGA_DIRTY_FLAG)) {
+            if (y_start < 0)
                 y_start = y;
             if (page < page_min)
                 page_min = page;
             if (page > page_max)
                 page_max = page;
-	    f(ts, d, s, ts->width);
-	    d += dd;
-	    s += ds;
-	    f(ts, d, s, ts->width);
-	    d += dd;
-	    s += ds;
-	    f(ts, d, s, ts->width);
-	    d += dd;
-	    s += ds;
-	    f(ts, d, s, ts->width);
-	    d += dd;
-	    s += ds;
-	} else {
+            f(ts, d, s, ts->width);
+            d += dd;
+            s += ds;
+            f(ts, d, s, ts->width);
+            d += dd;
+            s += ds;
+            f(ts, d, s, ts->width);
+            d += dd;
+            s += ds;
+            f(ts, d, s, ts->width);
+            d += dd;
+            s += ds;
+        } else {
             if (y_start >= 0) {
                 /* flush to display */
                 dpy_update(ts->ds, 0, y_start,
                            ts->width, y - y_start);
                 y_start = -1;
             }
-	    d += dd * 4;
-	    s += ds * 4;
-	}
+            d += dd * 4;
+            s += ds * 4;
+        }
     }
     if (y_start >= 0) {
-	/* flush to display */
-	dpy_update(ts->ds, 0, y_start,
-		   ts->width, y - y_start);
+        /* flush to display */
+        dpy_update(ts->ds, 0, y_start,
+                   ts->width, y - y_start);
     }
     /* reset modified pages */
     if (page_min <= page_max) {
@@ -334,7 +334,7 @@
     int i;
 
     for (i = 0; i < MAXX*MAXY; i += TARGET_PAGE_SIZE) {
-	cpu_physical_memory_set_dirty(s->vram_offset + i);
+        cpu_physical_memory_set_dirty(s->vram_offset + i);
     }
 }
 
@@ -424,32 +424,32 @@
     saddr = (addr & (TCX_DAC_NREGS - 1)) >> 2;
     switch (saddr) {
     case 0:
-	s->dac_index = val >> 24;
-	s->dac_state = 0;
-	break;
+        s->dac_index = val >> 24;
+        s->dac_state = 0;
+        break;
     case 1:
-	switch (s->dac_state) {
-	case 0:
-	    s->r[s->dac_index] = val >> 24;
+        switch (s->dac_state) {
+        case 0:
+            s->r[s->dac_index] = val >> 24;
             update_palette_entries(s, s->dac_index, s->dac_index + 1);
-	    s->dac_state++;
-	    break;
-	case 1:
-	    s->g[s->dac_index] = val >> 24;
+            s->dac_state++;
+            break;
+        case 1:
+            s->g[s->dac_index] = val >> 24;
             update_palette_entries(s, s->dac_index, s->dac_index + 1);
-	    s->dac_state++;
-	    break;
-	case 2:
-	    s->b[s->dac_index] = val >> 24;
+            s->dac_state++;
+            break;
+        case 2:
+            s->b[s->dac_index] = val >> 24;
             update_palette_entries(s, s->dac_index, s->dac_index + 1);
             s->dac_index = (s->dac_index + 1) & 255; // Index autoincrement
-	default:
-	    s->dac_state = 0;
-	    break;
-	}
-	break;
+        default:
+            s->dac_state = 0;
+            break;
+        }
+        break;
     default:
-	break;
+        break;
     }
     return;
 }

Added: trunk/src/host/qemu-neo1973/hw/tsc210x.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/tsc210x.c	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/hw/tsc210x.c	2007-10-29 21:14:04 UTC (rev 3303)
@@ -0,0 +1,848 @@
+/*
+ * TI TSC2102 (touchscreen/sensors/audio controller) controller.
+ *
+ * Copyright (c) 2006 Andrzej Zaborowski  <balrog at zabor.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include "vl.h"
+
+#define TSC_DATA_REGISTERS_PAGE		0x0
+#define TSC_CONTROL_REGISTERS_PAGE	0x1
+#define TSC_AUDIO_REGISTERS_PAGE	0x2
+
+#define TSC_VERBOSE
+
+#define TSC_CUT_RESOLUTION(value, p)	((value) >> (16 - resolution[p]))
+
+struct tsc210x_state_s {
+    qemu_irq pint;
+    QEMUTimer *timer;
+    struct uwire_slave_s chip;
+
+    int x, y;
+    int pressure;
+
+    int state, page, offset, irq;
+    uint16_t command, dav;
+
+    int busy;
+    int enabled;
+    int host_mode;
+    int function;
+    int nextfunction;
+    int precision;
+    int nextprecision;
+    int filter;
+    int pin_func;
+    int ref;
+    int timing;
+    int noise;
+
+    uint16_t audio_ctrl1;
+    uint16_t audio_ctrl2;
+    uint16_t audio_ctrl3;
+    uint16_t pll[2];
+    uint16_t volume;
+    int64_t volume_change;
+    int softstep;
+    uint16_t dac_power;
+    int64_t powerdown;
+    uint16_t filter_data[0x14];
+};
+
+static const int resolution[4] = { 12, 8, 10, 12 };
+
+#define TSC_MODE_NO_SCAN	0x0
+#define TSC_MODE_XY_SCAN	0x1
+#define TSC_MODE_XYZ_SCAN	0x2
+#define TSC_MODE_X		0x3
+#define TSC_MODE_Y		0x4
+#define TSC_MODE_Z		0x5
+#define TSC_MODE_BAT1		0x6
+#define TSC_MODE_BAT2		0x7
+#define TSC_MODE_AUX		0x8
+#define TSC_MODE_AUX_SCAN	0x9
+#define TSC_MODE_TEMP1		0xa
+#define TSC_MODE_PORT_SCAN	0xb
+#define TSC_MODE_TEMP2		0xc
+#define TSC_MODE_XX_DRV		0xd
+#define TSC_MODE_YY_DRV		0xe
+#define TSC_MODE_YX_DRV		0xf
+
+static const uint16_t mode_regs[16] = {
+    0x0000,	/* No scan */
+    0x0600,	/* X, Y scan */
+    0x0780,	/* X, Y, Z scan */
+    0x0400,	/* X */
+    0x0200,	/* Y */
+    0x0180,	/* Z */
+    0x0040,	/* BAT1 */
+    0x0030,	/* BAT2 */
+    0x0010,	/* AUX */
+    0x0010,	/* AUX scan */
+    0x0004,	/* TEMP1 */
+    0x0070,	/* Port scan */
+    0x0002,	/* TEMP2 */
+    0x0000,	/* X+, X- drivers */
+    0x0000,	/* Y+, Y- drivers */
+    0x0000,	/* Y+, X- drivers */
+};
+
+/*
+ * Convert screen coordinates to arbitrary values that the
+ * touchscreen in my Palm Tungsten E device returns.
+ * This shouldn't really matter (because the guest system
+ * should calibrate the touchscreen anyway), but let's
+ * imitate some real hardware.
+ */
+#define X_TRANSFORM(value)		\
+    ((3850 - ((int) (value) * (3850 - 250) / 32768)) << 4)
+#define Y_TRANSFORM(value)		\
+    ((150 + ((int) (value) * (3037 - 150) / 32768)) << 4)
+#define Z1_TRANSFORM(s)			\
+    ((400 - (s)->x + ((s)->pressure << 9)) << 4)
+#define Z2_TRANSFORM(s)			\
+    ((4000 + (s)->y - ((s)->pressure << 10)) << 4)
+#define BAT1_VAL			0x8660
+#define BAT2_VAL			0x0000
+#define AUX1_VAL			0x35c0
+#define AUX2_VAL			0xffff
+#define TEMP1_VAL			0x8c70
+#define TEMP2_VAL			0xa5b0
+
+#define TSC_POWEROFF_DELAY		50
+#define TSC_SOFTSTEP_DELAY		50
+
+static void tsc210x_reset(struct tsc210x_state_s *s)
+{
+    s->state = 0;
+    s->pin_func = 2;
+    s->enabled = 0;
+    s->busy = 0;
+    s->nextfunction = 0;
+    s->ref = 0;
+    s->timing = 0;
+    s->irq = 0;
+    s->dav = 0;
+
+    s->audio_ctrl1 = 0x0000;
+    s->audio_ctrl2 = 0x4410;
+    s->audio_ctrl3 = 0x0000;
+    s->pll[0] = 0x1004;
+    s->pll[1] = 0x0000;
+    s->volume = 0xffff;
+    s->dac_power = 0x8540;
+    s->softstep = 1;
+    s->volume_change = 0;
+    s->powerdown = 0;
+    s->filter_data[0x00] = 0x6be3;
+    s->filter_data[0x01] = 0x9666;
+    s->filter_data[0x02] = 0x675d;
+    s->filter_data[0x03] = 0x6be3;
+    s->filter_data[0x04] = 0x9666;
+    s->filter_data[0x05] = 0x675d;
+    s->filter_data[0x06] = 0x7d83;
+    s->filter_data[0x07] = 0x84ee;
+    s->filter_data[0x08] = 0x7d83;
+    s->filter_data[0x09] = 0x84ee;
+    s->filter_data[0x0a] = 0x6be3;
+    s->filter_data[0x0b] = 0x9666;
+    s->filter_data[0x0c] = 0x675d;
+    s->filter_data[0x0d] = 0x6be3;
+    s->filter_data[0x0e] = 0x9666;
+    s->filter_data[0x0f] = 0x675d;
+    s->filter_data[0x10] = 0x7d83;
+    s->filter_data[0x11] = 0x84ee;
+    s->filter_data[0x12] = 0x7d83;
+    s->filter_data[0x13] = 0x84ee;
+
+    qemu_set_irq(s->pint, s->irq);
+}
+
+static uint16_t tsc2102_data_register_read(struct tsc210x_state_s *s, int reg)
+{
+    switch (reg) {
+    case 0x00:	/* X */
+        s->dav &= 0xfbff;
+        return TSC_CUT_RESOLUTION(X_TRANSFORM(s->x), s->precision) +
+                (s->noise & 3);
+
+    case 0x01:	/* Y */
+        s->noise ++;
+        s->dav &= 0xfdff;
+        return TSC_CUT_RESOLUTION(Y_TRANSFORM(s->y), s->precision) ^
+                (s->noise & 3);
+
+    case 0x02:	/* Z1 */
+        s->dav &= 0xfeff;
+        return TSC_CUT_RESOLUTION(Z1_TRANSFORM(s), s->precision) -
+                (s->noise & 3);
+
+    case 0x03:	/* Z2 */
+        s->dav &= 0xff7f;
+        return TSC_CUT_RESOLUTION(Z2_TRANSFORM(s), s->precision) |
+                (s->noise & 3);
+
+    case 0x04:	/* KPData */
+        return 0xffff;
+
+    case 0x05:	/* BAT1 */
+        s->dav &= 0xffbf;
+        return TSC_CUT_RESOLUTION(BAT1_VAL, s->precision);
+
+    case 0x06:	/* BAT2 */
+        s->dav &= 0xffdf;
+        return TSC_CUT_RESOLUTION(BAT2_VAL, s->precision);
+
+    case 0x07:	/* AUX1 */
+        s->dav &= 0xffef;
+        return TSC_CUT_RESOLUTION(AUX1_VAL, s->precision);
+
+    case 0x08:	/* AUX2 */
+        s->dav &= 0xfff7;
+        return 0xffff;
+
+    case 0x09:	/* TEMP1 */
+        s->dav &= 0xfffb;
+        return TSC_CUT_RESOLUTION(TEMP1_VAL, s->precision);
+
+    case 0x0a:	/* TEMP2 */
+        s->dav &= 0xfffd;
+        return TSC_CUT_RESOLUTION(TEMP2_VAL, s->precision);
+
+    case 0x0b:	/* DAC */
+        s->dav &= 0xfffe;
+        return 0xffff;
+
+    default:
+#ifdef TSC_VERBOSE
+        fprintf(stderr, "tsc2102_data_register_read: "
+                        "no such register: 0x%02x\n", reg);
+#endif
+        return 0xffff;
+    }
+}
+
+static uint16_t tsc2102_control_register_read(
+                struct tsc210x_state_s *s, int reg)
+{
+    switch (reg) {
+    case 0x00:	/* TSC ADC */
+        return (s->pressure << 15) | ((!s->busy) << 14) |
+                (s->nextfunction << 10) | (s->nextprecision << 8) | s->filter; 
+
+    case 0x01:	/* Status */
+        return (s->pin_func << 14) | ((!s->enabled) << 13) |
+                (s->host_mode << 12) | ((!!s->dav) << 11) | s->dav;
+
+    case 0x03:	/* Reference */
+        return s->ref;
+
+    case 0x04:	/* Reset */
+        return 0xffff;
+
+    case 0x05:	/* Configuration */
+        return s->timing;
+
+    default:
+#ifdef TSC_VERBOSE
+        fprintf(stderr, "tsc2102_control_register_read: "
+                        "no such register: 0x%02x\n", reg);
+#endif
+        return 0xffff;
+    }
+}
+
+static uint16_t tsc2102_audio_register_read(struct tsc210x_state_s *s, int reg)
+{
+    int l_ch, r_ch;
+    uint16_t val;
+
+    switch (reg) {
+    case 0x00:	/* Audio Control 1 */
+        return s->audio_ctrl1;
+
+    case 0x01:
+        return 0xff00;
+
+    case 0x02:	/* DAC Volume Control */
+        return s->volume;
+
+    case 0x03:
+        return 0x8b00;
+
+    case 0x04:	/* Audio Control 2 */
+        l_ch = 1;
+        r_ch = 1;
+        if (s->softstep && !(s->dac_power & (1 << 10))) {
+            l_ch = (qemu_get_clock(vm_clock) >
+                            s->volume_change + TSC_SOFTSTEP_DELAY);
+            r_ch = (qemu_get_clock(vm_clock) >
+                            s->volume_change + TSC_SOFTSTEP_DELAY);
+        }
+
+        return s->audio_ctrl2 | (l_ch << 3) | (r_ch << 2);
+
+    case 0x05:	/* Stereo DAC Power Control */
+        return 0x2aa0 | s->dac_power |
+                (((s->dac_power & (1 << 10)) &&
+                  (qemu_get_clock(vm_clock) >
+                   s->powerdown + TSC_POWEROFF_DELAY)) << 6);
+
+    case 0x06:	/* Audio Control 3 */
+        val = s->audio_ctrl3 | 0x0001;
+        s->audio_ctrl3 &= 0xff3f;
+        return val;
+
+    case 0x07:	/* LCH_BASS_BOOST_N0 */
+    case 0x08:	/* LCH_BASS_BOOST_N1 */
+    case 0x09:	/* LCH_BASS_BOOST_N2 */
+    case 0x0a:	/* LCH_BASS_BOOST_N3 */
+    case 0x0b:	/* LCH_BASS_BOOST_N4 */
+    case 0x0c:	/* LCH_BASS_BOOST_N5 */
+    case 0x0d:	/* LCH_BASS_BOOST_D1 */
+    case 0x0e:	/* LCH_BASS_BOOST_D2 */
+    case 0x0f:	/* LCH_BASS_BOOST_D4 */
+    case 0x10:	/* LCH_BASS_BOOST_D5 */
+    case 0x11:	/* RCH_BASS_BOOST_N0 */
+    case 0x12:	/* RCH_BASS_BOOST_N1 */
+    case 0x13:	/* RCH_BASS_BOOST_N2 */
+    case 0x14:	/* RCH_BASS_BOOST_N3 */
+    case 0x15:	/* RCH_BASS_BOOST_N4 */
+    case 0x16:	/* RCH_BASS_BOOST_N5 */
+    case 0x17:	/* RCH_BASS_BOOST_D1 */
+    case 0x18:	/* RCH_BASS_BOOST_D2 */
+    case 0x19:	/* RCH_BASS_BOOST_D4 */
+    case 0x1a:	/* RCH_BASS_BOOST_D5 */
+        return s->filter_data[reg - 0x07];
+
+    case 0x1b:	/* PLL Programmability 1 */
+        return s->pll[0];
+
+    case 0x1c:	/* PLL Programmability 2 */
+        return s->pll[1];
+
+    case 0x1d:	/* Audio Control 4 */
+        return (!s->softstep) << 14;
+
+    default:
+#ifdef TSC_VERBOSE
+        fprintf(stderr, "tsc2102_audio_register_read: "
+                        "no such register: 0x%02x\n", reg);
+#endif
+        return 0xffff;
+    }
+}
+
+static void tsc2102_data_register_write(
+                struct tsc210x_state_s *s, int reg, uint16_t value)
+{
+    switch (reg) {
+    case 0x00:	/* X */
+    case 0x01:	/* Y */
+    case 0x02:	/* Z1 */
+    case 0x03:	/* Z2 */
+    case 0x05:	/* BAT1 */
+    case 0x06:	/* BAT2 */
+    case 0x07:	/* AUX1 */
+    case 0x08:	/* AUX2 */
+    case 0x09:	/* TEMP1 */
+    case 0x0a:	/* TEMP2 */
+        return;
+
+    default:
+#ifdef TSC_VERBOSE
+        fprintf(stderr, "tsc2102_data_register_write: "
+                        "no such register: 0x%02x\n", reg);
+#endif
+    }
+}
+
+static void tsc2102_control_register_write(
+                struct tsc210x_state_s *s, int reg, uint16_t value)
+{
+    switch (reg) {
+    case 0x00:	/* TSC ADC */
+        s->host_mode = value >> 15;
+        s->enabled = !(value & 0x4000);
+        if (s->busy && !s->enabled)
+            qemu_del_timer(s->timer);
+        s->busy &= s->enabled;
+        s->nextfunction = (value >> 10) & 0xf;
+        s->nextprecision = (value >> 8) & 3;
+        s->filter = value & 0xff;
+        return;
+
+    case 0x01:	/* Status */
+        s->pin_func = value >> 14;
+        return;
+
+    case 0x03:	/* Reference */
+        s->ref = value & 0x1f;
+        return;
+
+    case 0x04:	/* Reset */
+        if (value == 0xbb00) {
+            if (s->busy)
+                qemu_del_timer(s->timer);
+            tsc210x_reset(s);
+#ifdef TSC_VERBOSE
+        } else {
+            fprintf(stderr, "tsc2102_control_register_write: "
+                            "wrong value written into RESET\n");
+#endif
+        }
+        return;
+
+    case 0x05:	/* Configuration */
+        s->timing = value & 0x3f;
+#ifdef TSC_VERBOSE
+        if (value & ~0x3f)
+            fprintf(stderr, "tsc2102_control_register_write: "
+                            "wrong value written into CONFIG\n");
+#endif
+        return;
+
+    default:
+#ifdef TSC_VERBOSE
+        fprintf(stderr, "tsc2102_control_register_write: "
+                        "no such register: 0x%02x\n", reg);
+#endif
+    }
+}
+
+static void tsc2102_audio_register_write(
+                struct tsc210x_state_s *s, int reg, uint16_t value)
+{
+    switch (reg) {
+    case 0x00:	/* Audio Control 1 */
+        s->audio_ctrl1 = value & 0x0f3f;
+#ifdef TSC_VERBOSE
+        if ((value & ~0x0f3f) || ((value & 7) != ((value >> 3) & 7)))
+            fprintf(stderr, "tsc2102_audio_register_write: "
+                            "wrong value written into Audio 1\n");
+#endif
+        return;
+
+    case 0x01:
+#ifdef TSC_VERBOSE
+        if (value != 0xff00)
+            fprintf(stderr, "tsc2102_audio_register_write: "
+                            "wrong value written into reg 0x01\n");
+#endif
+        return;
+
+    case 0x02:	/* DAC Volume Control */
+        s->volume = value;
+        s->volume_change = qemu_get_clock(vm_clock);
+        return;
+
+    case 0x03:
+#ifdef TSC_VERBOSE
+        if (value != 0x8b00)
+            fprintf(stderr, "tsc2102_audio_register_write: "
+                            "wrong value written into reg 0x03\n");
+#endif
+        return;
+
+    case 0x04:	/* Audio Control 2 */
+        s->audio_ctrl2 = value & 0xf7f2;
+#ifdef TSC_VERBOSE
+        if (value & ~0xf7fd)
+            fprintf(stderr, "tsc2102_audio_register_write: "
+                            "wrong value written into Audio 2\n");
+#endif
+        return;
+
+    case 0x05:	/* Stereo DAC Power Control */
+        if ((value & ~s->dac_power) & (1 << 10))
+            s->powerdown = qemu_get_clock(vm_clock);
+
+        s->dac_power = value & 0x9543;
+#ifdef TSC_VERBOSE
+        if ((value & ~0x9543) != 0x2aa0)
+            fprintf(stderr, "tsc2102_audio_register_write: "
+                            "wrong value written into Power\n");
+#endif
+        return;
+
+    case 0x06:	/* Audio Control 3 */
+        s->audio_ctrl3 &= 0x00c0;
+        s->audio_ctrl3 |= value & 0xf800;
+#ifdef TSC_VERBOSE
+        if (value & ~0xf8c7)
+            fprintf(stderr, "tsc2102_audio_register_write: "
+                            "wrong value written into Audio 3\n");
+#endif
+        return;
+
+    case 0x07:	/* LCH_BASS_BOOST_N0 */
+    case 0x08:	/* LCH_BASS_BOOST_N1 */
+    case 0x09:	/* LCH_BASS_BOOST_N2 */
+    case 0x0a:	/* LCH_BASS_BOOST_N3 */
+    case 0x0b:	/* LCH_BASS_BOOST_N4 */
+    case 0x0c:	/* LCH_BASS_BOOST_N5 */
+    case 0x0d:	/* LCH_BASS_BOOST_D1 */
+    case 0x0e:	/* LCH_BASS_BOOST_D2 */
+    case 0x0f:	/* LCH_BASS_BOOST_D4 */
+    case 0x10:	/* LCH_BASS_BOOST_D5 */
+    case 0x11:	/* RCH_BASS_BOOST_N0 */
+    case 0x12:	/* RCH_BASS_BOOST_N1 */
+    case 0x13:	/* RCH_BASS_BOOST_N2 */
+    case 0x14:	/* RCH_BASS_BOOST_N3 */
+    case 0x15:	/* RCH_BASS_BOOST_N4 */
+    case 0x16:	/* RCH_BASS_BOOST_N5 */
+    case 0x17:	/* RCH_BASS_BOOST_D1 */
+    case 0x18:	/* RCH_BASS_BOOST_D2 */
+    case 0x19:	/* RCH_BASS_BOOST_D4 */
+    case 0x1a:	/* RCH_BASS_BOOST_D5 */
+        s->filter_data[reg - 0x07] = value;
+        return;
+
+    case 0x1b:	/* PLL Programmability 1 */
+        s->pll[0] = value & 0xfffc;
+#ifdef TSC_VERBOSE
+        if (value & ~0xfffc)
+            fprintf(stderr, "tsc2102_audio_register_write: "
+                            "wrong value written into PLL 1\n");
+#endif
+        return;
+
+    case 0x1c:	/* PLL Programmability 2 */
+        s->pll[1] = value & 0xfffc;
+#ifdef TSC_VERBOSE
+        if (value & ~0xfffc)
+            fprintf(stderr, "tsc2102_audio_register_write: "
+                            "wrong value written into PLL 2\n");
+#endif
+        return;
+
+    case 0x1d:	/* Audio Control 4 */
+        s->softstep = !(value & 0x4000);
+#ifdef TSC_VERBOSE
+        if (value & ~0x4000)
+            fprintf(stderr, "tsc2102_audio_register_write: "
+                            "wrong value written into Audio 4\n");
+#endif
+        return;
+
+    default:
+#ifdef TSC_VERBOSE
+        fprintf(stderr, "tsc2102_audio_register_write: "
+                        "no such register: 0x%02x\n", reg);
+#endif
+    }
+}
+
+/* This handles most of the chip logic.  */
+static void tsc210x_pin_update(struct tsc210x_state_s *s)
+{
+    int64_t expires;
+    int pin_state;
+
+    switch (s->pin_func) {
+    case 0:
+        pin_state = s->pressure;
+        break;
+    case 1:
+        pin_state = !!s->dav;
+        break;
+    case 2:
+    default:
+        pin_state = s->pressure && !s->dav;
+    }
+
+    if (!s->enabled)
+        pin_state = 0;
+
+    if (pin_state != s->irq) {
+        s->irq = pin_state;
+        qemu_set_irq(s->pint, s->irq);
+    }
+
+    switch (s->nextfunction) {
+    case TSC_MODE_XY_SCAN:
+    case TSC_MODE_XYZ_SCAN:
+        if (!s->pressure)
+            return;
+        break;
+
+    case TSC_MODE_X:
+    case TSC_MODE_Y:
+    case TSC_MODE_Z:
+        if (!s->pressure)
+            return;
+        /* Fall through */
+    case TSC_MODE_BAT1:
+    case TSC_MODE_BAT2:
+    case TSC_MODE_AUX:
+    case TSC_MODE_TEMP1:
+    case TSC_MODE_TEMP2:
+        if (s->dav)
+            s->enabled = 0;
+        break;
+
+    case TSC_MODE_AUX_SCAN:
+    case TSC_MODE_PORT_SCAN:
+        break;
+
+    case TSC_MODE_NO_SCAN:
+    case TSC_MODE_XX_DRV:
+    case TSC_MODE_YY_DRV:
+    case TSC_MODE_YX_DRV:
+    default:
+        return;
+    }
+
+    if (!s->enabled || s->busy)
+        return;
+
+    s->busy = 1;
+    s->precision = s->nextprecision;
+    s->function = s->nextfunction;
+    expires = qemu_get_clock(vm_clock) + (ticks_per_sec >> 10);
+    qemu_mod_timer(s->timer, expires);
+}
+
+static uint16_t tsc210x_read(struct tsc210x_state_s *s)
+{
+    uint16_t ret = 0x0000;
+
+    if (!s->command)
+        fprintf(stderr, "tsc210x_read: SPI underrun!\n");
+
+    switch (s->page) {
+    case TSC_DATA_REGISTERS_PAGE:
+        ret = tsc2102_data_register_read(s, s->offset);
+        break;
+    case TSC_CONTROL_REGISTERS_PAGE:
+        ret = tsc2102_control_register_read(s, s->offset);
+        break;
+    case TSC_AUDIO_REGISTERS_PAGE:
+        ret = tsc2102_audio_register_read(s, s->offset);
+        break;
+    default:
+        cpu_abort(cpu_single_env, "tsc210x_read: wrong memory page\n");
+    }
+
+    tsc210x_pin_update(s);
+
+    /* Allow sequential reads.  */
+    s->offset ++;
+    s->state = 0;
+    return ret;
+}
+
+static void tsc210x_write(struct tsc210x_state_s *s, uint16_t value)
+{
+    /*
+     * This is a two-state state machine for reading
+     * command and data every second time.
+     */
+    if (!s->state) {
+        s->command = value >> 15;
+        s->page = (value >> 11) & 0x0f;
+        s->offset = (value >> 5) & 0x3f;
+        s->state = 1;
+    } else {
+        if (s->command)
+            fprintf(stderr, "tsc210x_write: SPI overrun!\n");
+        else
+            switch (s->page) {
+            case TSC_DATA_REGISTERS_PAGE:
+                tsc2102_data_register_write(s, s->offset, value);
+                break;
+            case TSC_CONTROL_REGISTERS_PAGE:
+                tsc2102_control_register_write(s, s->offset, value);
+                break;
+            case TSC_AUDIO_REGISTERS_PAGE:
+                tsc2102_audio_register_write(s, s->offset, value);
+                break;
+            default:
+                cpu_abort(cpu_single_env,
+                                "tsc210x_write: wrong memory page\n");
+            }
+
+        tsc210x_pin_update(s);
+        s->state = 0;
+    }
+}
+
+static void tsc210x_timer_tick(void *opaque)
+{
+    struct tsc210x_state_s *s = opaque;
+
+    /* Timer ticked -- a set of conversions has been finished.  */
+
+    if (!s->busy)
+        return;
+
+    s->busy = 0;
+    s->dav |= mode_regs[s->function];
+    tsc210x_pin_update(s);
+}
+
+static void tsc210x_touchscreen_event(void *opaque,
+                int x, int y, int z, int buttons_state)
+{
+    struct tsc210x_state_s *s = opaque;
+    int p = s->pressure;
+
+    if (buttons_state) {
+        s->x = x;
+        s->y = y;
+    }
+    s->pressure = !!buttons_state;
+
+    /*
+     * Note: We would get better responsiveness in the guest by
+     * signaling TS events immediately, but for now we simulate
+     * the first conversion delay for sake of correctness.
+     */
+    if (p != s->pressure)
+        tsc210x_pin_update(s);
+}
+
+static void tsc210x_save(QEMUFile *f, void *opaque)
+{
+    struct tsc210x_state_s *s = (struct tsc210x_state_s *) opaque;
+    int64_t now = qemu_get_clock(vm_clock);
+    int i;
+
+    qemu_put_be16(f, s->x);
+    qemu_put_be16(f, s->y);
+    qemu_put_byte(f, s->pressure);
+
+    qemu_put_byte(f, s->state);
+    qemu_put_byte(f, s->page);
+    qemu_put_byte(f, s->offset);
+    qemu_put_byte(f, s->command);
+
+    qemu_put_byte(f, s->irq);
+    qemu_put_be16s(f, &s->dav);
+
+    qemu_put_timer(f, s->timer);
+    qemu_put_byte(f, s->enabled);
+    qemu_put_byte(f, s->host_mode);
+    qemu_put_byte(f, s->function);
+    qemu_put_byte(f, s->nextfunction);
+    qemu_put_byte(f, s->precision);
+    qemu_put_byte(f, s->nextprecision);
+    qemu_put_byte(f, s->filter);
+    qemu_put_byte(f, s->pin_func);
+    qemu_put_byte(f, s->ref);
+    qemu_put_byte(f, s->timing);
+    qemu_put_be32(f, s->noise);
+
+    qemu_put_be16s(f, &s->audio_ctrl1);
+    qemu_put_be16s(f, &s->audio_ctrl2);
+    qemu_put_be16s(f, &s->audio_ctrl3);
+    qemu_put_be16s(f, &s->pll[0]);
+    qemu_put_be16s(f, &s->pll[1]);
+    qemu_put_be16s(f, &s->volume);
+    qemu_put_be64(f, (uint64_t) (s->volume_change - now));
+    qemu_put_be64(f, (uint64_t) (s->powerdown - now));
+    qemu_put_byte(f, s->softstep);
+    qemu_put_be16s(f, &s->dac_power);
+
+    for (i = 0; i < 0x14; i ++)
+        qemu_put_be16s(f, &s->filter_data[i]);
+}
+
+static int tsc210x_load(QEMUFile *f, void *opaque, int version_id)
+{
+    struct tsc210x_state_s *s = (struct tsc210x_state_s *) opaque;
+    int64_t now = qemu_get_clock(vm_clock);
+    int i;
+
+    s->x = qemu_get_be16(f);
+    s->y = qemu_get_be16(f);
+    s->pressure = qemu_get_byte(f);
+
+    s->state = qemu_get_byte(f);
+    s->page = qemu_get_byte(f);
+    s->offset = qemu_get_byte(f);
+    s->command = qemu_get_byte(f);
+
+    s->irq = qemu_get_byte(f);
+    qemu_get_be16s(f, &s->dav);
+
+    qemu_get_timer(f, s->timer);
+    s->enabled = qemu_get_byte(f);
+    s->host_mode = qemu_get_byte(f);
+    s->function = qemu_get_byte(f);
+    s->nextfunction = qemu_get_byte(f);
+    s->precision = qemu_get_byte(f);
+    s->nextprecision = qemu_get_byte(f);
+    s->filter = qemu_get_byte(f);
+    s->pin_func = qemu_get_byte(f);
+    s->ref = qemu_get_byte(f);
+    s->timing = qemu_get_byte(f);
+    s->noise = qemu_get_be32(f);
+
+    qemu_get_be16s(f, &s->audio_ctrl1);
+    qemu_get_be16s(f, &s->audio_ctrl2);
+    qemu_get_be16s(f, &s->audio_ctrl3);
+    qemu_get_be16s(f, &s->pll[0]);
+    qemu_get_be16s(f, &s->pll[1]);
+    qemu_get_be16s(f, &s->volume);
+    s->volume_change = (int64_t) qemu_get_be64(f) + now;
+    s->powerdown = (int64_t) qemu_get_be64(f) + now;
+    s->softstep = qemu_get_byte(f);
+    qemu_get_be16s(f, &s->dac_power);
+
+    for (i = 0; i < 0x14; i ++)
+        qemu_get_be16s(f, &s->filter_data[i]);
+
+    s->busy = qemu_timer_pending(s->timer);
+    qemu_set_irq(s->pint, s->irq);
+
+    return 0;
+}
+
+static int tsc2102_iid = 0;
+
+struct uwire_slave_s *tsc2102_init(qemu_irq pint)
+{
+    struct tsc210x_state_s *s;
+
+    s = (struct tsc210x_state_s *)
+            qemu_mallocz(sizeof(struct tsc210x_state_s));
+    memset(s, 0, sizeof(struct tsc210x_state_s));
+    s->x = 160;
+    s->y = 160;
+    s->pressure = 0;
+    s->precision = s->nextprecision = 0;
+    s->timer = qemu_new_timer(vm_clock, tsc210x_timer_tick, s);
+    s->pint = pint;
+
+    s->chip.opaque = s;
+    s->chip.send = (void *) tsc210x_write;
+    s->chip.receive = (void *) tsc210x_read;
+
+    tsc210x_reset(s);
+
+    qemu_add_mouse_event_handler(tsc210x_touchscreen_event, s, 1,
+                    "QEMU TSC2102-driven Touchscreen");
+
+    qemu_register_reset((void *) tsc210x_reset, s);
+    register_savevm("tsc2102", tsc2102_iid ++, 0,
+                    tsc210x_save, tsc210x_load, s);
+
+    return &s->chip;
+}

Modified: trunk/src/host/qemu-neo1973/hw/usb-uhci.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/usb-uhci.c	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/hw/usb-uhci.c	2007-10-29 21:14:04 UTC (rev 3303)
@@ -25,6 +25,7 @@
 
 //#define DEBUG
 //#define DEBUG_PACKET
+//#define DEBUG_ISOCH
 
 #define UHCI_CMD_FGR      (1 << 4)
 #define UHCI_CMD_EGSM     (1 << 3)
@@ -88,6 +89,7 @@
        other queues will not be processed until the next frame.  The solution
        is to allow multiple pending requests.  */
     uint32_t async_qh;
+    uint32_t async_frame_addr;
     USBPacket usb_packet;
     uint8_t usb_buf[2048];
 } UHCIState;
@@ -146,6 +148,58 @@
     }
 }
 
+static void uhci_save(QEMUFile *f, void *opaque)
+{
+    UHCIState *s = opaque;
+    uint8_t num_ports = NB_PORTS;
+    int i;
+
+    pci_device_save(&s->dev, f);
+
+    qemu_put_8s(f, &num_ports);
+    for (i = 0; i < num_ports; ++i)
+        qemu_put_be16s(f, &s->ports[i].ctrl);
+    qemu_put_be16s(f, &s->cmd);
+    qemu_put_be16s(f, &s->status);
+    qemu_put_be16s(f, &s->intr);
+    qemu_put_be16s(f, &s->frnum);
+    qemu_put_be32s(f, &s->fl_base_addr);
+    qemu_put_8s(f, &s->sof_timing);
+    qemu_put_8s(f, &s->status2);
+    qemu_put_timer(f, s->frame_timer);
+}
+
+static int uhci_load(QEMUFile *f, void *opaque, int version_id)
+{
+    UHCIState *s = opaque;
+    uint8_t num_ports;
+    int i, ret;
+
+    if (version_id > 1)
+        return -EINVAL;
+
+    ret = pci_device_load(&s->dev, f);
+    if (ret < 0)
+        return ret;
+
+    qemu_get_8s(f, &num_ports);
+    if (num_ports != NB_PORTS)
+        return -EINVAL;
+
+    for (i = 0; i < num_ports; ++i)
+        qemu_get_be16s(f, &s->ports[i].ctrl);
+    qemu_get_be16s(f, &s->cmd);
+    qemu_get_be16s(f, &s->status);
+    qemu_get_be16s(f, &s->intr);
+    qemu_get_be16s(f, &s->frnum);
+    qemu_get_be32s(f, &s->fl_base_addr);
+    qemu_get_8s(f, &s->sof_timing);
+    qemu_get_8s(f, &s->status2);
+    qemu_get_timer(f, s->frame_timer);
+
+    return 0;
+}
+
 static void uhci_ioport_writeb(void *opaque, uint32_t addr, uint32_t val)
 {
     UHCIState *s = opaque;
@@ -449,10 +503,11 @@
           0 if TD successful
           1 if TD unsuccessful or inactive
 */
-static int uhci_handle_td(UHCIState *s, UHCI_TD *td, int *int_mask)
+static int uhci_handle_td(UHCIState *s, UHCI_TD *td, int *int_mask,
+                          int completion)
 {
     uint8_t pid;
-    int len, max_len, err, ret;
+    int len = 0, max_len, err, ret = 0;
 
     /* ??? This is wrong for async completion.  */
     if (td->ctrl & TD_CTRL_IOC) {
@@ -465,7 +520,8 @@
     /* TD is active */
     max_len = ((td->token >> 21) + 1) & 0x7ff;
     pid = td->token & 0xff;
-    if (s->async_qh) {
+
+    if (completion && (s->async_qh || s->async_frame_addr)) {
         ret = s->usb_packet.len;
         if (ret >= 0) {
             len = ret;
@@ -481,7 +537,8 @@
             len = 0;
         }
         s->async_qh = 0;
-    } else {
+        s->async_frame_addr = 0;
+    } else if (!completion) {
         s->usb_packet.pid = pid;
         s->usb_packet.devaddr = (td->token >> 8) & 0x7f;
         s->usb_packet.devep = (td->token >> 15) & 0xf;
@@ -519,6 +576,7 @@
             return -1;
         }
     }
+
     if (ret == USB_RET_ASYNC) {
         return 2;
     }
@@ -584,8 +642,42 @@
     uint32_t link;
     uint32_t old_td_ctrl;
     uint32_t val;
+    uint32_t frame_addr;
     int ret;
 
+    /* Handle async isochronous packet completion */
+    frame_addr = s->async_frame_addr;
+    if (frame_addr) {
+        cpu_physical_memory_read(frame_addr, (uint8_t *)&link, 4);
+        le32_to_cpus(&link);
+
+        cpu_physical_memory_read(link & ~0xf, (uint8_t *)&td, sizeof(td));
+        le32_to_cpus(&td.link);
+        le32_to_cpus(&td.ctrl);
+        le32_to_cpus(&td.token);
+        le32_to_cpus(&td.buffer);
+        old_td_ctrl = td.ctrl;
+        ret = uhci_handle_td(s, &td, &s->pending_int_mask, 1);
+
+        /* update the status bits of the TD */
+        if (old_td_ctrl != td.ctrl) {
+            val = cpu_to_le32(td.ctrl);
+            cpu_physical_memory_write((link & ~0xf) + 4,
+                                      (const uint8_t *)&val,
+                                      sizeof(val));
+        }
+        if (ret == 2) {
+            s->async_frame_addr = frame_addr;
+        } else if (ret == 0) {
+            /* update qh element link */
+            val = cpu_to_le32(td.link);
+            cpu_physical_memory_write(frame_addr,
+                                      (const uint8_t *)&val,
+                                      sizeof(val));
+        }
+        return;
+    }
+
     link = s->async_qh;
     if (!link) {
         /* This should never happen. It means a TD somehow got removed
@@ -604,7 +696,8 @@
         le32_to_cpus(&td.token);
         le32_to_cpus(&td.buffer);
         old_td_ctrl = td.ctrl;
-        ret = uhci_handle_td(s, &td, &s->pending_int_mask);
+        ret = uhci_handle_td(s, &td, &s->pending_int_mask, 1);
+
         /* update the status bits of the TD */
         if (old_td_ctrl != td.ctrl) {
             val = cpu_to_le32(td.ctrl);
@@ -697,7 +790,8 @@
                 le32_to_cpus(&td.token);
                 le32_to_cpus(&td.buffer);
                 old_td_ctrl = td.ctrl;
-                ret = uhci_handle_td(s, &td, &int_mask);
+                ret = uhci_handle_td(s, &td, &int_mask, 0);
+
                 /* update the status bits of the TD */
                 if (old_td_ctrl != td.ctrl) {
                     val = cpu_to_le32(td.ctrl);
@@ -731,28 +825,24 @@
             le32_to_cpus(&td.ctrl);
             le32_to_cpus(&td.token);
             le32_to_cpus(&td.buffer);
-            /* Ignore isochonous transfers while there is an async packet
-               pending.  This is wrong, but we don't implement isochronous
-               transfers anyway.  */
-            if (s->async_qh == 0) {
-                old_td_ctrl = td.ctrl;
-                ret = uhci_handle_td(s, &td, &int_mask);
-                /* update the status bits of the TD */
-                if (old_td_ctrl != td.ctrl) {
-                    val = cpu_to_le32(td.ctrl);
-                    cpu_physical_memory_write((link & ~0xf) + 4,
-                                              (const uint8_t *)&val,
-                                              sizeof(val));
-                }
-                if (ret < 0)
-                    break; /* interrupted frame */
-                if (ret == 2) {
-                    /* We can't handle async isochronous transfers.
-                       Cancel The packet.  */
-                    fprintf(stderr, "usb-uhci: Unimplemented async packet\n");
-                    usb_cancel_packet(&s->usb_packet);
-                }
+
+            /* Handle isochonous transfer.  */
+            /* FIXME: might be more than one isoc in frame */
+            old_td_ctrl = td.ctrl;
+            ret = uhci_handle_td(s, &td, &int_mask, 0);
+
+            /* update the status bits of the TD */
+            if (old_td_ctrl != td.ctrl) {
+                val = cpu_to_le32(td.ctrl);
+                cpu_physical_memory_write((link & ~0xf) + 4,
+                                          (const uint8_t *)&val,
+                                          sizeof(val));
             }
+            if (ret < 0)
+                break; /* interrupted frame */
+            if (ret == 2) {
+                s->async_frame_addr = frame_addr;
+            }
             link = td.link;
         }
     }
@@ -767,6 +857,7 @@
         usb_cancel_packet(&s->usb_packet);
         s->async_qh = 0;
     }
+
     /* prepare the timer for the next frame */
     expire_time = qemu_get_clock(vm_clock) +
         (ticks_per_sec / FRAME_TIMER_FREQ);
@@ -855,4 +946,3 @@
     pci_register_io_region(&s->dev, 4, 0x20,
                            PCI_ADDRESS_SPACE_IO, uhci_map);
 }
-

Modified: trunk/src/host/qemu-neo1973/hw/vmport.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/vmport.c	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/hw/vmport.c	2007-10-29 21:14:04 UTC (rev 3303)
@@ -52,7 +52,7 @@
 {
     VMPortState *s = opaque;
     unsigned char command;
-    target_ulong eax;
+    uint32_t eax;
 
     eax = s->env->regs[R_EAX];
     if (eax != VMPORT_MAGIC)

Modified: trunk/src/host/qemu-neo1973/linux-user/alpha/syscall.h
===================================================================
--- trunk/src/host/qemu-neo1973/linux-user/alpha/syscall.h	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/linux-user/alpha/syscall.h	2007-10-29 21:14:04 UTC (rev 3303)
@@ -2,40 +2,40 @@
 #define __USER_DS	(1)
 
 struct target_pt_regs {
-	target_ulong r0;
-	target_ulong r1;
-	target_ulong r2;
-	target_ulong r3;
-	target_ulong r4;
-	target_ulong r5;
-	target_ulong r6;
-	target_ulong r7;
-	target_ulong r8;
-	target_ulong r19;
-	target_ulong r20;
-	target_ulong r21;
-	target_ulong r22;
-	target_ulong r23;
-	target_ulong r24;
-	target_ulong r25;
-	target_ulong r26;
-	target_ulong r27;
-	target_ulong r28;
-	target_ulong hae;
+	abi_ulong r0;
+	abi_ulong r1;
+	abi_ulong r2;
+	abi_ulong r3;
+	abi_ulong r4;
+	abi_ulong r5;
+	abi_ulong r6;
+	abi_ulong r7;
+	abi_ulong r8;
+	abi_ulong r19;
+	abi_ulong r20;
+	abi_ulong r21;
+	abi_ulong r22;
+	abi_ulong r23;
+	abi_ulong r24;
+	abi_ulong r25;
+	abi_ulong r26;
+	abi_ulong r27;
+	abi_ulong r28;
+	abi_ulong hae;
 /* JRP - These are the values provided to a0-a2 by PALcode */
-	target_ulong trap_a0;
-	target_ulong trap_a1;
-	target_ulong trap_a2;
+	abi_ulong trap_a0;
+	abi_ulong trap_a1;
+	abi_ulong trap_a2;
 /* These are saved by PAL-code: */
-	target_ulong ps;
-	target_ulong pc;
-	target_ulong gp;
-	target_ulong r16;
-	target_ulong r17;
-	target_ulong r18;
+	abi_ulong ps;
+	abi_ulong pc;
+	abi_ulong gp;
+	abi_ulong r16;
+	abi_ulong r17;
+	abi_ulong r18;
 /* Those is needed by qemu to temporary store the user stack pointer */
-        target_ulong usp;
-        target_ulong unique;
+        abi_ulong usp;
+        abi_ulong unique;
 };
 
 #define UNAME_MACHINE "alpha"

Modified: trunk/src/host/qemu-neo1973/linux-user/alpha/syscall_nr.h
===================================================================
--- trunk/src/host/qemu-neo1973/linux-user/alpha/syscall_nr.h	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/linux-user/alpha/syscall_nr.h	2007-10-29 21:14:04 UTC (rev 3303)
@@ -379,3 +379,35 @@
 #define TARGET_NR_inotify_init		444
 #define TARGET_NR_inotify_add_watch		445
 #define TARGET_NR_inotify_rm_watch		446
+#define TARGET_NR_fdatasync			447
+#define TARGET_NR_kexec_load			448
+#define TARGET_NR_migrate_pages		449
+#define TARGET_NR_openat			450
+#define TARGET_NR_mkdirat			451
+#define TARGET_NR_mknodat			452
+#define TARGET_NR_fchownat			453
+#define TARGET_NR_futimesat			454
+#define TARGET_NR_fstatat64			455
+#define TARGET_NR_unlinkat			456
+#define TARGET_NR_renameat			457
+#define TARGET_NR_linkat			458
+#define TARGET_NR_symlinkat			459
+#define TARGET_NR_readlinkat			460
+#define TARGET_NR_fchmodat			461
+#define TARGET_NR_faccessat			462
+#define TARGET_NR_pselect6			463
+#define TARGET_NR_ppoll			464
+#define TARGET_NR_unshare			465
+#define TARGET_NR_set_robust_list		466
+#define TARGET_NR_get_robust_list		467
+#define TARGET_NR_splice			468
+#define TARGET_NR_sync_file_range		469
+#define TARGET_NR_tee			470
+#define TARGET_NR_vmsplice			471
+#define TARGET_NR_move_pages			472
+#define TARGET_NR_getcpu			473
+#define TARGET_NR_epoll_pwait		474
+#define TARGET_NR_utimensat			475
+#define TARGET_NR_signalfd			476
+#define TARGET_NR_timerfd			477
+#define TARGET_NR_eventfd			478

Added: trunk/src/host/qemu-neo1973/linux-user/alpha/target_signal.h
===================================================================
--- trunk/src/host/qemu-neo1973/linux-user/alpha/target_signal.h	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/linux-user/alpha/target_signal.h	2007-10-29 21:14:04 UTC (rev 3303)
@@ -0,0 +1,29 @@
+#ifndef TARGET_SIGNAL_H
+#define TARGET_SIGNAL_H
+
+#include "cpu.h"
+
+/* this struct defines a stack used during syscall handling */
+
+typedef struct target_sigaltstack {
+	abi_ulong ss_sp;
+	abi_long ss_flags;
+	abi_ulong ss_size;
+} target_stack_t;
+
+
+/*
+ * sigaltstack controls
+ */
+#define TARGET_SS_ONSTACK	1
+#define TARGET_SS_DISABLE	2
+
+#define TARGET_MINSIGSTKSZ	4096
+#define TARGET_SIGSTKSZ		16384
+
+static inline abi_ulong get_sp_from_cpustate(CPUAlphaState *state)
+{
+    return state->ir[IR_SP];
+}
+
+#endif /* TARGET_SIGNAL_H */

Modified: trunk/src/host/qemu-neo1973/linux-user/arm/syscall.h
===================================================================
--- trunk/src/host/qemu-neo1973/linux-user/arm/syscall.h	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/linux-user/arm/syscall.h	2007-10-29 21:14:04 UTC (rev 3303)
@@ -3,7 +3,7 @@
    stack during a system call. */
 
 struct target_pt_regs {
-    target_long uregs[18];
+    abi_long uregs[18];
 };
 
 #define ARM_cpsr	uregs[16]

Modified: trunk/src/host/qemu-neo1973/linux-user/arm/syscall_nr.h
===================================================================
--- trunk/src/host/qemu-neo1973/linux-user/arm/syscall_nr.h	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/linux-user/arm/syscall_nr.h	2007-10-29 21:14:04 UTC (rev 3303)
@@ -325,3 +325,34 @@
 #define TARGET_NR_mbind			319
 #define TARGET_NR_get_mempolicy		320
 #define TARGET_NR_set_mempolicy		321
+#define TARGET_NR_openat			(322)
+#define TARGET_NR_mkdirat			(323)
+#define TARGET_NR_mknodat			(324)
+#define TARGET_NR_fchownat			(325)
+#define TARGET_NR_futimesat			(326)
+#define TARGET_NR_fstatat64			(327)
+#define TARGET_NR_unlinkat			(328)
+#define TARGET_NR_renameat			(329)
+#define TARGET_NR_linkat			(330)
+#define TARGET_NR_symlinkat			(331)
+#define TARGET_NR_readlinkat			(332)
+#define TARGET_NR_fchmodat			(333)
+#define TARGET_NR_faccessat			(334)
+					/* 335 for pselect6 */
+					/* 336 for ppoll */
+#define TARGET_NR_unshare			(337)
+#define TARGET_NR_set_robust_list		(338)
+#define TARGET_NR_get_robust_list		(339)
+#define TARGET_NR_splice			(340)
+#define TARGET_NR_arm_sync_file_range	(341)
+#define TARGET_NR_sync_file_range2		TARGET_NR_arm_sync_file_range
+#define TARGET_NR_tee			(342)
+#define TARGET_NR_vmsplice			(343)
+#define TARGET_NR_move_pages			(344)
+#define TARGET_NR_getcpu			(345)
+					/* 346 for epoll_pwait */
+#define TARGET_NR_kexec_load			(347)
+#define TARGET_NR_utimensat			(348)
+#define TARGET_NR_signalfd			(349)
+#define TARGET_NR_timerfd			(350)
+#define TARGET_NR_eventfd			(351)

Added: trunk/src/host/qemu-neo1973/linux-user/arm/target_signal.h
===================================================================
--- trunk/src/host/qemu-neo1973/linux-user/arm/target_signal.h	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/linux-user/arm/target_signal.h	2007-10-29 21:14:04 UTC (rev 3303)
@@ -0,0 +1,29 @@
+#ifndef TARGET_SIGNAL_H
+#define TARGET_SIGNAL_H
+
+#include "cpu.h"
+
+/* this struct defines a stack used during syscall handling */
+
+typedef struct target_sigaltstack {
+	abi_ulong ss_sp;
+	abi_long ss_flags;
+	abi_ulong ss_size;
+} target_stack_t;
+
+
+/*
+ * sigaltstack controls
+ */
+#define TARGET_SS_ONSTACK	1
+#define TARGET_SS_DISABLE	2
+
+#define TARGET_MINSIGSTKSZ	2048
+#define TARGET_SIGSTKSZ		8192
+
+static inline abi_ulong get_sp_from_cpustate(CPUARMState *state)
+{
+   return state->regs[13];
+}
+
+#endif /* TARGET_SIGNAL_H */

Modified: trunk/src/host/qemu-neo1973/linux-user/arm/termbits.h
===================================================================
--- trunk/src/host/qemu-neo1973/linux-user/arm/termbits.h	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/linux-user/arm/termbits.h	2007-10-29 21:14:04 UTC (rev 3303)
@@ -27,6 +27,7 @@
 #define TARGET_IXANY   0004000
 #define TARGET_IXOFF   0010000
 #define TARGET_IMAXBEL 0020000
+#define TARGET_IUTF8   0040000
 
 /* c_oflag bits */
 #define TARGET_OPOST   0000001
@@ -98,7 +99,8 @@
 #define  TARGET_B230400 0010003
 #define  TARGET_B460800 0010004
 #define TARGET_CIBAUD    002003600000  /* input baud rate (not used) */
-#define TARGET_CRTSCTS   020000000000          /* flow control */
+#define TARGET_CMSPAR    010000000000  /* mark or space (stick) parity */
+#define TARGET_CRTSCTS   020000000000  /* flow control */
 
 /* c_lflag bits */
 #define TARGET_ISIG    0000001

Added: trunk/src/host/qemu-neo1973/linux-user/cris/syscall.h
===================================================================
--- trunk/src/host/qemu-neo1973/linux-user/cris/syscall.h	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/linux-user/cris/syscall.h	2007-10-29 21:14:04 UTC (rev 3303)
@@ -0,0 +1,37 @@
+
+#define UNAME_MACHINE "cris"
+
+/* pt_regs not only specifices the format in the user-struct during
+ * ptrace but is also the frame format used in the kernel prologue/epilogues
+ * themselves
+ */
+
+struct target_pt_regs {
+        unsigned long orig_r10;
+        /* pushed by movem r13, [sp] in SAVE_ALL. */
+        unsigned long r0;
+        unsigned long r1;
+        unsigned long r2;
+        unsigned long r3;
+        unsigned long r4;
+        unsigned long r5;
+        unsigned long r6;
+        unsigned long r7;
+        unsigned long r8;
+        unsigned long r9;
+        unsigned long r10;
+        unsigned long r11;
+        unsigned long r12;
+        unsigned long r13;
+        unsigned long acr;
+        unsigned long srs;
+        unsigned long mof;
+        unsigned long spc;
+        unsigned long ccs;
+        unsigned long srp;
+        unsigned long erp; /* This is actually the debugged process' PC */
+        /* For debugging purposes; saved only when needed. */
+        unsigned long exs;
+        unsigned long eda;
+};
+

Added: trunk/src/host/qemu-neo1973/linux-user/cris/syscall_nr.h
===================================================================
--- trunk/src/host/qemu-neo1973/linux-user/cris/syscall_nr.h	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/linux-user/cris/syscall_nr.h	2007-10-29 21:14:04 UTC (rev 3303)
@@ -0,0 +1,291 @@
+/*
+ * This file contains the system call numbers, and stub macros for libc.
+ */
+
+#define TARGET_NR_restart_syscall      0
+#define TARGET_NR_exit		  1
+#define TARGET_NR_fork		  2
+#define TARGET_NR_read		  3
+#define TARGET_NR_write		  4
+#define TARGET_NR_open		  5
+#define TARGET_NR_close		  6
+#define TARGET_NR_waitpid		  7
+#define TARGET_NR_creat		  8
+#define TARGET_NR_link		  9
+#define TARGET_NR_unlink		 10
+#define TARGET_NR_execve		 11
+#define TARGET_NR_chdir		 12
+#define TARGET_NR_time		 13
+#define TARGET_NR_mknod		 14
+#define TARGET_NR_chmod		 15
+#define TARGET_NR_lchown		 16
+#define TARGET_NR_break		 17
+#define TARGET_NR_oldstat		 18
+#define TARGET_NR_lseek		 19
+#define TARGET_NR_getpid		 20
+#define TARGET_NR_mount		 21
+#define TARGET_NR_umount		 22
+#define TARGET_NR_setuid		 23
+#define TARGET_NR_getuid		 24
+#define TARGET_NR_stime		 25
+#define TARGET_NR_ptrace		 26
+#define TARGET_NR_alarm		 27
+#define TARGET_NR_oldfstat		 28
+#define TARGET_NR_pause		 29
+#define TARGET_NR_utime		 30
+#define TARGET_NR_stty		 31
+#define TARGET_NR_gtty		 32
+#define TARGET_NR_access		 33
+#define TARGET_NR_nice		 34
+#define TARGET_NR_ftime		 35
+#define TARGET_NR_sync		 36
+#define TARGET_NR_kill		 37
+#define TARGET_NR_rename		 38
+#define TARGET_NR_mkdir		 39
+#define TARGET_NR_rmdir		 40
+#define TARGET_NR_dup		 41
+#define TARGET_NR_pipe		 42
+#define TARGET_NR_times		 43
+#define TARGET_NR_prof		 44
+#define TARGET_NR_brk		 45
+#define TARGET_NR_setgid		 46
+#define TARGET_NR_getgid		 47
+#define TARGET_NR_signal		 48
+#define TARGET_NR_geteuid		 49
+#define TARGET_NR_getegid		 50
+#define TARGET_NR_acct		 51
+#define TARGET_NR_umount2		 52
+#define TARGET_NR_lock		 53
+#define TARGET_NR_ioctl		 54
+#define TARGET_NR_fcntl		 55
+#define TARGET_NR_mpx		 56
+#define TARGET_NR_setpgid		 57
+#define TARGET_NR_ulimit		 58
+#define TARGET_NR_oldolduname	 59
+#define TARGET_NR_umask		 60
+#define TARGET_NR_chroot		 61
+#define TARGET_NR_ustat		 62
+#define TARGET_NR_dup2		 63
+#define TARGET_NR_getppid		 64
+#define TARGET_NR_getpgrp		 65
+#define TARGET_NR_setsid		 66
+#define TARGET_NR_sigaction		 67
+#define TARGET_NR_sgetmask		 68
+#define TARGET_NR_ssetmask		 69
+#define TARGET_NR_setreuid		 70
+#define TARGET_NR_setregid		 71
+#define TARGET_NR_sigsuspend		 72
+#define TARGET_NR_sigpending		 73
+#define TARGET_NR_sethostname	 74
+#define TARGET_NR_setrlimit		 75
+#define TARGET_NR_getrlimit		 76
+#define TARGET_NR_getrusage		 77
+#define TARGET_NR_gettimeofday	 78
+#define TARGET_NR_settimeofday	 79
+#define TARGET_NR_getgroups		 80
+#define TARGET_NR_setgroups		 81
+#define TARGET_NR_select		 82
+#define TARGET_NR_symlink		 83
+#define TARGET_NR_oldlstat		 84
+#define TARGET_NR_readlink		 85
+#define TARGET_NR_uselib		 86
+#define TARGET_NR_swapon		 87
+#define TARGET_NR_reboot		 88
+#define TARGET_NR_readdir		 89
+#define TARGET_NR_mmap		 90
+#define TARGET_NR_munmap		 91
+#define TARGET_NR_truncate		 92
+#define TARGET_NR_ftruncate		 93
+#define TARGET_NR_fchmod		 94
+#define TARGET_NR_fchown		 95
+#define TARGET_NR_getpriority	 96
+#define TARGET_NR_setpriority	 97
+#define TARGET_NR_profil		 98
+#define TARGET_NR_statfs		 99
+#define TARGET_NR_fstatfs		100
+#define TARGET_NR_ioperm		101
+#define TARGET_NR_socketcall		102
+#define TARGET_NR_syslog		103
+#define TARGET_NR_setitimer		104
+#define TARGET_NR_getitimer		105
+#define TARGET_NR_stat		106
+#define TARGET_NR_lstat		107
+#define TARGET_NR_fstat		108
+#define TARGET_NR_olduname		109
+#define TARGET_NR_iopl		110
+#define TARGET_NR_vhangup		111
+#define TARGET_NR_idle		112
+#define TARGET_NR_vm86		113
+#define TARGET_NR_wait4		114
+#define TARGET_NR_swapoff		115
+#define TARGET_NR_sysinfo		116
+#define TARGET_NR_ipc		117
+#define TARGET_NR_fsync		118
+#define TARGET_NR_sigreturn		119
+#define TARGET_NR_clone		120
+#define TARGET_NR_setdomainname	121
+#define TARGET_NR_uname		122
+#define TARGET_NR_modify_ldt		123
+#define TARGET_NR_adjtimex		124
+#define TARGET_NR_mprotect		125
+#define TARGET_NR_sigprocmask	126
+#define TARGET_NR_create_module	127
+#define TARGET_NR_init_module	128
+#define TARGET_NR_delete_module	129
+#define TARGET_NR_get_kernel_syms	130
+#define TARGET_NR_quotactl		131
+#define TARGET_NR_getpgid		132
+#define TARGET_NR_fchdir		133
+#define TARGET_NR_bdflush		134
+#define TARGET_NR_sysfs		135
+#define TARGET_NR_personality	136
+#define TARGET_NR_afs_syscall	137 /* Syscall for Andrew File System */
+#define TARGET_NR_setfsuid		138
+#define TARGET_NR_setfsgid		139
+#define TARGET_NR__llseek		140
+#define TARGET_NR_getdents		141
+#define TARGET_NR__newselect		142
+#define TARGET_NR_flock		143
+#define TARGET_NR_msync		144
+#define TARGET_NR_readv		145
+#define TARGET_NR_writev		146
+#define TARGET_NR_getsid		147
+#define TARGET_NR_fdatasync		148
+#define TARGET_NR__sysctl		149
+#define TARGET_NR_mlock		150
+#define TARGET_NR_munlock		151
+#define TARGET_NR_mlockall		152
+#define TARGET_NR_munlockall		153
+#define TARGET_NR_sched_setparam		154
+#define TARGET_NR_sched_getparam		155
+#define TARGET_NR_sched_setscheduler		156
+#define TARGET_NR_sched_getscheduler		157
+#define TARGET_NR_sched_yield		158
+#define TARGET_NR_sched_get_priority_max	159
+#define TARGET_NR_sched_get_priority_min	160
+#define TARGET_NR_sched_rr_get_interval	161
+#define TARGET_NR_nanosleep		162
+#define TARGET_NR_mremap		163
+#define TARGET_NR_setresuid		164
+#define TARGET_NR_getresuid		165
+
+#define TARGET_NR_query_module	167
+#define TARGET_NR_poll		168
+#define TARGET_NR_nfsservctl		169
+#define TARGET_NR_setresgid		170
+#define TARGET_NR_getresgid		171
+#define TARGET_NR_prctl              172
+#define TARGET_NR_rt_sigreturn	173
+#define TARGET_NR_rt_sigaction	174
+#define TARGET_NR_rt_sigprocmask	175
+#define TARGET_NR_rt_sigpending	176
+#define TARGET_NR_rt_sigtimedwait	177
+#define TARGET_NR_rt_sigqueueinfo	178
+#define TARGET_NR_rt_sigsuspend	179
+#define TARGET_NR_pread64		180
+#define TARGET_NR_pwrite64		181
+#define TARGET_NR_chown		182
+#define TARGET_NR_getcwd		183
+#define TARGET_NR_capget		184
+#define TARGET_NR_capset		185
+#define TARGET_NR_sigaltstack	186
+#define TARGET_NR_sendfile		187
+#define TARGET_NR_getpmsg		188	/* some people actually want streams */
+#define TARGET_NR_putpmsg		189	/* some people actually want streams */
+#define TARGET_NR_vfork		190
+#define TARGET_NR_ugetrlimit		191	/* SuS compliant getrlimit */
+#define TARGET_NR_mmap2		192
+#define TARGET_NR_truncate64		193
+#define TARGET_NR_ftruncate64	194
+#define TARGET_NR_stat64		195
+#define TARGET_NR_lstat64		196
+#define TARGET_NR_fstat64		197
+#define TARGET_NR_lchown32		198
+#define TARGET_NR_getuid32		199
+#define TARGET_NR_getgid32		200
+#define TARGET_NR_geteuid32		201
+#define TARGET_NR_getegid32		202
+#define TARGET_NR_setreuid32		203
+#define TARGET_NR_setregid32		204
+#define TARGET_NR_getgroups32	205
+#define TARGET_NR_setgroups32	206
+#define TARGET_NR_fchown32		207
+#define TARGET_NR_setresuid32	208
+#define TARGET_NR_getresuid32	209
+#define TARGET_NR_setresgid32	210
+#define TARGET_NR_getresgid32	211
+#define TARGET_NR_chown32		212
+#define TARGET_NR_setuid32		213
+#define TARGET_NR_setgid32		214
+#define TARGET_NR_setfsuid32		215
+#define TARGET_NR_setfsgid32		216
+#define TARGET_NR_pivot_root		217
+#define TARGET_NR_mincore		218
+#define TARGET_NR_madvise		219
+#define TARGET_NR_getdents64		220
+#define TARGET_NR_fcntl64		221
+/* 223 is unused */
+#define TARGET_NR_gettid             224
+#define TARGET_NR_readahead          225
+#define TARGET_NR_setxattr		226
+#define TARGET_NR_lsetxattr		227
+#define TARGET_NR_fsetxattr		228
+#define TARGET_NR_getxattr		229
+#define TARGET_NR_lgetxattr		230
+#define TARGET_NR_fgetxattr		231
+#define TARGET_NR_listxattr		232
+#define TARGET_NR_llistxattr		233
+#define TARGET_NR_flistxattr		234
+#define TARGET_NR_removexattr	235
+#define TARGET_NR_lremovexattr	236
+#define TARGET_NR_fremovexattr	237
+#define TARGET_NR_tkill		238
+#define TARGET_NR_sendfile64		239
+#define TARGET_NR_futex		240
+#define TARGET_NR_sched_setaffinity	241
+#define TARGET_NR_sched_getaffinity	242
+#define TARGET_NR_set_thread_area	243
+#define TARGET_NR_get_thread_area	244
+#define TARGET_NR_io_setup		245
+#define TARGET_NR_io_destroy		246
+#define TARGET_NR_io_getevents	247
+#define TARGET_NR_io_submit		248
+#define TARGET_NR_io_cancel		249
+#define TARGET_NR_fadvise64		250
+#define TARGET_NR_exit_group		252
+#define TARGET_NR_lookup_dcookie	253
+#define TARGET_NR_epoll_create	254
+#define TARGET_NR_epoll_ctl		255
+#define TARGET_NR_epoll_wait		256
+#define TARGET_NR_remap_file_pages	257
+#define TARGET_NR_set_tid_address	258
+#define TARGET_NR_timer_create	259
+#define TARGET_NR_timer_settime	(TARGET_NR_timer_create+1)
+#define TARGET_NR_timer_gettime	(TARGET_NR_timer_create+2)
+#define TARGET_NR_timer_getoverrun	(TARGET_NR_timer_create+3)
+#define TARGET_NR_timer_delete	(TARGET_NR_timer_create+4)
+#define TARGET_NR_clock_settime	(TARGET_NR_timer_create+5)
+#define TARGET_NR_clock_gettime	(TARGET_NR_timer_create+6)
+#define TARGET_NR_clock_getres	(TARGET_NR_timer_create+7)
+#define TARGET_NR_clock_nanosleep	(TARGET_NR_timer_create+8)
+#define TARGET_NR_statfs64		268
+#define TARGET_NR_fstatfs64		269
+#define TARGET_NR_tgkill		270
+#define TARGET_NR_utimes		271
+#define TARGET_NR_fadvise64_64	272
+#define TARGET_NR_vserver		273
+#define TARGET_NR_mbind		274
+#define TARGET_NR_get_mempolicy	275
+#define TARGET_NR_set_mempolicy	276
+#define TARGET_NR_mq_open 		277
+#define TARGET_NR_mq_unlink		(TARGET_NR_mq_open+1)
+#define TARGET_NR_mq_timedsend	(TARGET_NR_mq_open+2)
+#define TARGET_NR_mq_timedreceive	(TARGET_NR_mq_open+3)
+#define TARGET_NR_mq_notify		(TARGET_NR_mq_open+4)
+#define TARGET_NR_mq_getsetattr	(TARGET_NR_mq_open+5)
+#define TARGET_NR_kexec_load		283
+#define TARGET_NR_waitid		284
+/* #define TARGET_NR_sys_setaltroot	285 */
+#define TARGET_NR_add_key		286
+#define TARGET_NR_request_key	287
+#define TARGET_NR_keyctl		288

Added: trunk/src/host/qemu-neo1973/linux-user/cris/target_signal.h
===================================================================
--- trunk/src/host/qemu-neo1973/linux-user/cris/target_signal.h	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/linux-user/cris/target_signal.h	2007-10-29 21:14:04 UTC (rev 3303)
@@ -0,0 +1,29 @@
+#ifndef TARGET_SIGNAL_H
+#define TARGET_SIGNAL_H
+
+#include "cpu.h"
+
+/* this struct defines a stack used during syscall handling */
+
+typedef struct target_sigaltstack {
+	abi_ulong ss_sp;
+	abi_ulong ss_size;
+	abi_long ss_flags;
+} target_stack_t;
+
+
+/*
+ * sigaltstack controls
+ */
+#define TARGET_SS_ONSTACK     1
+#define TARGET_SS_DISABLE     2
+
+#define TARGET_MINSIGSTKSZ    2048
+#define TARGET_SIGSTKSZ       8192
+
+static inline abi_ulong get_sp_from_cpustate(CPUCRISState *state)
+{
+    return state->regs[14];
+}
+
+#endif /* TARGET_SIGNAL_H */

Added: trunk/src/host/qemu-neo1973/linux-user/cris/termbits.h
===================================================================
--- trunk/src/host/qemu-neo1973/linux-user/cris/termbits.h	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/linux-user/cris/termbits.h	2007-10-29 21:14:04 UTC (rev 3303)
@@ -0,0 +1,214 @@
+/* from asm/termbits.h */
+
+#define TARGET_NCCS 19
+
+struct target_termios {
+    unsigned int c_iflag;               /* input mode flags */
+    unsigned int c_oflag;               /* output mode flags */
+    unsigned int c_cflag;               /* control mode flags */
+    unsigned int c_lflag;               /* local mode flags */
+    unsigned char c_line;                    /* line discipline */
+    unsigned char c_cc[TARGET_NCCS];                /* control characters */
+};
+
+/* c_iflag bits */
+#define TARGET_IGNBRK  0000001
+#define TARGET_BRKINT  0000002
+#define TARGET_IGNPAR  0000004
+#define TARGET_PARMRK  0000010
+#define TARGET_INPCK   0000020
+#define TARGET_ISTRIP  0000040
+#define TARGET_INLCR   0000100
+#define TARGET_IGNCR   0000200
+#define TARGET_ICRNL   0000400
+#define TARGET_IUCLC   0001000
+#define TARGET_IXON    0002000
+#define TARGET_IXANY   0004000
+#define TARGET_IXOFF   0010000
+#define TARGET_IMAXBEL 0020000
+
+/* c_oflag bits */
+#define TARGET_OPOST   0000001
+#define TARGET_OLCUC   0000002
+#define TARGET_ONLCR   0000004
+#define TARGET_OCRNL   0000010
+#define TARGET_ONOCR   0000020
+#define TARGET_ONLRET  0000040
+#define TARGET_OFILL   0000100
+#define TARGET_OFDEL   0000200
+#define TARGET_NLDLY   0000400
+#define   TARGET_NL0   0000000
+#define   TARGET_NL1   0000400
+#define TARGET_CRDLY   0003000
+#define   TARGET_CR0   0000000
+#define   TARGET_CR1   0001000
+#define   TARGET_CR2   0002000
+#define   TARGET_CR3   0003000
+#define TARGET_TABDLY  0014000
+#define   TARGET_TAB0  0000000
+#define   TARGET_TAB1  0004000
+#define   TARGET_TAB2  0010000
+#define   TARGET_TAB3  0014000
+#define   TARGET_XTABS 0014000
+#define TARGET_BSDLY   0020000
+#define   TARGET_BS0   0000000
+#define   TARGET_BS1   0020000
+#define TARGET_VTDLY   0040000
+#define   TARGET_VT0   0000000
+#define   TARGET_VT1   0040000
+#define TARGET_FFDLY   0100000
+#define   TARGET_FF0   0000000
+#define   TARGET_FF1   0100000
+
+/* c_cflag bit meaning */
+#define TARGET_CBAUD   0010017
+#define  TARGET_B0     0000000         /* hang up */
+#define  TARGET_B50    0000001
+#define  TARGET_B75    0000002
+#define  TARGET_B110   0000003
+#define  TARGET_B134   0000004
+#define  TARGET_B150   0000005
+#define  TARGET_B200   0000006
+#define  TARGET_B300   0000007
+#define  TARGET_B600   0000010
+#define  TARGET_B1200  0000011
+#define  TARGET_B1800  0000012
+#define  TARGET_B2400  0000013
+#define  TARGET_B4800  0000014
+#define  TARGET_B9600  0000015
+#define  TARGET_B19200 0000016
+#define  TARGET_B38400 0000017
+#define TARGET_EXTA B19200
+#define TARGET_EXTB B38400
+#define TARGET_CSIZE   0000060
+#define   TARGET_CS5   0000000
+#define   TARGET_CS6   0000020
+#define   TARGET_CS7   0000040
+#define   TARGET_CS8   0000060
+#define TARGET_CSTOPB  0000100
+#define TARGET_CREAD   0000200
+#define TARGET_PARENB  0000400
+#define TARGET_PARODD  0001000
+#define TARGET_HUPCL   0002000
+#define TARGET_CLOCAL  0004000
+#define TARGET_CBAUDEX 0010000
+#define  TARGET_B57600  0010001
+#define  TARGET_B115200 0010002
+#define  TARGET_B230400 0010003
+#define  TARGET_B460800 0010004
+#define TARGET_CIBAUD    002003600000  /* input baud rate (not used) */
+#define TARGET_CRTSCTS   020000000000          /* flow control */
+
+/* c_lflag bits */
+#define TARGET_ISIG    0000001
+#define TARGET_ICANON  0000002
+#define TARGET_XCASE   0000004
+#define TARGET_ECHO    0000010
+#define TARGET_ECHOE   0000020
+#define TARGET_ECHOK   0000040
+#define TARGET_ECHONL  0000100
+#define TARGET_NOFLSH  0000200
+#define TARGET_TOSTOP  0000400
+#define TARGET_ECHOCTL 0001000
+#define TARGET_ECHOPRT 0002000
+#define TARGET_ECHOKE  0004000
+#define TARGET_FLUSHO  0010000
+#define TARGET_PENDIN  0040000
+#define TARGET_IEXTEN  0100000
+
+/* c_cc character offsets */
+#define TARGET_VINTR	0
+#define TARGET_VQUIT	1
+#define TARGET_VERASE	2
+#define TARGET_VKILL	3
+#define TARGET_VEOF	4
+#define TARGET_VTIME	5
+#define TARGET_VMIN	6
+#define TARGET_VSWTC	7
+#define TARGET_VSTART	8
+#define TARGET_VSTOP	9
+#define TARGET_VSUSP	10
+#define TARGET_VEOL	11
+#define TARGET_VREPRINT	12
+#define TARGET_VDISCARD	13
+#define TARGET_VWERASE	14
+#define TARGET_VLNEXT	15
+#define TARGET_VEOL2	16
+
+/* ioctls */
+
+#define TARGET_TCGETS		0x5401
+#define TARGET_TCSETS		0x5402
+#define TARGET_TCSETSW		0x5403
+#define TARGET_TCSETSF		0x5404
+#define TARGET_TCGETA		0x5405
+#define TARGET_TCSETA		0x5406
+#define TARGET_TCSETAW		0x5407
+#define TARGET_TCSETAF		0x5408
+#define TARGET_TCSBRK		0x5409
+#define TARGET_TCXONC		0x540A
+#define TARGET_TCFLSH		0x540B
+
+#define TARGET_TIOCEXCL	0x540C
+#define TARGET_TIOCNXCL	0x540D
+#define TARGET_TIOCSCTTY	0x540E
+#define TARGET_TIOCGPGRP	0x540F
+#define TARGET_TIOCSPGRP	0x5410
+#define TARGET_TIOCOUTQ	0x5411
+#define TARGET_TIOCSTI		0x5412
+#define TARGET_TIOCGWINSZ	0x5413
+#define TARGET_TIOCSWINSZ	0x5414
+#define TARGET_TIOCMGET	0x5415
+#define TARGET_TIOCMBIS	0x5416
+#define TARGET_TIOCMBIC	0x5417
+#define TARGET_TIOCMSET	0x5418
+#define TARGET_TIOCGSOFTCAR	0x5419
+#define TARGET_TIOCSSOFTCAR	0x541A
+#define TARGET_FIONREAD	0x541B
+#define TARGET_TIOCINQ		TARGET_FIONREAD
+#define TARGET_TIOCLINUX	0x541C
+#define TARGET_TIOCCONS	0x541D
+#define TARGET_TIOCGSERIAL	0x541E
+#define TARGET_TIOCSSERIAL	0x541F
+#define TARGET_TIOCPKT		0x5420
+#define TARGET_FIONBIO		0x5421
+#define TARGET_TIOCNOTTY	0x5422
+#define TARGET_TIOCSETD	0x5423
+#define TARGET_TIOCGETD	0x5424
+#define TARGET_TCSBRKP		0x5425	/* Needed for POSIX tcsendbreak() */
+#define TARGET_TIOCTTYGSTRUCT	0x5426  /* For debugging only */
+#define TARGET_TIOCSBRK	0x5427  /* BSD compatibility */
+#define TARGET_TIOCCBRK	0x5428  /* BSD compatibility */
+#define TARGET_TIOCGSID	0x5429  /* Return the session ID of FD */
+#define TARGET_TIOCGPTN	TARGET_IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */
+#define TARGET_TIOCSPTLCK	TARGET_IOW('T',0x31, int)  /* Lock/unlock Pty */
+
+#define TARGET_FIONCLEX	0x5450  /* these numbers need to be adjusted. */
+#define TARGET_FIOCLEX		0x5451
+#define TARGET_FIOASYNC	0x5452
+#define TARGET_TIOCSERCONFIG	0x5453
+#define TARGET_TIOCSERGWILD	0x5454
+#define TARGET_TIOCSERSWILD	0x5455
+#define TARGET_TIOCGLCKTRMIOS	0x5456
+#define TARGET_TIOCSLCKTRMIOS	0x5457
+#define TARGET_TIOCSERGSTRUCT	0x5458 /* For debugging only */
+#define TARGET_TIOCSERGETLSR   0x5459 /* Get line status register */
+#define TARGET_TIOCSERGETMULTI 0x545A /* Get multiport config  */
+#define TARGET_TIOCSERSETMULTI 0x545B /* Set multiport config */
+
+#define TARGET_TIOCMIWAIT	0x545C	/* wait for a change on serial input line(s) */
+#define TARGET_TIOCGICOUNT	0x545D	/* read serial port inline interrupt counts */
+#define TARGET_TIOCGHAYESESP   0x545E  /* Get Hayes ESP configuration */
+#define TARGET_TIOCSHAYESESP   0x545F  /* Set Hayes ESP configuration */
+
+/* Used for packet mode */
+#define TARGET_TIOCPKT_DATA		 0
+#define TARGET_TIOCPKT_FLUSHREAD	 1
+#define TARGET_TIOCPKT_FLUSHWRITE	 2
+#define TARGET_TIOCPKT_STOP		 4
+#define TARGET_TIOCPKT_START		 8
+#define TARGET_TIOCPKT_NOSTOP		16
+#define TARGET_TIOCPKT_DOSTOP		32
+
+#define TARGET_TIOCSER_TEMT    0x01	/* Transmitter physically empty */
+

Modified: trunk/src/host/qemu-neo1973/linux-user/elfload.c
===================================================================
--- trunk/src/host/qemu-neo1973/linux-user/elfload.c	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/linux-user/elfload.c	2007-10-29 21:14:04 UTC (rev 3303)
@@ -12,6 +12,66 @@
 #include "qemu.h"
 #include "disas.h"
 
+/* from personality.h */
+
+/*
+ * Flags for bug emulation.
+ *
+ * These occupy the top three bytes.
+ */
+enum {
+	ADDR_NO_RANDOMIZE = 	0x0040000,	/* disable randomization of VA space */
+	FDPIC_FUNCPTRS =	0x0080000,	/* userspace function ptrs point to descriptors
+						 * (signal handling)
+						 */
+	MMAP_PAGE_ZERO =	0x0100000,
+	ADDR_COMPAT_LAYOUT =	0x0200000,
+	READ_IMPLIES_EXEC =	0x0400000,
+	ADDR_LIMIT_32BIT =	0x0800000,
+	SHORT_INODE =		0x1000000,
+	WHOLE_SECONDS =		0x2000000,
+	STICKY_TIMEOUTS	=	0x4000000,
+	ADDR_LIMIT_3GB = 	0x8000000,
+};
+
+/*
+ * Personality types.
+ *
+ * These go in the low byte.  Avoid using the top bit, it will
+ * conflict with error returns.
+ */
+enum {
+	PER_LINUX =		0x0000,
+	PER_LINUX_32BIT =	0x0000 | ADDR_LIMIT_32BIT,
+	PER_LINUX_FDPIC =	0x0000 | FDPIC_FUNCPTRS,
+	PER_SVR4 =		0x0001 | STICKY_TIMEOUTS | MMAP_PAGE_ZERO,
+	PER_SVR3 =		0x0002 | STICKY_TIMEOUTS | SHORT_INODE,
+	PER_SCOSVR3 =		0x0003 | STICKY_TIMEOUTS |
+					 WHOLE_SECONDS | SHORT_INODE,
+	PER_OSR5 =		0x0003 | STICKY_TIMEOUTS | WHOLE_SECONDS,
+	PER_WYSEV386 =		0x0004 | STICKY_TIMEOUTS | SHORT_INODE,
+	PER_ISCR4 =		0x0005 | STICKY_TIMEOUTS,
+	PER_BSD =		0x0006,
+	PER_SUNOS =		0x0006 | STICKY_TIMEOUTS,
+	PER_XENIX =		0x0007 | STICKY_TIMEOUTS | SHORT_INODE,
+	PER_LINUX32 =		0x0008,
+	PER_LINUX32_3GB =	0x0008 | ADDR_LIMIT_3GB,
+	PER_IRIX32 =		0x0009 | STICKY_TIMEOUTS,/* IRIX5 32-bit */
+	PER_IRIXN32 =		0x000a | STICKY_TIMEOUTS,/* IRIX6 new 32-bit */
+	PER_IRIX64 =		0x000b | STICKY_TIMEOUTS,/* IRIX6 64-bit */
+	PER_RISCOS =		0x000c,
+	PER_SOLARIS =		0x000d | STICKY_TIMEOUTS,
+	PER_UW7 =		0x000e | STICKY_TIMEOUTS | MMAP_PAGE_ZERO,
+	PER_OSF4 =		0x000f,			 /* OSF/1 v4 */
+	PER_HPUX =		0x0010,
+	PER_MASK =		0x00ff,
+};
+
+/*
+ * Return the base personality without flags.
+ */
+#define personality(pers)	(pers & PER_MASK)
+
 /* this flag is uneffective under linux too, should be deleted */
 #ifndef MAP_DENYWRITE
 #define MAP_DENYWRITE 0
@@ -112,7 +172,7 @@
 
 static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
 {
-    target_long stack = infop->start_stack;
+    abi_long stack = infop->start_stack;
     memset(regs, 0, sizeof(*regs));
     regs->ARM_cpsr = 0x10;
     if (infop->entry & 1)
@@ -124,6 +184,7 @@
     /* XXX: it seems that r0 is zeroed after ! */
     regs->ARM_r0 = 0;
     /* For uClinux PIC binaries.  */
+    /* XXX: Linux does this only on ARM with no MMU (do we care ?) */
     regs->ARM_r10 = infop->start_data;
 }
 
@@ -153,7 +214,11 @@
 
 #define ELF_START_MMAP 0x80000000
 
-#define elf_check_arch(x) ( (x) == EM_SPARCV9 )
+#ifndef TARGET_ABI32
+#define elf_check_arch(x) ( (x) == EM_SPARCV9 || (x) == EM_SPARC32PLUS )
+#else
+#define elf_check_arch(x) ( (x) == EM_SPARC32PLUS || (x) == EM_SPARC )
+#endif
 
 #define ELF_CLASS   ELFCLASS64
 #define ELF_DATA    ELFDATA2MSB
@@ -163,11 +228,20 @@
 
 static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
 {
+#ifndef TARGET_ABI32
     regs->tstate = 0;
+#endif
     regs->pc = infop->entry;
     regs->npc = regs->pc + 4;
     regs->y = 0;
-    regs->u_regs[14] = infop->start_stack - 16 * 8 - STACK_BIAS;
+#ifdef TARGET_ABI32
+    regs->u_regs[14] = infop->start_stack - 16 * 4;
+#else
+    if (personality(infop->personality) == PER_LINUX32)
+        regs->u_regs[14] = infop->start_stack - 16 * 4;
+    else
+        regs->u_regs[14] = infop->start_stack - 16 * 8 - STACK_BIAS;
+#endif
 }
 
 #else
@@ -195,7 +269,7 @@
 
 #define ELF_START_MMAP 0x80000000
 
-#ifdef TARGET_PPC64
+#if defined(TARGET_PPC64) && !defined(TARGET_ABI32)
 
 #define elf_check_arch(x) ( (x) == EM_PPC64 )
 
@@ -249,15 +323,14 @@
 
 static inline void init_thread(struct target_pt_regs *_regs, struct image_info *infop)
 {
-    target_ulong pos = infop->start_stack;
-    target_ulong tmp;
-#ifdef TARGET_PPC64
-    target_ulong entry, toc;
+    abi_ulong pos = infop->start_stack;
+    abi_ulong tmp;
+#if defined(TARGET_PPC64) && !defined(TARGET_ABI32)
+    abi_ulong entry, toc;
 #endif
 
-    _regs->msr = 1 << MSR_PR; /* Set user mode */
     _regs->gpr[1] = infop->start_stack;
-#ifdef TARGET_PPC64
+#if defined(TARGET_PPC64) && !defined(TARGET_ABI32)
     entry = ldq_raw(infop->entry) + infop->load_addr;
     toc = ldq_raw(infop->entry + 8) + infop->load_addr;
     _regs->gpr[2] = toc;
@@ -269,9 +342,9 @@
      * execution of PPC BSD programs.
      */
     _regs->gpr[3] = tgetl(pos);
-    pos += sizeof(target_ulong);
+    pos += sizeof(abi_ulong);
     _regs->gpr[4] = pos;
-    for (tmp = 1; tmp != 0; pos += sizeof(target_ulong))
+    for (tmp = 1; tmp != 0; pos += sizeof(abi_ulong))
         tmp = ldl(pos);
     _regs->gpr[5] = pos;
 }
@@ -301,7 +374,7 @@
 
 static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
 {
-    regs->cp0_status = CP0St_UM;
+    regs->cp0_status = 2 << CP0St_KSU;
     regs->cp0_epc = infop->entry;
     regs->regs[29] = infop->start_stack;
 }
@@ -333,6 +406,26 @@
 
 #endif
 
+#ifdef TARGET_CRIS
+
+#define ELF_START_MMAP 0x80000000
+
+#define elf_check_arch(x) ( (x) == EM_CRIS )
+
+#define ELF_CLASS ELFCLASS32
+#define ELF_DATA  ELFDATA2LSB
+#define ELF_ARCH  EM_CRIS
+
+static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
+{
+  regs->erp = infop->entry;
+}
+
+#define USE_ELF_CORE_DUMP
+#define ELF_EXEC_PAGESIZE        8192
+
+#endif
+
 #ifdef TARGET_M68K
 
 #define ELF_START_MMAP 0x80000000
@@ -391,6 +484,13 @@
 #define ELF_HWCAP 0
 #endif
 
+#ifdef TARGET_ABI32
+#undef ELF_CLASS
+#define ELF_CLASS ELFCLASS32
+#undef bswaptls
+#define bswaptls(ptr) bswap32s(ptr)
+#endif
+
 #include "elf.h"
 
 struct exec
@@ -418,25 +518,6 @@
 /* max code+data+bss+brk space allocated to ET_DYN executables */
 #define ET_DYN_MAP_SIZE (128 * 1024 * 1024)
 
-/* from personality.h */
-
-/* Flags for bug emulation. These occupy the top three bytes. */
-#define STICKY_TIMEOUTS		0x4000000
-#define WHOLE_SECONDS		0x2000000
-
-/* Personality types. These go in the low byte. Avoid using the top bit,
- * it will conflict with error returns.
- */
-#define PER_MASK		(0x00ff)
-#define PER_LINUX		(0x0000)
-#define PER_SVR4		(0x0001 | STICKY_TIMEOUTS)
-#define PER_SVR3		(0x0002 | STICKY_TIMEOUTS)
-#define PER_SCOSVR3		(0x0003 | STICKY_TIMEOUTS | WHOLE_SECONDS)
-#define PER_WYSEV386		(0x0004 | STICKY_TIMEOUTS)
-#define PER_ISCR4		(0x0005 | STICKY_TIMEOUTS)
-#define PER_BSD			(0x0006)
-#define PER_XENIX		(0x0007 | STICKY_TIMEOUTS)
-
 /* Necessary parameters */
 #define TARGET_ELF_EXEC_PAGESIZE TARGET_PAGE_SIZE
 #define TARGET_ELF_PAGESTART(_v) ((_v) & ~(unsigned long)(TARGET_ELF_EXEC_PAGESIZE-1))
@@ -516,8 +597,8 @@
  * to be put directly into the top of new user memory.
  *
  */
-static unsigned long copy_elf_strings(int argc,char ** argv, void **page,
-                                      unsigned long p)
+static abi_ulong copy_elf_strings(int argc,char ** argv, void **page,
+                                  abi_ulong p)
 {
     char *tmp, *tmp1, *pag = NULL;
     int len, offset = 0;
@@ -544,6 +625,7 @@
                 pag = (char *)page[p/TARGET_PAGE_SIZE];
                 if (!pag) {
                     pag = (char *)malloc(TARGET_PAGE_SIZE);
+                    memset(pag, 0, TARGET_PAGE_SIZE);
                     page[p/TARGET_PAGE_SIZE] = pag;
                     if (!pag)
                         return 0;
@@ -565,10 +647,10 @@
     return p;
 }
 
-unsigned long setup_arg_pages(target_ulong p, struct linux_binprm * bprm,
-					      struct image_info * info)
+static abi_ulong setup_arg_pages(abi_ulong p, struct linux_binprm *bprm,
+                                 struct image_info *info)
 {
-    target_ulong stack_base, size, error;
+    abi_ulong stack_base, size, error;
     int i;
 
     /* Create enough stack to hold everything.  If we don't use
@@ -604,7 +686,7 @@
     return p;
 }
 
-static void set_brk(unsigned long start, unsigned long end)
+static void set_brk(abi_ulong start, abi_ulong end)
 {
 	/* page-align the start and end addresses... */
         start = HOST_PAGE_ALIGN(start);
@@ -623,9 +705,9 @@
 /* We need to explicitly zero any fractional pages after the data
    section (i.e. bss).  This would contain the junk from the file that
    should not be in memory. */
-static void padzero(unsigned long elf_bss, unsigned long last_bss)
+static void padzero(abi_ulong elf_bss, abi_ulong last_bss)
 {
-        unsigned long nbyte;
+        abi_ulong nbyte;
 
 	if (elf_bss >= last_bss)
 		return;
@@ -636,12 +718,12 @@
            patch target_mmap(), but it is more complicated as the file
            size must be known */
         if (qemu_real_host_page_size < qemu_host_page_size) {
-            unsigned long end_addr, end_addr1;
+            abi_ulong end_addr, end_addr1;
             end_addr1 = (elf_bss + qemu_real_host_page_size - 1) &
                 ~(qemu_real_host_page_size - 1);
             end_addr = HOST_PAGE_ALIGN(elf_bss);
             if (end_addr1 < end_addr) {
-                mmap((void *)end_addr1, end_addr - end_addr1,
+                mmap((void *)g2h(end_addr1), end_addr - end_addr1,
                      PROT_READ|PROT_WRITE|PROT_EXEC,
                      MAP_FIXED|MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
             }
@@ -658,18 +740,18 @@
 }
 
 
-static unsigned long create_elf_tables(target_ulong p, int argc, int envc,
-                                       struct elfhdr * exec,
-                                       unsigned long load_addr,
-                                       unsigned long load_bias,
-                                       unsigned long interp_load_addr, int ibcs,
-                                       struct image_info *info)
+static abi_ulong create_elf_tables(abi_ulong p, int argc, int envc,
+                                   struct elfhdr * exec,
+                                   abi_ulong load_addr,
+                                   abi_ulong load_bias,
+                                   abi_ulong interp_load_addr, int ibcs,
+                                   struct image_info *info)
 {
-        target_ulong sp;
+        abi_ulong sp;
         int size;
-        target_ulong u_platform;
+        abi_ulong u_platform;
         const char *k_platform;
-        const int n = sizeof(target_ulong);
+        const int n = sizeof(elf_addr_t);
 
         sp = p;
         u_platform = 0;
@@ -683,7 +765,7 @@
 	/*
 	 * Force 16 byte _final_ alignment here for generality.
 	 */
-        sp = sp &~ (target_ulong)15;
+        sp = sp &~ (abi_ulong)15;
         size = (DLINFO_ITEMS + 1) * 2;
         if (k_platform)
           size += 2;
@@ -696,25 +778,35 @@
         if (size & 15)
             sp -= 16 - (size & 15);
 
+        /* This is correct because Linux defines
+         * elf_addr_t as Elf32_Off / Elf64_Off
+         */
+#if ELF_CLASS == ELFCLASS32
 #define NEW_AUX_ENT(id, val) do { \
-            sp -= n; tputl(sp, val); \
-            sp -= n; tputl(sp, id); \
+            sp -= n; tput32(sp, val); \
+            sp -= n; tput32(sp, id); \
           } while(0)
+#else
+#define NEW_AUX_ENT(id, val) do { \
+            sp -= n; tput64(sp, val); \
+            sp -= n; tput64(sp, id); \
+          } while(0)
+#endif
         NEW_AUX_ENT (AT_NULL, 0);
 
         /* There must be exactly DLINFO_ITEMS entries here.  */
-        NEW_AUX_ENT(AT_PHDR, (target_ulong)(load_addr + exec->e_phoff));
-        NEW_AUX_ENT(AT_PHENT, (target_ulong)(sizeof (struct elf_phdr)));
-        NEW_AUX_ENT(AT_PHNUM, (target_ulong)(exec->e_phnum));
-        NEW_AUX_ENT(AT_PAGESZ, (target_ulong)(TARGET_PAGE_SIZE));
-        NEW_AUX_ENT(AT_BASE, (target_ulong)(interp_load_addr));
-        NEW_AUX_ENT(AT_FLAGS, (target_ulong)0);
+        NEW_AUX_ENT(AT_PHDR, (abi_ulong)(load_addr + exec->e_phoff));
+        NEW_AUX_ENT(AT_PHENT, (abi_ulong)(sizeof (struct elf_phdr)));
+        NEW_AUX_ENT(AT_PHNUM, (abi_ulong)(exec->e_phnum));
+        NEW_AUX_ENT(AT_PAGESZ, (abi_ulong)(TARGET_PAGE_SIZE));
+        NEW_AUX_ENT(AT_BASE, (abi_ulong)(interp_load_addr));
+        NEW_AUX_ENT(AT_FLAGS, (abi_ulong)0);
         NEW_AUX_ENT(AT_ENTRY, load_bias + exec->e_entry);
-        NEW_AUX_ENT(AT_UID, (target_ulong) getuid());
-        NEW_AUX_ENT(AT_EUID, (target_ulong) geteuid());
-        NEW_AUX_ENT(AT_GID, (target_ulong) getgid());
-        NEW_AUX_ENT(AT_EGID, (target_ulong) getegid());
-        NEW_AUX_ENT(AT_HWCAP, (target_ulong) ELF_HWCAP);
+        NEW_AUX_ENT(AT_UID, (abi_ulong) getuid());
+        NEW_AUX_ENT(AT_EUID, (abi_ulong) geteuid());
+        NEW_AUX_ENT(AT_GID, (abi_ulong) getgid());
+        NEW_AUX_ENT(AT_EGID, (abi_ulong) getegid());
+        NEW_AUX_ENT(AT_HWCAP, (abi_ulong) ELF_HWCAP);
         if (k_platform)
             NEW_AUX_ENT(AT_PLATFORM, u_platform);
 #ifdef ARCH_DLINFO
@@ -731,17 +823,17 @@
 }
 
 
-static unsigned long load_elf_interp(struct elfhdr * interp_elf_ex,
-				     int interpreter_fd,
-				     unsigned long *interp_load_addr)
+static abi_ulong load_elf_interp(struct elfhdr * interp_elf_ex,
+                                 int interpreter_fd,
+                                 abi_ulong *interp_load_addr)
 {
 	struct elf_phdr *elf_phdata  =  NULL;
 	struct elf_phdr *eppnt;
-	unsigned long load_addr = 0;
+	abi_ulong load_addr = 0;
 	int load_addr_set = 0;
 	int retval;
-	unsigned long last_bss, elf_bss;
-	unsigned long error;
+	abi_ulong last_bss, elf_bss;
+	abi_ulong error;
 	int i;
 
 	elf_bss = 0;
@@ -755,20 +847,20 @@
 	if ((interp_elf_ex->e_type != ET_EXEC &&
              interp_elf_ex->e_type != ET_DYN) ||
 	   !elf_check_arch(interp_elf_ex->e_machine)) {
-		return ~0UL;
+		return ~((abi_ulong)0UL);
 	}
 
 
 	/* Now read in all of the header information */
 
 	if (sizeof(struct elf_phdr) * interp_elf_ex->e_phnum > TARGET_PAGE_SIZE)
-	    return ~0UL;
+	    return ~(abi_ulong)0UL;
 
 	elf_phdata =  (struct elf_phdr *)
 		malloc(sizeof(struct elf_phdr) * interp_elf_ex->e_phnum);
 
 	if (!elf_phdata)
-	  return ~0UL;
+	  return ~((abi_ulong)0UL);
 
 	/*
 	 * If the size of this structure has changed, then punt, since
@@ -776,7 +868,7 @@
 	 */
 	if (interp_elf_ex->e_phentsize != sizeof(struct elf_phdr)) {
 	    free(elf_phdata);
-	    return ~0UL;
+	    return ~((abi_ulong)0UL);
         }
 
 	retval = lseek(interpreter_fd, interp_elf_ex->e_phoff, SEEK_SET);
@@ -817,8 +909,8 @@
 	  if (eppnt->p_type == PT_LOAD) {
 	    int elf_type = MAP_PRIVATE | MAP_DENYWRITE;
 	    int elf_prot = 0;
-	    unsigned long vaddr = 0;
-	    unsigned long k;
+	    abi_ulong vaddr = 0;
+	    abi_ulong k;
 
 	    if (eppnt->p_flags & PF_R) elf_prot =  PROT_READ;
 	    if (eppnt->p_flags & PF_W) elf_prot |= PROT_WRITE;
@@ -838,7 +930,7 @@
 	      /* Real error */
 	      close(interpreter_fd);
 	      free(elf_phdata);
-	      return ~0UL;
+	      return ~((abi_ulong)0UL);
 	    }
 
 	    if (!load_addr_set && interp_elf_ex->e_type == ET_DYN) {
@@ -883,7 +975,7 @@
 	free(elf_phdata);
 
 	*interp_load_addr = load_addr;
-	return ((unsigned long) interp_elf_ex->e_entry) + load_addr;
+	return ((abi_ulong) interp_elf_ex->e_entry) + load_addr;
 }
 
 /* Best attempt to load symbols from this ELF object. */
@@ -971,22 +1063,22 @@
     struct elfhdr interp_elf_ex;
     struct exec interp_ex;
     int interpreter_fd = -1; /* avoid warning */
-    unsigned long load_addr, load_bias;
+    abi_ulong load_addr, load_bias;
     int load_addr_set = 0;
     unsigned int interpreter_type = INTERPRETER_NONE;
     unsigned char ibcs2_interpreter;
     int i;
-    unsigned long mapped_addr;
+    abi_ulong mapped_addr;
     struct elf_phdr * elf_ppnt;
     struct elf_phdr *elf_phdata;
-    unsigned long elf_bss, k, elf_brk;
+    abi_ulong elf_bss, k, elf_brk;
     int retval;
     char * elf_interpreter;
-    unsigned long elf_entry, interp_load_addr = 0;
+    abi_ulong elf_entry, interp_load_addr = 0;
     int status;
-    unsigned long start_code, end_code, end_data;
-    unsigned long reloc_func_desc = 0;
-    unsigned long elf_stack;
+    abi_ulong start_code, end_code, start_data, end_data;
+    abi_ulong reloc_func_desc = 0;
+    abi_ulong elf_stack;
     char passed_fileno[6];
 
     ibcs2_interpreter = 0;
@@ -1042,10 +1134,11 @@
     elf_brk = 0;
 
 
-    elf_stack = ~0UL;
+    elf_stack = ~((abi_ulong)0UL);
     elf_interpreter = NULL;
-    start_code = ~0UL;
+    start_code = ~((abi_ulong)0UL);
     end_code = 0;
+    start_data = 0;
     end_data = 0;
 
     for(i=0;i < elf_ex.e_phnum; i++) {
@@ -1179,9 +1272,9 @@
     /* OK, This is the point of no return */
     info->end_data = 0;
     info->end_code = 0;
-    info->start_mmap = (unsigned long)ELF_START_MMAP;
+    info->start_mmap = (abi_ulong)ELF_START_MMAP;
     info->mmap = 0;
-    elf_entry = (unsigned long) elf_ex.e_entry;
+    elf_entry = (abi_ulong) elf_ex.e_entry;
 
     /* Do this so that we can load the interpreter, if need be.  We will
        change some of these later */
@@ -1198,7 +1291,7 @@
     for(i = 0, elf_ppnt = elf_phdata; i < elf_ex.e_phnum; i++, elf_ppnt++) {
         int elf_prot = 0;
         int elf_flags = 0;
-        unsigned long error;
+        abi_ulong error;
 
 	if (elf_ppnt->p_type != PT_LOAD)
             continue;
@@ -1256,6 +1349,8 @@
         k = elf_ppnt->p_vaddr;
         if (k < start_code)
             start_code = k;
+        if (start_data < k)
+            start_data = k;
         k = elf_ppnt->p_vaddr + elf_ppnt->p_filesz;
         if (k > elf_bss)
             elf_bss = k;
@@ -1272,7 +1367,7 @@
     elf_brk += load_bias;
     start_code += load_bias;
     end_code += load_bias;
-    //    start_data += load_bias;
+    start_data += load_bias;
     end_data += load_bias;
 
     if (elf_interpreter) {
@@ -1288,7 +1383,7 @@
 	close(interpreter_fd);
 	free(elf_interpreter);
 
-	if (elf_entry == ~0UL) {
+	if (elf_entry == ~((abi_ulong)0UL)) {
 	    printf("Unable to load interpreter\n");
 	    free(elf_phdata);
 	    exit(-1);
@@ -1315,10 +1410,11 @@
 		    interp_load_addr,
 		    (interpreter_type == INTERPRETER_AOUT ? 0 : 1),
 		    info);
+    info->load_addr = reloc_func_desc;
     info->start_brk = info->brk = elf_brk;
     info->end_code = end_code;
     info->start_code = start_code;
-    info->start_data = end_code;
+    info->start_data = start_data;
     info->end_data = end_data;
     info->start_stack = bprm->p;
 

Added: trunk/src/host/qemu-neo1973/linux-user/elfload32.c
===================================================================
--- trunk/src/host/qemu-neo1973/linux-user/elfload32.c	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/linux-user/elfload32.c	2007-10-29 21:14:04 UTC (rev 3303)
@@ -0,0 +1,30 @@
+#define TARGET_ABI32
+#define load_elf_binary load_elf_binary32
+#define do_init_thread do_init_thread32
+
+#include "elfload.c"
+
+#undef load_elf_binary
+#undef do_init_thread
+
+int load_elf_binary(struct linux_binprm *bprm, struct target_pt_regs *regs,
+                    struct image_info *info);
+
+int load_elf_binary_multi(struct linux_binprm *bprm,
+                          struct target_pt_regs *regs,
+                          struct image_info *info)
+{
+    struct elfhdr *elf_ex;
+    int retval;
+
+    elf_ex = (struct elfhdr *) bprm->buf;          /* exec-header */
+    if (elf_ex->e_ident[EI_CLASS] == ELFCLASS64) {
+        retval = load_elf_binary(bprm, regs, info);
+    } else {
+        retval = load_elf_binary32(bprm, regs, info);
+        if (personality(info->personality) == PER_LINUX)
+            info->personality = PER_LINUX32;
+    }
+
+    return retval;
+}


Property changes on: trunk/src/host/qemu-neo1973/linux-user/elfload32.c
___________________________________________________________________
Name: svn:executable
   + *

Modified: trunk/src/host/qemu-neo1973/linux-user/flat.h
===================================================================
--- trunk/src/host/qemu-neo1973/linux-user/flat.h	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/linux-user/flat.h	2007-10-29 21:14:04 UTC (rev 3303)
@@ -22,25 +22,25 @@
 
 struct flat_hdr {
 	char magic[4];
-	target_ulong rev;          /* version (as above) */
-	target_ulong entry;        /* Offset of first executable instruction
-	                               with text segment from beginning of file */
-	target_ulong data_start;   /* Offset of data segment from beginning of
-	                               file */
-	target_ulong data_end;     /* Offset of end of data segment
-	                               from beginning of file */
-	target_ulong bss_end;      /* Offset of end of bss segment from beginning
-	                               of file */
+	abi_ulong rev;          /* version (as above) */
+	abi_ulong entry;        /* Offset of first executable instruction
+                                   with text segment from beginning of file */
+	abi_ulong data_start;   /* Offset of data segment from beginning of
+                                   file */
+	abi_ulong data_end;     /* Offset of end of data segment
+                                   from beginning of file */
+	abi_ulong bss_end;      /* Offset of end of bss segment from beginning
+                                   of file */
 
 	/* (It is assumed that data_end through bss_end forms the bss segment.) */
 
-	target_ulong stack_size;   /* Size of stack, in bytes */
-	target_ulong reloc_start;  /* Offset of relocation records from
-	                               beginning of file */
-	target_ulong reloc_count;  /* Number of relocation records */
-	target_ulong flags;
-	target_ulong build_date;   /* When the program/library was built */
-	target_ulong filler[5];    /* Reservered, set to zero */
+	abi_ulong stack_size;   /* Size of stack, in bytes */
+	abi_ulong reloc_start;  /* Offset of relocation records from
+                                   beginning of file */
+	abi_ulong reloc_count;  /* Number of relocation records */
+	abi_ulong flags;
+	abi_ulong build_date;   /* When the program/library was built */
+	abi_ulong filler[5];    /* Reservered, set to zero */
 };
 
 #define FLAT_FLAG_RAM    0x0001 /* load program entirely into RAM */

Modified: trunk/src/host/qemu-neo1973/linux-user/flatload.c
===================================================================
--- trunk/src/host/qemu-neo1973/linux-user/flatload.c	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/linux-user/flatload.c	2007-10-29 21:14:04 UTC (rev 3303)
@@ -63,13 +63,13 @@
 #define UNLOADED_LIB 0x7ff000ff		/* Placeholder for unused library */
 
 struct lib_info {
-    target_ulong start_code;	/* Start of text segment */
-    target_ulong start_data;	/* Start of data segment */
-    target_ulong end_data;      /* Start of bss section */
-    target_ulong start_brk;	/* End of data segment */
-    target_ulong text_len;	/* Length of text segment */
-    target_ulong entry;		/* Start address for this module */
-    target_ulong build_date;	/* When this one was compiled */
+    abi_ulong start_code;       /* Start of text segment */
+    abi_ulong start_data;       /* Start of data segment */
+    abi_ulong end_data;         /* Start of bss section */
+    abi_ulong start_brk;        /* End of data segment */
+    abi_ulong text_len;	        /* Length of text segment */
+    abi_ulong entry;	        /* Start address for this module */
+    abi_ulong build_date;       /* When this one was compiled */
     short loaded;		/* Has this library been loaded? */
 };
 
@@ -89,7 +89,7 @@
  */
 
 /* Push a block of strings onto the guest stack.  */
-static target_ulong copy_strings(target_ulong p, int n, char **s)
+static abi_ulong copy_strings(abi_ulong p, int n, char **s)
 {
     int len;
 
@@ -102,8 +102,8 @@
     return p;
 }
 
-int target_pread(int fd, target_ulong ptr, target_ulong len,
-                 target_ulong offset)
+int target_pread(int fd, abi_ulong ptr, abi_ulong len,
+                 abi_ulong offset)
 {
     void *buf;
     int ret;
@@ -262,15 +262,15 @@
 
 /****************************************************************************/
 
-static target_ulong
-calc_reloc(target_ulong r, struct lib_info *p, int curid, int internalp)
+static abi_ulong
+calc_reloc(abi_ulong r, struct lib_info *p, int curid, int internalp)
 {
-    target_ulong addr;
+    abi_ulong addr;
     int id;
-    target_ulong start_brk;
-    target_ulong start_data;
-    target_ulong text_len;
-    target_ulong start_code;
+    abi_ulong start_brk;
+    abi_ulong start_data;
+    abi_ulong text_len;
+    abi_ulong start_code;
 
 #ifdef CONFIG_BINFMT_SHARED_FLAT
 #error needs checking
@@ -381,19 +381,19 @@
 /****************************************************************************/
 
 static int load_flat_file(struct linux_binprm * bprm,
-		struct lib_info *libinfo, int id, target_ulong *extra_stack)
+		struct lib_info *libinfo, int id, abi_ulong *extra_stack)
 {
     struct flat_hdr * hdr;
-    target_ulong textpos = 0, datapos = 0, result;
-    target_ulong realdatastart = 0;
-    target_ulong text_len, data_len, bss_len, stack_len, flags;
-    target_ulong memp = 0; /* for finding the brk area */
-    target_ulong extra;
-    target_ulong reloc = 0, rp;
+    abi_ulong textpos = 0, datapos = 0, result;
+    abi_ulong realdatastart = 0;
+    abi_ulong text_len, data_len, bss_len, stack_len, flags;
+    abi_ulong memp = 0; /* for finding the brk area */
+    abi_ulong extra;
+    abi_ulong reloc = 0, rp;
     int i, rev, relocs = 0;
-    target_ulong fpos;
-    target_ulong start_code, end_code;
-    target_ulong indx_len;
+    abi_ulong fpos;
+    abi_ulong start_code, end_code;
+    abi_ulong indx_len;
 
     hdr = ((struct flat_hdr *) bprm->buf);		/* exec-header */
 
@@ -440,14 +440,14 @@
     /*
      * calculate the extra space we need to map in
      */
-    extra = relocs * sizeof(target_ulong);
+    extra = relocs * sizeof(abi_ulong);
     if (extra < bss_len + stack_len)
         extra = bss_len + stack_len;
 
     /* Add space for library base pointers.  Make sure this does not
        misalign the  doesn't misalign the data segment.  */
-    indx_len = MAX_SHARED_LIBS * sizeof(target_ulong);
-    indx_len = (indx_len + 15) & ~(target_ulong)15;
+    indx_len = MAX_SHARED_LIBS * sizeof(abi_ulong);
+    indx_len = (indx_len + 15) & ~(abi_ulong)15;
 
     /*
      * there are a couple of cases here,  the separate code/data
@@ -485,12 +485,12 @@
 #ifdef CONFIG_BINFMT_ZFLAT
         if (flags & FLAT_FLAG_GZDATA) {
             result = decompress_exec(bprm, fpos, (char *) datapos,
-                                     data_len + (relocs * sizeof(target_ulong)))
+                                     data_len + (relocs * sizeof(abi_ulong)))
         } else
 #endif
         {
             result = target_pread(bprm->fd, datapos,
-                                  data_len + (relocs * sizeof(target_ulong)),
+                                  data_len + (relocs * sizeof(abi_ulong)),
                                   fpos);
         }
         if (result < 0) {
@@ -544,7 +544,7 @@
                                   text_len, 0);
             if (result >= 0) {
                 result = target_pread(bprm->fd, datapos,
-                    data_len + (relocs * sizeof(target_ulong)),
+                    data_len + (relocs * sizeof(abi_ulong)),
                     ntohl(hdr->data_start));
             }
         }
@@ -597,7 +597,7 @@
     if (flags & FLAT_FLAG_GOTPIC) {
         rp = datapos;
         while (1) {
-            target_ulong addr;
+            abi_ulong addr;
             addr = tgetl(rp);
             if (addr == -1)
                 break;
@@ -607,7 +607,7 @@
                     return -ENOEXEC;
                 tputl(rp, addr);
             }
-            rp += sizeof(target_ulong);
+            rp += sizeof(abi_ulong);
         }
     }
 
@@ -624,12 +624,12 @@
      */
     if (rev > OLD_FLAT_VERSION) {
         for (i = 0; i < relocs; i++) {
-            target_ulong addr, relval;
+            abi_ulong addr, relval;
 
             /* Get the address of the pointer to be
                relocated (of course, the address has to be
                relocated first).  */
-            relval = tgetl(reloc + i * sizeof (target_ulong));
+            relval = tgetl(reloc + i * sizeof (abi_ulong));
             addr = flat_get_relocate_addr(relval);
             rp = calc_reloc(addr, libinfo, id, 1);
             if (rp == RELOC_FAILED)
@@ -657,8 +657,8 @@
         }
     } else {
         for (i = 0; i < relocs; i++) {
-            target_ulong relval;
-            relval = tgetl(reloc + i * sizeof (target_ulong));
+            abi_ulong relval;
+            relval = tgetl(reloc + i * sizeof (abi_ulong));
             old_reloc(&libinfo[0], relval);
         }
     }
@@ -712,10 +712,10 @@
                     struct image_info * info)
 {
     struct lib_info libinfo[MAX_SHARED_LIBS];
-    target_ulong p = bprm->p;
-    target_ulong stack_len;
-    target_ulong start_addr;
-    target_ulong sp;
+    abi_ulong p = bprm->p;
+    abi_ulong stack_len;
+    abi_ulong start_addr;
+    abi_ulong sp;
     int res;
     int i, j;
 
@@ -740,7 +740,7 @@
     /* Update data segment pointers for all libraries */
     for (i=0; i<MAX_SHARED_LIBS; i++) {
         if (libinfo[i].loaded) {
-            target_ulong p;
+            abi_ulong p;
             p = libinfo[i].start_data;
             for (j=0; j<MAX_SHARED_LIBS; j++) {
                 p -= 4;
@@ -758,12 +758,12 @@
     p = copy_strings(p, bprm->envc, bprm->envp);
     p = copy_strings(p, bprm->argc, bprm->argv);
     /* Align stack.  */
-    sp = p & ~(target_ulong)(sizeof(target_ulong) - 1);
+    sp = p & ~(abi_ulong)(sizeof(abi_ulong) - 1);
     /* Enforce final stack alignment of 16 bytes.  This is sufficient
        for all current targets, and excess alignment is harmless.  */
     stack_len = bprm->envc + bprm->argc + 2;
     stack_len += 3;	/* argc, arvg, argp */
-    stack_len *= sizeof(target_ulong);
+    stack_len *= sizeof(abi_ulong);
     if ((sp + stack_len) & 15)
         sp -= 16 - ((sp + stack_len) & 15);
     sp = loader_build_argptr(bprm->envc, bprm->argc, sp, p, 1);

Modified: trunk/src/host/qemu-neo1973/linux-user/i386/syscall.h
===================================================================
--- trunk/src/host/qemu-neo1973/linux-user/i386/syscall.h	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/linux-user/i386/syscall.h	2007-10-29 21:14:04 UTC (rev 3303)
@@ -31,7 +31,7 @@
 
 struct target_modify_ldt_ldt_s {
     unsigned int  entry_number;
-    target_ulong base_addr;
+    abi_ulong base_addr;
     unsigned int limit;
     unsigned int flags;
 };
@@ -79,22 +79,22 @@
 /*
  * normal regs, with special meaning for the segment descriptors..
  */
-	target_long ebx;
-	target_long ecx;
-	target_long edx;
-	target_long esi;
-	target_long edi;
-	target_long ebp;
-	target_long eax;
-	target_long __null_ds;
-	target_long __null_es;
-	target_long __null_fs;
-	target_long __null_gs;
-	target_long orig_eax;
-	target_long eip;
+	abi_long ebx;
+	abi_long ecx;
+	abi_long edx;
+	abi_long esi;
+	abi_long edi;
+	abi_long ebp;
+	abi_long eax;
+	abi_long __null_ds;
+	abi_long __null_es;
+	abi_long __null_fs;
+	abi_long __null_gs;
+	abi_long orig_eax;
+	abi_long eip;
 	unsigned short cs, __csh;
-	target_long eflags;
-	target_long esp;
+	abi_long eflags;
+	abi_long esp;
 	unsigned short ss, __ssh;
 /*
  * these are specific to v86 mode:
@@ -106,14 +106,14 @@
 };
 
 struct target_revectored_struct {
-	target_ulong __map[8];			/* 256 bits */
+	abi_ulong __map[8];			/* 256 bits */
 };
 
 struct target_vm86_struct {
 	struct target_vm86_regs regs;
-	target_ulong flags;
-	target_ulong screen_bitmap;
-	target_ulong cpu_type;
+	abi_ulong flags;
+	abi_ulong screen_bitmap;
+	abi_ulong cpu_type;
 	struct target_revectored_struct int_revectored;
 	struct target_revectored_struct int21_revectored;
 };
@@ -124,7 +124,7 @@
 #define TARGET_VM86_SCREEN_BITMAP	0x0001
 
 struct target_vm86plus_info_struct {
-        target_ulong flags;
+        abi_ulong flags;
 #define TARGET_force_return_for_pic (1 << 0)
 #define TARGET_vm86dbg_active       (1 << 1)  /* for debugger */
 #define TARGET_vm86dbg_TFpendig     (1 << 2)  /* for debugger */
@@ -134,9 +134,9 @@
 
 struct target_vm86plus_struct {
 	struct target_vm86_regs regs;
-	target_ulong flags;
-	target_ulong screen_bitmap;
-	target_ulong cpu_type;
+	abi_ulong flags;
+	abi_ulong screen_bitmap;
+	abi_ulong cpu_type;
 	struct target_revectored_struct int_revectored;
 	struct target_revectored_struct int21_revectored;
 	struct target_vm86plus_info_struct vm86plus;

Modified: trunk/src/host/qemu-neo1973/linux-user/i386/syscall_nr.h
===================================================================
--- trunk/src/host/qemu-neo1973/linux-user/i386/syscall_nr.h	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/linux-user/i386/syscall_nr.h	2007-10-29 21:14:04 UTC (rev 3303)
@@ -253,7 +253,7 @@
 #define TARGET_NR_io_submit		248
 #define TARGET_NR_io_cancel		249
 #define TARGET_NR_fadvise64		250
-
+/* 251 is available for reuse (was briefly sys_set_zone_reclaim) */
 #define TARGET_NR_exit_group		252
 #define TARGET_NR_lookup_dcookie	253
 #define TARGET_NR_epoll_create	254
@@ -270,8 +270,60 @@
 #define TARGET_NR_clock_gettime	(TARGET_NR_timer_create+6)
 #define TARGET_NR_clock_getres	(TARGET_NR_timer_create+7)
 #define TARGET_NR_clock_nanosleep	(TARGET_NR_timer_create+8)
-
+#define TARGET_NR_statfs64		268
+#define TARGET_NR_fstatfs64		269
 #define TARGET_NR_tgkill		270
 #define TARGET_NR_utimes		271
-
+#define TARGET_NR_fadvise64_64	272
+#define TARGET_NR_vserver		273
+#define TARGET_NR_mbind		274
+#define TARGET_NR_get_mempolicy	275
+#define TARGET_NR_set_mempolicy	276
+#define TARGET_NR_mq_open 		277
+#define TARGET_NR_mq_unlink		(TARGET_NR_mq_open+1)
+#define TARGET_NR_mq_timedsend	(TARGET_NR_mq_open+2)
+#define TARGET_NR_mq_timedreceive	(TARGET_NR_mq_open+3)
+#define TARGET_NR_mq_notify		(TARGET_NR_mq_open+4)
+#define TARGET_NR_mq_getsetattr	(TARGET_NR_mq_open+5)
+#define TARGET_NR_kexec_load		283
+#define TARGET_NR_waitid		284
+/* #define TARGET_NR_sys_setaltroot	285 */
+#define TARGET_NR_add_key		286
+#define TARGET_NR_request_key	287
+#define TARGET_NR_keyctl		288
+#define TARGET_NR_ioprio_set		289
+#define TARGET_NR_ioprio_get		290
+#define TARGET_NR_inotify_init	291
+#define TARGET_NR_inotify_add_watch	292
+#define TARGET_NR_inotify_rm_watch	293
+#define TARGET_NR_migrate_pages	294
+#define TARGET_NR_openat		295
+#define TARGET_NR_mkdirat		296
+#define TARGET_NR_mknodat		297
+#define TARGET_NR_fchownat		298
+#define TARGET_NR_futimesat		299
+#define TARGET_NR_fstatat64		300
+#define TARGET_NR_unlinkat		301
+#define TARGET_NR_renameat		302
+#define TARGET_NR_linkat		303
+#define TARGET_NR_symlinkat		304
+#define TARGET_NR_readlinkat		305
+#define TARGET_NR_fchmodat		306
+#define TARGET_NR_faccessat		307
+#define TARGET_NR_pselect6		308
+#define TARGET_NR_ppoll		309
+#define TARGET_NR_unshare		310
 #define TARGET_NR_set_robust_list	311
+#define TARGET_NR_get_robust_list	312
+#define TARGET_NR_splice		313
+#define TARGET_NR_sync_file_range	314
+#define TARGET_NR_tee		315
+#define TARGET_NR_vmsplice		316
+#define TARGET_NR_move_pages		317
+#define TARGET_NR_getcpu		318
+#define TARGET_NR_epoll_pwait	319
+#define TARGET_NR_utimensat		320
+#define TARGET_NR_signalfd		321
+#define TARGET_NR_timerfd		322
+#define TARGET_NR_eventfd		323
+#define TARGET_NR_fallocate		324

Added: trunk/src/host/qemu-neo1973/linux-user/i386/target_signal.h
===================================================================
--- trunk/src/host/qemu-neo1973/linux-user/i386/target_signal.h	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/linux-user/i386/target_signal.h	2007-10-29 21:14:04 UTC (rev 3303)
@@ -0,0 +1,29 @@
+#ifndef TARGET_SIGNAL_H
+#define TARGET_SIGNAL_H
+
+#include "cpu.h"
+
+/* this struct defines a stack used during syscall handling */
+
+typedef struct target_sigaltstack {
+	abi_ulong ss_sp;
+	abi_long ss_flags;
+	abi_ulong ss_size;
+} target_stack_t;
+
+
+/*
+ * sigaltstack controls
+ */
+#define TARGET_SS_ONSTACK	1
+#define TARGET_SS_DISABLE	2
+
+#define TARGET_MINSIGSTKSZ	2048
+#define TARGET_SIGSTKSZ		8192
+
+static inline abi_ulong get_sp_from_cpustate(CPUX86State *state)
+{
+    return state->regs[R_ESP];
+}
+
+#endif /* TARGET_SIGNAL_H */

Modified: trunk/src/host/qemu-neo1973/linux-user/i386/termbits.h
===================================================================
--- trunk/src/host/qemu-neo1973/linux-user/i386/termbits.h	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/linux-user/i386/termbits.h	2007-10-29 21:14:04 UTC (rev 3303)
@@ -26,6 +26,7 @@
 #define TARGET_IXANY   0004000
 #define TARGET_IXOFF   0010000
 #define TARGET_IMAXBEL 0020000
+#define TARGET_IUTF8   0040000
 
 /* c_oflag bits */
 #define TARGET_OPOST   0000001
@@ -96,8 +97,20 @@
 #define  TARGET_B115200 0010002
 #define  TARGET_B230400 0010003
 #define  TARGET_B460800 0010004
+#define  TARGET_B500000 0010005
+#define  TARGET_B576000 0010006
+#define  TARGET_B921600 0010007
+#define  TARGET_B1000000 0010010
+#define  TARGET_B1152000 0010011
+#define  TARGET_B1500000 0010012
+#define  TARGET_B2000000 0010013
+#define  TARGET_B2500000 0010014
+#define  TARGET_B3000000 0010015
+#define  TARGET_B3500000 0010016
+#define  TARGET_B4000000 0010017
 #define TARGET_CIBAUD    002003600000  /* input baud rate (not used) */
-#define TARGET_CRTSCTS   020000000000          /* flow control */
+#define TARGET_CMSPAR    010000000000  /* mark or space (stick) parity */
+#define TARGET_CRTSCTS   020000000000  /* flow control */
 
 /* c_lflag bits */
 #define TARGET_ISIG    0000001

Modified: trunk/src/host/qemu-neo1973/linux-user/linuxload.c
===================================================================
--- trunk/src/host/qemu-neo1973/linux-user/linuxload.c	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/linux-user/linuxload.c	2007-10-29 21:14:04 UTC (rev 3303)
@@ -13,7 +13,7 @@
 #define NGROUPS 32
 
 /* ??? This should really be somewhere else.  */
-void memcpy_to_target(target_ulong dest, const void *src,
+void memcpy_to_target(abi_ulong dest, const void *src,
                       unsigned long len)
 {
     void *host_ptr;
@@ -109,12 +109,12 @@
 }
 
 /* Construct the envp and argv tables on the target stack.  */
-target_ulong loader_build_argptr(int envc, int argc, target_ulong sp,
-                                 target_ulong stringp, int push_ptr)
+abi_ulong loader_build_argptr(int envc, int argc, abi_ulong sp,
+                              abi_ulong stringp, int push_ptr)
 {
-    int n = sizeof(target_ulong);
-    target_ulong envp;
-    target_ulong argv;
+    int n = sizeof(abi_ulong);
+    abi_ulong envp;
+    abi_ulong argv;
 
     sp -= (envc + 1) * n;
     envp = sp;
@@ -169,7 +169,11 @@
                 && bprm.buf[1] == 'E'
                 && bprm.buf[2] == 'L'
                 && bprm.buf[3] == 'F') {
+#ifndef TARGET_HAS_ELFLOAD32
             retval = load_elf_binary(&bprm,regs,infop);
+#else
+            retval = load_elf_binary_multi(&bprm, regs, infop);
+#endif
 #if defined(TARGET_HAS_BFLT)
         } else if (bprm.buf[0] == 'b'
                 && bprm.buf[1] == 'F'

Modified: trunk/src/host/qemu-neo1973/linux-user/m68k/syscall.h
===================================================================
--- trunk/src/host/qemu-neo1973/linux-user/m68k/syscall.h	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/linux-user/m68k/syscall.h	2007-10-29 21:14:04 UTC (rev 3303)
@@ -3,14 +3,14 @@
    stack during a system call. */
 
 struct target_pt_regs {
-    target_long d1, d2, d3, d4, d5, d6, d7;
-    target_long a0, a1, a2, a3, a4, a5, a6;
-    target_ulong d0;
-    target_ulong usp;
-    target_ulong orig_d0;
+    abi_long d1, d2, d3, d4, d5, d6, d7;
+    abi_long a0, a1, a2, a3, a4, a5, a6;
+    abi_ulong d0;
+    abi_ulong usp;
+    abi_ulong orig_d0;
     int16_t stkadj;
     uint16_t sr;
-    target_ulong pc;
+    abi_ulong pc;
     uint16_t fntvex;
     uint16_t __fill;
 };

Modified: trunk/src/host/qemu-neo1973/linux-user/m68k/syscall_nr.h
===================================================================
--- trunk/src/host/qemu-neo1973/linux-user/m68k/syscall_nr.h	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/linux-user/m68k/syscall_nr.h	2007-10-29 21:14:04 UTC (rev 3303)
@@ -281,3 +281,42 @@
 #define TARGET_NR_add_key            279
 #define TARGET_NR_request_key        280
 #define TARGET_NR_keyctl             281
+#define TARGET_NR_ioprio_set		282
+#define TARGET_NR_ioprio_get		283
+#define TARGET_NR_inotify_init	284
+#define TARGET_NR_inotify_add_watch	285
+#define TARGET_NR_inotify_rm_watch	286
+#define TARGET_NR_migrate_pages	287
+#define TARGET_NR_openat		288
+#define TARGET_NR_mkdirat		289
+#define TARGET_NR_mknodat		290
+#define TARGET_NR_fchownat		291
+#define TARGET_NR_futimesat		292
+#define TARGET_NR_fstatat64		293
+#define TARGET_NR_unlinkat		294
+#define TARGET_NR_renameat		295
+#define TARGET_NR_linkat		296
+#define TARGET_NR_symlinkat		297
+#define TARGET_NR_readlinkat		298
+#define TARGET_NR_fchmodat		299
+#define TARGET_NR_faccessat		300
+#define TARGET_NR_pselect6		301
+#define TARGET_NR_ppoll		302
+#define TARGET_NR_unshare		303
+#define TARGET_NR_set_robust_list	304
+#define TARGET_NR_get_robust_list	305
+#define TARGET_NR_splice		306
+#define TARGET_NR_sync_file_range	307
+#define TARGET_NR_tee		308
+#define TARGET_NR_vmsplice		309
+#define TARGET_NR_move_pages		310
+#define TARGET_NR_sched_setaffinity	311
+#define TARGET_NR_sched_getaffinity	312
+#define TARGET_NR_kexec_load		313
+#define TARGET_NR_getcpu		314
+#define TARGET_NR_epoll_pwait	315
+#define TARGET_NR_utimensat		316
+#define TARGET_NR_signalfd		317
+#define TARGET_NR_timerfd		318
+#define TARGET_NR_eventfd		319
+#define TARGET_NR_fallocate		320

Added: trunk/src/host/qemu-neo1973/linux-user/m68k/target_signal.h
===================================================================
--- trunk/src/host/qemu-neo1973/linux-user/m68k/target_signal.h	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/linux-user/m68k/target_signal.h	2007-10-29 21:14:04 UTC (rev 3303)
@@ -0,0 +1,24 @@
+#ifndef TARGET_SIGNAL_H
+#define TARGET_SIGNAL_H
+
+#include "cpu.h"
+
+/* this struct defines a stack used during syscall handling */
+
+typedef struct target_sigaltstack {
+	abi_ulong ss_sp;
+	abi_long ss_flags;
+	abi_ulong ss_size;
+} target_stack_t;
+
+
+/*
+ * sigaltstack controls
+ */
+#define TARGET_SS_ONSTACK	1
+#define TARGET_SS_DISABLE	2
+
+#define TARGET_MINSIGSTKSZ	2048
+#define TARGET_SIGSTKSZ	8192
+
+#endif /* TARGET_SIGNAL_H */

Modified: trunk/src/host/qemu-neo1973/linux-user/m68k/termbits.h
===================================================================
--- trunk/src/host/qemu-neo1973/linux-user/m68k/termbits.h	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/linux-user/m68k/termbits.h	2007-10-29 21:14:04 UTC (rev 3303)
@@ -27,6 +27,7 @@
 #define TARGET_IXANY   0004000
 #define TARGET_IXOFF   0010000
 #define TARGET_IMAXBEL 0020000
+#define TARGET_IUTF8   0040000
 
 /* c_oflag bits */
 #define TARGET_OPOST   0000001
@@ -97,8 +98,20 @@
 #define  TARGET_B115200 0010002
 #define  TARGET_B230400 0010003
 #define  TARGET_B460800 0010004
+#define  TARGET_B500000 0010005
+#define  TARGET_B576000 0010006
+#define  TARGET_B921600 0010007
+#define  TARGET_B1000000 0010010
+#define  TARGET_B1152000 0010011
+#define  TARGET_B1500000 0010012
+#define  TARGET_B2000000 0010013
+#define  TARGET_B2500000 0010014
+#define  TARGET_B3000000 0010015
+#define  TARGET_B3500000 0010016
+#define  TARGET_B4000000 0010017
 #define TARGET_CIBAUD    002003600000  /* input baud rate (not used) */
-#define TARGET_CRTSCTS   020000000000          /* flow control */
+#define TARGET_CMSPAR    010000000000  /* mark or space (stick) parity */
+#define TARGET_CRTSCTS   020000000000  /* flow control */
 
 /* c_lflag bits */
 #define TARGET_ISIG    0000001

Modified: trunk/src/host/qemu-neo1973/linux-user/main.c
===================================================================
--- trunk/src/host/qemu-neo1973/linux-user/main.c	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/linux-user/main.c	2007-10-29 21:14:04 UTC (rev 3303)
@@ -168,7 +168,7 @@
 void cpu_loop(CPUX86State *env)
 {
     int trapnr;
-    target_ulong pc;
+    abi_ulong pc;
     target_siginfo_t info;
 
     for(;;) {
@@ -305,11 +305,11 @@
 #ifdef TARGET_ARM
 
 /* XXX: find a better solution */
-extern void tb_invalidate_page_range(target_ulong start, target_ulong end);
+extern void tb_invalidate_page_range(abi_ulong start, abi_ulong end);
 
-static void arm_cache_flush(target_ulong start, target_ulong last)
+static void arm_cache_flush(abi_ulong start, abi_ulong last)
 {
-    target_ulong addr, last1;
+    abi_ulong addr, last1;
 
     if (last < start)
         return;
@@ -474,7 +474,7 @@
 static inline void save_window_offset(CPUSPARCState *env, int cwp1)
 {
     unsigned int i;
-    target_ulong sp_ptr;
+    abi_ulong sp_ptr;
 
     sp_ptr = env->regbase[get_reg_index(env, cwp1, 6)];
 #if defined(DEBUG_WIN)
@@ -483,7 +483,7 @@
 #endif
     for(i = 0; i < 16; i++) {
         tputl(sp_ptr, env->regbase[get_reg_index(env, cwp1, 8 + i)]);
-        sp_ptr += sizeof(target_ulong);
+        sp_ptr += sizeof(abi_ulong);
     }
 }
 
@@ -505,7 +505,7 @@
 static void restore_window(CPUSPARCState *env)
 {
     unsigned int new_wim, i, cwp1;
-    target_ulong sp_ptr;
+    abi_ulong sp_ptr;
 
     new_wim = ((env->wim << 1) | (env->wim >> (NWINDOWS - 1))) &
         ((1LL << NWINDOWS) - 1);
@@ -519,7 +519,7 @@
 #endif
     for(i = 0; i < 16; i++) {
         env->regbase[get_reg_index(env, cwp1, 8 + i)] = tgetl(sp_ptr);
-        sp_ptr += sizeof(target_ulong);
+        sp_ptr += sizeof(abi_ulong);
     }
     env->wim = new_wim;
 #ifdef TARGET_SPARC64
@@ -564,6 +564,7 @@
         case 0x88:
         case 0x90:
 #else
+        case 0x110:
         case 0x16d:
 #endif
             ret = do_syscall (env, env->gregs[1],
@@ -571,14 +572,14 @@
                               env->regwptr[2], env->regwptr[3],
                               env->regwptr[4], env->regwptr[5]);
             if ((unsigned int)ret >= (unsigned int)(-515)) {
-#ifdef TARGET_SPARC64
+#if defined(TARGET_SPARC64) && !defined(TARGET_ABI32)
                 env->xcc |= PSR_CARRY;
 #else
                 env->psr |= PSR_CARRY;
 #endif
                 ret = -ret;
             } else {
-#ifdef TARGET_SPARC64
+#if defined(TARGET_SPARC64) && !defined(TARGET_ABI32)
                 env->xcc &= ~PSR_CARRY;
 #else
                 env->psr &= ~PSR_CARRY;
@@ -590,6 +591,9 @@
             env->npc = env->npc + 4;
             break;
         case 0x83: /* flush windows */
+#ifdef TARGET_ABI32
+        case 0x103:
+#endif
             flush_windows(env);
             /* next instruction */
             env->pc = env->npc;
@@ -634,6 +638,14 @@
                 queue_signal(info.si_signo, &info);
             }
             break;
+        case 0x16e:
+            flush_windows(env);
+            sparc64_get_context(env);
+            break;
+        case 0x16f:
+            flush_windows(env);
+            sparc64_set_context(env);
+            break;
 #endif
         case EXCP_INTERRUPT:
             /* just indicate that signals should be handled asap */
@@ -664,7 +676,6 @@
 #endif
 
 #ifdef TARGET_PPC
-
 static inline uint64_t cpu_ppc_get_tb (CPUState *env)
 {
     /* TO FIX */
@@ -681,37 +692,45 @@
     return cpu_ppc_get_tb(env) >> 32;
 }
 
-static void cpu_ppc_store_tb (CPUState *env, uint64_t value)
+uint32_t cpu_ppc_load_atbl (CPUState *env)
 {
-    /* TO FIX */
+    return cpu_ppc_get_tb(env) & 0xFFFFFFFF;
 }
 
-void cpu_ppc_store_tbu (CPUState *env, uint32_t value)
+uint32_t cpu_ppc_load_atbu (CPUState *env)
 {
-    cpu_ppc_store_tb(env, ((uint64_t)value << 32) | cpu_ppc_load_tbl(env));
+    return cpu_ppc_get_tb(env) >> 32;
 }
 
-void cpu_ppc_store_tbl (CPUState *env, uint32_t value)
-{
-    cpu_ppc_store_tb(env, ((uint64_t)cpu_ppc_load_tbl(env) << 32) | value);
-}
-
-void cpu_ppc601_store_rtcu (CPUState *env, uint32_t value)
-__attribute__ (( alias ("cpu_ppc_store_tbu") ));
-
 uint32_t cpu_ppc601_load_rtcu (CPUState *env)
 __attribute__ (( alias ("cpu_ppc_load_tbu") ));
 
-void cpu_ppc601_store_rtcl (CPUState *env, uint32_t value)
+uint32_t cpu_ppc601_load_rtcl (CPUState *env)
 {
-    cpu_ppc_store_tbl(env, value & 0x3FFFFF80);
+    return cpu_ppc_load_tbl(env) & 0x3FFFFF80;
 }
 
-uint32_t cpu_ppc601_load_rtcl (CPUState *env)
+/* XXX: to be fixed */
+int ppc_dcr_read (ppc_dcr_t *dcr_env, int dcrn, target_ulong *valp)
 {
-    return cpu_ppc_load_tbl(env) & 0x3FFFFF80;
+    return -1;
 }
 
+int ppc_dcr_write (ppc_dcr_t *dcr_env, int dcrn, target_ulong val)
+{
+    return -1;
+}
+
+#define EXCP_DUMP(env, fmt, args...)                                         \
+do {                                                                          \
+    fprintf(stderr, fmt , ##args);                                            \
+    cpu_dump_state(env, stderr, fprintf, 0);                                  \
+    if (loglevel != 0) {                                                      \
+        fprintf(logfile, fmt , ##args);                                       \
+        cpu_dump_state(env, logfile, fprintf, 0);                             \
+    }                                                                         \
+} while (0)
+
 void cpu_loop(CPUPPCState *env)
 {
     target_siginfo_t info;
@@ -720,60 +739,22 @@
 
     for(;;) {
         trapnr = cpu_ppc_exec(env);
-        if (trapnr != EXCP_SYSCALL_USER && trapnr != EXCP_BRANCH &&
-            trapnr != EXCP_TRACE) {
-            if (loglevel > 0) {
-                cpu_dump_state(env, logfile, fprintf, 0);
-            }
-        }
         switch(trapnr) {
-        case EXCP_NONE:
+        case POWERPC_EXCP_NONE:
+            /* Just go on */
             break;
-        case EXCP_SYSCALL_USER:
-            /* system call */
-            /* WARNING:
-             * PPC ABI uses overflow flag in cr0 to signal an error
-             * in syscalls.
-             */
-#if 0
-            printf("syscall %d 0x%08x 0x%08x 0x%08x 0x%08x\n", env->gpr[0],
-                   env->gpr[3], env->gpr[4], env->gpr[5], env->gpr[6]);
-#endif
-            env->crf[0] &= ~0x1;
-            ret = do_syscall(env, env->gpr[0], env->gpr[3], env->gpr[4],
-                             env->gpr[5], env->gpr[6], env->gpr[7],
-                             env->gpr[8]);
-            if (ret > (uint32_t)(-515)) {
-                env->crf[0] |= 0x1;
-                ret = -ret;
-            }
-            env->gpr[3] = ret;
-#if 0
-            printf("syscall returned 0x%08x (%d)\n", ret, ret);
-#endif
+        case POWERPC_EXCP_CRITICAL: /* Critical input                        */
+            cpu_abort(env, "Critical interrupt while in user mode. "
+                      "Aborting\n");
             break;
-        case EXCP_RESET:
-            /* Should not happen ! */
-            fprintf(stderr, "RESET asked... Stop emulation\n");
-            if (loglevel)
-                fprintf(logfile, "RESET asked... Stop emulation\n");
-            abort();
-        case EXCP_MACHINE_CHECK:
-            fprintf(stderr, "Machine check exeption...  Stop emulation\n");
-            if (loglevel)
-                fprintf(logfile, "RESET asked... Stop emulation\n");
-            info.si_signo = TARGET_SIGBUS;
-            info.si_errno = 0;
-            info.si_code = TARGET_BUS_OBJERR;
-            info._sifields._sigfault._addr = env->nip - 4;
-            queue_signal(info.si_signo, &info);
-        case EXCP_DSI:
-            fprintf(stderr, "Invalid data memory access: 0x" ADDRX "\n",
-                    env->spr[SPR_DAR]);
-            if (loglevel) {
-                fprintf(logfile, "Invalid data memory access: 0x" ADDRX "\n",
-                        env->spr[SPR_DAR]);
-            }
+        case POWERPC_EXCP_MCHECK:   /* Machine check exception               */
+            cpu_abort(env, "Machine check exception while in user mode. "
+                      "Aborting\n");
+            break;
+        case POWERPC_EXCP_DSI:      /* Data storage exception                */
+            EXCP_DUMP(env, "Invalid data memory access: 0x" ADDRX "\n",
+                      env->spr[SPR_DAR]);
+            /* XXX: check this. Seems bugged */
             switch (env->error_code & 0xFF000000) {
             case 0x40000000:
                 info.si_signo = TARGET_SIGSEGV;
@@ -792,12 +773,8 @@
                 break;
             default:
                 /* Let's send a regular segfault... */
-                fprintf(stderr, "Invalid segfault errno (%02x)\n",
-                        env->error_code);
-                if (loglevel) {
-                    fprintf(logfile, "Invalid segfault errno (%02x)\n",
-                            env->error_code);
-                }
+                EXCP_DUMP(env, "Invalid segfault errno (%02x)\n",
+                          env->error_code);
                 info.si_signo = TARGET_SIGSEGV;
                 info.si_errno = 0;
                 info.si_code = TARGET_SEGV_MAPERR;
@@ -806,10 +783,10 @@
             info._sifields._sigfault._addr = env->nip;
             queue_signal(info.si_signo, &info);
             break;
-        case EXCP_ISI:
-            fprintf(stderr, "Invalid instruction fetch\n");
-            if (loglevel)
-                fprintf(logfile, "Invalid instruction fetch\n");
+        case POWERPC_EXCP_ISI:      /* Instruction storage exception         */
+            EXCP_DUMP(env, "Invalid instruction fetch: 0x\n" ADDRX "\n",
+                      env->spr[SPR_DAR]);
+            /* XXX: check this */
             switch (env->error_code & 0xFF000000) {
             case 0x40000000:
                 info.si_signo = TARGET_SIGSEGV;
@@ -824,12 +801,8 @@
                 break;
             default:
                 /* Let's send a regular segfault... */
-                fprintf(stderr, "Invalid segfault errno (%02x)\n",
-                        env->error_code);
-                if (loglevel) {
-                    fprintf(logfile, "Invalid segfault errno (%02x)\n",
-                            env->error_code);
-                }
+                EXCP_DUMP(env, "Invalid segfault errno (%02x)\n",
+                          env->error_code);
                 info.si_signo = TARGET_SIGSEGV;
                 info.si_errno = 0;
                 info.si_code = TARGET_SEGV_MAPERR;
@@ -838,186 +811,159 @@
             info._sifields._sigfault._addr = env->nip - 4;
             queue_signal(info.si_signo, &info);
             break;
-        case EXCP_EXTERNAL:
-            /* Should not happen ! */
-            fprintf(stderr, "External interruption... Stop emulation\n");
-            if (loglevel)
-                fprintf(logfile, "External interruption... Stop emulation\n");
-            abort();
-        case EXCP_ALIGN:
-            fprintf(stderr, "Invalid unaligned memory access\n");
-            if (loglevel)
-                fprintf(logfile, "Invalid unaligned memory access\n");
+        case POWERPC_EXCP_EXTERNAL: /* External input                        */
+            cpu_abort(env, "External interrupt while in user mode. "
+                      "Aborting\n");
+            break;
+        case POWERPC_EXCP_ALIGN:    /* Alignment exception                   */
+            EXCP_DUMP(env, "Unaligned memory access\n");
+            /* XXX: check this */
             info.si_signo = TARGET_SIGBUS;
             info.si_errno = 0;
             info.si_code = TARGET_BUS_ADRALN;
             info._sifields._sigfault._addr = env->nip - 4;
             queue_signal(info.si_signo, &info);
             break;
-        case EXCP_PROGRAM:
+        case POWERPC_EXCP_PROGRAM:  /* Program exception                     */
+            /* XXX: check this */
             switch (env->error_code & ~0xF) {
-            case EXCP_FP:
-            fprintf(stderr, "Program exception\n");
-                if (loglevel)
-                    fprintf(logfile, "Program exception\n");
-                /* Set FX */
-                env->fpscr[7] |= 0x8;
-                /* Finally, update FEX */
-                if ((((env->fpscr[7] & 0x3) << 3) | (env->fpscr[6] >> 1)) &
-                    ((env->fpscr[1] << 1) | (env->fpscr[0] >> 3)))
-                    env->fpscr[7] |= 0x4;
+            case POWERPC_EXCP_FP:
+                EXCP_DUMP(env, "Floating point program exception\n");
                 info.si_signo = TARGET_SIGFPE;
                 info.si_errno = 0;
                 switch (env->error_code & 0xF) {
-                case EXCP_FP_OX:
+                case POWERPC_EXCP_FP_OX:
                     info.si_code = TARGET_FPE_FLTOVF;
                     break;
-                case EXCP_FP_UX:
+                case POWERPC_EXCP_FP_UX:
                     info.si_code = TARGET_FPE_FLTUND;
                     break;
-                case EXCP_FP_ZX:
-                case EXCP_FP_VXZDZ:
+                case POWERPC_EXCP_FP_ZX:
+                case POWERPC_EXCP_FP_VXZDZ:
                     info.si_code = TARGET_FPE_FLTDIV;
                     break;
-                case EXCP_FP_XX:
+                case POWERPC_EXCP_FP_XX:
                     info.si_code = TARGET_FPE_FLTRES;
                     break;
-                case EXCP_FP_VXSOFT:
+                case POWERPC_EXCP_FP_VXSOFT:
                     info.si_code = TARGET_FPE_FLTINV;
                     break;
-                case EXCP_FP_VXNAN:
-                case EXCP_FP_VXISI:
-                case EXCP_FP_VXIDI:
-                case EXCP_FP_VXIMZ:
-                case EXCP_FP_VXVC:
-                case EXCP_FP_VXSQRT:
-                case EXCP_FP_VXCVI:
+                case POWERPC_EXCP_FP_VXSNAN:
+                case POWERPC_EXCP_FP_VXISI:
+                case POWERPC_EXCP_FP_VXIDI:
+                case POWERPC_EXCP_FP_VXIMZ:
+                case POWERPC_EXCP_FP_VXVC:
+                case POWERPC_EXCP_FP_VXSQRT:
+                case POWERPC_EXCP_FP_VXCVI:
                     info.si_code = TARGET_FPE_FLTSUB;
                     break;
                 default:
-                    fprintf(stderr, "Unknown floating point exception "
-                            "(%02x)\n", env->error_code);
-                    if (loglevel) {
-                        fprintf(logfile, "Unknown floating point exception "
-                                "(%02x)\n", env->error_code & 0xF);
-                    }
+                    EXCP_DUMP(env, "Unknown floating point exception (%02x)\n",
+                              env->error_code);
+                    break;
                 }
-            break;
-        case EXCP_INVAL:
-                fprintf(stderr, "Invalid instruction\n");
-                if (loglevel)
-                    fprintf(logfile, "Invalid instruction\n");
+                break;
+            case POWERPC_EXCP_INVAL:
+                EXCP_DUMP(env, "Invalid instruction\n");
                 info.si_signo = TARGET_SIGILL;
                 info.si_errno = 0;
                 switch (env->error_code & 0xF) {
-                case EXCP_INVAL_INVAL:
+                case POWERPC_EXCP_INVAL_INVAL:
                     info.si_code = TARGET_ILL_ILLOPC;
                     break;
-                case EXCP_INVAL_LSWX:
-            info.si_code = TARGET_ILL_ILLOPN;
+                case POWERPC_EXCP_INVAL_LSWX:
+                    info.si_code = TARGET_ILL_ILLOPN;
                     break;
-                case EXCP_INVAL_SPR:
+                case POWERPC_EXCP_INVAL_SPR:
                     info.si_code = TARGET_ILL_PRVREG;
                     break;
-                case EXCP_INVAL_FP:
+                case POWERPC_EXCP_INVAL_FP:
                     info.si_code = TARGET_ILL_COPROC;
                     break;
                 default:
-                    fprintf(stderr, "Unknown invalid operation (%02x)\n",
-                            env->error_code & 0xF);
-                    if (loglevel) {
-                        fprintf(logfile, "Unknown invalid operation (%02x)\n",
-                                env->error_code & 0xF);
-                    }
+                    EXCP_DUMP(env, "Unknown invalid operation (%02x)\n",
+                              env->error_code & 0xF);
                     info.si_code = TARGET_ILL_ILLADR;
                     break;
                 }
                 break;
-            case EXCP_PRIV:
-                fprintf(stderr, "Privilege violation\n");
-                if (loglevel)
-                    fprintf(logfile, "Privilege violation\n");
+            case POWERPC_EXCP_PRIV:
+                EXCP_DUMP(env, "Privilege violation\n");
                 info.si_signo = TARGET_SIGILL;
                 info.si_errno = 0;
                 switch (env->error_code & 0xF) {
-                case EXCP_PRIV_OPC:
+                case POWERPC_EXCP_PRIV_OPC:
                     info.si_code = TARGET_ILL_PRVOPC;
                     break;
-                case EXCP_PRIV_REG:
+                case POWERPC_EXCP_PRIV_REG:
                     info.si_code = TARGET_ILL_PRVREG;
-                break;
+                    break;
                 default:
-                    fprintf(stderr, "Unknown privilege violation (%02x)\n",
-                            env->error_code & 0xF);
+                    EXCP_DUMP(env, "Unknown privilege violation (%02x)\n",
+                              env->error_code & 0xF);
                     info.si_code = TARGET_ILL_PRVOPC;
                     break;
                 }
                 break;
-            case EXCP_TRAP:
-                fprintf(stderr, "Tried to call a TRAP\n");
-                if (loglevel)
-                    fprintf(logfile, "Tried to call a TRAP\n");
-                abort();
+            case POWERPC_EXCP_TRAP:
+                cpu_abort(env, "Tried to call a TRAP\n");
+                break;
             default:
                 /* Should not happen ! */
-                fprintf(stderr, "Unknown program exception (%02x)\n",
-                        env->error_code);
-                if (loglevel) {
-                    fprintf(logfile, "Unknwon program exception (%02x)\n",
-                            env->error_code);
-                }
-                abort();
+                cpu_abort(env, "Unknown program exception (%02x)\n",
+                          env->error_code);
+                break;
             }
             info._sifields._sigfault._addr = env->nip - 4;
             queue_signal(info.si_signo, &info);
             break;
-        case EXCP_NO_FP:
-            fprintf(stderr, "No floating point allowed\n");
-            if (loglevel)
-                fprintf(logfile, "No floating point allowed\n");
+        case POWERPC_EXCP_FPU:      /* Floating-point unavailable exception  */
+            EXCP_DUMP(env, "No floating point allowed\n");
             info.si_signo = TARGET_SIGILL;
             info.si_errno = 0;
             info.si_code = TARGET_ILL_COPROC;
             info._sifields._sigfault._addr = env->nip - 4;
             queue_signal(info.si_signo, &info);
             break;
-        case EXCP_DECR:
-            /* Should not happen ! */
-            fprintf(stderr, "Decrementer exception\n");
-            if (loglevel)
-                fprintf(logfile, "Decrementer exception\n");
-            abort();
-        case EXCP_TRACE:
-            /* Do nothing: we use this to trace execution */
+        case POWERPC_EXCP_SYSCALL:  /* System call exception                 */
+            cpu_abort(env, "Syscall exception while in user mode. "
+                      "Aborting\n");
             break;
-        case EXCP_FP_ASSIST:
-            /* Should not happen ! */
-            fprintf(stderr, "Floating point assist exception\n");
-            if (loglevel)
-                fprintf(logfile, "Floating point assist exception\n");
-            abort();
-        case EXCP_MTMSR:
-            /* We reloaded the msr, just go on */
-            if (msr_pr == 0) {
-                fprintf(stderr, "Tried to go into supervisor mode !\n");
-                if (loglevel)
-                    fprintf(logfile, "Tried to go into supervisor mode !\n");
-                abort();
-        }
+        case POWERPC_EXCP_APU:      /* Auxiliary processor unavailable       */
+            EXCP_DUMP(env, "No APU instruction allowed\n");
+            info.si_signo = TARGET_SIGILL;
+            info.si_errno = 0;
+            info.si_code = TARGET_ILL_COPROC;
+            info._sifields._sigfault._addr = env->nip - 4;
+            queue_signal(info.si_signo, &info);
             break;
-        case EXCP_BRANCH:
-            /* We stopped because of a jump... */
+        case POWERPC_EXCP_DECR:     /* Decrementer exception                 */
+            cpu_abort(env, "Decrementer interrupt while in user mode. "
+                      "Aborting\n");
             break;
-        case EXCP_INTERRUPT:
-            /* Don't know why this should ever happen... */
+        case POWERPC_EXCP_FIT:      /* Fixed-interval timer interrupt        */
+            cpu_abort(env, "Fix interval timer interrupt while in user mode. "
+                      "Aborting\n");
             break;
-        case EXCP_DEBUG:
+        case POWERPC_EXCP_WDT:      /* Watchdog timer interrupt              */
+            cpu_abort(env, "Watchdog timer interrupt while in user mode. "
+                      "Aborting\n");
+            break;
+        case POWERPC_EXCP_DTLB:     /* Data TLB error                        */
+            cpu_abort(env, "Data TLB exception while in user mode. "
+                      "Aborting\n");
+            break;
+        case POWERPC_EXCP_ITLB:     /* Instruction TLB error                 */
+            cpu_abort(env, "Instruction TLB exception while in user mode. "
+                      "Aborting\n");
+            break;
+        case POWERPC_EXCP_DEBUG:    /* Debug interrupt                       */
+            /* XXX: check this */
             {
                 int sig;
 
-                sig = gdb_handlesig (env, TARGET_SIGTRAP);
-                if (sig)
-                  {
+                sig = gdb_handlesig(env, TARGET_SIGTRAP);
+                if (sig) {
                     info.si_signo = sig;
                     info.si_errno = 0;
                     info.si_code = TARGET_TRAP_BRKPT;
@@ -1025,14 +971,176 @@
                   }
             }
             break;
+#if defined(TARGET_PPCEMB)
+        case POWERPC_EXCP_SPEU:     /* SPE/embedded floating-point unavail.  */
+            EXCP_DUMP(env, "No SPE/floating-point instruction allowed\n");
+            info.si_signo = TARGET_SIGILL;
+            info.si_errno = 0;
+            info.si_code = TARGET_ILL_COPROC;
+            info._sifields._sigfault._addr = env->nip - 4;
+            queue_signal(info.si_signo, &info);
+            break;
+        case POWERPC_EXCP_EFPDI:    /* Embedded floating-point data IRQ      */
+            cpu_abort(env, "Embedded floating-point data IRQ not handled\n");
+            break;
+        case POWERPC_EXCP_EFPRI:    /* Embedded floating-point round IRQ     */
+            cpu_abort(env, "Embedded floating-point round IRQ not handled\n");
+            break;
+        case POWERPC_EXCP_EPERFM:   /* Embedded performance monitor IRQ      */
+            cpu_abort(env, "Performance monitor exception not handled\n");
+            break;
+        case POWERPC_EXCP_DOORI:    /* Embedded doorbell interrupt           */
+            cpu_abort(env, "Doorbell interrupt while in user mode. "
+                       "Aborting\n");
+            break;
+        case POWERPC_EXCP_DOORCI:   /* Embedded doorbell critical interrupt  */
+            cpu_abort(env, "Doorbell critical interrupt while in user mode. "
+                      "Aborting\n");
+            break;
+        case POWERPC_EXCP_RESET:    /* System reset exception                */
+            cpu_abort(env, "Reset interrupt while in user mode. "
+                      "Aborting\n");
+            break;
+#endif /* defined(TARGET_PPCEMB) */
+#if defined(TARGET_PPC64) && !defined(TARGET_ABI32) /* PowerPC 64 */
+        case POWERPC_EXCP_DSEG:     /* Data segment exception                */
+            cpu_abort(env, "Data segment exception while in user mode. "
+                      "Aborting\n");
+            break;
+        case POWERPC_EXCP_ISEG:     /* Instruction segment exception         */
+            cpu_abort(env, "Instruction segment exception "
+                      "while in user mode. Aborting\n");
+            break;
+#endif /* defined(TARGET_PPC64) && !defined(TARGET_ABI32) */
+#if defined(TARGET_PPC64H) && !defined(TARGET_ABI32)
+        /* PowerPC 64 with hypervisor mode support */
+        case POWERPC_EXCP_HDECR:    /* Hypervisor decrementer exception      */
+            cpu_abort(env, "Hypervisor decrementer interrupt "
+                      "while in user mode. Aborting\n");
+            break;
+#endif /* defined(TARGET_PPC64H) && !defined(TARGET_ABI32) */
+        case POWERPC_EXCP_TRACE:    /* Trace exception                       */
+            /* Nothing to do:
+             * we use this exception to emulate step-by-step execution mode.
+             */
+            break;
+#if defined(TARGET_PPC64H) && !defined(TARGET_ABI32)
+        /* PowerPC 64 with hypervisor mode support */
+        case POWERPC_EXCP_HDSI:     /* Hypervisor data storage exception     */
+            cpu_abort(env, "Hypervisor data storage exception "
+                      "while in user mode. Aborting\n");
+            break;
+        case POWERPC_EXCP_HISI:     /* Hypervisor instruction storage excp   */
+            cpu_abort(env, "Hypervisor instruction storage exception "
+                      "while in user mode. Aborting\n");
+            break;
+        case POWERPC_EXCP_HDSEG:    /* Hypervisor data segment exception     */
+            cpu_abort(env, "Hypervisor data segment exception "
+                      "while in user mode. Aborting\n");
+            break;
+        case POWERPC_EXCP_HISEG:    /* Hypervisor instruction segment excp   */
+            cpu_abort(env, "Hypervisor instruction segment exception "
+                      "while in user mode. Aborting\n");
+            break;
+#endif /* defined(TARGET_PPC64H) && !defined(TARGET_ABI32) */
+        case POWERPC_EXCP_VPU:      /* Vector unavailable exception          */
+            EXCP_DUMP(env, "No Altivec instructions allowed\n");
+            info.si_signo = TARGET_SIGILL;
+            info.si_errno = 0;
+            info.si_code = TARGET_ILL_COPROC;
+            info._sifields._sigfault._addr = env->nip - 4;
+            queue_signal(info.si_signo, &info);
+            break;
+        case POWERPC_EXCP_PIT:      /* Programmable interval timer IRQ       */
+            cpu_abort(env, "Programable interval timer interrupt "
+                      "while in user mode. Aborting\n");
+            break;
+        case POWERPC_EXCP_IO:       /* IO error exception                    */
+            cpu_abort(env, "IO error exception while in user mode. "
+                      "Aborting\n");
+            break;
+        case POWERPC_EXCP_RUNM:     /* Run mode exception                    */
+            cpu_abort(env, "Run mode exception while in user mode. "
+                      "Aborting\n");
+            break;
+        case POWERPC_EXCP_EMUL:     /* Emulation trap exception              */
+            cpu_abort(env, "Emulation trap exception not handled\n");
+            break;
+        case POWERPC_EXCP_IFTLB:    /* Instruction fetch TLB error           */
+            cpu_abort(env, "Instruction fetch TLB exception "
+                      "while in user-mode. Aborting");
+            break;
+        case POWERPC_EXCP_DLTLB:    /* Data load TLB miss                    */
+            cpu_abort(env, "Data load TLB exception while in user-mode. "
+                      "Aborting");
+            break;
+        case POWERPC_EXCP_DSTLB:    /* Data store TLB miss                   */
+            cpu_abort(env, "Data store TLB exception while in user-mode. "
+                      "Aborting");
+            break;
+        case POWERPC_EXCP_FPA:      /* Floating-point assist exception       */
+            cpu_abort(env, "Floating-point assist exception not handled\n");
+            break;
+        case POWERPC_EXCP_IABR:     /* Instruction address breakpoint        */
+            cpu_abort(env, "Instruction address breakpoint exception "
+                      "not handled\n");
+            break;
+        case POWERPC_EXCP_SMI:      /* System management interrupt           */
+            cpu_abort(env, "System management interrupt while in user mode. "
+                      "Aborting\n");
+            break;
+        case POWERPC_EXCP_THERM:    /* Thermal interrupt                     */
+            cpu_abort(env, "Thermal interrupt interrupt while in user mode. "
+                      "Aborting\n");
+            break;
+        case POWERPC_EXCP_PERFM:   /* Embedded performance monitor IRQ      */
+            cpu_abort(env, "Performance monitor exception not handled\n");
+            break;
+        case POWERPC_EXCP_VPUA:     /* Vector assist exception               */
+            cpu_abort(env, "Vector assist exception not handled\n");
+            break;
+        case POWERPC_EXCP_SOFTP:    /* Soft patch exception                  */
+            cpu_abort(env, "Soft patch exception not handled\n");
+            break;
+        case POWERPC_EXCP_MAINT:    /* Maintenance exception                 */
+            cpu_abort(env, "Maintenance exception while in user mode. "
+                      "Aborting\n");
+            break;
+        case POWERPC_EXCP_STOP:     /* stop translation                      */
+            /* We did invalidate the instruction cache. Go on */
+            break;
+        case POWERPC_EXCP_BRANCH:   /* branch instruction:                   */
+            /* We just stopped because of a branch. Go on */
+            break;
+        case POWERPC_EXCP_SYSCALL_USER:
+            /* system call in user-mode emulation */
+            /* WARNING:
+             * PPC ABI uses overflow flag in cr0 to signal an error
+             * in syscalls.
+             */
+#if 0
+            printf("syscall %d 0x%08x 0x%08x 0x%08x 0x%08x\n", env->gpr[0],
+                   env->gpr[3], env->gpr[4], env->gpr[5], env->gpr[6]);
+#endif
+            env->crf[0] &= ~0x1;
+            ret = do_syscall(env, env->gpr[0], env->gpr[3], env->gpr[4],
+                             env->gpr[5], env->gpr[6], env->gpr[7],
+                             env->gpr[8]);
+            if (ret > (uint32_t)(-515)) {
+                env->crf[0] |= 0x1;
+                ret = -ret;
+            }
+            env->gpr[3] = ret;
+#if 0
+            printf("syscall returned 0x%08x (%d)\n", ret, ret);
+#endif
+            break;
+        case EXCP_INTERRUPT:
+            /* just indicate that signals should be handled asap */
+            break;
         default:
-            fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n",
-                    trapnr);
-            if (loglevel) {
-                fprintf(logfile, "qemu: unhandled CPU exception 0x%02x - "
-                        "0x%02x - aborting\n", trapnr, env->error_code);
-            }
-            abort();
+            cpu_abort(env, "Unknown exception 0x%d. Aborting\n", trapnr);
+            break;
         }
         process_pending_signals(env);
     }
@@ -1380,8 +1488,8 @@
                 ret = -ENOSYS;
             } else {
                 int nb_args;
-                target_ulong sp_reg;
-                target_ulong arg5 = 0, arg6 = 0, arg7 = 0, arg8 = 0;
+                abi_ulong sp_reg;
+                abi_ulong arg5 = 0, arg6 = 0, arg7 = 0, arg8 = 0;
 
                 nb_args = mips_syscall_args[syscall_num];
                 sp_reg = env->gpr[29][env->current_tc];
@@ -1493,6 +1601,61 @@
 }
 #endif
 
+#ifdef TARGET_CRIS
+void cpu_loop (CPUState *env)
+{
+    int trapnr, ret;
+    target_siginfo_t info;
+    
+    while (1) {
+        trapnr = cpu_cris_exec (env);
+        switch (trapnr) {
+        case 0xaa:
+            {
+                info.si_signo = SIGSEGV;
+                info.si_errno = 0;
+                /* XXX: check env->error_code */
+                info.si_code = TARGET_SEGV_MAPERR;
+                info._sifields._sigfault._addr = env->debug1;
+                queue_signal(info.si_signo, &info);
+            }
+            break;
+        case EXCP_BREAK:
+            ret = do_syscall(env, 
+                             env->regs[9], 
+                             env->regs[10], 
+                             env->regs[11], 
+                             env->regs[12], 
+                             env->regs[13], 
+                             env->pregs[7], 
+                             env->pregs[11]);
+            env->regs[10] = ret;
+            env->pc += 2;
+            break;
+        case EXCP_DEBUG:
+            {
+                int sig;
+
+                sig = gdb_handlesig (env, TARGET_SIGTRAP);
+                if (sig)
+                  {
+                    info.si_signo = sig;
+                    info.si_errno = 0;
+                    info.si_code = TARGET_TRAP_BRKPT;
+                    queue_signal(info.si_signo, &info);
+                  }
+            }
+            break;
+        default:
+            printf ("Unhandled trap: 0x%x\n", trapnr);
+            cpu_dump_state(env, stderr, fprintf, 0);
+            exit (1);
+        }
+        process_pending_signals (env);
+    }
+}
+#endif
+
 #ifdef TARGET_M68K
 
 void cpu_loop(CPUM68KState *env)
@@ -1781,14 +1944,9 @@
         } else if (!strcmp(r, "cpu")) {
             cpu_model = argv[optind++];
             if (strcmp(cpu_model, "?") == 0) {
-#if defined(TARGET_PPC)
-                ppc_cpu_list(stdout, &fprintf);
-#elif defined(TARGET_ARM)
-                arm_cpu_list();
-#elif defined(TARGET_MIPS)
-                mips_cpu_list(stdout, &fprintf);
-#elif defined(TARGET_SPARC)
-                sparc_cpu_list(stdout, &fprintf);
+/* XXX: implement xxx_cpu_list for targets that still miss it */
+#if defined(cpu_list)
+                    cpu_list(stdout, &fprintf);
 #endif
                 _exit(1);
             }
@@ -1850,14 +2008,17 @@
     if (loglevel) {
         page_dump(logfile);
 
-        fprintf(logfile, "start_brk   0x%08lx\n" , info->start_brk);
-        fprintf(logfile, "end_code    0x%08lx\n" , info->end_code);
-        fprintf(logfile, "start_code  0x%08lx\n" , info->start_code);
-        fprintf(logfile, "start_data  0x%08lx\n" , info->start_data);
-        fprintf(logfile, "end_data    0x%08lx\n" , info->end_data);
-        fprintf(logfile, "start_stack 0x%08lx\n" , info->start_stack);
-        fprintf(logfile, "brk         0x%08lx\n" , info->brk);
-        fprintf(logfile, "entry       0x%08lx\n" , info->entry);
+        fprintf(logfile, "start_brk   0x" TARGET_FMT_lx "\n", info->start_brk);
+        fprintf(logfile, "end_code    0x" TARGET_FMT_lx "\n", info->end_code);
+        fprintf(logfile, "start_code  0x" TARGET_FMT_lx "\n",
+                info->start_code);
+        fprintf(logfile, "start_data  0x" TARGET_FMT_lx "\n",
+                info->start_data);
+        fprintf(logfile, "end_data    0x" TARGET_FMT_lx "\n", info->end_data);
+        fprintf(logfile, "start_stack 0x" TARGET_FMT_lx "\n",
+                info->start_stack);
+        fprintf(logfile, "brk         0x" TARGET_FMT_lx "\n", info->brk);
+        fprintf(logfile, "entry       0x" TARGET_FMT_lx "\n", info->entry);
     }
 
     target_set_brk(info->brk);
@@ -1977,7 +2138,7 @@
             fprintf(stderr, "Unable to find Sparc CPU definition\n");
             exit(1);
         }
-        cpu_sparc_register(env, def);
+        cpu_sparc_register(env, def, 0);
 	env->pc = regs->pc;
 	env->npc = regs->npc;
         env->y = regs->y;
@@ -2000,14 +2161,14 @@
                       "Unable to find PowerPC CPU definition\n");
         }
         cpu_ppc_register(env, def);
-
-        for (i = 0; i < 32; i++) {
-            if (i != 12 && i != 6 && i != 13)
-                env->msr[i] = (regs->msr >> i) & 1;
-        }
+        cpu_ppc_reset(env);
 #if defined(TARGET_PPC64)
-        msr_sf = 1;
+#if defined(TARGET_ABI32)
+        env->msr &= ~((target_ulong)1 << MSR_SF);
+#else
+        env->msr |= (target_ulong)1 << MSR_SF;
 #endif
+#endif
         env->nip = regs->nip;
         for(i = 0; i < 32; i++) {
             env->gpr[i] = regs->gpr[i];
@@ -2048,7 +2209,11 @@
 
         /* Choose and initialise CPU */
         if (cpu_model == NULL)
+#if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)
+            cpu_model = "20Kc";
+#else
             cpu_model = "24Kf";
+#endif
         mips_find_by_name(cpu_model, &def);
         if (def == NULL)
             cpu_abort(env, "Unable to find MIPS CPU definition\n");
@@ -2073,13 +2238,33 @@
         int i;
 
         for(i = 0; i < 28; i++) {
-            env->ir[i] = ((target_ulong *)regs)[i];
+            env->ir[i] = ((abi_ulong *)regs)[i];
         }
         env->ipr[IPR_USP] = regs->usp;
         env->ir[30] = regs->usp;
         env->pc = regs->pc;
         env->unique = regs->unique;
     }
+#elif defined(TARGET_CRIS)
+    {
+	    env->regs[0] = regs->r0;
+	    env->regs[1] = regs->r1;
+	    env->regs[2] = regs->r2;
+	    env->regs[3] = regs->r3;
+	    env->regs[4] = regs->r4;
+	    env->regs[5] = regs->r5;
+	    env->regs[6] = regs->r6;
+	    env->regs[7] = regs->r7;
+	    env->regs[8] = regs->r8;
+	    env->regs[9] = regs->r9;
+	    env->regs[10] = regs->r10;
+	    env->regs[11] = regs->r11;
+	    env->regs[12] = regs->r12;
+	    env->regs[13] = regs->r13;
+	    env->regs[14] = info->start_stack;
+	    env->regs[15] = regs->acr;	    
+	    env->pc = regs->erp;
+    }
 #else
 #error unsupported target CPU
 #endif

Modified: trunk/src/host/qemu-neo1973/linux-user/mips/syscall.h
===================================================================
--- trunk/src/host/qemu-neo1973/linux-user/mips/syscall.h	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/linux-user/mips/syscall.h	2007-10-29 21:14:04 UTC (rev 3303)
@@ -3,21 +3,19 @@
    stack during a system call. */
 
 struct target_pt_regs {
-#if 1
 	/* Pad bytes for argument save space on the stack. */
-	target_ulong pad0[6];
-#endif
+	abi_ulong pad0[6];
 
 	/* Saved main processor registers. */
-	target_ulong regs[32];
+	abi_ulong regs[32];
 
 	/* Saved special registers. */
-	target_ulong cp0_status;
-	target_ulong lo;
-	target_ulong hi;
-	target_ulong cp0_badvaddr;
-	target_ulong cp0_cause;
-	target_ulong cp0_epc;
+	abi_ulong cp0_status;
+	abi_ulong lo;
+	abi_ulong hi;
+	abi_ulong cp0_badvaddr;
+	abi_ulong cp0_cause;
+	abi_ulong cp0_epc;
 };
 
 /* Target errno definitions taken from asm-mips/errno.h */

Modified: trunk/src/host/qemu-neo1973/linux-user/mips/syscall_nr.h
===================================================================
--- trunk/src/host/qemu-neo1973/linux-user/mips/syscall_nr.h	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/linux-user/mips/syscall_nr.h	2007-10-29 21:14:04 UTC (rev 3303)
@@ -318,3 +318,8 @@
 #define TARGET_NR_epoll_pwait		(TARGET_NR_Linux + 313)
 #define TARGET_NR_ioprio_set		(TARGET_NR_Linux + 314)
 #define TARGET_NR_ioprio_get		(TARGET_NR_Linux + 315)
+#define TARGET_NR_utimensat		(TARGET_NR_Linux + 316)
+#define TARGET_NR_signalfd		(TARGET_NR_Linux + 317)
+#define TARGET_NR_timerfd		(TARGET_NR_Linux + 318)
+#define TARGET_NR_eventfd		(TARGET_NR_Linux + 319)
+#define TARGET_NR_fallocate		(TARGET_NR_Linux + 320)

Added: trunk/src/host/qemu-neo1973/linux-user/mips/target_signal.h
===================================================================
--- trunk/src/host/qemu-neo1973/linux-user/mips/target_signal.h	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/linux-user/mips/target_signal.h	2007-10-29 21:14:04 UTC (rev 3303)
@@ -0,0 +1,29 @@
+#ifndef TARGET_SIGNAL_H
+#define TARGET_SIGNAL_H
+
+#include "cpu.h"
+
+/* this struct defines a stack used during syscall handling */
+
+typedef struct target_sigaltstack {
+	abi_long ss_sp;
+	abi_ulong ss_size;
+	abi_long ss_flags;
+} target_stack_t;
+
+
+/*
+ * sigaltstack controls
+ */
+#define TARGET_SS_ONSTACK     1
+#define TARGET_SS_DISABLE     2
+
+#define TARGET_MINSIGSTKSZ    2048
+#define TARGET_SIGSTKSZ       8192
+
+static inline abi_ulong get_sp_from_cpustate(CPUMIPSState *state)
+{
+    return state->gpr[29][state->current_tc];
+}
+
+#endif /* TARGET_SIGNAL_H */

Modified: trunk/src/host/qemu-neo1973/linux-user/mips/termbits.h
===================================================================
--- trunk/src/host/qemu-neo1973/linux-user/mips/termbits.h	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/linux-user/mips/termbits.h	2007-10-29 21:14:04 UTC (rev 3303)
@@ -26,6 +26,7 @@
 #define TARGET_IXANY   0004000
 #define TARGET_IXOFF   0010000
 #define TARGET_IMAXBEL 0020000
+#define TARGET_IUTF8   0040000
 
 /* c_oflag bits */
 #define TARGET_OPOST   0000001
@@ -92,12 +93,25 @@
 #define TARGET_HUPCL   0002000
 #define TARGET_CLOCAL  0004000
 #define TARGET_CBAUDEX 0010000
-#define  TARGET_B57600  0010001
-#define  TARGET_B115200 0010002
-#define  TARGET_B230400 0010003
-#define  TARGET_B460800 0010004
+#define  TARGET_BOTHER   0010000
+#define  TARGET_B57600   0010001
+#define  TARGET_B115200  0010002
+#define  TARGET_B230400  0010003
+#define  TARGET_B460800  0010004
+#define  TARGET_B500000  0010005
+#define  TARGET_B576000  0010006
+#define  TARGET_B921600  0010007
+#define  TARGET_B1000000 0010010
+#define  TARGET_B1152000 0010011
+#define  TARGET_B1500000 0010012
+#define  TARGET_B2000000 0010013
+#define  TARGET_B2500000 0010014
+#define  TARGET_B3000000 0010015
+#define  TARGET_B3500000 0010016
+#define  TARGET_B4000000 0010017
 #define TARGET_CIBAUD    002003600000  /* input baud rate (not used) */
-#define TARGET_CRTSCTS   020000000000          /* flow control */
+#define TARGET_CMSPAR    010000000000  /* mark or space (stick) parity */
+#define TARGET_CRTSCTS   020000000000  /* flow control */
 
 /* c_lflag bits */
 #define TARGET_ISIG    0000001
@@ -108,32 +122,34 @@
 #define TARGET_ECHOK   0000040
 #define TARGET_ECHONL  0000100
 #define TARGET_NOFLSH  0000200
-#define TARGET_TOSTOP  0000400
+#define TARGET_IEXTEN  0000400
 #define TARGET_ECHOCTL 0001000
 #define TARGET_ECHOPRT 0002000
 #define TARGET_ECHOKE  0004000
 #define TARGET_FLUSHO  0010000
 #define TARGET_PENDIN  0040000
-#define TARGET_IEXTEN  0100000
+#define TARGET_TOSTOP  0100000
+#define TARGET_ITOSTOP TARGET_TOSTOP
 
 /* c_cc character offsets */
 #define TARGET_VINTR	0
 #define TARGET_VQUIT	1
 #define TARGET_VERASE	2
 #define TARGET_VKILL	3
-#define TARGET_VEOF	4
+#define TARGET_VMIN	4
 #define TARGET_VTIME	5
-#define TARGET_VMIN	6
+#define TARGET_VEOL2	6
 #define TARGET_VSWTC	7
 #define TARGET_VSTART	8
 #define TARGET_VSTOP	9
 #define TARGET_VSUSP	10
-#define TARGET_VEOL	11
+/* VDSUSP not supported */
 #define TARGET_VREPRINT	12
 #define TARGET_VDISCARD	13
 #define TARGET_VWERASE	14
 #define TARGET_VLNEXT	15
-#define TARGET_VEOL2	16
+#define TARGET_VEOF	16
+#define TARGET_VEOL	17
 
 /* ioctls */
 
@@ -154,7 +170,7 @@
 #define TARGET_TIOCEXCL	0x740d		/* set exclusive use of tty */
 #define TARGET_TIOCNXCL	0x740e		/* reset exclusive use of tty */
 #define TARGET_TIOCOUTQ	0x7472		/* output queue size */
-#define TARGET_TIOCSTI		0x5472		/* simulate terminal input */
+#define TARGET_TIOCSTI	0x5472		/* simulate terminal input */
 #define TARGET_TIOCMGET	0x741d		/* get all modem bits */
 #define TARGET_TIOCMBIS	0x741b		/* bis modem bits */
 #define TARGET_TIOCMBIC	0x741c		/* bic modem bits */

Modified: trunk/src/host/qemu-neo1973/linux-user/mmap.c
===================================================================
--- trunk/src/host/qemu-neo1973/linux-user/mmap.c	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/linux-user/mmap.c	2007-10-29 21:14:04 UTC (rev 3303)
@@ -30,13 +30,14 @@
 //#define DEBUG_MMAP
 
 /* NOTE: all the constants are the HOST ones, but addresses are target. */
-int target_mprotect(target_ulong start, target_ulong len, int prot)
+int target_mprotect(abi_ulong start, abi_ulong len, int prot)
 {
-    target_ulong end, host_start, host_end, addr;
+    abi_ulong end, host_start, host_end, addr;
     int prot1, ret;
 
 #ifdef DEBUG_MMAP
-    printf("mprotect: start=0x%lx len=0x%lx prot=%c%c%c\n", start, len,
+    printf("mprotect: start=0x" TARGET_FMT_lx
+	   "len=0x" TARGET_FMT_lx " prot=%c%c%c\n", start, len,
            prot & PROT_READ ? 'r' : '-',
            prot & PROT_WRITE ? 'w' : '-',
            prot & PROT_EXEC ? 'x' : '-');
@@ -95,11 +96,11 @@
 }
 
 /* map an incomplete host page */
-static int mmap_frag(target_ulong real_start,
-                     target_ulong start, target_ulong end,
-                     int prot, int flags, int fd, target_ulong offset)
+static int mmap_frag(abi_ulong real_start,
+                     abi_ulong start, abi_ulong end,
+                     int prot, int flags, int fd, abi_ulong offset)
 {
-    target_ulong real_end, ret, addr;
+    abi_ulong real_end, ret, addr;
     void *host_start;
     int prot1, prot_new;
 
@@ -151,22 +152,23 @@
 }
 
 /* NOTE: all the constants are the HOST ones */
-long target_mmap(target_ulong start, target_ulong len, int prot,
-                 int flags, int fd, target_ulong offset)
+abi_long target_mmap(abi_ulong start, abi_ulong len, int prot,
+                     int flags, int fd, abi_ulong offset)
 {
-    target_ulong ret, end, real_start, real_end, retaddr, host_offset, host_len;
-    long host_start;
+    abi_ulong ret, end, real_start, real_end, retaddr, host_offset, host_len;
+    unsigned long host_start;
 #if defined(__alpha__) || defined(__sparc__) || defined(__x86_64__) || \
         defined(__ia64) || defined(__mips__)
-    static target_ulong last_start = 0x40000000;
+    static abi_ulong last_start = 0x40000000;
 #elif defined(__CYGWIN__)
     /* Cygwin doesn't have a whole lot of address space.  */
-    static target_ulong last_start = 0x18000000;
+    static abi_ulong last_start = 0x18000000;
 #endif
 
 #ifdef DEBUG_MMAP
     {
-        printf("mmap: start=0x%lx len=0x%lx prot=%c%c%c flags=",
+        printf("mmap: start=0x" TARGET_FMT_lx
+	       " len=0x" TARGET_FMT_lx " prot=%c%c%c flags=",
                start, len,
                prot & PROT_READ ? 'r' : '-',
                prot & PROT_WRITE ? 'w' : '-',
@@ -186,7 +188,7 @@
             printf("[MAP_TYPE=0x%x] ", flags & MAP_TYPE);
             break;
         }
-        printf("fd=%d offset=%lx\n", fd, offset);
+        printf("fd=%d offset=" TARGET_FMT_lx "\n", fd, offset);
     }
 #endif
 
@@ -209,34 +211,59 @@
             last_start += HOST_PAGE_ALIGN(len);
         }
 #endif
-        if (0 && qemu_host_page_size != qemu_real_host_page_size) {
-            /* NOTE: this code is only for debugging with '-p' option */
-            /* ??? Can also occur when TARGET_PAGE_SIZE > host page size.  */
-            /* reserve a memory area */
-            /* ??? This needs fixing for remapping.  */
-abort();
-            host_len = HOST_PAGE_ALIGN(len) + qemu_host_page_size - TARGET_PAGE_SIZE;
-            real_start = (long)mmap(g2h(real_start), host_len, PROT_NONE,
-                                    MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
-            if (real_start == -1)
-                return real_start;
-            real_end = real_start + host_len;
-            start = HOST_PAGE_ALIGN(real_start);
-            end = start + HOST_PAGE_ALIGN(len);
-            if (start > real_start)
-                munmap((void *)real_start, start - real_start);
-            if (end < real_end)
-                munmap((void *)end, real_end - end);
-            /* use it as a fixed mapping */
-            flags |= MAP_FIXED;
+            host_offset = offset & qemu_host_page_mask;
+            host_len = len + offset - host_offset;
+
+        if (qemu_host_page_size > qemu_real_host_page_size) {
+            /*
+             * The guest expects to see mmapped areas aligned to it's pagesize.
+             * If the host's real page size is smaller than the guest's, we need
+             * to fixup the maps. It is done by allocating a larger area,
+             * displacing the map (if needed) and finally chopping off the spare
+             * room at the edges.
+             */
+
+            /*
+             * We assume qemu_host_page_size is always the same as
+             * TARGET_PAGE_SIZE, see exec.c. qemu_real_host_page_size is the
+             * hosts real page size.
+             */
+            abi_ulong host_end;
+            unsigned long host_aligned_start;
+
+            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)
+                return -1;
+
+            host_end = host_start + host_len;
+
+            /* Find start and end, aligned to the targets pagesize with-in the
+               large mmaped area.  */
+            host_aligned_start = TARGET_PAGE_ALIGN(host_start);
+            if (!(flags & MAP_ANONYMOUS))
+                host_aligned_start += offset - host_offset;
+
+            start = h2g(host_aligned_start);
+            end = start + TARGET_PAGE_ALIGN(len);
+
+            /* Chop off the leftovers, if any.  */
+            if (host_aligned_start > host_start)
+                munmap((void *)host_start, host_aligned_start - host_start);
+            if (end < host_end)
+                munmap((void *)g2h(end), host_end - end);
+
+            goto the_end1;
         } else {
             /* if not fixed, no need to do anything */
-            host_offset = offset & qemu_host_page_mask;
-            host_len = len + offset - host_offset;
             host_start = (long)mmap(real_start ? g2h(real_start) : NULL,
                                     host_len, prot, flags, fd, host_offset);
             if (host_start == -1)
-                return host_start;
+                return -1;
             /* update start so that it points to the file position at 'offset' */
             if (!(flags & MAP_ANONYMOUS))
                 host_start += offset - host_offset;
@@ -267,7 +294,7 @@
                               MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS,
                               -1, 0);
         if (retaddr == -1)
-            return retaddr;
+            return -1;
         pread(fd, g2h(start), len, offset);
         if (!(prot & PROT_WRITE)) {
             ret = target_mprotect(start, len, prot);
@@ -300,7 +327,7 @@
                         prot, flags, fd,
                         offset + real_end - qemu_host_page_size - start);
         if (ret == -1)
-            return ret;
+            return -1;
         real_end -= qemu_host_page_size;
     }
 
@@ -314,22 +341,22 @@
         ret = (long)mmap(g2h(real_start), real_end - real_start,
                          prot, flags, fd, offset1);
         if (ret == -1)
-            return ret;
+            return -1;
     }
  the_end1:
     page_set_flags(start, start + len, prot | PAGE_VALID);
  the_end:
 #ifdef DEBUG_MMAP
-    printf("ret=0x%lx\n", (long)start);
+    printf("ret=0x%llx\n", start);
     page_dump(stdout);
     printf("\n");
 #endif
     return start;
 }
 
-int target_munmap(target_ulong start, target_ulong len)
+int target_munmap(abi_ulong start, abi_ulong len)
 {
-    target_ulong end, real_start, real_end, addr;
+    abi_ulong end, real_start, real_end, addr;
     int prot, ret;
 
 #ifdef DEBUG_MMAP
@@ -370,7 +397,7 @@
 
     /* unmap what we can */
     if (real_start < real_end) {
-        ret = munmap((void *)real_start, real_end - real_start);
+        ret = munmap(g2h(real_start), real_end - real_start);
         if (ret != 0)
             return ret;
     }
@@ -381,26 +408,27 @@
 
 /* XXX: currently, we only handle MAP_ANONYMOUS and not MAP_FIXED
    blocks which have been allocated starting on a host page */
-long target_mremap(target_ulong old_addr, target_ulong old_size,
-                   target_ulong new_size, unsigned long flags,
-                   target_ulong new_addr)
+abi_long target_mremap(abi_ulong old_addr, abi_ulong old_size,
+                       abi_ulong new_size, unsigned long flags,
+                       abi_ulong new_addr)
 {
     int prot;
+    unsigned long host_addr;
 
     /* XXX: use 5 args syscall */
-    new_addr = (long)mremap(g2h(old_addr), old_size, new_size, flags);
-    if (new_addr == -1)
-        return new_addr;
-    new_addr = h2g(new_addr);
+    host_addr = (long)mremap(g2h(old_addr), old_size, new_size, flags);
+    if (host_addr == -1)
+        return -1;
+    new_addr = h2g(host_addr);
     prot = page_get_flags(old_addr);
     page_set_flags(old_addr, old_addr + old_size, 0);
     page_set_flags(new_addr, new_addr + new_size, prot | PAGE_VALID);
     return new_addr;
 }
 
-int target_msync(target_ulong start, target_ulong len, int flags)
+int target_msync(abi_ulong start, abi_ulong len, int flags)
 {
-    target_ulong end;
+    abi_ulong end;
 
     if (start & ~TARGET_PAGE_MASK)
         return -EINVAL;

Modified: trunk/src/host/qemu-neo1973/linux-user/ppc/syscall.h
===================================================================
--- trunk/src/host/qemu-neo1973/linux-user/ppc/syscall.h	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/linux-user/ppc/syscall.h	2007-10-29 21:14:04 UTC (rev 3303)
@@ -44,11 +44,15 @@
 
 /* ioctls */
 struct target_revectored_struct {
-	target_ulong __map[8];			/* 256 bits */
+	abi_ulong __map[8];			/* 256 bits */
 };
 
 /*
  * flags masks
  */
 
+#if defined(TARGET_PPC64) && !defined(TARGET_ABI32)
+#define UNAME_MACHINE "ppc64"
+#else
 #define UNAME_MACHINE "ppc"
+#endif

Modified: trunk/src/host/qemu-neo1973/linux-user/ppc/syscall_nr.h
===================================================================
--- trunk/src/host/qemu-neo1973/linux-user/ppc/syscall_nr.h	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/linux-user/ppc/syscall_nr.h	2007-10-29 21:14:04 UTC (rev 3303)
@@ -193,19 +193,23 @@
 #define TARGET_NR_vfork                  189
 #define TARGET_NR_ugetrlimit             190     /* SuS compliant getrlimit */
 #define TARGET_NR_readahead              191
+#if !defined(TARGET_PPC64) || defined(TARGET_ABI32)
 #define TARGET_NR_mmap2                  192
 #define TARGET_NR_truncate64             193
 #define TARGET_NR_ftruncate64            194
 #define TARGET_NR_stat64                 195
 #define TARGET_NR_lstat64                196
 #define TARGET_NR_fstat64                197
+#endif
 #define TARGET_NR_pciconfig_read         198
 #define TARGET_NR_pciconfig_write        199
 #define TARGET_NR_pciconfig_iobase       200
 #define TARGET_NR_multiplexer            201
 #define TARGET_NR_getdents64             202
 #define TARGET_NR_pivot_root             203
+#if !defined(TARGET_PPC64) || defined(TARGET_ABI32)
 #define TARGET_NR_fcntl64                204
+#endif
 #define TARGET_NR_madvise                205
 #define TARGET_NR_mincore                206
 #define TARGET_NR_gettid                 207
@@ -227,7 +231,9 @@
 #define TARGET_NR_sched_getaffinity      223
 /* 224 currently unused */
 #define TARGET_NR_tuxcall                225
+#if !defined(TARGET_PPC64) || defined(TARGET_ABI32)
 #define TARGET_NR_sendfile64             226
+#endif
 #define TARGET_NR_io_setup               227
 #define TARGET_NR_io_destroy             228
 #define TARGET_NR_io_getevents           229
@@ -255,4 +261,65 @@
 #define TARGET_NR_utimes                 251
 #define TARGET_NR_statfs64               252
 #define TARGET_NR_fstatfs64              253
+#if !defined(TARGET_PPC64) || defined(TARGET_ABI32)
 #define TARGET_NR_fadvise64_64           254
+#endif
+#define TARGET_NR_rtas		255
+#define TARGET_NR_sys_debug_setcontext 256
+/* Number 257 is reserved for vserver */
+#define TARGET_NR_migrate_pages	258
+#define TARGET_NR_mbind		259
+#define TARGET_NR_get_mempolicy	260
+#define TARGET_NR_set_mempolicy	261
+#define TARGET_NR_mq_open		262
+#define TARGET_NR_mq_unlink		263
+#define TARGET_NR_mq_timedsend	264
+#define TARGET_NR_mq_timedreceive	265
+#define TARGET_NR_mq_notify		266
+#define TARGET_NR_mq_getsetattr	267
+#define TARGET_NR_kexec_load		268
+#define TARGET_NR_add_key		269
+#define TARGET_NR_request_key	270
+#define TARGET_NR_keyctl		271
+#define TARGET_NR_waitid		272
+#define TARGET_NR_ioprio_set		273
+#define TARGET_NR_ioprio_get		274
+#define TARGET_NR_inotify_init	275
+#define TARGET_NR_inotify_add_watch	276
+#define TARGET_NR_inotify_rm_watch	277
+#define TARGET_NR_spu_run		278
+#define TARGET_NR_spu_create		279
+#define TARGET_NR_pselect6		280
+#define TARGET_NR_ppoll		281
+#define TARGET_NR_unshare		282
+#define TARGET_NR_splice		283
+#define TARGET_NR_tee		284
+#define TARGET_NR_vmsplice		285
+#define TARGET_NR_openat		286
+#define TARGET_NR_mkdirat		287
+#define TARGET_NR_mknodat		288
+#define TARGET_NR_fchownat		289
+#define TARGET_NR_futimesat		290
+#if defined(TARGET_PPC64) && !defined(TARGET_ABI32)
+#define TARGET_NR_newfstatat		291
+#else
+#define TARGET_NR_fstatat64		291
+#endif
+#define TARGET_NR_unlinkat		292
+#define TARGET_NR_renameat		293
+#define TARGET_NR_linkat		294
+#define TARGET_NR_symlinkat		295
+#define TARGET_NR_readlinkat		296
+#define TARGET_NR_fchmodat		297
+#define TARGET_NR_faccessat		298
+#define TARGET_NR_get_robust_list	299
+#define TARGET_NR_set_robust_list	300
+#define TARGET_NR_move_pages		301
+#define TARGET_NR_getcpu		302
+#define TARGET_NR_epoll_pwait	303
+#define TARGET_NR_utimensat		304
+#define TARGET_NR_signalfd		305
+#define TARGET_NR_timerfd		306
+#define TARGET_NR_eventfd		307
+#define TARGET_NR_sync_file_range2	308
+#define TARGET_NR_fallocate		309

Added: trunk/src/host/qemu-neo1973/linux-user/ppc/target_signal.h
===================================================================
--- trunk/src/host/qemu-neo1973/linux-user/ppc/target_signal.h	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/linux-user/ppc/target_signal.h	2007-10-29 21:14:04 UTC (rev 3303)
@@ -0,0 +1,29 @@
+#ifndef TARGET_SIGNAL_H
+#define TARGET_SIGNAL_H
+
+#include "cpu.h"
+
+/* this struct defines a stack used during syscall handling */
+
+typedef struct target_sigaltstack {
+	abi_ulong ss_sp;
+	abi_long ss_flags;
+	abi_ulong ss_size;
+} target_stack_t;
+
+
+/*
+ * sigaltstack controls
+ */
+#define TARGET_SS_ONSTACK     1
+#define TARGET_SS_DISABLE     2
+
+#define TARGET_MINSIGSTKSZ    2048
+#define TARGET_SIGSTKSZ       8192
+
+static inline abi_ulong get_sp_from_cpustate(CPUPPCState *state)
+{
+    return state->gpr[1];
+}
+
+#endif /* TARGET_SIGNAL_H */

Modified: trunk/src/host/qemu-neo1973/linux-user/ppc/termbits.h
===================================================================
--- trunk/src/host/qemu-neo1973/linux-user/ppc/termbits.h	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/linux-user/ppc/termbits.h	2007-10-29 21:14:04 UTC (rev 3303)
@@ -47,6 +47,7 @@
 #define TARGET_IXANY	0004000
 #define TARGET_IUCLC	0010000
 #define TARGET_IMAXBEL	0020000
+#define	TARGET_IUTF8	0040000
 
 /* c_oflag bits */
 #define TARGET_OPOST	0000001
@@ -69,6 +70,7 @@
 #define   TARGET_TAB1	00002000
 #define   TARGET_TAB2	00004000
 #define   TARGET_TAB3	00006000
+#define   TARGET_XTABS	00006000	/* required by POSIX to == TAB3 */
 #define TARGET_CRDLY	00030000
 #define   TARGET_CR0	00000000
 #define   TARGET_CR1	00010000
@@ -83,7 +85,6 @@
 #define TARGET_VTDLY	00200000
 #define   TARGET_VT0	00000000
 #define   TARGET_VT1	00200000
-#define TARGET_XTABS	01000000 /* Hmm.. Linux/i386 considers this part of TABDLY.. */
 
 /* c_cflag bit meaning */
 #define TARGET_CBAUD	0000377
@@ -135,7 +136,8 @@
 #define TARGET_HUPCL	00040000
 
 #define TARGET_CLOCAL	00100000
-#define TARGET_CRTSCTS	  020000000000		/* flow control */
+#define TARGET_CMSPAR	010000000000		/* mark or space (stick) parity */
+#define TARGET_CRTSCTS	020000000000		/* flow control */
 
 /* c_lflag bits */
 #define TARGET_ISIG	0x00000080

Modified: trunk/src/host/qemu-neo1973/linux-user/qemu.h
===================================================================
--- trunk/src/host/qemu-neo1973/linux-user/qemu.h	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/linux-user/qemu.h	2007-10-29 21:14:04 UTC (rev 3303)
@@ -1,14 +1,25 @@
 #ifndef QEMU_H
 #define QEMU_H
 
-#include "thunk.h"
-
 #include <signal.h>
 #include <string.h>
-#include "syscall_defs.h"
 
 #include "cpu.h"
+
+#ifdef TARGET_ABI32
+typedef uint32_t abi_ulong;
+typedef int32_t abi_long;
+#define TARGET_ABI_BITS 32
+#else
+typedef target_ulong abi_ulong;
+typedef target_long abi_long;
+#define TARGET_ABI_BITS TARGET_LONG_BITS
+#endif
+
+#include "thunk.h"
+#include "syscall_defs.h"
 #include "syscall.h"
+#include "target_signal.h"
 #include "gdbstub.h"
 
 /* This struct is used to hold certain information about the image.
@@ -16,19 +27,20 @@
  * task_struct fields in the kernel
  */
 struct image_info {
-	unsigned long	start_code;
-	unsigned long	end_code;
-        unsigned long   start_data;
-	unsigned long	end_data;
-	unsigned long	start_brk;
-	unsigned long	brk;
-	unsigned long	start_mmap;
-	unsigned long	mmap;
-	unsigned long	rss;
-	unsigned long	start_stack;
-	unsigned long	entry;
-        target_ulong    code_offset;
-        target_ulong    data_offset;
+        abi_ulong       load_addr;
+        abi_ulong       start_code;
+        abi_ulong       end_code;
+        abi_ulong       start_data;
+        abi_ulong       end_data;
+        abi_ulong       start_brk;
+        abi_ulong       brk;
+        abi_ulong       start_mmap;
+        abi_ulong       mmap;
+        abi_ulong       rss;
+        abi_ulong       start_stack;
+        abi_ulong       entry;
+        abi_ulong       code_offset;
+        abi_ulong       data_offset;
         char            **host_argv;
 	int		personality;
 };
@@ -65,7 +77,7 @@
     int swi_errno;
 #endif
 #if defined(TARGET_I386) && !defined(TARGET_X86_64)
-    target_ulong target_v86;
+    abi_ulong target_v86;
     struct vm86_saved_state vm86_saved_regs;
     struct target_vm86plus_struct vm86plus;
     uint32_t v86flags;
@@ -103,7 +115,7 @@
 struct linux_binprm {
         char buf[128];
         void *page[MAX_ARG_PAGES];
-        unsigned long p;
+        abi_ulong p;
 	int fd;
         int e_uid, e_gid;
         int argc, envc;
@@ -113,8 +125,8 @@
 };
 
 void do_init_thread(struct target_pt_regs *regs, struct image_info *infop);
-target_ulong loader_build_argptr(int envc, int argc, target_ulong sp,
-                                 target_ulong stringp, int push_ptr);
+abi_ulong loader_build_argptr(int envc, int argc, abi_ulong sp,
+                              abi_ulong stringp, int push_ptr);
 int loader_exec(const char * filename, char ** argv, char ** envp,
              struct target_pt_regs * regs, struct image_info *infop);
 
@@ -122,14 +134,20 @@
                     struct image_info * info);
 int load_flt_binary(struct linux_binprm * bprm, struct target_pt_regs * regs,
                     struct image_info * info);
+#ifdef TARGET_HAS_ELFLOAD32
+int load_elf_binary_multi(struct linux_binprm *bprm,
+                          struct target_pt_regs *regs,
+                          struct image_info *info);
+#endif
 
-void memcpy_to_target(target_ulong dest, const void *src,
+void memcpy_to_target(abi_ulong dest, const void *src,
                       unsigned long len);
-void target_set_brk(target_ulong new_brk);
-long do_brk(target_ulong new_brk);
+void target_set_brk(abi_ulong new_brk);
+abi_long do_brk(abi_ulong new_brk);
 void syscall_init(void);
-long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
-                long arg4, long arg5, long arg6);
+abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
+                    abi_long arg2, abi_long arg3, abi_long arg4,
+                    abi_long arg5, abi_long arg6);
 void gemu_log(const char *fmt, ...) __attribute__((format(printf,1,2)));
 extern CPUState *global_env;
 void cpu_loop(CPUState *env);
@@ -147,24 +165,30 @@
 void target_to_host_siginfo(siginfo_t *info, const target_siginfo_t *tinfo);
 long do_sigreturn(CPUState *env);
 long do_rt_sigreturn(CPUState *env);
+int do_sigaltstack(const struct target_sigaltstack *uss,
+                   struct target_sigaltstack *uoss,
+                   abi_ulong sp);
 
 #ifdef TARGET_I386
 /* vm86.c */
 void save_v86_state(CPUX86State *env);
 void handle_vm86_trap(CPUX86State *env, int trapno);
 void handle_vm86_fault(CPUX86State *env);
-int do_vm86(CPUX86State *env, long subfunction, target_ulong v86_addr);
+int do_vm86(CPUX86State *env, long subfunction, abi_ulong v86_addr);
+#elif defined(TARGET_SPARC64)
+void sparc64_set_context(CPUSPARCState *env);
+void sparc64_get_context(CPUSPARCState *env);
 #endif
 
 /* mmap.c */
-int target_mprotect(target_ulong start, target_ulong len, int prot);
-long target_mmap(target_ulong start, target_ulong len, int prot,
-                 int flags, int fd, target_ulong offset);
-int target_munmap(target_ulong start, target_ulong len);
-long target_mremap(target_ulong old_addr, target_ulong old_size,
-                   target_ulong new_size, unsigned long flags,
-                   target_ulong new_addr);
-int target_msync(target_ulong start, target_ulong len, int flags);
+int target_mprotect(abi_ulong start, abi_ulong len, int prot);
+abi_long target_mmap(abi_ulong start, abi_ulong len, int prot,
+                     int flags, int fd, abi_ulong offset);
+int target_munmap(abi_ulong start, abi_ulong len);
+abi_long target_mremap(abi_ulong old_addr, abi_ulong old_size,
+                       abi_ulong new_size, unsigned long flags,
+                       abi_ulong new_addr);
+int target_msync(abi_ulong start, abi_ulong len, int flags);
 
 /* user access */
 
@@ -246,7 +270,7 @@
 
 /* Lock an area of guest memory into the host.  If copy is true then the
    host area will have the same contents as the guest.  */
-static inline void *lock_user(target_ulong guest_addr, long len, int copy)
+static inline void *lock_user(abi_ulong guest_addr, long len, int copy)
 {
 #ifdef DEBUG_REMAP
     void *addr;
@@ -263,8 +287,8 @@
 
 /* Unlock an area of guest memory.  The first LEN bytes must be flushed back
    to guest memory.  */
-static inline void unlock_user(void *host_addr, target_ulong guest_addr,
-                                long len)
+static inline void unlock_user(void *host_addr, abi_ulong guest_addr,
+                               long len)
 {
 #ifdef DEBUG_REMAP
     if (host_addr == g2h(guest_addr))
@@ -276,13 +300,13 @@
 }
 
 /* Return the length of a string in target memory.  */
-static inline int target_strlen(target_ulong ptr)
+static inline int target_strlen(abi_ulong ptr)
 {
   return strlen(g2h(ptr));
 }
 
 /* Like lock_user but for null terminated strings.  */
-static inline void *lock_user_string(target_ulong guest_addr)
+static inline void *lock_user_string(abi_ulong guest_addr)
 {
     long len;
     len = target_strlen(guest_addr) + 1;
@@ -303,7 +327,7 @@
 #define tput32(addr, val) stl(addr, val)
 #define tget64(addr) ldq(addr)
 #define tput64(addr, val) stq(addr, val)
-#if TARGET_LONG_BITS == 64
+#if TARGET_ABI_BITS == 64
 #define tgetl(addr) ldq(addr)
 #define tputl(addr, val) stq(addr, val)
 #else

Modified: trunk/src/host/qemu-neo1973/linux-user/sh4/syscall_nr.h
===================================================================
--- trunk/src/host/qemu-neo1973/linux-user/sh4/syscall_nr.h	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/linux-user/sh4/syscall_nr.h	2007-10-29 21:14:04 UTC (rev 3303)
@@ -226,6 +226,7 @@
 #define TARGET_NR_fcntl64		221
 /* 223 is unused */
 #define TARGET_NR_gettid		224
+#define TARGET_NR_readahead		225
 #define TARGET_NR_setxattr		226
 #define TARGET_NR_lsetxattr		227
 #define TARGET_NR_fsetxattr		228
@@ -288,5 +289,40 @@
 #define TARGET_NR_add_key		285
 #define TARGET_NR_request_key	286
 #define TARGET_NR_keyctl		287
-
-#define TARGET_NR_readahead             225        /* XXXXX */
+#define TARGET_NR_ioprio_set		288
+#define TARGET_NR_ioprio_get		289
+#define TARGET_NR_inotify_init	290
+#define TARGET_NR_inotify_add_watch	291
+#define TARGET_NR_inotify_rm_watch	292
+/* 293 is unused */
+#define TARGET_NR_migrate_pages	294
+#define TARGET_NR_openat		295
+#define TARGET_NR_mkdirat		296
+#define TARGET_NR_mknodat		297
+#define TARGET_NR_fchownat		298
+#define TARGET_NR_futimesat		299
+#define TARGET_NR_fstatat64		300
+#define TARGET_NR_unlinkat		301
+#define TARGET_NR_renameat		302
+#define TARGET_NR_linkat		303
+#define TARGET_NR_symlinkat		304
+#define TARGET_NR_readlinkat		305
+#define TARGET_NR_fchmodat		306
+#define TARGET_NR_faccessat		307
+#define TARGET_NR_pselect6		308
+#define TARGET_NR_ppoll		309
+#define TARGET_NR_unshare		310
+#define TARGET_NR_set_robust_list	311
+#define TARGET_NR_get_robust_list	312
+#define TARGET_NR_splice		313
+#define TARGET_NR_sync_file_range	314
+#define TARGET_NR_tee		315
+#define TARGET_NR_vmsplice		316
+#define TARGET_NR_move_pages		317
+#define TARGET_NR_getcpu		318
+#define TARGET_NR_epoll_pwait	319
+#define TARGET_NR_utimensat		320
+#define TARGET_NR_signalfd		321
+#define TARGET_NR_timerfd		322
+#define TARGET_NR_eventfd		323
+#define TARGET_NR_fallocate		324

Added: trunk/src/host/qemu-neo1973/linux-user/sh4/target_signal.h
===================================================================
--- trunk/src/host/qemu-neo1973/linux-user/sh4/target_signal.h	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/linux-user/sh4/target_signal.h	2007-10-29 21:14:04 UTC (rev 3303)
@@ -0,0 +1,24 @@
+#ifndef TARGET_SIGNAL_H
+#define TARGET_SIGNAL_H
+
+#include "cpu.h"
+
+/* this struct defines a stack used during syscall handling */
+
+typedef struct target_sigaltstack {
+	abi_ulong ss_sp;
+	abi_long ss_flags;
+	abi_ulong ss_size;
+} target_stack_t;
+
+
+/*
+ * sigaltstack controls
+ */
+#define TARGET_SS_ONSTACK     1
+#define TARGET_SS_DISABLE     2
+
+#define TARGET_MINSIGSTKSZ    2048
+#define TARGET_SIGSTKSZ       8192
+
+#endif /* TARGET_SIGNAL_H */

Modified: trunk/src/host/qemu-neo1973/linux-user/signal.c
===================================================================
--- trunk/src/host/qemu-neo1973/linux-user/signal.c	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/linux-user/signal.c	2007-10-29 21:14:04 UTC (rev 3303)
@@ -27,6 +27,7 @@
 #include <sys/ucontext.h>
 
 #include "qemu.h"
+#include "target_signal.h"
 
 //#define DEBUG_SIGNAL
 
@@ -45,6 +46,12 @@
                              first signal, we put it here */
 };
 
+struct target_sigaltstack target_sigaltstack_used = {
+    .ss_sp = 0,
+    .ss_size = 0,
+    .ss_flags = TARGET_SS_DISABLE,
+};
+
 static struct emulated_sigaction sigact_table[TARGET_NSIG];
 static struct sigqueue sigqueue_table[MAX_SIGQUEUE_SIZE]; /* siginfo queue */
 static struct sigqueue *first_free; /* first free siginfo queue entry */
@@ -92,6 +99,18 @@
 };
 static uint8_t target_to_host_signal_table[65];
 
+static inline int on_sig_stack(unsigned long sp)
+{
+    return (sp - target_sigaltstack_used.ss_sp
+            < target_sigaltstack_used.ss_size);
+}
+
+static inline int sas_ss_flags(unsigned long sp)
+{
+    return (target_sigaltstack_used.ss_size == 0 ? SS_DISABLE
+            : on_sig_stack(sp) ? SS_ONSTACK : 0);
+}
+
 static inline int host_to_target_signal(int sig)
 {
     return host_to_target_signal_table[sig];
@@ -115,12 +134,12 @@
         if (sigmask & (1 << i))
             target_sigmask |= 1 << (host_to_target_signal(i + 1) - 1);
     }
-#if TARGET_LONG_BITS == 32 && HOST_LONG_BITS == 32
+#if TARGET_ABI_BITS == 32 && HOST_LONG_BITS == 32
     d->sig[0] = target_sigmask;
     for(i = 1;i < TARGET_NSIG_WORDS; i++) {
         d->sig[i] = ((unsigned long *)s)[i];
     }
-#elif TARGET_LONG_BITS == 32 && HOST_LONG_BITS == 64 && TARGET_NSIG_WORDS == 2
+#elif TARGET_ABI_BITS == 32 && HOST_LONG_BITS == 64 && TARGET_NSIG_WORDS == 2
     d->sig[0] = target_sigmask;
     d->sig[1] = sigmask >> 32;
 #else
@@ -142,7 +161,7 @@
 {
     int i;
     unsigned long sigmask;
-    target_ulong target_sigmask;
+    abi_ulong target_sigmask;
 
     target_sigmask = s->sig[0];
     sigmask = 0;
@@ -150,16 +169,16 @@
         if (target_sigmask & (1 << i))
             sigmask |= 1 << (target_to_host_signal(i + 1) - 1);
     }
-#if TARGET_LONG_BITS == 32 && HOST_LONG_BITS == 32
+#if TARGET_ABI_BITS == 32 && HOST_LONG_BITS == 32
     ((unsigned long *)d)[0] = sigmask;
     for(i = 1;i < TARGET_NSIG_WORDS; i++) {
         ((unsigned long *)d)[i] = s->sig[i];
     }
-#elif TARGET_LONG_BITS == 32 && HOST_LONG_BITS == 64 && TARGET_NSIG_WORDS == 2
+#elif TARGET_ABI_BITS == 32 && HOST_LONG_BITS == 64 && TARGET_NSIG_WORDS == 2
     ((unsigned long *)d)[0] = sigmask | ((unsigned long)(s->sig[1]) << 32);
 #else
 #warning target_to_host_sigset
-#endif /* TARGET_LONG_BITS */
+#endif /* TARGET_ABI_BITS */
 }
 
 void target_to_host_sigset(sigset_t *d, const target_sigset_t *s)
@@ -172,7 +191,7 @@
     target_to_host_sigset_internal(d, &s1);
 }
 
-void host_to_target_old_sigset(target_ulong *old_sigset,
+void host_to_target_old_sigset(abi_ulong *old_sigset,
                                const sigset_t *sigset)
 {
     target_sigset_t d;
@@ -181,7 +200,7 @@
 }
 
 void target_to_host_old_sigset(sigset_t *sigset,
-                               const target_ulong *old_sigset)
+                               const abi_ulong *old_sigset)
 {
     target_sigset_t d;
     int i;
@@ -214,7 +233,7 @@
         tinfo->_sifields._rt._uid = info->si_uid;
         /* XXX: potential problem if 64 bit */
         tinfo->_sifields._rt._sigval.sival_ptr =
-            (target_ulong)info->si_value.sival_ptr;
+            (abi_ulong)info->si_value.sival_ptr;
     }
 }
 
@@ -336,7 +355,7 @@
 {
     struct emulated_sigaction *k;
     struct sigqueue *q, **pq;
-    target_ulong handler;
+    abi_ulong handler;
 
 #if defined(DEBUG_SIGNAL)
     fprintf(stderr, "queue_signal: sig=%d\n",
@@ -419,12 +438,76 @@
     }
 }
 
+/* do_sigaltstack() returns target values and errnos. */
+int do_sigaltstack(const struct target_sigaltstack *uss,
+                   struct target_sigaltstack *uoss,
+                   abi_ulong sp)
+{
+    int ret;
+    struct target_sigaltstack oss;
+
+    /* XXX: test errors */
+    if(uoss)
+    {
+        __put_user(target_sigaltstack_used.ss_sp, &oss.ss_sp);
+        __put_user(target_sigaltstack_used.ss_size, &oss.ss_size);
+        __put_user(sas_ss_flags(sp), &oss.ss_flags);
+    }
+
+    if(uss)
+    {
+	struct target_sigaltstack ss;
+
+	ret = -TARGET_EFAULT;
+	if (!access_ok(VERIFY_READ, uss, sizeof(*uss))
+	    || __get_user(ss.ss_sp, &uss->ss_sp)
+	    || __get_user(ss.ss_size, &uss->ss_size)
+	    || __get_user(ss.ss_flags, &uss->ss_flags))
+            goto out;
+
+	ret = -TARGET_EPERM;
+	if (on_sig_stack(sp))
+            goto out;
+
+	ret = -TARGET_EINVAL;
+	if (ss.ss_flags != TARGET_SS_DISABLE
+            && ss.ss_flags != TARGET_SS_ONSTACK
+            && ss.ss_flags != 0)
+            goto out;
+
+	if (ss.ss_flags == TARGET_SS_DISABLE) {
+            ss.ss_size = 0;
+            ss.ss_sp = 0;
+	} else {
+            ret = -TARGET_ENOMEM;
+            if (ss.ss_size < MINSIGSTKSZ)
+                goto out;
+	}
+
+        target_sigaltstack_used.ss_sp = ss.ss_sp;
+        target_sigaltstack_used.ss_size = ss.ss_size;
+    }
+
+    if (uoss) {
+        ret = -TARGET_EFAULT;
+        if (!access_ok(VERIFY_WRITE, uoss, sizeof(oss)))
+            goto out;
+        memcpy(uoss, &oss, sizeof(oss));
+    }
+
+    ret = 0;
+out:
+    return ret;
+}
+
+/* do_sigaction() return host values and errnos */
 int do_sigaction(int sig, const struct target_sigaction *act,
                  struct target_sigaction *oact)
 {
     struct emulated_sigaction *k;
     struct sigaction act1;
     int host_sig;
+    int ret = 0;
 
     if (sig < 1 || sig > TARGET_NSIG || sig == SIGKILL || sig == SIGSTOP)
         return -EINVAL;
@@ -466,10 +549,10 @@
             } else {
                 act1.sa_sigaction = host_signal_handler;
             }
-            sigaction(host_sig, &act1, NULL);
+            ret = sigaction(host_sig, &act1, NULL);
         }
     }
-    return 0;
+    return ret;
 }
 
 #ifndef offsetof
@@ -499,29 +582,29 @@
 };
 
 struct target_xmmreg {
-	target_ulong element[4];
+	abi_ulong element[4];
 };
 
 struct target_fpstate {
 	/* Regular FPU environment */
-	target_ulong 	cw;
-	target_ulong	sw;
-	target_ulong	tag;
-	target_ulong	ipoff;
-	target_ulong	cssel;
-	target_ulong	dataoff;
-	target_ulong	datasel;
+        abi_ulong       cw;
+        abi_ulong       sw;
+        abi_ulong       tag;
+        abi_ulong       ipoff;
+        abi_ulong       cssel;
+        abi_ulong       dataoff;
+        abi_ulong       datasel;
 	struct target_fpreg	_st[8];
 	uint16_t	status;
 	uint16_t	magic;		/* 0xffff = regular FPU data only */
 
 	/* FXSR FPU environment */
-	target_ulong	_fxsr_env[6];	/* FXSR FPU env is ignored */
-	target_ulong	mxcsr;
-	target_ulong	reserved;
+        abi_ulong       _fxsr_env[6];   /* FXSR FPU env is ignored */
+        abi_ulong       mxcsr;
+        abi_ulong       reserved;
 	struct target_fpxreg	_fxsr_st[8];	/* FXSR FPU reg data is ignored */
 	struct target_xmmreg	_xmm[8];
-	target_ulong	padding[56];
+        abi_ulong       padding[56];
 };
 
 #define X86_FXSR_MAGIC		0x0000
@@ -531,35 +614,29 @@
 	uint16_t fs, __fsh;
 	uint16_t es, __esh;
 	uint16_t ds, __dsh;
-	target_ulong edi;
-	target_ulong esi;
-	target_ulong ebp;
-	target_ulong esp;
-	target_ulong ebx;
-	target_ulong edx;
-	target_ulong ecx;
-	target_ulong eax;
-	target_ulong trapno;
-	target_ulong err;
-	target_ulong eip;
+        abi_ulong edi;
+        abi_ulong esi;
+        abi_ulong ebp;
+        abi_ulong esp;
+        abi_ulong ebx;
+        abi_ulong edx;
+        abi_ulong ecx;
+        abi_ulong eax;
+        abi_ulong trapno;
+        abi_ulong err;
+        abi_ulong eip;
 	uint16_t cs, __csh;
-	target_ulong eflags;
-	target_ulong esp_at_signal;
+        abi_ulong eflags;
+        abi_ulong esp_at_signal;
 	uint16_t ss, __ssh;
-        target_ulong fpstate; /* pointer */
-	target_ulong oldmask;
-	target_ulong cr2;
+        abi_ulong fpstate; /* pointer */
+        abi_ulong oldmask;
+        abi_ulong cr2;
 };
 
-typedef struct target_sigaltstack {
-	target_ulong ss_sp;
-	int ss_flags;
-	target_ulong ss_size;
-} target_stack_t;
-
 struct target_ucontext {
-        target_ulong	  tuc_flags;
-	target_ulong      tuc_link;
+        abi_ulong         tuc_flags;
+        abi_ulong         tuc_link;
 	target_stack_t	  tuc_stack;
 	struct target_sigcontext tuc_mcontext;
 	target_sigset_t	  tuc_sigmask;	/* mask last for extensibility */
@@ -567,20 +644,20 @@
 
 struct sigframe
 {
-    target_ulong pretcode;
+    abi_ulong pretcode;
     int sig;
     struct target_sigcontext sc;
     struct target_fpstate fpstate;
-    target_ulong extramask[TARGET_NSIG_WORDS-1];
+    abi_ulong extramask[TARGET_NSIG_WORDS-1];
     char retcode[8];
 };
 
 struct rt_sigframe
 {
-    target_ulong pretcode;
+    abi_ulong pretcode;
     int sig;
-    target_ulong pinfo;
-    target_ulong puc;
+    abi_ulong pinfo;
+    abi_ulong puc;
     struct target_siginfo info;
     struct target_ucontext uc;
     struct target_fpstate fpstate;
@@ -640,16 +717,14 @@
 
 	/* Default to using normal stack */
 	esp = env->regs[R_ESP];
-#if 0
 	/* This is the X/Open sanctioned signal stack switching.  */
-	if (ka->sa.sa_flags & SA_ONSTACK) {
-		if (sas_ss_flags(esp) == 0)
-			esp = current->sas_ss_sp + current->sas_ss_size;
-	}
+        if (ka->sa.sa_flags & TARGET_SA_ONSTACK) {
+            if (sas_ss_flags(esp) == 0)
+                esp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
+        }
 
 	/* This is the legacy signal stack switching. */
 	else
-#endif
         if ((env->segs[R_SS].selector & 0xffff) != __USER_DS &&
             !(ka->sa.sa_flags & TARGET_SA_RESTORER) &&
             ka->sa.sa_restorer) {
@@ -741,8 +816,8 @@
 		    	   ? current->exec_domain->signal_invmap[sig]
 			   : */sig),
 			  &frame->sig);
-	err |= __put_user((target_ulong)&frame->info, &frame->pinfo);
-	err |= __put_user((target_ulong)&frame->uc, &frame->puc);
+	err |= __put_user((abi_ulong)&frame->info, &frame->pinfo);
+	err |= __put_user((abi_ulong)&frame->uc, &frame->puc);
 	err |= copy_siginfo_to_user(&frame->info, info);
 	if (err)
 		goto give_sigsegv;
@@ -750,11 +825,11 @@
 	/* Create the ucontext.  */
 	err |= __put_user(0, &frame->uc.tuc_flags);
 	err |= __put_user(0, &frame->uc.tuc_link);
-	err |= __put_user(/*current->sas_ss_sp*/ 0,
+	err |= __put_user(target_sigaltstack_used.ss_sp,
 			  &frame->uc.tuc_stack.ss_sp);
-	err |= __put_user(/* sas_ss_flags(regs->esp) */ 0,
+	err |= __put_user(sas_ss_flags(get_sp_from_cpustate(env)),
 			  &frame->uc.tuc_stack.ss_flags);
-	err |= __put_user(/* current->sas_ss_size */ 0,
+	err |= __put_user(target_sigaltstack_used.ss_size,
 			  &frame->uc.tuc_stack.ss_size);
 	err |= setup_sigcontext(&frame->uc.tuc_mcontext, &frame->fpstate,
 			        env, set->sig[0]);
@@ -880,7 +955,6 @@
 {
 	struct rt_sigframe *frame = (struct rt_sigframe *)g2h(env->regs[R_ESP] - 4);
         sigset_t set;
-        //	stack_t st;
 	int eax;
 
 #if 0
@@ -893,13 +967,9 @@
 	if (restore_sigcontext(env, &frame->uc.tuc_mcontext, &eax))
 		goto badframe;
 
-#if 0
-	if (__copy_from_user(&st, &frame->uc.tuc_stack, sizeof(st)))
+	if (do_sigaltstack(&frame->uc.tuc_stack, NULL, get_sp_from_cpustate(env)) == -EFAULT)
 		goto badframe;
-	/* It is more difficult to avoid calling this function than to
-	   call it and ignore errors.  */
-	do_sigaltstack(&st, NULL, regs->esp);
-#endif
+
 	return eax;
 
 badframe:
@@ -910,38 +980,32 @@
 #elif defined(TARGET_ARM)
 
 struct target_sigcontext {
-	target_ulong trap_no;
-	target_ulong error_code;
-	target_ulong oldmask;
-	target_ulong arm_r0;
-	target_ulong arm_r1;
-	target_ulong arm_r2;
-	target_ulong arm_r3;
-	target_ulong arm_r4;
-	target_ulong arm_r5;
-	target_ulong arm_r6;
-	target_ulong arm_r7;
-	target_ulong arm_r8;
-	target_ulong arm_r9;
-	target_ulong arm_r10;
-	target_ulong arm_fp;
-	target_ulong arm_ip;
-	target_ulong arm_sp;
-	target_ulong arm_lr;
-	target_ulong arm_pc;
-	target_ulong arm_cpsr;
-	target_ulong fault_address;
+	abi_ulong trap_no;
+	abi_ulong error_code;
+	abi_ulong oldmask;
+	abi_ulong arm_r0;
+	abi_ulong arm_r1;
+	abi_ulong arm_r2;
+	abi_ulong arm_r3;
+	abi_ulong arm_r4;
+	abi_ulong arm_r5;
+	abi_ulong arm_r6;
+	abi_ulong arm_r7;
+	abi_ulong arm_r8;
+	abi_ulong arm_r9;
+	abi_ulong arm_r10;
+	abi_ulong arm_fp;
+	abi_ulong arm_ip;
+	abi_ulong arm_sp;
+	abi_ulong arm_lr;
+	abi_ulong arm_pc;
+	abi_ulong arm_cpsr;
+	abi_ulong fault_address;
 };
 
-typedef struct target_sigaltstack {
-	target_ulong ss_sp;
-	int ss_flags;
-	target_ulong ss_size;
-} target_stack_t;
-
 struct target_ucontext {
-    target_ulong tuc_flags;
-    target_ulong tuc_link;
+    abi_ulong tuc_flags;
+    abi_ulong tuc_link;
     target_stack_t tuc_stack;
     struct target_sigcontext tuc_mcontext;
     target_sigset_t  tuc_sigmask;	/* mask last for extensibility */
@@ -950,8 +1014,8 @@
 struct sigframe
 {
     struct target_sigcontext sc;
-    target_ulong extramask[TARGET_NSIG_WORDS-1];
-    target_ulong retcode;
+    abi_ulong extramask[TARGET_NSIG_WORDS-1];
+    abi_ulong retcode;
 };
 
 struct rt_sigframe
@@ -960,7 +1024,7 @@
     void *puc;
     struct target_siginfo info;
     struct target_ucontext uc;
-    target_ulong retcode;
+    abi_ulong retcode;
 };
 
 #define TARGET_CONFIG_CPU_32 1
@@ -978,7 +1042,7 @@
 #define SWI_THUMB_SIGRETURN	(0xdf00 << 16 | 0x2700 | (TARGET_NR_sigreturn))
 #define SWI_THUMB_RT_SIGRETURN	(0xdf00 << 16 | 0x2700 | (TARGET_NR_rt_sigreturn))
 
-static const target_ulong retcodes[4] = {
+static const abi_ulong retcodes[4] = {
 	SWI_SYS_SIGRETURN,	SWI_THUMB_SIGRETURN,
 	SWI_SYS_RT_SIGRETURN,	SWI_THUMB_RT_SIGRETURN
 };
@@ -1031,13 +1095,11 @@
 {
 	unsigned long sp = regs->regs[13];
 
-#if 0
 	/*
 	 * This is the X/Open sanctioned signal stack switching.
 	 */
-	if ((ka->sa.sa_flags & SA_ONSTACK) && !sas_ss_flags(sp))
-		sp = current->sas_ss_sp + current->sas_ss_size;
-#endif
+	if ((ka->sa.sa_flags & TARGET_SA_ONSTACK) && !sas_ss_flags(sp))
+            sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
 	/*
 	 * ATPCS B01 mandates 8-byte alignment
 	 */
@@ -1046,14 +1108,14 @@
 
 static int
 setup_return(CPUState *env, struct emulated_sigaction *ka,
-	     target_ulong *rc, void *frame, int usig)
+	     abi_ulong *rc, void *frame, int usig)
 {
-	target_ulong handler = (target_ulong)ka->sa._sa_handler;
-	target_ulong retcode;
+	abi_ulong handler = (abi_ulong)ka->sa._sa_handler;
+	abi_ulong retcode;
 	int thumb = 0;
 #if defined(TARGET_CONFIG_CPU_32)
 #if 0
-	target_ulong cpsr = env->cpsr;
+	abi_ulong cpsr = env->cpsr;
 
 	/*
 	 * Maybe we need to deliver a 32-bit signal to a 26-bit task.
@@ -1074,12 +1136,12 @@
 		else
 			cpsr &= ~T_BIT;
 	}
-#endif
-#endif
+#endif /* CONFIG_ARM_THUMB */
+#endif /* 0 */
 #endif /* TARGET_CONFIG_CPU_32 */
 
 	if (ka->sa.sa_flags & TARGET_SA_RESTORER) {
-		retcode = (target_ulong)ka->sa.sa_restorer;
+		retcode = (abi_ulong)ka->sa.sa_restorer;
 	} else {
 		unsigned int idx = thumb;
 
@@ -1089,10 +1151,10 @@
 		if (__put_user(retcodes[idx], rc))
 			return 1;
 #if 0
-		flush_icache_range((target_ulong)rc,
-				   (target_ulong)(rc + 1));
+		flush_icache_range((abi_ulong)rc,
+				   (abi_ulong)(rc + 1));
 #endif
-		retcode = ((target_ulong)rc) + thumb;
+		retcode = ((abi_ulong)rc) + thumb;
 	}
 
 	env->regs[0] = usig;
@@ -1132,18 +1194,28 @@
 			   target_sigset_t *set, CPUState *env)
 {
 	struct rt_sigframe *frame = get_sigframe(ka, env, sizeof(*frame));
+	struct target_sigaltstack stack;
 	int i, err = 0;
 
 	if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
             return /* 1 */;
 
-	__put_user_error(&frame->info, (target_ulong *)&frame->pinfo, err);
-	__put_user_error(&frame->uc, (target_ulong *)&frame->puc, err);
+	__put_user_error(&frame->info, (abi_ulong *)&frame->pinfo, err);
+	__put_user_error(&frame->uc, (abi_ulong *)&frame->puc, err);
 	err |= copy_siginfo_to_user(&frame->info, info);
 
 	/* Clear all the bits of the ucontext we don't use.  */
 	memset(&frame->uc, 0, offsetof(struct target_ucontext, tuc_mcontext));
 
+        memset(&stack, 0, sizeof(stack));
+        __put_user(target_sigaltstack_used.ss_sp, &stack.ss_sp);
+        __put_user(target_sigaltstack_used.ss_size, &stack.ss_size);
+        __put_user(sas_ss_flags(get_sp_from_cpustate(env)), &stack.ss_flags);
+        if (!access_ok(VERIFY_WRITE, &frame->uc.tuc_stack, sizeof(stack)))
+            err = 1;
+        else
+            memcpy(&frame->uc.tuc_stack, &stack, sizeof(stack));
+
 	err |= setup_sigcontext(&frame->uc.tuc_mcontext, /*&frame->fpstate,*/
 				env, set->sig[0]);
         for(i = 0; i < TARGET_NSIG_WORDS; i++) {
@@ -1160,8 +1232,8 @@
 		 * arguments for the signal handler.
 		 *   -- Peter Maydell <pmaydell at chiark.greenend.org.uk> 2000-12-06
 		 */
-            env->regs[1] = (target_ulong)frame->pinfo;
-            env->regs[2] = (target_ulong)frame->puc;
+            env->regs[1] = (abi_ulong)frame->pinfo;
+            env->regs[2] = (abi_ulong)frame->puc;
 	}
 
         //	return err;
@@ -1270,6 +1342,9 @@
 	if (restore_sigcontext(env, &frame->uc.tuc_mcontext))
 		goto badframe;
 
+	if (do_sigaltstack(&frame->uc.tuc_stack, NULL, get_sp_from_cpustate(env)) == -EFAULT)
+		goto badframe;
+
 #if 0
 	/* Send SIGTRAP if we're single-stepping */
 	if (ptrace_cancel_bpt(current))
@@ -1288,48 +1363,48 @@
 
 /* This is what SunOS does, so shall I. */
 struct target_sigcontext {
-        target_ulong sigc_onstack;      /* state to restore */
+        abi_ulong sigc_onstack;      /* state to restore */
 
-        target_ulong sigc_mask;         /* sigmask to restore */
-        target_ulong sigc_sp;           /* stack pointer */
-        target_ulong sigc_pc;           /* program counter */
-        target_ulong sigc_npc;          /* next program counter */
-        target_ulong sigc_psr;          /* for condition codes etc */
-        target_ulong sigc_g1;           /* User uses these two registers */
-        target_ulong sigc_o0;           /* within the trampoline code. */
+        abi_ulong sigc_mask;         /* sigmask to restore */
+        abi_ulong sigc_sp;           /* stack pointer */
+        abi_ulong sigc_pc;           /* program counter */
+        abi_ulong sigc_npc;          /* next program counter */
+        abi_ulong sigc_psr;          /* for condition codes etc */
+        abi_ulong sigc_g1;           /* User uses these two registers */
+        abi_ulong sigc_o0;           /* within the trampoline code. */
 
         /* Now comes information regarding the users window set
          * at the time of the signal.
          */
-        target_ulong sigc_oswins;       /* outstanding windows */
+        abi_ulong sigc_oswins;       /* outstanding windows */
 
         /* stack ptrs for each regwin buf */
         char *sigc_spbuf[__SUNOS_MAXWIN];
 
         /* Windows to restore after signal */
         struct {
-                target_ulong locals[8];
-                target_ulong ins[8];
+                abi_ulong locals[8];
+                abi_ulong ins[8];
         } sigc_wbuf[__SUNOS_MAXWIN];
 };
 /* A Sparc stack frame */
 struct sparc_stackf {
-        target_ulong locals[8];
-        target_ulong ins[6];
+        abi_ulong locals[8];
+        abi_ulong ins[6];
         struct sparc_stackf *fp;
-        target_ulong callers_pc;
+        abi_ulong callers_pc;
         char *structptr;
-        target_ulong xargs[6];
-        target_ulong xxargs[1];
+        abi_ulong xargs[6];
+        abi_ulong xxargs[1];
 };
 
 typedef struct {
         struct {
-                target_ulong psr;
-                target_ulong pc;
-                target_ulong npc;
-                target_ulong y;
-                target_ulong u_regs[16]; /* globals and ins */
+                abi_ulong psr;
+                abi_ulong pc;
+                abi_ulong npc;
+                abi_ulong y;
+                abi_ulong u_regs[16]; /* globals and ins */
         }               si_regs;
         int             si_mask;
 } __siginfo_t;
@@ -1349,15 +1424,15 @@
 	struct sparc_stackf	ss;
 	__siginfo_t		info;
 	qemu_siginfo_fpu_t 	*fpu_save;
-	target_ulong		insns[2] __attribute__ ((aligned (8)));
-	target_ulong		extramask[TARGET_NSIG_WORDS - 1];
-	target_ulong		extra_size; /* Should be 0 */
+	abi_ulong		insns[2] __attribute__ ((aligned (8)));
+	abi_ulong		extramask[TARGET_NSIG_WORDS - 1];
+	abi_ulong		extra_size; /* Should be 0 */
 	qemu_siginfo_fpu_t	fpu_state;
 };
 struct target_rt_signal_frame {
 	struct sparc_stackf	ss;
 	siginfo_t		info;
-	target_ulong		regs[20];
+	abi_ulong		regs[20];
 	sigset_t		mask;
 	qemu_siginfo_fpu_t 	*fpu_save;
 	unsigned int		insns[2];
@@ -1371,6 +1446,9 @@
 #define UREG_I0        0
 #define UREG_I1        1
 #define UREG_I2        2
+#define UREG_I3        3
+#define UREG_I4        4
+#define UREG_I5        5
 #define UREG_I6        6
 #define UREG_I7        7
 #define UREG_L0	       8
@@ -1382,19 +1460,18 @@
 	unsigned long sp;
 
 	sp = env->regwptr[UREG_FP];
-#if 0
 
 	/* This is the X/Open sanctioned signal stack switching.  */
-	if (sa->sa_flags & TARGET_SA_ONSTACK) {
-		if (!on_sig_stack(sp) && !((current->sas_ss_sp + current->sas_ss_size) & 7))
-			sp = current->sas_ss_sp + current->sas_ss_size;
+	if (sa->sa.sa_flags & TARGET_SA_ONSTACK) {
+            if (!on_sig_stack(sp)
+                && !((target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size) & 7))
+                sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
 	}
-#endif
 	return g2h(sp - framesize);
 }
 
 static int
-setup___siginfo(__siginfo_t *si, CPUState *env, target_ulong mask)
+setup___siginfo(__siginfo_t *si, CPUState *env, abi_ulong mask)
 {
 	int err = 0, i;
 
@@ -1560,7 +1637,7 @@
         uint32_t up_psr, pc, npc;
         target_sigset_t set;
         sigset_t host_set;
-        target_ulong fpu_save;
+        abi_ulong fpu_save;
         int err, i;
 
         sf = (struct target_signal_frame *)g2h(env->regwptr[UREG_FP]);
@@ -1602,7 +1679,7 @@
 		err |= __get_user(env->regwptr[i + UREG_I0], &sf->info.si_regs.u_regs[i+8]);
 	}
 
-        err |= __get_user(fpu_save, (target_ulong *)&sf->fpu_save);
+        err |= __get_user(fpu_save, (abi_ulong *)&sf->fpu_save);
 
         //if (fpu_save)
         //        err |= restore_fpu_state(env, fpu_save);
@@ -1633,6 +1710,297 @@
     return -ENOSYS;
 }
 
+#ifdef TARGET_SPARC64
+#define MC_TSTATE 0
+#define MC_PC 1
+#define MC_NPC 2
+#define MC_Y 3
+#define MC_G1 4
+#define MC_G2 5
+#define MC_G3 6
+#define MC_G4 7
+#define MC_G5 8
+#define MC_G6 9
+#define MC_G7 10
+#define MC_O0 11
+#define MC_O1 12
+#define MC_O2 13
+#define MC_O3 14
+#define MC_O4 15
+#define MC_O5 16
+#define MC_O6 17
+#define MC_O7 18
+#define MC_NGREG 19
+
+typedef abi_ulong target_mc_greg_t;
+typedef target_mc_greg_t target_mc_gregset_t[MC_NGREG];
+
+struct target_mc_fq {
+    abi_ulong *mcfq_addr;
+    uint32_t mcfq_insn;
+};
+
+struct target_mc_fpu {
+    union {
+        uint32_t sregs[32];
+        uint64_t dregs[32];
+        //uint128_t qregs[16];
+    } mcfpu_fregs;
+    abi_ulong mcfpu_fsr;
+    abi_ulong mcfpu_fprs;
+    abi_ulong mcfpu_gsr;
+    struct target_mc_fq *mcfpu_fq;
+    unsigned char mcfpu_qcnt;
+    unsigned char mcfpu_qentsz;
+    unsigned char mcfpu_enab;
+};
+typedef struct target_mc_fpu target_mc_fpu_t;
+
+typedef struct {
+    target_mc_gregset_t mc_gregs;
+    target_mc_greg_t mc_fp;
+    target_mc_greg_t mc_i7;
+    target_mc_fpu_t mc_fpregs;
+} target_mcontext_t;
+
+struct target_ucontext {
+    struct target_ucontext *uc_link;
+    abi_ulong uc_flags;
+    target_sigset_t uc_sigmask;
+    target_mcontext_t uc_mcontext;
+};
+
+/* A V9 register window */
+struct target_reg_window {
+    abi_ulong locals[8];
+    abi_ulong ins[8];
+};
+
+#define TARGET_STACK_BIAS 2047
+
+/* {set, get}context() needed for 64-bit SparcLinux userland. */
+void sparc64_set_context(CPUSPARCState *env)
+{
+    struct target_ucontext *ucp = (struct target_ucontext *)
+        env->regwptr[UREG_I0];
+    target_mc_gregset_t *grp;
+    abi_ulong pc, npc, tstate;
+    abi_ulong fp, i7;
+    unsigned char fenab;
+    int err;
+    unsigned int i;
+    abi_ulong *src, *dst;
+
+    grp  = &ucp->uc_mcontext.mc_gregs;
+    err  = get_user(pc, &((*grp)[MC_PC]));
+    err |= get_user(npc, &((*grp)[MC_NPC]));
+    if (err || ((pc | npc) & 3))
+        goto do_sigsegv;
+    if (env->regwptr[UREG_I1]) {
+        target_sigset_t target_set;
+        sigset_t set;
+
+        if (TARGET_NSIG_WORDS == 1) {
+            if (get_user(target_set.sig[0], &ucp->uc_sigmask.sig[0]))
+                goto do_sigsegv;
+        } else {
+            src = &ucp->uc_sigmask;
+            dst = &target_set;
+            for (i = 0; i < sizeof(target_sigset_t) / sizeof(abi_ulong);
+                 i++, dst++, src++)
+                err |= get_user(dst, src);
+            if (err)
+                goto do_sigsegv;
+        }
+        target_to_host_sigset_internal(&set, &target_set);
+        sigprocmask(SIG_SETMASK, &set, NULL);
+    }
+    env->pc = pc;
+    env->npc = npc;
+    err |= get_user(env->y, &((*grp)[MC_Y]));
+    err |= get_user(tstate, &((*grp)[MC_TSTATE]));
+    env->asi = (tstate >> 24) & 0xff;
+    PUT_CCR(env, tstate >> 32);
+    PUT_CWP64(env, tstate & 0x1f);
+    err |= get_user(env->gregs[1], (&(*grp)[MC_G1]));
+    err |= get_user(env->gregs[2], (&(*grp)[MC_G2]));
+    err |= get_user(env->gregs[3], (&(*grp)[MC_G3]));
+    err |= get_user(env->gregs[4], (&(*grp)[MC_G4]));
+    err |= get_user(env->gregs[5], (&(*grp)[MC_G5]));
+    err |= get_user(env->gregs[6], (&(*grp)[MC_G6]));
+    err |= get_user(env->gregs[7], (&(*grp)[MC_G7]));
+    err |= get_user(env->regwptr[UREG_I0], (&(*grp)[MC_O0]));
+    err |= get_user(env->regwptr[UREG_I1], (&(*grp)[MC_O1]));
+    err |= get_user(env->regwptr[UREG_I2], (&(*grp)[MC_O2]));
+    err |= get_user(env->regwptr[UREG_I3], (&(*grp)[MC_O3]));
+    err |= get_user(env->regwptr[UREG_I4], (&(*grp)[MC_O4]));
+    err |= get_user(env->regwptr[UREG_I5], (&(*grp)[MC_O5]));
+    err |= get_user(env->regwptr[UREG_I6], (&(*grp)[MC_O6]));
+    err |= get_user(env->regwptr[UREG_I7], (&(*grp)[MC_O7]));
+
+    err |= get_user(fp, &(ucp->uc_mcontext.mc_fp));
+    err |= get_user(i7, &(ucp->uc_mcontext.mc_i7));
+    err |= put_user(fp,
+                    (&(((struct target_reg_window *)(TARGET_STACK_BIAS+env->regwptr[UREG_I6]))->ins[6])));
+    err |= put_user(i7,
+                    (&(((struct target_reg_window *)(TARGET_STACK_BIAS+env->regwptr[UREG_I6]))->ins[7])));
+
+    err |= get_user(fenab, &(ucp->uc_mcontext.mc_fpregs.mcfpu_enab));
+    err |= get_user(env->fprs, &(ucp->uc_mcontext.mc_fpregs.mcfpu_fprs));
+    src = &(ucp->uc_mcontext.mc_fpregs.mcfpu_fregs);
+    dst = &env->fpr;
+    for (i = 0; i < 64; i++, dst++, src++)
+        err |= get_user(dst, src);
+    err |= get_user(env->fsr,
+                    &(ucp->uc_mcontext.mc_fpregs.mcfpu_fsr));
+    err |= get_user(env->gsr,
+                    &(ucp->uc_mcontext.mc_fpregs.mcfpu_gsr));
+    if (err)
+        goto do_sigsegv;
+
+    return;
+ do_sigsegv:
+    force_sig(SIGSEGV);
+}
+
+void sparc64_get_context(CPUSPARCState *env)
+{
+    struct target_ucontext *ucp = (struct target_ucontext *)
+        env->regwptr[UREG_I0];
+    target_mc_gregset_t *grp;
+    target_mcontext_t *mcp;
+    abi_ulong fp, i7;
+    int err;
+    unsigned int i;
+    abi_ulong *src, *dst;
+    target_sigset_t target_set;
+    sigset_t set;
+
+    mcp = &ucp->uc_mcontext;
+    grp = &mcp->mc_gregs;
+
+    /* Skip over the trap instruction, first. */
+    env->pc = env->npc;
+    env->npc += 4;
+
+    err = 0;
+
+    sigprocmask(0, NULL, &set);
+    host_to_target_sigset_internal(&target_set, &set);
+    if (TARGET_NSIG_WORDS == 1)
+        err |= put_user(target_set.sig[0],
+                        (abi_ulong *)&ucp->uc_sigmask);
+    else {
+        src = &target_set;
+        dst = &ucp->uc_sigmask;
+        for (i = 0; i < sizeof(target_sigset_t) / sizeof(abi_ulong);
+             i++, dst++, src++)
+            err |= put_user(src, dst);
+        if (err)
+            goto do_sigsegv;
+    }
+
+    err |= put_user(env->tstate, &((*grp)[MC_TSTATE]));
+    err |= put_user(env->pc, &((*grp)[MC_PC]));
+    err |= put_user(env->npc, &((*grp)[MC_NPC]));
+    err |= put_user(env->y, &((*grp)[MC_Y]));
+    err |= put_user(env->gregs[1], &((*grp)[MC_G1]));
+    err |= put_user(env->gregs[2], &((*grp)[MC_G2]));
+    err |= put_user(env->gregs[3], &((*grp)[MC_G3]));
+    err |= put_user(env->gregs[4], &((*grp)[MC_G4]));
+    err |= put_user(env->gregs[5], &((*grp)[MC_G5]));
+    err |= put_user(env->gregs[6], &((*grp)[MC_G6]));
+    err |= put_user(env->gregs[7], &((*grp)[MC_G7]));
+    err |= put_user(env->regwptr[UREG_I0], &((*grp)[MC_O0]));
+    err |= put_user(env->regwptr[UREG_I1], &((*grp)[MC_O1]));
+    err |= put_user(env->regwptr[UREG_I2], &((*grp)[MC_O2]));
+    err |= put_user(env->regwptr[UREG_I3], &((*grp)[MC_O3]));
+    err |= put_user(env->regwptr[UREG_I4], &((*grp)[MC_O4]));
+    err |= put_user(env->regwptr[UREG_I5], &((*grp)[MC_O5]));
+    err |= put_user(env->regwptr[UREG_I6], &((*grp)[MC_O6]));
+    err |= put_user(env->regwptr[UREG_I7], &((*grp)[MC_O7]));
+
+    err |= get_user(fp,
+                    (&(((struct target_reg_window *)(TARGET_STACK_BIAS+env->regwptr[UREG_I6]))->ins[6])));
+    err |= get_user(i7,
+                    (&(((struct target_reg_window *)(TARGET_STACK_BIAS+env->regwptr[UREG_I6]))->ins[7])));
+    err |= put_user(fp, &(mcp->mc_fp));
+    err |= put_user(i7, &(mcp->mc_i7));
+
+    src = &env->fpr;
+    dst = &(ucp->uc_mcontext.mc_fpregs.mcfpu_fregs);
+    for (i = 0; i < 64; i++, dst++, src++)
+        err |= put_user(src, dst);
+    err |= put_user(env->fsr, &(mcp->mc_fpregs.mcfpu_fsr));
+    err |= put_user(env->gsr, &(mcp->mc_fpregs.mcfpu_gsr));
+    err |= put_user(env->fprs, &(mcp->mc_fpregs.mcfpu_fprs));
+
+    if (err)
+        goto do_sigsegv;
+
+    return;
+ do_sigsegv:
+    force_sig(SIGSEGV);
+}
+#endif
+#elif defined(TARGET_MIPS64)
+
+# warning signal handling not implemented
+
+static void setup_frame(int sig, struct emulated_sigaction *ka,
+			target_sigset_t *set, CPUState *env)
+{
+    fprintf(stderr, "setup_frame: not implemented\n");
+}
+
+static void setup_rt_frame(int sig, struct emulated_sigaction *ka,
+                           target_siginfo_t *info,
+			   target_sigset_t *set, CPUState *env)
+{
+    fprintf(stderr, "setup_rt_frame: not implemented\n");
+}
+
+long do_sigreturn(CPUState *env)
+{
+    fprintf(stderr, "do_sigreturn: not implemented\n");
+    return -ENOSYS;
+}
+
+long do_rt_sigreturn(CPUState *env)
+{
+    fprintf(stderr, "do_rt_sigreturn: not implemented\n");
+    return -ENOSYS;
+}
+
+#elif defined(TARGET_MIPSN32)
+
+# warning signal handling not implemented
+
+static void setup_frame(int sig, struct emulated_sigaction *ka,
+			target_sigset_t *set, CPUState *env)
+{
+    fprintf(stderr, "setup_frame: not implemented\n");
+}
+
+static void setup_rt_frame(int sig, struct emulated_sigaction *ka,
+                           target_siginfo_t *info,
+			   target_sigset_t *set, CPUState *env)
+{
+    fprintf(stderr, "setup_rt_frame: not implemented\n");
+}
+
+long do_sigreturn(CPUState *env)
+{
+    fprintf(stderr, "do_sigreturn: not implemented\n");
+    return -ENOSYS;
+}
+
+long do_rt_sigreturn(CPUState *env)
+{
+    fprintf(stderr, "do_rt_sigreturn: not implemented\n");
+    return -ENOSYS;
+}
+
 #elif defined(TARGET_MIPS)
 
 struct target_sigcontext {
@@ -1842,11 +2210,10 @@
      */
     sp -= 32;
 
-#if 0
     /* This is the X/Open sanctioned signal stack switching.  */
-    if ((ka->sa.sa_flags & SA_ONSTACK) && (sas_ss_flags (sp) == 0))
-	sp = current->sas_ss_sp + current->sas_ss_size;
-#endif
+    if ((ka->sa.sa_flags & TARGET_SA_ONSTACK) && (sas_ss_flags (sp) == 0)) {
+        sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
+    }
 
     return g2h((sp - frame_size) & ~7);
 }
@@ -1990,7 +2357,7 @@
 void process_pending_signals(void *cpu_env)
 {
     int sig;
-    target_ulong handler;
+    abi_ulong handler;
     sigset_t set, old_set;
     target_sigset_t target_old_set;
     struct emulated_sigaction *k;

Modified: trunk/src/host/qemu-neo1973/linux-user/sparc/syscall.h
===================================================================
--- trunk/src/host/qemu-neo1973/linux-user/sparc/syscall.h	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/linux-user/sparc/syscall.h	2007-10-29 21:14:04 UTC (rev 3303)
@@ -1,9 +1,9 @@
 struct target_pt_regs {
-	target_ulong psr;
-	target_ulong pc;
-	target_ulong npc;
-	target_ulong y;
-	target_ulong u_regs[16];
+	abi_ulong psr;
+	abi_ulong pc;
+	abi_ulong npc;
+	abi_ulong y;
+	abi_ulong u_regs[16];
 };
 
 #define UNAME_MACHINE "sun4"

Modified: trunk/src/host/qemu-neo1973/linux-user/sparc/syscall_nr.h
===================================================================
--- trunk/src/host/qemu-neo1973/linux-user/sparc/syscall_nr.h	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/linux-user/sparc/syscall_nr.h	2007-10-29 21:14:04 UTC (rev 3303)
@@ -217,4 +217,62 @@
 #define TARGET_NR_fdatasync          253
 #define TARGET_NR_nfsservctl         254
 #define TARGET_NR_aplib              255
-#define TARGET_NR__exit TARGET_NR_exit
+#define TARGET_NR_clock_settime	256
+#define TARGET_NR_clock_gettime	257
+#define TARGET_NR_clock_getres	258
+#define TARGET_NR_clock_nanosleep	259
+#define TARGET_NR_sched_getaffinity	260
+#define TARGET_NR_sched_setaffinity	261
+#define TARGET_NR_timer_settime	262
+#define TARGET_NR_timer_gettime	263
+#define TARGET_NR_timer_getoverrun	264
+#define TARGET_NR_timer_delete	265
+#define TARGET_NR_timer_create	266
+/* #define TARGET_NR_vserver		267 Reserved for VSERVER */
+#define TARGET_NR_io_setup		268
+#define TARGET_NR_io_destroy		269
+#define TARGET_NR_io_submit		270
+#define TARGET_NR_io_cancel		271
+#define TARGET_NR_io_getevents	272
+#define TARGET_NR_mq_open		273
+#define TARGET_NR_mq_unlink		274
+#define TARGET_NR_mq_timedsend	275
+#define TARGET_NR_mq_timedreceive	276
+#define TARGET_NR_mq_notify		277
+#define TARGET_NR_mq_getsetattr	278
+#define TARGET_NR_waitid		279
+#define TARGET_NR_tee		280
+#define TARGET_NR_add_key		281
+#define TARGET_NR_request_key	282
+#define TARGET_NR_keyctl		283
+#define TARGET_NR_openat		284
+#define TARGET_NR_mkdirat		285
+#define TARGET_NR_mknodat		286
+#define TARGET_NR_fchownat		287
+#define TARGET_NR_futimesat		288
+#define TARGET_NR_fstatat64		289
+#define TARGET_NR_unlinkat		290
+#define TARGET_NR_renameat		291
+#define TARGET_NR_linkat		292
+#define TARGET_NR_symlinkat		293
+#define TARGET_NR_readlinkat		294
+#define TARGET_NR_fchmodat		295
+#define TARGET_NR_faccessat		296
+#define TARGET_NR_pselect6		297
+#define TARGET_NR_ppoll		298
+#define TARGET_NR_unshare		299
+#define TARGET_NR_set_robust_list	300
+#define TARGET_NR_get_robust_list	301
+#define TARGET_NR_migrate_pages	302
+#define TARGET_NR_mbind		303
+#define TARGET_NR_get_mempolicy	304
+#define TARGET_NR_set_mempolicy	305
+#define TARGET_NR_kexec_load		306
+#define TARGET_NR_move_pages		307
+#define TARGET_NR_getcpu		308
+#define TARGET_NR_epoll_pwait	309
+#define TARGET_NR_utimensat		310
+#define TARGET_NR_signalfd		311
+#define TARGET_NR_timerfd		312
+#define TARGET_NR_eventfd		313
+#define TARGET_NR_fallocate		314

Added: trunk/src/host/qemu-neo1973/linux-user/sparc/target_signal.h
===================================================================
--- trunk/src/host/qemu-neo1973/linux-user/sparc/target_signal.h	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/linux-user/sparc/target_signal.h	2007-10-29 21:14:04 UTC (rev 3303)
@@ -0,0 +1,36 @@
+#ifndef TARGET_SIGNAL_H
+#define TARGET_SIGNAL_H
+
+#include "cpu.h"
+
+/* this struct defines a stack used during syscall handling */
+
+typedef struct target_sigaltstack {
+	abi_ulong ss_sp;
+	abi_long ss_flags;
+	abi_ulong ss_size;
+} target_stack_t;
+
+
+/*
+ * sigaltstack controls
+ */
+#define TARGET_SS_ONSTACK	1
+#define TARGET_SS_DISABLE	2
+
+#define TARGET_MINSIGSTKSZ	4096
+#define TARGET_SIGSTKSZ		16384
+
+#ifndef UREG_I6
+#define UREG_I6        6
+#endif
+#ifndef UREG_FP
+#define UREG_FP        UREG_I6
+#endif
+
+static inline abi_ulong get_sp_from_cpustate(CPUSPARCState *state)
+{
+    return state->regwptr[UREG_FP];
+}
+
+#endif /* TARGET_SIGNAL_H */

Modified: trunk/src/host/qemu-neo1973/linux-user/sparc/termbits.h
===================================================================
--- trunk/src/host/qemu-neo1973/linux-user/sparc/termbits.h	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/linux-user/sparc/termbits.h	2007-10-29 21:14:04 UTC (rev 3303)
@@ -51,6 +51,7 @@
 #define TARGET_IXANY	0x00000800
 #define TARGET_IXOFF	0x00001000
 #define TARGET_IMAXBEL	0x00002000
+#define TARGET_IUTF8	0x00004000
 
 /* c_oflag bits */
 #define TARGET_OPOST	0x00000001

Modified: trunk/src/host/qemu-neo1973/linux-user/sparc64/syscall.h
===================================================================
--- trunk/src/host/qemu-neo1973/linux-user/sparc64/syscall.h	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/linux-user/sparc64/syscall.h	2007-10-29 21:14:04 UTC (rev 3303)
@@ -1,10 +1,10 @@
 struct target_pt_regs {
-	target_ulong u_regs[16];
-	target_ulong tstate;
-	target_ulong pc;
-	target_ulong npc;
-	target_ulong y;
-	target_ulong fprs;
+	abi_ulong u_regs[16];
+	abi_ulong tstate;
+	abi_ulong pc;
+	abi_ulong npc;
+	abi_ulong y;
+	abi_ulong fprs;
 };
 
 #define UNAME_MACHINE "sun4u"

Modified: trunk/src/host/qemu-neo1973/linux-user/sparc64/syscall_nr.h
===================================================================
--- trunk/src/host/qemu-neo1973/linux-user/sparc64/syscall_nr.h	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/linux-user/sparc64/syscall_nr.h	2007-10-29 21:14:04 UTC (rev 3303)
@@ -29,11 +29,11 @@
 #define TARGET_NR_sigaltstack	 28 /* Common					   */
 #define TARGET_NR_pause               29 /* Is sigblock(0)->sigpause() in SunOS         */
 #define TARGET_NR_utime               30 /* Implemented via utimes() under SunOS        */
-/* #define TARGET_NR_lchown32         31    Linux sparc32 specific                      */
-/* #define TARGET_NR_fchown32         32    Linux sparc32 specific                      */
+#define TARGET_NR_lchown32            31 /* Linux sparc32 specific                      */
+#define TARGET_NR_fchown32            32 /* Linux sparc32 specific                      */
 #define TARGET_NR_access              33 /* Common                                      */
 #define TARGET_NR_nice                34 /* Implemented via get/setpriority() in SunOS  */
-/* #define TARGET_NR_chown32          35    Linux sparc32 specific                      */
+#define TARGET_NR_chown32             35 /*  Linux sparc32 specific                     */
 #define TARGET_NR_sync                36 /* Common                                      */
 #define TARGET_NR_kill                37 /* Common                                      */
 #define TARGET_NR_stat                38 /* Common                                      */
@@ -42,7 +42,7 @@
 #define TARGET_NR_dup                 41 /* Common                                      */
 #define TARGET_NR_pipe                42 /* Common                                      */
 #define TARGET_NR_times               43 /* Implemented via getrusage() in SunOS        */
-/* #define TARGET_NR_getuid32         44    Linux sparc32 specific                      */
+#define TARGET_NR_getuid32            44 /* Linux sparc32 specific                      */
 #define TARGET_NR_umount2             45 /* Linux Specific                              */
 #define TARGET_NR_setgid              46 /* Implemented via setregid() in SunOS         */
 #define TARGET_NR_getgid              47 /* Common                                      */
@@ -51,48 +51,48 @@
 #define TARGET_NR_getegid             50 /* SunOS calls getgid()                        */
 #define TARGET_NR_acct                51 /* Common                                      */
 #define TARGET_NR_memory_ordering	 52 /* Linux Specific				   */
-/* #define TARGET_NR_getgid32         53    Linux sparc32 specific                      */
+#define TARGET_NR_getgid32            53 /* Linux sparc32 specific                      */
 #define TARGET_NR_ioctl               54 /* Common                                      */
 #define TARGET_NR_reboot              55 /* Common                                      */
-/* #define TARGET_NR_mmap2		 56    Linux sparc32 Specific                      */
+#define TARGET_NR_mmap2		      56 /* Linux sparc32 Specific                      */
 #define TARGET_NR_symlink             57 /* Common                                      */
 #define TARGET_NR_readlink            58 /* Common                                      */
 #define TARGET_NR_execve              59 /* Common                                      */
 #define TARGET_NR_umask               60 /* Common                                      */
 #define TARGET_NR_chroot              61 /* Common                                      */
 #define TARGET_NR_fstat               62 /* Common                                      */
-/* #define TARGET_NR_fstat64          63    Linux sparc32 Specific                      */
+#define TARGET_NR_fstat64             63 /* Linux sparc32 Specific                      */
 #define TARGET_NR_getpagesize         64 /* Common                                      */
 #define TARGET_NR_msync               65 /* Common in newer 1.3.x revs...               */
 #define TARGET_NR_vfork               66 /* Common                                      */
 #define TARGET_NR_pread64             67 /* Linux Specific                              */
 #define TARGET_NR_pwrite64            68 /* Linux Specific                              */
-/* #define TARGET_NR_geteuid32        69    Linux sparc32, sbrk under SunOS             */
-/* #define TARGET_NR_getegid32        70    Linux sparc32, sstk under SunOS             */
+#define TARGET_NR_geteuid32           69 /* Linux sparc32, sbrk under SunOS             */
+#define TARGET_NR_getegid32           70 /* Linux sparc32, sstk under SunOS             */
 #define TARGET_NR_mmap                71 /* Common                                      */
-/* #define TARGET_NR_setreuid32       72    Linux sparc32, vadvise under SunOS          */
+#define TARGET_NR_setreuid32          72 /* Linux sparc32, vadvise under SunOS          */
 #define TARGET_NR_munmap              73 /* Common                                      */
 #define TARGET_NR_mprotect            74 /* Common                                      */
 #define TARGET_NR_madvise             75 /* Common                                      */
 #define TARGET_NR_vhangup             76 /* Common                                      */
-/* #define TARGET_NR_truncate64       77    Linux sparc32 Specific			   */
+#define TARGET_NR_truncate64          77 /* Linux sparc32 Specific			*/
 #define TARGET_NR_mincore             78 /* Common                                      */
 #define TARGET_NR_getgroups           79 /* Common                                      */
 #define TARGET_NR_setgroups           80 /* Common                                      */
 #define TARGET_NR_getpgrp             81 /* Common                                      */
-/* #define TARGET_NR_setgroups32      82    Linux sparc32, setpgrp under SunOS          */
+#define TARGET_NR_setgroups32         82 /* Linux sparc32, setpgrp under SunOS          */
 #define TARGET_NR_setitimer           83 /* Common                                      */
-/* #define TARGET_NR_ftruncate64      84    Linux sparc32 Specific			   */
+#define TARGET_NR_ftruncate64         84 /* Linux sparc32 Specific                      */
 #define TARGET_NR_swapon              85 /* Common                                      */
 #define TARGET_NR_getitimer           86 /* Common                                      */
-/* #define TARGET_NR_setuid32         87    Linux sparc32, gethostname under SunOS      */
+#define TARGET_NR_setuid32            87 /* Linux sparc32, gethostname under SunOS      */
 #define TARGET_NR_sethostname         88 /* Common                                      */
-/* #define TARGET_NR_setgid32         89    Linux sparc32, getdtablesize under SunOS    */
+#define TARGET_NR_setgid32            89 /* Linux sparc32, getdtablesize under SunOS    */
 #define TARGET_NR_dup2                90 /* Common                                      */
-/* #define TARGET_NR_setfsuid32       91    Linux sparc32, getdopt under SunOS          */
+#define TARGET_NR_setfsuid32          91 /* Linux sparc32, getdopt under SunOS          */
 #define TARGET_NR_fcntl               92 /* Common                                      */
 #define TARGET_NR_select              93 /* Common                                      */
-/* #define TARGET_NR_setfsgid32       94    Linux sparc32, setdopt under SunOS          */
+#define TARGET_NR_setfsgid32          94 /* Linux sparc32, setdopt under SunOS          */
 #define TARGET_NR_fsync               95 /* Common                                      */
 #define TARGET_NR_setpriority         96 /* Common                                      */
 #define TARGET_NR_socket              97 /* Common                                      */
@@ -110,10 +110,10 @@
 #define TARGET_NR_getresuid          109 /* Linux Specific, sigblock under SunOS	   */
 #define TARGET_NR_setresgid          110 /* Linux Specific, sigsetmask under SunOS	   */
 #define TARGET_NR_getresgid          111 /* Linux Specific, sigpause under SunOS	   */
-/* #define TARGET_NR_setregid32       75    Linux sparc32, sigstack under SunOS         */
+/* #define TARGET_NR_setregid32          75  Linux sparc32, sigstack under SunOS         */
 #define TARGET_NR_recvmsg            113 /* Common                                      */
 #define TARGET_NR_sendmsg            114 /* Common                                      */
-/* #define TARGET_NR_getgroups32     115    Linux sparc32, vtrace under SunOS           */
+#define TARGET_NR_getgroups32        115 /* Linux sparc32, vtrace under SunOS           */
 #define TARGET_NR_gettimeofday       116 /* Common                                      */
 #define TARGET_NR_getrusage          117 /* Common                                      */
 #define TARGET_NR_getsockopt         118 /* Common                                      */
@@ -130,14 +130,14 @@
 #define TARGET_NR_truncate           129 /* Common                                      */
 #define TARGET_NR_ftruncate          130 /* Common                                      */
 #define TARGET_NR_flock              131 /* Common                                      */
-/* #define TARGET_NR_lstat64		132    Linux sparc32 Specific                      */
+#define TARGET_NR_lstat64	     132 /* Linux sparc32 Specific                      */
 #define TARGET_NR_sendto             133 /* Common                                      */
 #define TARGET_NR_shutdown           134 /* Common                                      */
 #define TARGET_NR_socketpair         135 /* Common                                      */
 #define TARGET_NR_mkdir              136 /* Common                                      */
 #define TARGET_NR_rmdir              137 /* Common                                      */
 #define TARGET_NR_utimes             138 /* SunOS Specific                              */
-/* #define TARGET_NR_stat64		139    Linux sparc32 Specific			   */
+#define TARGET_NR_stat64	     139 /* Linux sparc32 Specific			   */
 #define TARGET_NR_sendfile64         140 /* adjtime under SunOS                         */
 #define TARGET_NR_getpeername        141 /* Common                                      */
 #define TARGET_NR_futex              142 /* gethostid under SunOS                       */
@@ -153,7 +153,7 @@
 /* #define TARGET_NR_putmsg          152    SunOS Specific                              */
 #define TARGET_NR_poll               153 /* Common                                      */
 #define TARGET_NR_getdents64		154 /* Linux specific				   */
-/* #define TARGET_NR_fcntl64         155    Linux sparc32 Specific                      */
+#define TARGET_NR_fcntl64            155 /* Linux sparc32 Specific                      */
 /* #define TARGET_NR_getdirentries   156    SunOS Specific                              */
 #define TARGET_NR_statfs             157 /* Common                                      */
 #define TARGET_NR_fstatfs            158 /* Common                                      */
@@ -229,9 +229,7 @@
 #define TARGET_NR_setfsuid           228 /* Linux Specific                              */
 #define TARGET_NR_setfsgid           229 /* Linux Specific                              */
 #define TARGET_NR__newselect         230 /* Linux Specific                              */
-#ifdef __KERNEL__
-#define TARGET_NR_time		231 /* Linux sparc32                               */
-#endif
+#define TARGET_NR_time               231 /* Linux sparc32                               */
 /* #define TARGET_NR_oldstat         232    Linux Specific                              */
 #define TARGET_NR_stime              233 /* Linux Specific                              */
 #define TARGET_NR_statfs64           234 /* Linux Specific                              */
@@ -284,3 +282,34 @@
 #define TARGET_NR_add_key		281
 #define TARGET_NR_request_key	282
 #define TARGET_NR_keyctl		283
+#define TARGET_NR_openat		284
+#define TARGET_NR_mkdirat		285
+#define TARGET_NR_mknodat		286
+#define TARGET_NR_fchownat		287
+#define TARGET_NR_futimesat		288
+#define TARGET_NR_fstatat64		289
+#define TARGET_NR_unlinkat		290
+#define TARGET_NR_renameat		291
+#define TARGET_NR_linkat		292
+#define TARGET_NR_symlinkat		293
+#define TARGET_NR_readlinkat		294
+#define TARGET_NR_fchmodat		295
+#define TARGET_NR_faccessat		296
+#define TARGET_NR_pselect6		297
+#define TARGET_NR_ppoll		298
+#define TARGET_NR_unshare		299
+#define TARGET_NR_set_robust_list	300
+#define TARGET_NR_get_robust_list	301
+#define TARGET_NR_migrate_pages	302
+#define TARGET_NR_mbind		303
+#define TARGET_NR_get_mempolicy	304
+#define TARGET_NR_set_mempolicy	305
+#define TARGET_NR_kexec_load		306
+#define TARGET_NR_move_pages		307
+#define TARGET_NR_getcpu		308
+#define TARGET_NR_epoll_pwait	309
+#define TARGET_NR_utimensat		310
+#define TARGET_NR_signalfd		311
+#define TARGET_NR_timerfd		312
+#define TARGET_NR_eventfd		313
+#define TARGET_NR_fallocate		314

Added: trunk/src/host/qemu-neo1973/linux-user/sparc64/target_signal.h
===================================================================
--- trunk/src/host/qemu-neo1973/linux-user/sparc64/target_signal.h	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/linux-user/sparc64/target_signal.h	2007-10-29 21:14:04 UTC (rev 3303)
@@ -0,0 +1,36 @@
+#ifndef TARGET_SIGNAL_H
+#define TARGET_SIGNAL_H
+
+#include "cpu.h"
+
+/* this struct defines a stack used during syscall handling */
+
+typedef struct target_sigaltstack {
+	abi_ulong ss_sp;
+	abi_long ss_flags;
+	abi_ulong ss_size;
+} target_stack_t;
+
+
+/*
+ * sigaltstack controls
+ */
+#define TARGET_SS_ONSTACK	1
+#define TARGET_SS_DISABLE	2
+
+#define TARGET_MINSIGSTKSZ	4096
+#define TARGET_SIGSTKSZ		16384
+
+#ifndef UREG_I6
+#define UREG_I6        6
+#endif
+#ifndef UREG_FP
+#define UREG_FP        UREG_I6
+#endif
+
+static inline abi_ulong get_sp_from_cpustate(CPUSPARCState *state)
+{
+    return state->regwptr[UREG_FP];
+}
+
+#endif /* TARGET_SIGNAL_H */

Modified: trunk/src/host/qemu-neo1973/linux-user/sparc64/termbits.h
===================================================================
--- trunk/src/host/qemu-neo1973/linux-user/sparc64/termbits.h	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/linux-user/sparc64/termbits.h	2007-10-29 21:14:04 UTC (rev 3303)
@@ -51,6 +51,7 @@
 #define TARGET_IXANY	0x00000800
 #define TARGET_IXOFF	0x00001000
 #define TARGET_IMAXBEL	0x00002000
+#define TARGET_IUTF8	0x00004000
 
 /* c_oflag bits */
 #define TARGET_OPOST	0x00000001

Modified: trunk/src/host/qemu-neo1973/linux-user/syscall.c
===================================================================
--- trunk/src/host/qemu-neo1973/linux-user/syscall.c	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/linux-user/syscall.c	2007-10-29 21:14:04 UTC (rev 3303)
@@ -74,7 +74,7 @@
 //#define DEBUG
 
 #if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SPARC) \
-    || defined(TARGET_M68K) || defined(TARGET_SH4)
+    || defined(TARGET_M68K) || defined(TARGET_SH4) || defined(TARGET_CRIS)
 /* 16 bit uid wrappers emulation */
 #define USE_UID16
 #endif
@@ -139,13 +139,26 @@
 
 
 #define __NR_sys_uname __NR_uname
+#define __NR_sys_faccessat __NR_faccessat
+#define __NR_sys_fchmodat __NR_fchmodat
+#define __NR_sys_fchownat __NR_fchownat
 #define __NR_sys_getcwd1 __NR_getcwd
 #define __NR_sys_getdents __NR_getdents
 #define __NR_sys_getdents64 __NR_getdents64
+#define __NR_sys_getpriority __NR_getpriority
+#define __NR_sys_linkat __NR_linkat
+#define __NR_sys_mkdirat __NR_mkdirat
+#define __NR_sys_mknodat __NR_mknodat
+#define __NR_sys_openat __NR_openat
+#define __NR_sys_readlinkat __NR_readlinkat
+#define __NR_sys_renameat __NR_renameat
 #define __NR_sys_rt_sigqueueinfo __NR_rt_sigqueueinfo
+#define __NR_sys_symlinkat __NR_symlinkat
 #define __NR_sys_syslog __NR_syslog
 #define __NR_sys_tgkill __NR_tgkill
 #define __NR_sys_tkill __NR_tkill
+#define __NR_sys_unlinkat __NR_unlinkat
+#define __NR_sys_utimensat __NR_utimensat
 
 #if defined(__alpha__) || defined (__ia64__) || defined(__x86_64__)
 #define __NR__llseek __NR_lseek
@@ -154,19 +167,59 @@
 #ifdef __NR_gettid
 _syscall0(int, gettid)
 #else
+/* This is a replacement for the host gettid() and must return a host
+   errno. */
 static int gettid(void) {
     return -ENOSYS;
 }
 #endif
 _syscall1(int,sys_uname,struct new_utsname *,buf)
+#if defined(TARGET_NR_faccessat) && defined(__NR_faccessat)
+_syscall4(int,sys_faccessat,int,dirfd,const char *,pathname,int,mode,int,flags)
+#endif
+#if defined(TARGET_NR_fchmodat) && defined(__NR_fchmodat)
+_syscall4(int,sys_fchmodat,int,dirfd,const char *,pathname,
+          mode_t,mode,int,flags)
+#endif
+#if defined(TARGET_NR_fchownat) && defined(__NR_fchownat)
+_syscall5(int,sys_fchownat,int,dirfd,const char *,pathname,
+          uid_t,owner,gid_t,group,int,flags)
+#endif
 _syscall2(int,sys_getcwd1,char *,buf,size_t,size)
 _syscall3(int, sys_getdents, uint, fd, struct dirent *, dirp, uint, count);
 #if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
 _syscall3(int, sys_getdents64, uint, fd, struct dirent64 *, dirp, uint, count);
 #endif
+_syscall2(int, sys_getpriority, int, which, int, who);
 _syscall5(int, _llseek,  uint,  fd, ulong, hi, ulong, lo,
           loff_t *, res, uint, wh);
+#if defined(TARGET_NR_linkat) && defined(__NR_linkat)
+_syscall5(int,sys_linkat,int,olddirfd,const char *,oldpath,
+	  int,newdirfd,const char *,newpath,int,flags)
+#endif
+#if defined(TARGET_NR_mkdirat) && defined(__NR_mkdirat)
+_syscall3(int,sys_mkdirat,int,dirfd,const char *,pathname,mode_t,mode)
+#endif
+#if defined(TARGET_NR_mknodat) && defined(__NR_mknodat)
+_syscall4(int,sys_mknodat,int,dirfd,const char *,pathname,
+          mode_t,mode,dev_t,dev)
+#endif
+#if defined(TARGET_NR_openat) && defined(__NR_openat)
+_syscall4(int,sys_openat,int,dirfd,const char *,pathname,int,flags,mode_t,mode)
+#endif
+#if defined(TARGET_NR_readlinkat) && defined(__NR_readlinkat)
+_syscall4(int,sys_readlinkat,int,dirfd,const char *,pathname,
+          char *,buf,size_t,bufsize)
+#endif
+#if defined(TARGET_NR_renameat) && defined(__NR_renameat)
+_syscall4(int,sys_renameat,int,olddirfd,const char *,oldpath,
+          int,newdirfd,const char *,newpath)
+#endif
 _syscall3(int,sys_rt_sigqueueinfo,int,pid,int,sig,siginfo_t *,uinfo)
+#if defined(TARGET_NR_symlinkat) && defined(__NR_symlinkat)
+_syscall3(int,sys_symlinkat,const char *,oldpath,
+          int,newdirfd,const char *,newpath)
+#endif
 _syscall3(int,sys_syslog,int,type,char*,bufp,int,len)
 #if defined(TARGET_NR_tgkill) && defined(__NR_tgkill)
 _syscall3(int,sys_tgkill,int,tgid,int,pid,int,sig)
@@ -180,6 +233,13 @@
 #if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
 _syscall1(int,set_tid_address,int *,tidptr)
 #endif
+#if defined(TARGET_NR_unlinkat) && defined(__NR_unlinkat)
+_syscall3(int,sys_unlinkat,int,dirfd,const char *,pathname,int,flags)
+#endif
+#if defined(TARGET_NR_utimensat) && defined(__NR_utimensat)
+_syscall4(int,sys_utimensat,int,dirfd,const char *,pathname,
+          const struct timespec *,tsp,int,flags)
+#endif
 
 extern int personality(int);
 extern int flock(int, int);
@@ -310,7 +370,7 @@
     return err;
 }
 
-static inline long get_errno(long ret)
+static inline abi_long get_errno(abi_long ret)
 {
     if (ret == -1)
         return -host_to_target_errno(errno);
@@ -318,29 +378,30 @@
         return ret;
 }
 
-static inline int is_error(long ret)
+static inline int is_error(abi_long ret)
 {
-    return (unsigned long)ret >= (unsigned long)(-4096);
+    return (abi_ulong)ret >= (abi_ulong)(-4096);
 }
 
-static target_ulong target_brk;
-static target_ulong target_original_brk;
+static abi_ulong target_brk;
+static abi_ulong target_original_brk;
 
-void target_set_brk(target_ulong new_brk)
+void target_set_brk(abi_ulong new_brk)
 {
     target_original_brk = target_brk = HOST_PAGE_ALIGN(new_brk);
 }
 
-long do_brk(target_ulong new_brk)
+/* do_brk() must return target values and target errnos. */
+abi_long do_brk(abi_ulong new_brk)
 {
-    target_ulong brk_page;
-    long mapped_addr;
+    abi_ulong brk_page;
+    abi_long mapped_addr;
     int	new_alloc_size;
 
     if (!new_brk)
         return target_brk;
     if (new_brk < target_original_brk)
-        return -ENOMEM;
+        return -TARGET_ENOMEM;
 
     brk_page = HOST_PAGE_ALIGN(target_brk);
 
@@ -364,7 +425,7 @@
 }
 
 static inline fd_set *target_to_host_fds(fd_set *fds,
-                                         target_long *target_fds, int n)
+                                         abi_long *target_fds, int n)
 {
 #if !defined(BSWAP_NEEDED) && !defined(WORDS_BIGENDIAN)
     return (fd_set *)target_fds;
@@ -373,8 +434,8 @@
     if (target_fds) {
         FD_ZERO(fds);
         for(i = 0;i < n; i++) {
-            b = (tswapl(target_fds[i / TARGET_LONG_BITS]) >>
-                 (i & (TARGET_LONG_BITS - 1))) & 1;
+            b = (tswapl(target_fds[i / TARGET_ABI_BITS]) >>
+                 (i & (TARGET_ABI_BITS - 1))) & 1;
             if (b)
                 FD_SET(i, fds);
         }
@@ -385,21 +446,21 @@
 #endif
 }
 
-static inline void host_to_target_fds(target_long *target_fds,
+static inline void host_to_target_fds(abi_long *target_fds,
                                       fd_set *fds, int n)
 {
 #if !defined(BSWAP_NEEDED) && !defined(WORDS_BIGENDIAN)
     /* nothing to do */
 #else
     int i, nw, j, k;
-    target_long v;
+    abi_long v;
 
     if (target_fds) {
-        nw = (n + TARGET_LONG_BITS - 1) / TARGET_LONG_BITS;
+        nw = (n + TARGET_ABI_BITS - 1) / TARGET_ABI_BITS;
         k = 0;
         for(i = 0;i < nw; i++) {
             v = 0;
-            for(j = 0; j < TARGET_LONG_BITS; j++) {
+            for(j = 0; j < TARGET_ABI_BITS; j++) {
                 v |= ((FD_ISSET(k, fds) != 0) << j);
                 k++;
             }
@@ -415,7 +476,7 @@
 #define HOST_HZ 100
 #endif
 
-static inline long host_to_target_clock_t(long ticks)
+static inline abi_long host_to_target_clock_t(long ticks)
 {
 #if HOST_HZ == TARGET_HZ
     return ticks;
@@ -424,7 +485,7 @@
 #endif
 }
 
-static inline void host_to_target_rusage(target_ulong target_addr,
+static inline void host_to_target_rusage(abi_ulong target_addr,
                                          const struct rusage *rusage)
 {
     struct target_rusage *target_rusage;
@@ -452,7 +513,7 @@
 }
 
 static inline void target_to_host_timeval(struct timeval *tv,
-                                          target_ulong target_addr)
+                                          abi_ulong target_addr)
 {
     struct target_timeval *target_tv;
 
@@ -462,7 +523,7 @@
     unlock_user_struct(target_tv, target_addr, 0);
 }
 
-static inline void host_to_target_timeval(target_ulong target_addr,
+static inline void host_to_target_timeval(abi_ulong target_addr,
                                           const struct timeval *tv)
 {
     struct target_timeval *target_tv;
@@ -474,33 +535,34 @@
 }
 
 
-static long do_select(long n,
-                      target_ulong rfd_p, target_ulong wfd_p,
-                      target_ulong efd_p, target_ulong target_tv)
+/* do_select() must return target values and target errnos. */
+static abi_long do_select(int n,
+                          abi_ulong rfd_p, abi_ulong wfd_p,
+                          abi_ulong efd_p, abi_ulong target_tv)
 {
     fd_set rfds, wfds, efds;
     fd_set *rfds_ptr, *wfds_ptr, *efds_ptr;
-    target_long *target_rfds, *target_wfds, *target_efds;
+    abi_long *target_rfds, *target_wfds, *target_efds;
     struct timeval tv, *tv_ptr;
-    long ret;
+    abi_long ret;
     int ok;
 
     if (rfd_p) {
-        target_rfds = lock_user(rfd_p, sizeof(target_long) * n, 1);
+        target_rfds = lock_user(rfd_p, sizeof(abi_long) * n, 1);
         rfds_ptr = target_to_host_fds(&rfds, target_rfds, n);
     } else {
         target_rfds = NULL;
         rfds_ptr = NULL;
     }
     if (wfd_p) {
-        target_wfds = lock_user(wfd_p, sizeof(target_long) * n, 1);
+        target_wfds = lock_user(wfd_p, sizeof(abi_long) * n, 1);
         wfds_ptr = target_to_host_fds(&wfds, target_wfds, n);
     } else {
         target_wfds = NULL;
         wfds_ptr = NULL;
     }
     if (efd_p) {
-        target_efds = lock_user(efd_p, sizeof(target_long) * n, 1);
+        target_efds = lock_user(efd_p, sizeof(abi_long) * n, 1);
         efds_ptr = target_to_host_fds(&efds, target_efds, n);
     } else {
         target_efds = NULL;
@@ -526,17 +588,17 @@
         }
     }
     if (target_rfds)
-        unlock_user(target_rfds, rfd_p, ok ? sizeof(target_long) * n : 0);
+        unlock_user(target_rfds, rfd_p, ok ? sizeof(abi_long) * n : 0);
     if (target_wfds)
-        unlock_user(target_wfds, wfd_p, ok ? sizeof(target_long) * n : 0);
+        unlock_user(target_wfds, wfd_p, ok ? sizeof(abi_long) * n : 0);
     if (target_efds)
-        unlock_user(target_efds, efd_p, ok ? sizeof(target_long) * n : 0);
+        unlock_user(target_efds, efd_p, ok ? sizeof(abi_long) * n : 0);
 
     return ret;
 }
 
 static inline void target_to_host_sockaddr(struct sockaddr *addr,
-                                           target_ulong target_addr,
+                                           abi_ulong target_addr,
                                            socklen_t len)
 {
     struct target_sockaddr *target_saddr;
@@ -547,7 +609,7 @@
     unlock_user(target_saddr, target_addr, 0);
 }
 
-static inline void host_to_target_sockaddr(target_ulong target_addr,
+static inline void host_to_target_sockaddr(abi_ulong target_addr,
                                            struct sockaddr *addr,
                                            socklen_t len)
 {
@@ -648,16 +710,18 @@
     msgh->msg_controllen = tswapl(space);
 }
 
-static long do_setsockopt(int sockfd, int level, int optname,
-                          target_ulong optval, socklen_t optlen)
+/* do_setsockopt() Must return target values and target errnos. */
+static abi_long do_setsockopt(int sockfd, int level, int optname,
+                              abi_ulong optval, socklen_t optlen)
 {
-    int val, ret;
+    abi_long ret;
+    int val;
 
     switch(level) {
     case SOL_TCP:
         /* TCP options all take an 'int' value.  */
         if (optlen < sizeof(uint32_t))
-            return -EINVAL;
+            return -TARGET_EINVAL;
 
         val = tget32(optval);
         ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));
@@ -755,7 +819,7 @@
             goto unimplemented;
         }
 	if (optlen < sizeof(uint32_t))
-	return -EINVAL;
+	return -TARGET_EINVAL;
 
 	val = tget32(optval);
 	ret = get_errno(setsockopt(sockfd, SOL_SOCKET, optname, &val, sizeof(val)));
@@ -763,15 +827,17 @@
     default:
     unimplemented:
         gemu_log("Unsupported setsockopt level=%d optname=%d \n", level, optname);
-        ret = -ENOSYS;
+        ret = -TARGET_ENOSYS;
     }
     return ret;
 }
 
-static long do_getsockopt(int sockfd, int level, int optname,
-                          target_ulong optval, target_ulong optlen)
+/* do_getsockopt() Must return target values and target errnos. */
+static abi_long do_getsockopt(int sockfd, int level, int optname,
+                              abi_ulong optval, abi_ulong optlen)
 {
-    int len, lv, val, ret;
+    abi_long ret;
+    int len, lv, val;
 
     switch(level) {
     case TARGET_SOL_SOCKET:
@@ -793,7 +859,7 @@
     int_case:
         len = tget32(optlen);
         if (len < 0)
-            return -EINVAL;
+            return -TARGET_EINVAL;
         lv = sizeof(int);
         ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv));
         if (ret < 0)
@@ -826,7 +892,7 @@
         case IP_MULTICAST_LOOP:
             len = tget32(optlen);
             if (len < 0)
-                return -EINVAL;
+                return -TARGET_EINVAL;
             lv = sizeof(int);
             ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv));
             if (ret < 0)
@@ -850,17 +916,17 @@
     unimplemented:
         gemu_log("getsockopt level=%d optname=%d not yet supported\n",
                  level, optname);
-        ret = -ENOSYS;
+        ret = -TARGET_ENOSYS;
         break;
     }
     return ret;
 }
 
-static void lock_iovec(struct iovec *vec, target_ulong target_addr,
+static void lock_iovec(struct iovec *vec, abi_ulong target_addr,
                        int count, int copy)
 {
     struct target_iovec *target_vec;
-    target_ulong base;
+    abi_ulong base;
     int i;
 
     target_vec = lock_user(target_addr, count * sizeof(struct target_iovec), 1);
@@ -872,11 +938,11 @@
     unlock_user (target_vec, target_addr, 0);
 }
 
-static void unlock_iovec(struct iovec *vec, target_ulong target_addr,
+static void unlock_iovec(struct iovec *vec, abi_ulong target_addr,
                          int count, int copy)
 {
     struct target_iovec *target_vec;
-    target_ulong base;
+    abi_ulong base;
     int i;
 
     target_vec = lock_user(target_addr, count * sizeof(struct target_iovec), 1);
@@ -887,7 +953,8 @@
     unlock_user (target_vec, target_addr, 0);
 }
 
-static long do_socket(int domain, int type, int protocol)
+/* do_socket() Must return target values and target errnos. */
+static abi_long do_socket(int domain, int type, int protocol)
 {
 #if defined(TARGET_MIPS)
     switch(type) {
@@ -914,8 +981,9 @@
     return get_errno(socket(domain, type, protocol));
 }
 
-static long do_bind(int sockfd, target_ulong target_addr,
-                    socklen_t addrlen)
+/* do_bind() Must return target values and target errnos. */
+static abi_long do_bind(int sockfd, abi_ulong target_addr,
+                        socklen_t addrlen)
 {
     void *addr = alloca(addrlen);
 
@@ -923,8 +991,9 @@
     return get_errno(bind(sockfd, addr, addrlen));
 }
 
-static long do_connect(int sockfd, target_ulong target_addr,
-                    socklen_t addrlen)
+/* do_connect() Must return target values and target errnos. */
+static abi_long do_connect(int sockfd, abi_ulong target_addr,
+                           socklen_t addrlen)
 {
     void *addr = alloca(addrlen);
 
@@ -932,15 +1001,16 @@
     return get_errno(connect(sockfd, addr, addrlen));
 }
 
-static long do_sendrecvmsg(int fd, target_ulong target_msg,
-                           int flags, int send)
+/* do_sendrecvmsg() Must return target values and target errnos. */
+static abi_long do_sendrecvmsg(int fd, abi_ulong target_msg,
+                               int flags, int send)
 {
-    long ret;
+    abi_long ret;
     struct target_msghdr *msgp;
     struct msghdr msg;
     int count;
     struct iovec *vec;
-    target_ulong target_vec;
+    abi_ulong target_vec;
 
     lock_user_struct(msgp, target_msg, 1);
     if (msgp->msg_name) {
@@ -975,12 +1045,13 @@
     return ret;
 }
 
-static long do_accept(int fd, target_ulong target_addr,
-                      target_ulong target_addrlen)
+/* do_accept() Must return target values and target errnos. */
+static abi_long do_accept(int fd, abi_ulong target_addr,
+                          abi_ulong target_addrlen)
 {
     socklen_t addrlen = tget32(target_addrlen);
     void *addr = alloca(addrlen);
-    long ret;
+    abi_long ret;
 
     ret = get_errno(accept(fd, addr, &addrlen));
     if (!is_error(ret)) {
@@ -990,12 +1061,13 @@
     return ret;
 }
 
-static long do_getpeername(int fd, target_ulong target_addr,
-                           target_ulong target_addrlen)
+/* do_getpeername() Must return target values and target errnos. */
+static abi_long do_getpeername(int fd, abi_ulong target_addr,
+                               abi_ulong target_addrlen)
 {
     socklen_t addrlen = tget32(target_addrlen);
     void *addr = alloca(addrlen);
-    long ret;
+    abi_long ret;
 
     ret = get_errno(getpeername(fd, addr, &addrlen));
     if (!is_error(ret)) {
@@ -1005,12 +1077,13 @@
     return ret;
 }
 
-static long do_getsockname(int fd, target_ulong target_addr,
-                           target_ulong target_addrlen)
+/* do_getsockname() Must return target values and target errnos. */
+static abi_long do_getsockname(int fd, abi_ulong target_addr,
+                               abi_ulong target_addrlen)
 {
     socklen_t addrlen = tget32(target_addrlen);
     void *addr = alloca(addrlen);
-    long ret;
+    abi_long ret;
 
     ret = get_errno(getsockname(fd, addr, &addrlen));
     if (!is_error(ret)) {
@@ -1020,11 +1093,12 @@
     return ret;
 }
 
-static long do_socketpair(int domain, int type, int protocol,
-                          target_ulong target_tab)
+/* do_socketpair() Must return target values and target errnos. */
+static abi_long do_socketpair(int domain, int type, int protocol,
+                              abi_ulong target_tab)
 {
     int tab[2];
-    long ret;
+    abi_long ret;
 
     ret = get_errno(socketpair(domain, type, protocol, tab));
     if (!is_error(ret)) {
@@ -1034,12 +1108,13 @@
     return ret;
 }
 
-static long do_sendto(int fd, target_ulong msg, size_t len, int flags,
-                      target_ulong target_addr, socklen_t addrlen)
+/* do_sendto() Must return target values and target errnos. */
+static abi_long do_sendto(int fd, abi_ulong msg, size_t len, int flags,
+                          abi_ulong target_addr, socklen_t addrlen)
 {
     void *addr;
     void *host_msg;
-    long ret;
+    abi_long ret;
 
     host_msg = lock_user(msg, len, 1);
     if (target_addr) {
@@ -1053,13 +1128,15 @@
     return ret;
 }
 
-static long do_recvfrom(int fd, target_ulong msg, size_t len, int flags,
-                        target_ulong target_addr, target_ulong target_addrlen)
+/* do_recvfrom() Must return target values and target errnos. */
+static abi_long do_recvfrom(int fd, abi_ulong msg, size_t len, int flags,
+                            abi_ulong target_addr,
+                            abi_ulong target_addrlen)
 {
     socklen_t addrlen;
     void *addr;
     void *host_msg;
-    long ret;
+    abi_long ret;
 
     host_msg = lock_user(msg, len, 0);
     if (target_addr) {
@@ -1082,10 +1159,12 @@
     return ret;
 }
 
-static long do_socketcall(int num, target_ulong vptr)
+#ifdef TARGET_NR_socketcall
+/* do_socketcall() Must return target values and target errnos. */
+static abi_long do_socketcall(int num, abi_ulong vptr)
 {
-    long ret;
-    const int n = sizeof(target_ulong);
+    abi_long ret;
+    const int n = sizeof(abi_ulong);
 
     switch(num) {
     case SOCKOP_socket:
@@ -1099,7 +1178,7 @@
     case SOCKOP_bind:
 	{
             int sockfd = tgetl(vptr);
-            target_ulong target_addr = tgetl(vptr + n);
+            abi_ulong target_addr = tgetl(vptr + n);
             socklen_t addrlen = tgetl(vptr + 2 * n);
             ret = do_bind(sockfd, target_addr, addrlen);
         }
@@ -1107,7 +1186,7 @@
     case SOCKOP_connect:
         {
             int sockfd = tgetl(vptr);
-            target_ulong target_addr = tgetl(vptr + n);
+            abi_ulong target_addr = tgetl(vptr + n);
             socklen_t addrlen = tgetl(vptr + 2 * n);
             ret = do_connect(sockfd, target_addr, addrlen);
         }
@@ -1122,24 +1201,24 @@
     case SOCKOP_accept:
         {
             int sockfd = tgetl(vptr);
-            target_ulong target_addr = tgetl(vptr + n);
-            target_ulong target_addrlen = tgetl(vptr + 2 * n);
+            abi_ulong target_addr = tgetl(vptr + n);
+            abi_ulong target_addrlen = tgetl(vptr + 2 * n);
             ret = do_accept(sockfd, target_addr, target_addrlen);
         }
         break;
     case SOCKOP_getsockname:
         {
             int sockfd = tgetl(vptr);
-            target_ulong target_addr = tgetl(vptr + n);
-            target_ulong target_addrlen = tgetl(vptr + 2 * n);
+            abi_ulong target_addr = tgetl(vptr + n);
+            abi_ulong target_addrlen = tgetl(vptr + 2 * n);
             ret = do_getsockname(sockfd, target_addr, target_addrlen);
         }
         break;
     case SOCKOP_getpeername:
         {
             int sockfd = tgetl(vptr);
-            target_ulong target_addr = tgetl(vptr + n);
-            target_ulong target_addrlen = tgetl(vptr + 2 * n);
+            abi_ulong target_addr = tgetl(vptr + n);
+            abi_ulong target_addrlen = tgetl(vptr + 2 * n);
             ret = do_getpeername(sockfd, target_addr, target_addrlen);
         }
         break;
@@ -1148,14 +1227,14 @@
             int domain = tgetl(vptr);
             int type = tgetl(vptr + n);
             int protocol = tgetl(vptr + 2 * n);
-            target_ulong tab = tgetl(vptr + 3 * n);
+            abi_ulong tab = tgetl(vptr + 3 * n);
             ret = do_socketpair(domain, type, protocol, tab);
         }
         break;
     case SOCKOP_send:
         {
             int sockfd = tgetl(vptr);
-            target_ulong msg = tgetl(vptr + n);
+            abi_ulong msg = tgetl(vptr + n);
             size_t len = tgetl(vptr + 2 * n);
             int flags = tgetl(vptr + 3 * n);
             ret = do_sendto(sockfd, msg, len, flags, 0, 0);
@@ -1164,7 +1243,7 @@
     case SOCKOP_recv:
         {
             int sockfd = tgetl(vptr);
-            target_ulong msg = tgetl(vptr + n);
+            abi_ulong msg = tgetl(vptr + n);
             size_t len = tgetl(vptr + 2 * n);
             int flags = tgetl(vptr + 3 * n);
             ret = do_recvfrom(sockfd, msg, len, flags, 0, 0);
@@ -1173,10 +1252,10 @@
     case SOCKOP_sendto:
         {
             int sockfd = tgetl(vptr);
-            target_ulong msg = tgetl(vptr + n);
+            abi_ulong msg = tgetl(vptr + n);
             size_t len = tgetl(vptr + 2 * n);
             int flags = tgetl(vptr + 3 * n);
-            target_ulong addr = tgetl(vptr + 4 * n);
+            abi_ulong addr = tgetl(vptr + 4 * n);
             socklen_t addrlen = tgetl(vptr + 5 * n);
             ret = do_sendto(sockfd, msg, len, flags, addr, addrlen);
         }
@@ -1184,11 +1263,11 @@
     case SOCKOP_recvfrom:
         {
             int sockfd = tgetl(vptr);
-            target_ulong msg = tgetl(vptr + n);
+            abi_ulong msg = tgetl(vptr + n);
             size_t len = tgetl(vptr + 2 * n);
             int flags = tgetl(vptr + 3 * n);
-            target_ulong addr = tgetl(vptr + 4 * n);
-            target_ulong addrlen = tgetl(vptr + 5 * n);
+            abi_ulong addr = tgetl(vptr + 4 * n);
+            abi_ulong addrlen = tgetl(vptr + 5 * n);
             ret = do_recvfrom(sockfd, msg, len, flags, addr, addrlen);
         }
         break;
@@ -1204,7 +1283,7 @@
     case SOCKOP_recvmsg:
         {
             int fd;
-            target_ulong target_msg;
+            abi_ulong target_msg;
             int flags;
 
             fd = tgetl(vptr);
@@ -1220,7 +1299,7 @@
             int sockfd = tgetl(vptr);
             int level = tgetl(vptr + n);
             int optname = tgetl(vptr + 2 * n);
-            target_ulong optval = tgetl(vptr + 3 * n);
+            abi_ulong optval = tgetl(vptr + 3 * n);
             socklen_t optlen = tgetl(vptr + 4 * n);
 
             ret = do_setsockopt(sockfd, level, optname, optval, optlen);
@@ -1231,20 +1310,22 @@
             int sockfd = tgetl(vptr);
             int level = tgetl(vptr + n);
             int optname = tgetl(vptr + 2 * n);
-            target_ulong optval = tgetl(vptr + 3 * n);
-            target_ulong poptlen = tgetl(vptr + 4 * n);
+            abi_ulong optval = tgetl(vptr + 3 * n);
+            abi_ulong poptlen = tgetl(vptr + 4 * n);
 
             ret = do_getsockopt(sockfd, level, optname, optval, poptlen);
         }
         break;
     default:
         gemu_log("Unsupported socketcall: %d\n", num);
-        ret = -ENOSYS;
+        ret = -TARGET_ENOSYS;
         break;
     }
     return ret;
 }
+#endif
 
+#ifdef TARGET_NR_ipc
 #define N_SHM_REGIONS	32
 
 static struct shm_region {
@@ -1254,33 +1335,33 @@
 
 struct target_ipc_perm
 {
-    target_long __key;
-    target_ulong uid;
-    target_ulong gid;
-    target_ulong cuid;
-    target_ulong cgid;
+    abi_long __key;
+    abi_ulong uid;
+    abi_ulong gid;
+    abi_ulong cuid;
+    abi_ulong cgid;
     unsigned short int mode;
     unsigned short int __pad1;
     unsigned short int __seq;
     unsigned short int __pad2;
-    target_ulong __unused1;
-    target_ulong __unused2;
+    abi_ulong __unused1;
+    abi_ulong __unused2;
 };
 
 struct target_semid_ds
 {
   struct target_ipc_perm sem_perm;
-  target_ulong sem_otime;
-  target_ulong __unused1;
-  target_ulong sem_ctime;
-  target_ulong __unused2;
-  target_ulong sem_nsems;
-  target_ulong __unused3;
-  target_ulong __unused4;
+  abi_ulong sem_otime;
+  abi_ulong __unused1;
+  abi_ulong sem_ctime;
+  abi_ulong __unused2;
+  abi_ulong sem_nsems;
+  abi_ulong __unused3;
+  abi_ulong __unused4;
 };
 
 static inline void target_to_host_ipc_perm(struct ipc_perm *host_ip,
-                                           target_ulong target_addr)
+                                           abi_ulong target_addr)
 {
     struct target_ipc_perm *target_ip;
     struct target_semid_ds *target_sd;
@@ -1296,7 +1377,7 @@
     unlock_user_struct(target_sd, target_addr, 0);
 }
 
-static inline void host_to_target_ipc_perm(target_ulong target_addr,
+static inline void host_to_target_ipc_perm(abi_ulong target_addr,
                                            struct ipc_perm *host_ip)
 {
     struct target_ipc_perm *target_ip;
@@ -1314,7 +1395,7 @@
 }
 
 static inline void target_to_host_semid_ds(struct semid_ds *host_sd,
-                                          target_ulong target_addr)
+                                          abi_ulong target_addr)
 {
     struct target_semid_ds *target_sd;
 
@@ -1326,7 +1407,7 @@
     unlock_user_struct(target_sd, target_addr, 0);
 }
 
-static inline void host_to_target_semid_ds(target_ulong target_addr,
+static inline void host_to_target_semid_ds(abi_ulong target_addr,
                                            struct semid_ds *host_sd)
 {
     struct target_semid_ds *target_sd;
@@ -1347,13 +1428,13 @@
 
 union target_semun {
 	int val;
-	target_long buf;
+	abi_long buf;
 	unsigned short int *array;
 };
 
-static inline void target_to_host_semun(unsigned long cmd,
+static inline void target_to_host_semun(int cmd,
                                         union semun *host_su,
-                                        target_ulong target_addr,
+                                        abi_ulong target_addr,
                                         struct semid_ds *ds)
 {
     union target_semun *target_su;
@@ -1383,8 +1464,8 @@
     }
 }
 
-static inline void host_to_target_semun(unsigned long cmd,
-                                        target_ulong target_addr,
+static inline void host_to_target_semun(int cmd,
+                                        abi_ulong target_addr,
                                         union semun *host_su,
                                         struct semid_ds *ds)
 {
@@ -1414,12 +1495,13 @@
     }
 }
 
-static inline long do_semctl(long first, long second, long third, long ptr)
+static inline abi_long do_semctl(int first, int second, int third,
+                                 abi_long ptr)
 {
     union semun arg;
     struct semid_ds dsarg;
     int cmd = third&0xff;
-    long ret = 0;
+    abi_long ret = 0;
 
     switch( cmd ) {
 	case GETVAL:
@@ -1462,23 +1544,23 @@
 struct target_msqid_ds
 {
   struct target_ipc_perm msg_perm;
-  target_ulong msg_stime;
-  target_ulong __unused1;
-  target_ulong msg_rtime;
-  target_ulong __unused2;
-  target_ulong msg_ctime;
-  target_ulong __unused3;
-  target_ulong __msg_cbytes;
-  target_ulong msg_qnum;
-  target_ulong msg_qbytes;
-  target_ulong msg_lspid;
-  target_ulong msg_lrpid;
-  target_ulong __unused4;
-  target_ulong __unused5;
+  abi_ulong msg_stime;
+  abi_ulong __unused1;
+  abi_ulong msg_rtime;
+  abi_ulong __unused2;
+  abi_ulong msg_ctime;
+  abi_ulong __unused3;
+  abi_ulong __msg_cbytes;
+  abi_ulong msg_qnum;
+  abi_ulong msg_qbytes;
+  abi_ulong msg_lspid;
+  abi_ulong msg_lrpid;
+  abi_ulong __unused4;
+  abi_ulong __unused5;
 };
 
 static inline void target_to_host_msqid_ds(struct msqid_ds *host_md,
-                                          target_ulong target_addr)
+                                           abi_ulong target_addr)
 {
     struct target_msqid_ds *target_md;
 
@@ -1495,7 +1577,7 @@
     unlock_user_struct(target_md, target_addr, 0);
 }
 
-static inline void host_to_target_msqid_ds(target_ulong target_addr,
+static inline void host_to_target_msqid_ds(abi_ulong target_addr,
                                            struct msqid_ds *host_md)
 {
     struct target_msqid_ds *target_md;
@@ -1513,11 +1595,11 @@
     unlock_user_struct(target_md, target_addr, 1);
 }
 
-static inline long do_msgctl(long first, long second, long ptr)
+static inline abi_long do_msgctl(int first, int second, abi_long ptr)
 {
     struct msqid_ds dsarg;
     int cmd = second&0xff;
-    long ret = 0;
+    abi_long ret = 0;
     switch( cmd ) {
     case IPC_STAT:
     case IPC_SET:
@@ -1531,15 +1613,16 @@
 }
 
 struct target_msgbuf {
-	target_ulong mtype;
+	abi_ulong mtype;
 	char	mtext[1];
 };
 
-static inline long do_msgsnd(long msqid, long msgp, long msgsz, long msgflg)
+static inline abi_long do_msgsnd(int msqid, abi_long msgp,
+                                 unsigned int msgsz, int msgflg)
 {
     struct target_msgbuf *target_mb;
     struct msgbuf *host_mb;
-    long ret = 0;
+    abi_long ret = 0;
 
     lock_user_struct(target_mb,msgp,0);
     host_mb = malloc(msgsz+sizeof(long));
@@ -1552,11 +1635,13 @@
     return ret;
 }
 
-static inline long do_msgrcv(long msqid, long msgp, long msgsz, long msgtype, long msgflg)
+static inline abi_long do_msgrcv(int msqid, abi_long msgp,
+                                 unsigned int msgsz, int msgtype,
+                                 int msgflg)
 {
     struct target_msgbuf *target_mb;
     struct msgbuf *host_mb;
-    long ret = 0;
+    abi_long ret = 0;
 
     lock_user_struct(target_mb, msgp, 0);
     host_mb = malloc(msgsz+sizeof(long));
@@ -1571,11 +1656,13 @@
 }
 
 /* ??? This only works with linear mappings.  */
-static long do_ipc(long call, long first, long second, long third,
-		   long ptr, long fifth)
+/* do_ipc() must return target values and target errnos. */
+static abi_long do_ipc(unsigned int call, int first,
+                       int second, int third,
+                       abi_long ptr, abi_long fifth)
 {
     int version;
-    long ret = 0;
+    abi_long ret = 0;
     unsigned long raddr;
     struct shmid_ds shm_info;
     int i;
@@ -1597,8 +1684,8 @@
         break;
 
     case IPCOP_semtimedop:
-        gemu_log("Unsupported ipc call: %ld (version %d)\n", call, version);
-        ret = -ENOSYS;
+        gemu_log("Unsupported ipc call: %d (version %d)\n", call, version);
+        ret = -TARGET_ENOSYS;
         break;
 
 	case IPCOP_msgget:
@@ -1653,8 +1740,8 @@
                 break;
 	    }
 	}
-	if (put_user(raddr, (uint32_t *)third))
-            return -EFAULT;
+	if (put_user(raddr, (abi_ulong *)third))
+            return -TARGET_EFAULT;
         ret = 0;
 	break;
     case IPCOP_shmdt:
@@ -1687,12 +1774,13 @@
         break;
     default:
     unimplemented:
-	gemu_log("Unsupported ipc call: %ld (version %d)\n", call, version);
-	ret = -ENOSYS;
+	gemu_log("Unsupported ipc call: %d (version %d)\n", call, version);
+	ret = -TARGET_ENOSYS;
 	break;
     }
     return ret;
 }
+#endif
 
 /* kernel structure types definitions */
 #define IFNAMSIZ        16
@@ -1733,11 +1821,12 @@
 };
 
 /* ??? Implement proper locking for ioctls.  */
-static long do_ioctl(long fd, long cmd, long arg)
+/* do_ioctl() Must return target values and target errnos. */
+static abi_long do_ioctl(int fd, abi_long cmd, abi_long arg)
 {
     const IOCTLEntry *ie;
     const argtype *arg_type;
-    long ret;
+    abi_long ret;
     uint8_t buf_temp[MAX_STRUCT_SIZE];
     int target_size;
     void *argptr;
@@ -1745,8 +1834,8 @@
     ie = ioctl_entries;
     for(;;) {
         if (ie->target_cmd == 0) {
-            gemu_log("Unsupported ioctl: cmd=0x%04lx\n", cmd);
-            return -ENOSYS;
+            gemu_log("Unsupported ioctl: cmd=0x%04lx\n", (long)cmd);
+            return -TARGET_ENOSYS;
         }
         if (ie->target_cmd == cmd)
             break;
@@ -1754,7 +1843,7 @@
     }
     arg_type = ie->arg_type;
 #if defined(DEBUG)
-    gemu_log("ioctl: cmd=0x%04lx (%s)\n", cmd, ie->name);
+    gemu_log("ioctl: cmd=0x%04lx (%s)\n", (long)cmd, ie->name);
 #endif
     switch(arg_type[0]) {
     case TYPE_NULL:
@@ -1799,8 +1888,9 @@
         }
         break;
     default:
-        gemu_log("Unsupported ioctl type: cmd=0x%04lx type=%d\n", cmd, arg_type[0]);
-        ret = -ENOSYS;
+        gemu_log("Unsupported ioctl type: cmd=0x%04lx type=%d\n",
+                 (long)cmd, arg_type[0]);
+        ret = -TARGET_ENOSYS;
         break;
     }
     return ret;
@@ -2017,7 +2107,7 @@
 /* NOTE: there is really one LDT for all the threads */
 uint8_t *ldt_table;
 
-static int read_ldt(target_ulong ptr, unsigned long bytecount)
+static int read_ldt(abi_ulong ptr, unsigned long bytecount)
 {
     int size;
     void *p;
@@ -2035,8 +2125,9 @@
 }
 
 /* XXX: add locking support */
+/* write_ldt() returns host errnos */
 static int write_ldt(CPUX86State *env,
-                     target_ulong ptr, unsigned long bytecount, int oldmode)
+                     abi_ulong ptr, unsigned long bytecount, int oldmode)
 {
     struct target_modify_ldt_ldt_s ldt_info;
     struct target_modify_ldt_ldt_s *target_ldt_info;
@@ -2117,7 +2208,9 @@
 }
 
 /* specific and weird i386 syscalls */
-int do_modify_ldt(CPUX86State *env, int func, target_ulong ptr, unsigned long bytecount)
+/* do_modify_ldt() returns host errnos (it is inconsistent with the
+   other do_*() functions which return target errnos). */
+int do_modify_ldt(CPUX86State *env, int func, abi_ulong ptr, unsigned long bytecount)
 {
     int ret = -ENOSYS;
 
@@ -2149,7 +2242,9 @@
     return 0;
 }
 
-int do_fork(CPUState *env, unsigned int flags, unsigned long newsp)
+/* do_fork() Must return host values and target errnos (unlike most
+   do_*() functions). */
+int do_fork(CPUState *env, unsigned int flags, abi_ulong newsp)
 {
     int ret;
     TaskState *ts;
@@ -2217,6 +2312,10 @@
             for (i = 7; i < 30; i++)
                 new_env->ir[i] = 0;
         }
+#elif defined(TARGET_CRIS)
+	if (!newsp)
+	  newsp = env->regs[14];
+	new_env->regs[14] = newsp;
 #else
 #error unsupported target CPU
 #endif
@@ -2235,13 +2334,13 @@
     return ret;
 }
 
-static long do_fcntl(int fd, int cmd, target_ulong arg)
+static abi_long do_fcntl(int fd, int cmd, abi_ulong arg)
 {
     struct flock fl;
     struct target_flock *target_fl;
     struct flock64 fl64;
     struct target_flock64 *target_fl64;
-    long ret;
+    abi_long ret;
 
     switch(cmd) {
     case TARGET_F_GETLK:
@@ -2400,6 +2499,7 @@
     }
 }
 
+#if TARGET_ABI_BITS == 32
 static inline uint64_t target_offset64(uint32_t word0, uint32_t word1)
 {
 #ifdef TARGET_WORDS_BIG_ENDIAN
@@ -2408,10 +2508,18 @@
     return ((uint64_t)word1 << 32) | word0;
 #endif
 }
+#else /* TARGET_ABI_BITS == 32 */
+static inline uint64_t target_offset64(uint64_t word0, uint64_t word1)
+{
+    return word0;
+}
+#endif /* TARGET_ABI_BITS != 32 */
 
 #ifdef TARGET_NR_truncate64
-static inline long target_truncate64(void *cpu_env, const char *arg1,
-                                     long arg2, long arg3, long arg4)
+static inline abi_long target_truncate64(void *cpu_env, const char *arg1,
+                                         abi_long arg2,
+                                         abi_long arg3,
+                                         abi_long arg4)
 {
 #ifdef TARGET_ARM
     if (((CPUARMState *)cpu_env)->eabi)
@@ -2425,8 +2533,10 @@
 #endif
 
 #ifdef TARGET_NR_ftruncate64
-static inline long target_ftruncate64(void *cpu_env, long arg1, long arg2,
-                                      long arg3, long arg4)
+static inline abi_long target_ftruncate64(void *cpu_env, abi_long arg1,
+                                          abi_long arg2,
+                                          abi_long arg3,
+                                          abi_long arg4)
 {
 #ifdef TARGET_ARM
     if (((CPUARMState *)cpu_env)->eabi)
@@ -2440,7 +2550,7 @@
 #endif
 
 static inline void target_to_host_timespec(struct timespec *host_ts,
-                                           target_ulong target_addr)
+                                           abi_ulong target_addr)
 {
     struct target_timespec *target_ts;
 
@@ -2450,7 +2560,7 @@
     unlock_user_struct(target_ts, target_addr, 0);
 }
 
-static inline void host_to_target_timespec(target_ulong target_addr,
+static inline void host_to_target_timespec(abi_ulong target_addr,
                                            struct timespec *host_ts)
 {
     struct target_timespec *target_ts;
@@ -2461,10 +2571,14 @@
     unlock_user_struct(target_ts, target_addr, 1);
 }
 
-long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
-                long arg4, long arg5, long arg6)
+/* do_syscall() should always have a single exit point at the end so
+   that actions, such as logging of syscall results, can be performed.
+   All errnos that do_syscall() returns must be -TARGET_<errcode>. */
+abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
+                    abi_long arg2, abi_long arg3, abi_long arg4,
+                    abi_long arg5, abi_long arg6)
 {
-    long ret;
+    abi_long ret;
     struct stat st;
     struct statfs stfs;
     void *p;
@@ -2500,6 +2614,25 @@
                              arg3));
         unlock_user(p, arg1, 0);
         break;
+#if defined(TARGET_NR_openat) && defined(__NR_openat)
+    case TARGET_NR_openat:
+        if (!arg2) {
+            ret = -TARGET_EFAULT;
+            goto fail;
+        }
+        p = lock_user_string(arg2);
+        if (!access_ok(VERIFY_READ, p, 1))
+            /* Don't "goto fail" so that cleanup can happen. */
+            ret = -TARGET_EFAULT;
+        else
+            ret = get_errno(sys_openat(arg1,
+                                       path(p),
+                                       target_to_host_bitmask(arg3, fcntl_flags_tbl),
+                                       arg4));
+        if (p)
+            unlock_user(p, arg2, 0);
+        break;
+#endif
     case TARGET_NR_close:
         ret = get_errno(close(arg1));
         break;
@@ -2536,19 +2669,58 @@
             unlock_user(p, arg1, 0);
         }
         break;
+#if defined(TARGET_NR_linkat) && defined(__NR_linkat)
+    case TARGET_NR_linkat:
+        if (!arg2 || !arg4) {
+            ret = -TARGET_EFAULT;
+            goto fail;
+        }
+        {
+            void * p2 = NULL;
+            p  = lock_user_string(arg2);
+            p2 = lock_user_string(arg4);
+            if (!access_ok(VERIFY_READ, p, 1)
+                || !access_ok(VERIFY_READ, p2, 1))
+                /* Don't "goto fail" so that cleanup can happen. */
+                ret = -TARGET_EFAULT;
+            else
+                ret = get_errno(sys_linkat(arg1, p, arg3, p2, arg5));
+            if (p2)
+                unlock_user(p, arg2, 0);
+            if (p)
+                unlock_user(p2, arg4, 0);
+        }
+        break;
+#endif
     case TARGET_NR_unlink:
         p = lock_user_string(arg1);
         ret = get_errno(unlink(p));
         unlock_user(p, arg1, 0);
         break;
+#if defined(TARGET_NR_unlinkat) && defined(__NR_unlinkat)
+    case TARGET_NR_unlinkat:
+        if (!arg2) {
+            ret = -TARGET_EFAULT;
+            goto fail;
+        }
+        p = lock_user_string(arg2);
+        if (!access_ok(VERIFY_READ, p, 1))
+            /* Don't "goto fail" so that cleanup can happen. */
+            ret = -TARGET_EFAULT;
+        else
+            ret = get_errno(sys_unlinkat(arg1, p, arg3));
+        if (p)
+            unlock_user(p, arg2, 0);
+        break;
+#endif
     case TARGET_NR_execve:
         {
             char **argp, **envp;
             int argc, envc;
-            target_ulong gp;
-            target_ulong guest_argp;
-            target_ulong guest_envp;
-            target_ulong addr;
+            abi_ulong gp;
+            abi_ulong guest_argp;
+            abi_ulong guest_envp;
+            abi_ulong addr;
             char **q;
 
             argc = 0;
@@ -2564,7 +2736,7 @@
             envp = alloca((envc + 1) * sizeof(void *));
 
             for (gp = guest_argp, q = argp; ;
-                  gp += sizeof(target_ulong), q++) {
+                  gp += sizeof(abi_ulong), q++) {
                 addr = tgetl(gp);
                 if (!addr)
                     break;
@@ -2573,7 +2745,7 @@
             *q = NULL;
 
             for (gp = guest_envp, q = envp; ;
-                  gp += sizeof(target_ulong), q++) {
+                  gp += sizeof(abi_ulong), q++) {
                 addr = tgetl(gp);
                 if (!addr)
                     break;
@@ -2586,12 +2758,12 @@
             unlock_user(p, arg1, 0);
 
             for (gp = guest_argp, q = argp; *q;
-                  gp += sizeof(target_ulong), q++) {
+                  gp += sizeof(abi_ulong), q++) {
                 addr = tgetl(gp);
                 unlock_user(*q, addr, 0);
             }
             for (gp = guest_envp, q = envp; *q;
-                  gp += sizeof(target_ulong), q++) {
+                  gp += sizeof(abi_ulong), q++) {
                 addr = tgetl(gp);
                 unlock_user(*q, addr, 0);
             }
@@ -2617,6 +2789,22 @@
         ret = get_errno(mknod(p, arg2, arg3));
         unlock_user(p, arg1, 0);
         break;
+#if defined(TARGET_NR_mknodat) && defined(__NR_mknodat)
+    case TARGET_NR_mknodat:
+        if (!arg2) {
+            ret = -TARGET_EFAULT;
+            goto fail;
+        }
+        p = lock_user_string(arg2);
+        if (!access_ok(VERIFY_READ, p, 1))
+            /* Don't "goto fail" so that cleanup can happen. */
+            ret = -TARGET_EFAULT;
+        else
+            ret = get_errno(sys_mknodat(arg1, p, arg3, arg4));
+        if (p)
+            unlock_user(p, arg2, 0);
+        break;
+#endif
     case TARGET_NR_chmod:
         p = lock_user_string(arg1);
         ret = get_errno(chmod(p, arg2));
@@ -2734,6 +2922,22 @@
         ret = get_errno(access(p, arg2));
         unlock_user(p, arg1, 0);
         break;
+#if defined(TARGET_NR_faccessat) && defined(__NR_faccessat)
+    case TARGET_NR_faccessat:
+        if (!arg2) {
+            ret = -TARGET_EFAULT;
+            goto fail;
+        }
+        p = lock_user_string(arg2);
+        if (!access_ok(VERIFY_READ, p, 1))
+            /* Don't "goto fail" so that cleanup can happen. */
+    	    ret = -TARGET_EFAULT;
+        else
+            ret = get_errno(sys_faccessat(arg1, p, arg3, arg4));
+        if (p)
+            unlock_user(p, arg2, 0);
+        break;
+#endif
 #ifdef TARGET_NR_nice /* not on alpha */
     case TARGET_NR_nice:
         ret = get_errno(nice(arg1));
@@ -2760,11 +2964,50 @@
             unlock_user(p, arg1, 0);
         }
         break;
+#if defined(TARGET_NR_renameat) && defined(__NR_renameat)
+    case TARGET_NR_renameat:
+        if (!arg2 || !arg4) {
+            ret = -TARGET_EFAULT;
+            goto fail;
+        }
+        {
+            void *p2 = NULL;
+            p  = lock_user_string(arg2);
+            p2 = lock_user_string(arg4);
+            if (!access_ok(VERIFY_READ, p, 1)
+                || !access_ok(VERIFY_READ, p2, 1))
+                /* Don't "goto fail" so that cleanup can happen. */
+                ret = -TARGET_EFAULT;
+            else
+                ret = get_errno(sys_renameat(arg1, p, arg3, p2));
+            if (p2)
+                unlock_user(p2, arg4, 0);
+            if (p)
+                unlock_user(p, arg2, 0);
+        }
+        break;
+#endif
     case TARGET_NR_mkdir:
         p = lock_user_string(arg1);
         ret = get_errno(mkdir(p, arg2));
         unlock_user(p, arg1, 0);
         break;
+#if defined(TARGET_NR_mkdirat) && defined(__NR_mkdirat)
+    case TARGET_NR_mkdirat:
+        if (!arg2) {
+            ret = -TARGET_EFAULT;
+            goto fail;
+        }
+        p = lock_user_string(arg2);
+        if (!access_ok(VERIFY_READ, p, 1))
+            /* Don't "goto fail" so that cleanup can happen. */
+            ret = -TARGET_EFAULT;
+        else
+            ret = get_errno(sys_mkdirat(arg1, p, arg3));
+        if (p)
+            unlock_user(p, arg2, 0);
+        break;
+#endif
     case TARGET_NR_rmdir:
         p = lock_user_string(arg1);
         ret = get_errno(rmdir(p));
@@ -2954,7 +3197,7 @@
     case TARGET_NR_sgetmask:
         {
             sigset_t cur_set;
-            target_ulong target_set;
+            abi_ulong target_set;
             sigprocmask(0, NULL, &cur_set);
             host_to_target_old_sigset(&target_set, &cur_set);
             ret = target_set;
@@ -2965,7 +3208,7 @@
     case TARGET_NR_ssetmask:
         {
             sigset_t set, oset, cur_set;
-            target_ulong target_set = arg1;
+            abi_ulong target_set = arg1;
             sigprocmask(0, NULL, &cur_set);
             target_to_host_old_sigset(&set, &target_set);
             sigorset(&set, &set, &cur_set);
@@ -2993,7 +3236,7 @@
                     how = SIG_SETMASK;
                     break;
                 default:
-                    ret = -EINVAL;
+                    ret = -TARGET_EINVAL;
                     goto fail;
                 }
                 p = lock_user(arg2, sizeof(target_sigset_t), 1);
@@ -3030,7 +3273,7 @@
                     how = SIG_SETMASK;
                     break;
                 default:
-                    ret = -EINVAL;
+                    ret = -TARGET_EINVAL;
                     goto fail;
                 }
                 p = lock_user(arg2, sizeof(target_sigset_t), 1);
@@ -3198,7 +3441,7 @@
     case TARGET_NR_select:
         {
             struct target_sel_arg_struct *sel;
-            target_ulong inp, outp, exp, tvp;
+            abi_ulong inp, outp, exp, tvp;
             long nsel;
 
             lock_user_struct(sel, arg1, 1);
@@ -3222,6 +3465,29 @@
             unlock_user(p, arg1, 0);
         }
         break;
+#if defined(TARGET_NR_symlinkat) && defined(__NR_symlinkat)
+    case TARGET_NR_symlinkat:
+        if (!arg1 || !arg3) {
+            ret = -TARGET_EFAULT;
+            goto fail;
+        }
+        {
+            void *p2 = NULL;
+            p  = lock_user_string(arg1);
+            p2 = lock_user_string(arg3);
+            if (!access_ok(VERIFY_READ, p, 1)
+                || !access_ok(VERIFY_READ, p2, 1))
+                /* Don't "goto fail" so that cleanup can happen. */
+                ret = -TARGET_EFAULT;
+            else
+                ret = get_errno(sys_symlinkat(p, arg2, p2));
+            if (p2)
+                unlock_user(p2, arg3, 0);
+            if (p)
+                unlock_user(p, arg1, 0);
+        }
+        break;
+#endif
 #ifdef TARGET_NR_oldlstat
     case TARGET_NR_oldlstat:
         goto unimplemented;
@@ -3236,6 +3502,29 @@
             unlock_user(p, arg1, 0);
         }
         break;
+#if defined(TARGET_NR_readlinkat) && defined(__NR_readlinkat)
+    case TARGET_NR_readlinkat:
+        if (!arg2 || !arg3) {
+            ret = -TARGET_EFAULT;
+            goto fail;
+        }
+        {
+            void *p2 = NULL;
+            p  = lock_user_string(arg2);
+            p2 = lock_user(arg3, arg4, 0);
+            if (!access_ok(VERIFY_READ, p, 1)
+                || !access_ok(VERIFY_READ, p2, 1))
+                /* Don't "goto fail" so that cleanup can happen. */
+        	ret = -TARGET_EFAULT;
+            else
+                ret = get_errno(sys_readlinkat(arg1, path(p), p2, arg4));
+            if (p2)
+                unlock_user(p2, arg3, ret);
+            if (p)
+                unlock_user(p, arg2, 0);
+        }
+        break;
+#endif
 #ifdef TARGET_NR_uselib
     case TARGET_NR_uselib:
         goto unimplemented;
@@ -3255,11 +3544,11 @@
 #endif
 #ifdef TARGET_NR_mmap
     case TARGET_NR_mmap:
-#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_M68K)
+#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_M68K) || defined(TARGET_CRIS)
         {
-            target_ulong *v;
-            target_ulong v1, v2, v3, v4, v5, v6;
-            v = lock_user(arg1, 6 * sizeof(target_ulong), 1);
+            abi_ulong *v;
+            abi_ulong v1, v2, v3, v4, v5, v6;
+            v = lock_user(arg1, 6 * sizeof(abi_ulong), 1);
             v1 = tswapl(v[0]);
             v2 = tswapl(v[1]);
             v3 = tswapl(v[2]);
@@ -3340,8 +3629,27 @@
     case TARGET_NR_fchmod:
         ret = get_errno(fchmod(arg1, arg2));
         break;
+#if defined(TARGET_NR_fchmodat) && defined(__NR_fchmodat)
+    case TARGET_NR_fchmodat:
+        if (!arg2) {
+            ret = -TARGET_EFAULT;
+            goto fail;
+        }
+        p = lock_user_string(arg2);
+        if (!access_ok(VERIFY_READ, p, 1))
+            /* Don't "goto fail" so that cleanup can happen. */
+            ret = -TARGET_EFAULT;
+        else
+            ret = get_errno(sys_fchmodat(arg1, p, arg3, arg4));
+        if (p)
+            unlock_user(p, arg2, 0);
+        break;
+#endif
     case TARGET_NR_getpriority:
-        ret = get_errno(getpriority(arg1, arg2));
+        /* libc does special remapping of the return value of
+         * sys_getpriority() so it's just easiest to call
+         * sys_getpriority() directly rather than through libc. */
+        ret = sys_getpriority(arg1, arg2);
         break;
     case TARGET_NR_setpriority:
         ret = get_errno(setpriority(arg1, arg2, arg3));
@@ -3558,7 +3866,7 @@
                 struct target_stat *target_st;
 
                 lock_user_struct(target_st, arg2, 0);
-#if defined(TARGET_MIPS) || defined(TARGET_SPARC64)
+#if defined(TARGET_MIPS) || (defined(TARGET_SPARC64) && !defined(TARGET_ABI32))
                 target_st->st_dev = tswap32(st.st_dev);
 #else
                 target_st->st_dev = tswap16(st.st_dev);
@@ -3568,7 +3876,7 @@
                 target_st->st_mode = tswapl(st.st_mode); /* XXX: check this */
                 target_st->st_uid = tswap32(st.st_uid);
                 target_st->st_gid = tswap32(st.st_gid);
-#elif defined(TARGET_SPARC64)
+#elif defined(TARGET_SPARC64) && !defined(TARGET_ABI32)
                 target_st->st_mode = tswap32(st.st_mode);
                 target_st->st_uid = tswap32(st.st_uid);
                 target_st->st_gid = tswap32(st.st_gid);
@@ -3581,7 +3889,7 @@
 		/* If this is the same on PPC, then just merge w/ the above ifdef */
                 target_st->st_nlink = tswapl(st.st_nlink);
                 target_st->st_rdev = tswapl(st.st_rdev);
-#elif defined(TARGET_SPARC64)
+#elif defined(TARGET_SPARC64) && !defined(TARGET_ABI32)
                 target_st->st_nlink = tswap32(st.st_nlink);
                 target_st->st_rdev = tswap32(st.st_rdev);
 #else
@@ -3621,9 +3929,9 @@
     case TARGET_NR_wait4:
         {
             int status;
-            target_long status_ptr = arg2;
+            abi_long status_ptr = arg2;
             struct rusage rusage, *rusage_ptr;
-            target_ulong target_rusage = arg4;
+            abi_ulong target_rusage = arg4;
             if (target_rusage)
                 rusage_ptr = &rusage;
             else
@@ -3774,18 +4082,20 @@
         break;
 #endif
     case TARGET_NR_getdents:
-#if TARGET_LONG_SIZE != 4
+#if TARGET_ABI_BITS != 32
         goto unimplemented;
 #warning not supported
-#elif TARGET_LONG_SIZE == 4 && HOST_LONG_SIZE == 8
+#elif TARGET_ABI_BITS == 32 && HOST_LONG_BITS == 64
         {
             struct target_dirent *target_dirp;
             struct dirent *dirp;
-            long count = arg3;
+            abi_long count = arg3;
 
 	    dirp = malloc(count);
-	    if (!dirp)
-                return -ENOMEM;
+	    if (!dirp) {
+                ret = -TARGET_EFAULT;
+                goto fail;
+            }
 
             ret = get_errno(sys_getdents(arg1, dirp, count));
             if (!is_error(ret)) {
@@ -3801,11 +4111,11 @@
 		tde = target_dirp;
                 while (len > 0) {
                     reclen = de->d_reclen;
-		    treclen = reclen - (2 * (sizeof(long) - sizeof(target_long)));
+		    treclen = reclen - (2 * (sizeof(long) - sizeof(abi_long)));
                     tde->d_reclen = tswap16(treclen);
                     tde->d_ino = tswapl(de->d_ino);
                     tde->d_off = tswapl(de->d_off);
-		    tnamelen = treclen - (2 * sizeof(target_long) + 2);
+		    tnamelen = treclen - (2 * sizeof(abi_long) + 2);
 		    if (tnamelen > 256)
                         tnamelen = 256;
                     /* XXX: may not be correct */
@@ -3823,7 +4133,7 @@
 #else
         {
             struct dirent *dirp;
-            long count = arg3;
+            abi_long count = arg3;
 
             dirp = lock_user(arg2, count, 0);
             ret = get_errno(sys_getdents(arg1, dirp, count));
@@ -3851,7 +4161,7 @@
     case TARGET_NR_getdents64:
         {
             struct dirent64 *dirp;
-            long count = arg3;
+            abi_long count = arg3;
             dirp = lock_user(arg2, count, 0);
             ret = get_errno(sys_getdents64(arg1, dirp, count));
             if (!is_error(ret)) {
@@ -3942,9 +4252,10 @@
         break;
 #endif
     case TARGET_NR__sysctl:
-        /* We don't implement this, but ENODIR is always a safe
+        /* We don't implement this, but ENOTDIR is always a safe
            return value. */
-        return -ENOTDIR;
+        ret = -TARGET_ENOTDIR;
+        break;
     case TARGET_NR_sched_setparam:
         {
             struct sched_param *target_schp;
@@ -4056,7 +4367,15 @@
     case TARGET_NR_capset:
         goto unimplemented;
     case TARGET_NR_sigaltstack:
+#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_MIPS) || \
+    defined(TARGET_SPARC) || defined(TARGET_PPC) || defined(TARGET_ALPHA)
+        ret = do_sigaltstack((struct target_sigaltstack *)arg1,
+                             (struct target_sigaltstack *)arg2,
+                             get_sp_from_cpustate((CPUState *)cpu_env));
+        break;
+#else
         goto unimplemented;
+#endif
     case TARGET_NR_sendfile:
         goto unimplemented;
 #ifdef TARGET_NR_getpmsg
@@ -4232,6 +4551,22 @@
     case TARGET_NR_fchown:
         ret = get_errno(fchown(arg1, low2highuid(arg2), low2highgid(arg3)));
         break;
+#if defined(TARGET_NR_fchownat) && defined(__NR_fchownat)
+    case TARGET_NR_fchownat:
+        if (!arg2) {
+            ret = -TARGET_EFAULT;
+            goto fail;
+        }
+        p = lock_user_string(arg2);
+        if (!access_ok(VERIFY_READ, p, 1))
+            /* Don't "goto fail" so that cleanup can happen. */
+            ret = -TARGET_EFAULT;
+	else
+            ret = get_errno(sys_fchownat(arg1, p, low2highuid(arg3), low2highgid(arg4), arg5));
+        if (p)
+            unlock_user(p, arg2, 0);
+        break;
+#endif
 #ifdef TARGET_NR_setresuid
     case TARGET_NR_setresuid:
         ret = get_errno(setresuid(low2highuid(arg1),
@@ -4448,7 +4783,7 @@
         ret = get_errno(0);
         break;
 #endif
-#if TARGET_LONG_BITS == 32
+#if TARGET_ABI_BITS == 32
     case TARGET_NR_fcntl64:
     {
 	int cmd;
@@ -4653,13 +4988,35 @@
 	goto unimplemented_nowarn;
 #endif
 
+#if defined(TARGET_NR_utimensat) && defined(__NR_utimensat)
+    case TARGET_NR_utimensat:
+        {
+            struct timespec ts[2];
+            target_to_host_timespec(ts, arg3);
+            target_to_host_timespec(ts+1, arg3+sizeof(struct target_timespec));
+            if (!arg2)
+                ret = get_errno(sys_utimensat(arg1, NULL, ts, arg4));
+            else {
+                p = lock_user_string(arg2);
+                if (!access_ok(VERIFY_READ, p, 1))
+                    /* Don't "goto fail" so that cleanup can happen. */
+                    ret = -TARGET_EFAULT;
+                else
+                    ret = get_errno(sys_utimensat(arg1, path(p), ts, arg4));
+                if (p)
+                    unlock_user(p, arg2, 0);
+            }
+        }
+	break;
+#endif
+
     default:
     unimplemented:
         gemu_log("qemu: Unsupported syscall: %d\n", num);
 #if defined(TARGET_NR_setxattr) || defined(TARGET_NR_get_thread_area) || defined(TARGET_NR_getdomainname) || defined(TARGET_NR_set_robust_list)
     unimplemented_nowarn:
 #endif
-        ret = -ENOSYS;
+        ret = -TARGET_ENOSYS;
         break;
     }
  fail:
@@ -4668,4 +5025,3 @@
 #endif
     return ret;
 }
-

Modified: trunk/src/host/qemu-neo1973/linux-user/syscall_defs.h
===================================================================
--- trunk/src/host/qemu-neo1973/linux-user/syscall_defs.h	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/linux-user/syscall_defs.h	2007-10-29 21:14:04 UTC (rev 3303)
@@ -49,7 +49,7 @@
 #define TARGET_IOC_TYPEBITS	8
 
 #if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SH4) \
-    || defined(TARGET_M68K) || defined(TARGET_ALPHA)
+    || defined(TARGET_M68K) || defined(TARGET_ALPHA) || defined(TARGET_CRIS)
 
 #define TARGET_IOC_SIZEBITS	14
 #define TARGET_IOC_DIRBITS	2
@@ -105,13 +105,13 @@
 };
 
 struct target_timeval {
-    target_long tv_sec;
-    target_long tv_usec;
+    abi_long tv_sec;
+    abi_long tv_usec;
 };
 
 struct target_timespec {
-    target_long tv_sec;
-    target_long tv_nsec;
+    abi_long tv_sec;
+    abi_long tv_nsec;
 };
 
 struct target_itimerval {
@@ -119,7 +119,7 @@
     struct target_timeval it_value;
 };
 
-typedef target_long target_clock_t;
+typedef abi_long target_clock_t;
 
 #define TARGET_HZ 100
 
@@ -131,33 +131,33 @@
 };
 
 struct target_utimbuf {
-    target_long actime;
-    target_long modtime;
+    abi_long actime;
+    abi_long modtime;
 };
 
 struct target_sel_arg_struct {
-    target_long n;
-    target_long inp, outp, exp;
-    target_long tvp;
+    abi_long n;
+    abi_long inp, outp, exp;
+    abi_long tvp;
 };
 
 struct target_iovec {
-    target_long iov_base;   /* Starting address */
-    target_long iov_len;   /* Number of bytes */
+    abi_long iov_base;   /* Starting address */
+    abi_long iov_len;   /* Number of bytes */
 };
 
 struct target_msghdr {
-    target_long	 msg_name;	/* Socket name			*/
-    int		 msg_namelen;	/* Length of name		*/
-    target_long	 msg_iov;	/* Data blocks			*/
-    target_long	 msg_iovlen;	/* Number of blocks		*/
-    target_long  msg_control;	/* Per protocol magic (eg BSD file descriptor passing) */
-    target_long	 msg_controllen;	/* Length of cmsg list */
+    abi_long	 msg_name;	 /* Socket name			*/
+    int		 msg_namelen;	 /* Length of name		*/
+    abi_long	 msg_iov;	 /* Data blocks			*/
+    abi_long	 msg_iovlen;	 /* Number of blocks		*/
+    abi_long     msg_control;	 /* Per protocol magic (eg BSD file descriptor passing) */
+    abi_long	 msg_controllen; /* Length of cmsg list */
     unsigned int msg_flags;
 };
 
 struct target_cmsghdr {
-    target_long  cmsg_len;
+    abi_long     cmsg_len;
     int          cmsg_level;
     int          cmsg_type;
 };
@@ -167,8 +167,8 @@
 #define TARGET_CMSG_FIRSTHDR(mhdr) \
   ((size_t) tswapl((mhdr)->msg_controllen) >= sizeof (struct target_cmsghdr) \
    ? (struct target_cmsghdr *) tswapl((mhdr)->msg_control) : (struct target_cmsghdr *) NULL)
-#define TARGET_CMSG_ALIGN(len) (((len) + sizeof (target_long) - 1) \
-                               & (size_t) ~(sizeof (target_long) - 1))
+#define TARGET_CMSG_ALIGN(len) (((len) + sizeof (abi_long) - 1) \
+                               & (size_t) ~(sizeof (abi_long) - 1))
 #define TARGET_CMSG_SPACE(len) (TARGET_CMSG_ALIGN (len) \
                                + TARGET_CMSG_ALIGN (sizeof (struct target_cmsghdr)))
 #define TARGET_CMSG_LEN(len)   (TARGET_CMSG_ALIGN (sizeof (struct target_cmsghdr)) + (len))
@@ -191,20 +191,20 @@
 struct  target_rusage {
         struct target_timeval ru_utime;        /* user time used */
         struct target_timeval ru_stime;        /* system time used */
-        target_long    ru_maxrss;              /* maximum resident set size */
-        target_long    ru_ixrss;               /* integral shared memory size */
-        target_long    ru_idrss;               /* integral unshared data size */
-        target_long    ru_isrss;               /* integral unshared stack size */
-        target_long    ru_minflt;              /* page reclaims */
-        target_long    ru_majflt;              /* page faults */
-        target_long    ru_nswap;               /* swaps */
-        target_long    ru_inblock;             /* block input operations */
-        target_long    ru_oublock;             /* block output operations */
-        target_long    ru_msgsnd;              /* messages sent */
-        target_long    ru_msgrcv;              /* messages received */
-        target_long    ru_nsignals;            /* signals received */
-        target_long    ru_nvcsw;               /* voluntary context switches */
-        target_long    ru_nivcsw;              /* involuntary " */
+        abi_long    ru_maxrss;                 /* maximum resident set size */
+        abi_long    ru_ixrss;                  /* integral shared memory size */
+        abi_long    ru_idrss;                  /* integral unshared data size */
+        abi_long    ru_isrss;                  /* integral unshared stack size */
+        abi_long    ru_minflt;                 /* page reclaims */
+        abi_long    ru_majflt;                 /* page faults */
+        abi_long    ru_nswap;                  /* swaps */
+        abi_long    ru_inblock;                /* block input operations */
+        abi_long    ru_oublock;                /* block output operations */
+        abi_long    ru_msgsnd;                 /* messages sent */
+        abi_long    ru_msgrcv;                 /* messages received */
+        abi_long    ru_nsignals;               /* signals received */
+        abi_long    ru_nvcsw;                  /* voluntary context switches */
+        abi_long    ru_nivcsw;                 /* involuntary " */
 };
 
 typedef struct {
@@ -225,8 +225,8 @@
 };
 
 struct target_dirent {
-	target_long	d_ino;
-	target_long	d_off;
+	abi_long	d_ino;
+	abi_long	d_off;
 	unsigned short	d_reclen;
 	char		d_name[256]; /* We must not include limits.h! */
 };
@@ -241,20 +241,20 @@
 
 
 /* mostly generic signal stuff */
-#define TARGET_SIG_DFL	((target_long)0)	/* default signal handling */
-#define TARGET_SIG_IGN	((target_long)1)	/* ignore signal */
-#define TARGET_SIG_ERR	((target_long)-1)	/* error return from signal */
+#define TARGET_SIG_DFL	((abi_long)0)	/* default signal handling */
+#define TARGET_SIG_IGN	((abi_long)1)	/* ignore signal */
+#define TARGET_SIG_ERR	((abi_long)-1)	/* error return from signal */
 
 #ifdef TARGET_MIPS
 #define TARGET_NSIG	   128
 #else
 #define TARGET_NSIG	   64
 #endif
-#define TARGET_NSIG_BPW	   TARGET_LONG_BITS
+#define TARGET_NSIG_BPW	   TARGET_ABI_BITS
 #define TARGET_NSIG_WORDS  (TARGET_NSIG / TARGET_NSIG_BPW)
 
 typedef struct {
-    target_ulong sig[TARGET_NSIG_WORDS];
+    abi_ulong sig[TARGET_NSIG_WORDS];
 } target_sigset_t;
 
 #ifdef BSWAP_NEEDED
@@ -271,7 +271,7 @@
 }
 #endif
 
-static inline void target_siginitset(target_sigset_t *d, target_ulong set)
+static inline void target_siginitset(target_sigset_t *d, abi_ulong set)
 {
     int i;
     d->sig[0] = set;
@@ -281,15 +281,15 @@
 
 void host_to_target_sigset(target_sigset_t *d, const sigset_t *s);
 void target_to_host_sigset(sigset_t *d, const target_sigset_t *s);
-void host_to_target_old_sigset(target_ulong *old_sigset,
+void host_to_target_old_sigset(abi_ulong *old_sigset,
                                const sigset_t *sigset);
 void target_to_host_old_sigset(sigset_t *sigset,
-                               const target_ulong *old_sigset);
+                               const abi_ulong *old_sigset);
 struct target_sigaction;
 int do_sigaction(int sig, const struct target_sigaction *act,
                  struct target_sigaction *oact);
 
-#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SPARC) || defined(TARGET_PPC) || defined(TARGET_MIPS) || defined (TARGET_SH4) || defined(TARGET_M68K) || defined(TARGET_ALPHA)
+#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SPARC) || defined(TARGET_PPC) || defined(TARGET_MIPS) || defined (TARGET_SH4) || defined(TARGET_M68K) || defined(TARGET_ALPHA) || defined(TARGET_CRIS)
 
 #if defined(TARGET_SPARC)
 #define TARGET_SA_NOCLDSTOP    8u
@@ -307,7 +307,9 @@
 #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 */
+#endif
 #else
 #define TARGET_SA_NOCLDSTOP	0x00000001
 #define TARGET_SA_NOCLDWAIT	0x00000002 /* not supported yet */
@@ -447,40 +449,44 @@
 #if defined(TARGET_MIPS)
 
 struct target_sigaction {
-	target_ulong	sa_flags;
-	target_ulong	_sa_handler;
+	uint32_t	sa_flags;
+#if defined(TARGET_MIPSN32)
+	uint32_t	_sa_handler;
+#else
+	abi_ulong	_sa_handler;
+#endif
 	target_sigset_t	sa_mask;
 };
 
 #else
 struct target_old_sigaction {
-        target_ulong _sa_handler;
-        target_ulong sa_mask;
-        target_ulong sa_flags;
-        target_ulong sa_restorer;
+        abi_ulong _sa_handler;
+        abi_ulong sa_mask;
+        abi_ulong sa_flags;
+        abi_ulong sa_restorer;
 };
 
 struct target_sigaction {
-        target_ulong _sa_handler;
-        target_ulong sa_flags;
-        target_ulong sa_restorer;
+        abi_ulong _sa_handler;
+        abi_ulong sa_flags;
+        abi_ulong sa_restorer;
         target_sigset_t sa_mask;
 };
 #endif
 
 typedef union target_sigval {
 	int sival_int;
-        target_ulong sival_ptr;
+        abi_ulong sival_ptr;
 } target_sigval_t;
 #if 0
 #if defined (TARGET_SPARC)
 typedef struct {
 	struct {
-		target_ulong psr;
-		target_ulong pc;
-		target_ulong npc;
-		target_ulong y;
-		target_ulong u_regs[16]; /* globals and ins */
+		abi_ulong psr;
+		abi_ulong pc;
+		abi_ulong npc;
+		abi_ulong y;
+		abi_ulong u_regs[16]; /* globals and ins */
 	}		si_regs;
 	int		si_mask;
 } __siginfo_t;
@@ -538,7 +544,7 @@
 
 		/* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
 		struct {
-			target_ulong _addr; /* faulting insn/memory ref. */
+			abi_ulong _addr; /* faulting insn/memory ref. */
 		} _sigfault;
 
 		/* SIGPOLL */
@@ -608,8 +614,8 @@
 #endif /* defined(TARGET_I386) || defined(TARGET_ARM) */
 
 struct target_rlimit {
-        target_ulong   rlim_cur;
-        target_ulong   rlim_max;
+        abi_ulong   rlim_cur;
+        abi_ulong   rlim_max;
 };
 
 struct target_pollfd {
@@ -860,6 +866,8 @@
 #define TARGET_MAP_EXECUTABLE	0x4000		/* mark it as an executable */
 #define TARGET_MAP_LOCKED	0x8000		/* pages are locked */
 #define TARGET_MAP_NORESERVE	0x0400		/* don't check for reservations */
+#define TARGET_MAP_POPULATE	0x10000		/* populate (prefault) pagetables */
+#define TARGET_MAP_NONBLOCK	0x20000		/* do not block on IO */
 #else
 #define TARGET_MAP_ANONYMOUS	0x20		/* don't use a file */
 #define TARGET_MAP_GROWSDOWN	0x0100		/* stack-like segment */
@@ -872,30 +880,32 @@
 #define TARGET_MAP_LOCKED	0x2000		/* pages are locked */
 #define TARGET_MAP_NORESERVE	0x4000		/* don't check for reservations */
 #endif
+#define TARGET_MAP_POPULATE	0x8000		/* populate (prefault) pagetables */
+#define TARGET_MAP_NONBLOCK	0x10000		/* do not block on IO */
 #endif
 
-#if defined(TARGET_I386) || defined(TARGET_ARM)
+#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_CRIS)
 struct target_stat {
 	unsigned short st_dev;
 	unsigned short __pad1;
-	target_ulong st_ino;
+	abi_ulong st_ino;
 	unsigned short st_mode;
 	unsigned short st_nlink;
 	unsigned short st_uid;
 	unsigned short st_gid;
 	unsigned short st_rdev;
 	unsigned short __pad2;
-	target_ulong  st_size;
-	target_ulong  st_blksize;
-	target_ulong  st_blocks;
-	target_ulong  target_st_atime;
-	target_ulong  __unused1;
-	target_ulong  target_st_mtime;
-	target_ulong  __unused2;
-	target_ulong  target_st_ctime;
-	target_ulong  __unused3;
-	target_ulong  __unused4;
-	target_ulong  __unused5;
+	abi_ulong  st_size;
+	abi_ulong  st_blksize;
+	abi_ulong  st_blocks;
+	abi_ulong  target_st_atime;
+	abi_ulong  __unused1;
+	abi_ulong  target_st_mtime;
+	abi_ulong  __unused2;
+	abi_ulong  target_st_ctime;
+	abi_ulong  __unused3;
+	abi_ulong  __unused4;
+	abi_ulong  __unused5;
 };
 
 /* This matches struct stat64 in glibc2.1, hence the absolutely
@@ -906,31 +916,31 @@
 	unsigned char	__pad0[10];
 
 #define TARGET_STAT64_HAS_BROKEN_ST_INO	1
-	target_ulong	__st_ino;
+	abi_ulong	__st_ino;
 
 	unsigned int	st_mode;
 	unsigned int	st_nlink;
 
-	target_ulong	st_uid;
-	target_ulong	st_gid;
+	abi_ulong	st_uid;
+	abi_ulong	st_gid;
 
 	unsigned short	st_rdev;
 	unsigned char	__pad3[10];
 
 	long long	st_size;
-	target_ulong	st_blksize;
+	abi_ulong	st_blksize;
 
-	target_ulong	st_blocks;	/* Number 512-byte blocks allocated. */
-	target_ulong	__pad4;		/* future possible st_blocks high bits */
+	abi_ulong	st_blocks;	/* Number 512-byte blocks allocated. */
+	abi_ulong	__pad4;		/* future possible st_blocks high bits */
 
-	target_ulong	target_st_atime;
-	target_ulong	__pad5;
+	abi_ulong	target_st_atime;
+	abi_ulong	__pad5;
 
-	target_ulong	target_st_mtime;
-	target_ulong	__pad6;
+	abi_ulong	target_st_mtime;
+	abi_ulong	__pad6;
 
-	target_ulong	target_st_ctime;
-	target_ulong	__pad7;		/* will be high 32 bits of ctime someday */
+	abi_ulong	target_st_ctime;
+	abi_ulong	__pad7;		/* will be high 32 bits of ctime someday */
 
 	unsigned long long	st_ino;
 } __attribute__((packed));
@@ -939,50 +949,50 @@
 struct target_eabi_stat64 {
         unsigned long long st_dev;
         unsigned int    __pad1;
-        target_ulong    __st_ino;
+        abi_ulong    __st_ino;
         unsigned int    st_mode;
         unsigned int    st_nlink;
 
-        target_ulong    st_uid;
-        target_ulong    st_gid;
+        abi_ulong    st_uid;
+        abi_ulong    st_gid;
 
         unsigned long long st_rdev;
         unsigned int    __pad2[2];
 
         long long       st_size;
-        target_ulong    st_blksize;
+        abi_ulong    st_blksize;
         unsigned int    __pad3;
         unsigned long long st_blocks;
 
-        target_ulong    target_st_atime;
-        target_ulong    target_st_atime_nsec;
+        abi_ulong    target_st_atime;
+        abi_ulong    target_st_atime_nsec;
 
-        target_ulong    target_st_mtime;
-        target_ulong    target_st_mtime_nsec;
+        abi_ulong    target_st_mtime;
+        abi_ulong    target_st_mtime_nsec;
 
-        target_ulong    target_st_ctime;
-        target_ulong    target_st_ctime_nsec;
+        abi_ulong    target_st_ctime;
+        abi_ulong    target_st_ctime_nsec;
 
         unsigned long long st_ino;
 } __attribute__ ((packed));
 #endif
 
-#elif defined(TARGET_SPARC64)
+#elif defined(TARGET_SPARC64) && !defined(TARGET_ABI32)
 struct target_stat {
 	unsigned int	st_dev;
-	target_ulong	st_ino;
+	abi_ulong	st_ino;
 	unsigned int	st_mode;
 	unsigned int	st_nlink;
 	unsigned int	st_uid;
 	unsigned int	st_gid;
 	unsigned int	st_rdev;
-	target_long	st_size;
-	target_long	target_st_atime;
-	target_long	target_st_mtime;
-	target_long	target_st_ctime;
-	target_long	st_blksize;
-	target_long	st_blocks;
-	target_ulong	__unused4[2];
+	abi_long	st_size;
+	abi_long	target_st_atime;
+	abi_long	target_st_mtime;
+	abi_long	target_st_ctime;
+	abi_long	st_blksize;
+	abi_long	st_blocks;
+	abi_ulong	__unused4[2];
 };
 
 struct target_stat64 {
@@ -1006,38 +1016,38 @@
 	unsigned char	__pad4[4];
 	unsigned int	st_blocks;
 
-	target_ulong	target_st_atime;
-	target_ulong	__unused1;
+	abi_ulong	target_st_atime;
+	abi_ulong	__unused1;
 
-	target_ulong	target_st_mtime;
-	target_ulong	__unused2;
+	abi_ulong	target_st_mtime;
+	abi_ulong	__unused2;
 
-	target_ulong	target_st_ctime;
-	target_ulong	__unused3;
+	abi_ulong	target_st_ctime;
+	abi_ulong	__unused3;
 
-	target_ulong	__unused4[3];
+	abi_ulong	__unused4[3];
 };
 
 #elif defined(TARGET_SPARC)
 
 struct target_stat {
 	unsigned short	st_dev;
-	target_ulong	st_ino;
+	abi_ulong	st_ino;
 	unsigned short	st_mode;
 	short		st_nlink;
 	unsigned short	st_uid;
 	unsigned short	st_gid;
 	unsigned short	st_rdev;
-	target_long	st_size;
-	target_long	target_st_atime;
-	target_ulong	__unused1;
-	target_long	target_st_mtime;
-	target_ulong	__unused2;
-	target_long	target_st_ctime;
-	target_ulong	__unused3;
-	target_long	st_blksize;
-	target_long	st_blocks;
-	target_ulong	__unused4[2];
+	abi_long	st_size;
+	abi_long	target_st_atime;
+	abi_ulong	__unused1;
+	abi_long	target_st_mtime;
+	abi_ulong	__unused2;
+	abi_long	target_st_ctime;
+	abi_ulong	__unused3;
+	abi_long	st_blksize;
+	abi_long	st_blocks;
+	abi_ulong	__unused4[2];
 };
 
 struct target_stat64 {
@@ -1080,23 +1090,23 @@
 
 struct target_stat {
 	unsigned short st_dev;
-	target_ulong st_ino;
+	abi_ulong st_ino;
 	unsigned int st_mode;
 	unsigned short st_nlink;
 	unsigned int st_uid;
 	unsigned int st_gid;
 	unsigned short st_rdev;
-	target_ulong  st_size;
-	target_ulong  st_blksize;
-	target_ulong  st_blocks;
-	target_ulong  target_st_atime;
-	target_ulong  __unused1;
-	target_ulong  target_st_mtime;
-	target_ulong  __unused2;
-	target_ulong  target_st_ctime;
-	target_ulong  __unused3;
-	target_ulong  __unused4;
-	target_ulong  __unused5;
+	abi_ulong  st_size;
+	abi_ulong  st_blksize;
+	abi_ulong  st_blocks;
+	abi_ulong  target_st_atime;
+	abi_ulong  __unused1;
+	abi_ulong  target_st_mtime;
+	abi_ulong  __unused2;
+	abi_ulong  target_st_ctime;
+	abi_ulong  __unused3;
+	abi_ulong  __unused4;
+	abi_ulong  __unused5;
 };
 
 struct target_stat64 {
@@ -1109,17 +1119,17 @@
 	unsigned long long st_rdev;
 	long long pad0;
 	long long st_size;
-	target_ulong	st_blksize;
-	target_ulong	pad1;
+	abi_ulong	st_blksize;
+	abi_ulong	pad1;
 	long long	st_blocks;	/* Number 512-byte blocks allocated. */
-	target_ulong	target_st_atime;
-        target_ulong    target_st_atime_nsec;
-	target_ulong	target_st_mtime;
-        target_ulong    target_st_mtime_nsec;
-	target_ulong	target_st_ctime;
-        target_ulong    target_st_ctime_nsec;
-        target_ulong    __unused4;
-        target_ulong    __unused5;
+	abi_ulong	target_st_atime;
+        abi_ulong    target_st_atime_nsec;
+	abi_ulong	target_st_mtime;
+        abi_ulong    target_st_mtime_nsec;
+	abi_ulong	target_st_ctime;
+        abi_ulong    target_st_ctime_nsec;
+        abi_ulong    __unused4;
+        abi_ulong    __unused5;
 };
 
 #elif defined(TARGET_M68K)
@@ -1127,24 +1137,24 @@
 struct target_stat {
 	unsigned short st_dev;
 	unsigned short __pad1;
-	target_ulong st_ino;
+	abi_ulong st_ino;
 	unsigned short st_mode;
 	unsigned short st_nlink;
 	unsigned short st_uid;
 	unsigned short st_gid;
 	unsigned short st_rdev;
 	unsigned short __pad2;
-	target_ulong  st_size;
-	target_ulong  st_blksize;
-	target_ulong  st_blocks;
-	target_ulong  target_st_atime;
-	target_ulong  __unused1;
-	target_ulong  target_st_mtime;
-	target_ulong  __unused2;
-	target_ulong  target_st_ctime;
-	target_ulong  __unused3;
-	target_ulong  __unused4;
-	target_ulong  __unused5;
+	abi_ulong  st_size;
+	abi_ulong  st_blksize;
+	abi_ulong  st_blocks;
+	abi_ulong  target_st_atime;
+	abi_ulong  __unused1;
+	abi_ulong  target_st_mtime;
+	abi_ulong  __unused2;
+	abi_ulong  target_st_ctime;
+	abi_ulong  __unused3;
+	abi_ulong  __unused4;
+	abi_ulong  __unused5;
 };
 
 /* This matches struct stat64 in glibc2.1, hence the absolutely
@@ -1155,62 +1165,172 @@
 	unsigned char	__pad1[2];
 
 #define TARGET_STAT64_HAS_BROKEN_ST_INO	1
-	target_ulong	__st_ino;
+	abi_ulong	__st_ino;
 
 	unsigned int	st_mode;
 	unsigned int	st_nlink;
 
-	target_ulong	st_uid;
-	target_ulong	st_gid;
+	abi_ulong	st_uid;
+	abi_ulong	st_gid;
 
 	unsigned long long	st_rdev;
 	unsigned char	__pad3[2];
 
 	long long	st_size;
-	target_ulong	st_blksize;
+	abi_ulong	st_blksize;
 
-	target_ulong	__pad4;		/* future possible st_blocks high bits */
-	target_ulong	st_blocks;	/* Number 512-byte blocks allocated. */
+	abi_ulong	__pad4;		/* future possible st_blocks high bits */
+	abi_ulong	st_blocks;	/* Number 512-byte blocks allocated. */
 
-	target_ulong	target_st_atime;
-	target_ulong	target_st_atime_nsec;
+	abi_ulong	target_st_atime;
+	abi_ulong	target_st_atime_nsec;
 
-	target_ulong	target_st_mtime;
-	target_ulong	target_st_mtime_nsec;
+	abi_ulong	target_st_mtime;
+	abi_ulong	target_st_mtime_nsec;
 
-	target_ulong	target_st_ctime;
-	target_ulong	target_st_ctime_nsec;
+	abi_ulong	target_st_ctime;
+	abi_ulong	target_st_ctime_nsec;
 
 	unsigned long long	st_ino;
 } __attribute__((packed));
 
+#elif defined(TARGET_MIPS64)
+
+/* The memory layout is the same as of struct stat64 of the 32-bit kernel.  */
+struct target_stat {
+	unsigned int		st_dev;
+	unsigned int		st_pad0[3]; /* Reserved for st_dev expansion */
+
+	abi_ulong		st_ino;
+
+	unsigned int		st_mode;
+	unsigned int		st_nlink;
+
+	int			st_uid;
+	int			st_gid;
+
+	unsigned int		st_rdev;
+	unsigned int		st_pad1[3]; /* Reserved for st_rdev expansion */
+
+	abi_ulong		st_size;
+
+	/*
+	 * Actually this should be timestruc_t st_atime, st_mtime and st_ctime
+	 * but we don't have it under Linux.
+	 */
+	unsigned int		target_st_atime;
+	unsigned int		target_st_atime_nsec;
+
+	unsigned int		target_st_mtime;
+	unsigned int		target_st_mtime_nsec;
+
+	unsigned int		target_st_ctime;
+	unsigned int		target_st_ctime_nsec;
+
+	unsigned int		st_blksize;
+	unsigned int		st_pad2;
+
+	abi_ulong		st_blocks;
+};
+
+#elif defined(TARGET_MIPSN32)
+
+struct target_stat {
+	unsigned	st_dev;
+	int		st_pad1[3];		/* Reserved for network id */
+	unsigned int	st_ino;
+	unsigned int	st_mode;
+	unsigned int	st_nlink;
+	int		st_uid;
+	int		st_gid;
+	unsigned 	st_rdev;
+	unsigned int	st_pad2[2];
+	unsigned int	st_size;
+	unsigned int	st_pad3;
+	/*
+	 * Actually this should be timestruc_t st_atime, st_mtime and st_ctime
+	 * but we don't have it under Linux.
+	 */
+	unsigned int		target_st_atime;
+	unsigned int		target_st_atime_nsec;
+	unsigned int		target_st_mtime;
+	unsigned int		target_st_mtime_nsec;
+	unsigned int		target_st_ctime;
+	unsigned int		target_st_ctime_nsec;
+	unsigned int		st_blksize;
+	unsigned int		st_blocks;
+	unsigned int		st_pad4[14];
+};
+
+/*
+ * This matches struct stat64 in glibc2.1, hence the absolutely insane
+ * amounts of padding around dev_t's.  The memory layout is the same as of
+ * struct stat of the 64-bit kernel.
+ */
+
+struct target_stat64 {
+	unsigned int	st_dev;
+	unsigned int	st_pad0[3];	/* Reserved for st_dev expansion  */
+
+	target_ulong	st_ino;
+
+        unsigned int	st_mode;
+        unsigned int	st_nlink;
+
+	int		st_uid;
+	int		st_gid;
+
+	unsigned int	st_rdev;
+	unsigned int	st_pad1[3];	/* Reserved for st_rdev expansion  */
+
+	int		st_size;
+
+	/*
+	 * Actually this should be timestruc_t st_atime, st_mtime and st_ctime
+	 * but we don't have it under Linux.
+	 */
+	int		target_st_atime;
+	unsigned int	target_st_atime_nsec;	/* Reserved for st_atime expansion  */
+
+	int		target_st_mtime;
+	unsigned int	target_st_mtime_nsec;	/* Reserved for st_mtime expansion  */
+
+	int		target_st_ctime;
+	unsigned int	target_st_ctime_nsec;	/* Reserved for st_ctime expansion  */
+
+	unsigned int	st_blksize;
+	unsigned int	st_pad2;
+
+	int		st_blocks;
+};
+
 #elif defined(TARGET_MIPS)
 
 struct target_stat {
 	unsigned	st_dev;
-	target_long	st_pad1[3];		/* Reserved for network id */
-	target_ulong	st_ino;
+	abi_long	st_pad1[3];		/* Reserved for network id */
+	abi_ulong	st_ino;
 	unsigned int	st_mode;
 	unsigned int	st_nlink;
 	int		st_uid;
 	int		st_gid;
 	unsigned 	st_rdev;
-	target_long	st_pad2[2];
-	target_long	st_size;
-	target_long	st_pad3;
+	abi_long	st_pad2[2];
+	abi_long	st_size;
+	abi_long	st_pad3;
 	/*
 	 * Actually this should be timestruc_t st_atime, st_mtime and st_ctime
 	 * but we don't have it under Linux.
 	 */
-	target_long		target_st_atime;
-	target_long		target_st_atime_nsec;
-	target_long		target_st_mtime;
-	target_long		target_st_mtime_nsec;
-	target_long		target_st_ctime;
-	target_long		target_st_ctime_nsec;
-	target_long		st_blksize;
-	target_long		st_blocks;
-	target_long		st_pad4[14];
+	abi_long		target_st_atime;
+	abi_long		target_st_atime_nsec;
+	abi_long		target_st_mtime;
+	abi_long		target_st_mtime_nsec;
+	abi_long		target_st_ctime;
+	abi_long		target_st_ctime_nsec;
+	abi_long		st_blksize;
+	abi_long		st_blocks;
+	abi_long		st_pad4[14];
 };
 
 /*
@@ -1220,8 +1340,8 @@
  */
 
 struct target_stat64 {
-	target_ulong	st_dev;
-	target_ulong	st_pad0[3];	/* Reserved for st_dev expansion  */
+	abi_ulong	st_dev;
+	abi_ulong	st_pad0[3];	/* Reserved for st_dev expansion  */
 
 	uint64_t	st_ino;
 
@@ -1231,8 +1351,8 @@
 	int		st_uid;
 	int		st_gid;
 
-	target_ulong	st_rdev;
-	target_ulong	st_pad1[3];	/* Reserved for st_rdev expansion  */
+	abi_ulong	st_rdev;
+	abi_ulong	st_pad1[3];	/* Reserved for st_rdev expansion  */
 
 	int64_t 	st_size;
 
@@ -1240,17 +1360,17 @@
 	 * Actually this should be timestruc_t st_atime, st_mtime and st_ctime
 	 * but we don't have it under Linux.
 	 */
-	target_long	target_st_atime;
-	target_ulong	target_st_atime_nsec;	/* Reserved for st_atime expansion  */
+	abi_long	target_st_atime;
+	abi_ulong	target_st_atime_nsec;	/* Reserved for st_atime expansion  */
 
-	target_long	target_st_mtime;
-	target_ulong	target_st_mtime_nsec;	/* Reserved for st_mtime expansion  */
+	abi_long	target_st_mtime;
+	abi_ulong	target_st_mtime_nsec;	/* Reserved for st_mtime expansion  */
 
-	target_long	target_st_ctime;
-	target_ulong	target_st_ctime_nsec;	/* Reserved for st_ctime expansion  */
+	abi_long	target_st_ctime;
+	abi_ulong	target_st_ctime_nsec;	/* Reserved for st_ctime expansion  */
 
-	target_ulong	st_blksize;
-	target_ulong	st_pad2;
+	abi_ulong	st_blksize;
+	abi_ulong	st_pad2;
 
 	int64_t  	st_blocks;
 };
@@ -1265,10 +1385,10 @@
        unsigned int    st_uid;
        unsigned int    st_gid;
        unsigned int    st_rdev;
-       target_long     st_size;
-       target_ulong    target_st_atime;
-       target_ulong    target_st_mtime;
-       target_ulong    target_st_ctime;
+       abi_long     st_size;
+       abi_ulong    target_st_atime;
+       abi_ulong    target_st_mtime;
+       abi_ulong    target_st_ctime;
        unsigned int    st_blksize;
        unsigned int    st_blocks;
        unsigned int    st_flags;
@@ -1276,11 +1396,11 @@
 };
 
 struct target_stat64 {
-       target_ulong    st_dev;
-       target_ulong    st_ino;
-       target_ulong    st_rdev;
-       target_long     st_size;
-       target_ulong    st_blocks;
+       abi_ulong    st_dev;
+       abi_ulong    st_ino;
+       abi_ulong    st_rdev;
+       abi_long     st_size;
+       abi_ulong    st_blocks;
 
        unsigned int    st_mode;
        unsigned int    st_uid;
@@ -1289,36 +1409,36 @@
        unsigned int    st_nlink;
        unsigned int    __pad0;
 
-       target_ulong    target_st_atime;
-       target_ulong    target_st_atime_nsec;
-       target_ulong    target_st_mtime;
-       target_ulong    target_st_mtime_nsec;
-       target_ulong    target_st_ctime;
-       target_ulong    target_st_ctime_nsec;
-       target_long     __unused[3];
+       abi_ulong    target_st_atime;
+       abi_ulong    target_st_atime_nsec;
+       abi_ulong    target_st_mtime;
+       abi_ulong    target_st_mtime_nsec;
+       abi_ulong    target_st_ctime;
+       abi_ulong    target_st_ctime_nsec;
+       abi_long     __unused[3];
 };
 
 #elif defined(TARGET_SH4)
 
 struct target_stat {
-	target_ulong  st_dev;
-	target_ulong  st_ino;
+	abi_ulong  st_dev;
+	abi_ulong  st_ino;
 	unsigned short st_mode;
 	unsigned short st_nlink;
 	unsigned short st_uid;
 	unsigned short st_gid;
-	target_ulong  st_rdev;
-	target_ulong  st_size;
-	target_ulong  st_blksize;
-	target_ulong  st_blocks;
-	target_ulong  target_st_atime;
-	target_ulong  target_st_atime_nsec;
-	target_ulong  target_st_mtime;
-	target_ulong  target_st_mtime_nsec;
-	target_ulong  target_st_ctime;
-	target_ulong  target_st_ctime_nsec;
-	target_ulong  __unused4;
-	target_ulong  __unused5;
+	abi_ulong  st_rdev;
+	abi_ulong  st_size;
+	abi_ulong  st_blksize;
+	abi_ulong  st_blocks;
+	abi_ulong  target_st_atime;
+	abi_ulong  target_st_atime_nsec;
+	abi_ulong  target_st_mtime;
+	abi_ulong  target_st_mtime_nsec;
+	abi_ulong  target_st_ctime;
+	abi_ulong  target_st_ctime_nsec;
+	abi_ulong  __unused4;
+	abi_ulong  __unused5;
 };
 
 /* This matches struct stat64 in glibc2.1, hence the absolutely
@@ -1329,30 +1449,30 @@
 	unsigned char	__pad0[4];
 
 #define TARGET_STAT64_HAS_BROKEN_ST_INO	1
-	target_ulong	__st_ino;
+	abi_ulong	__st_ino;
 
 	unsigned int	st_mode;
 	unsigned int	st_nlink;
 
-	target_ulong	st_uid;
-	target_ulong	st_gid;
+	abi_ulong	st_uid;
+	abi_ulong	st_gid;
 
 	unsigned long long	st_rdev;
 	unsigned char	__pad3[4];
 
 	long long	st_size;
-	target_ulong	st_blksize;
+	abi_ulong	st_blksize;
 
 	unsigned long long	st_blocks;	/* Number 512-byte blocks allocated. */
 
-	target_ulong	target_st_atime;
-	target_ulong	target_st_atime_nsec;
+	abi_ulong	target_st_atime;
+	abi_ulong	target_st_atime_nsec;
 
-	target_ulong	target_st_mtime;
-	target_ulong	target_st_mtime_nsec;
+	abi_ulong	target_st_mtime;
+	abi_ulong	target_st_mtime_nsec;
 
-	target_ulong	target_st_ctime;
-	target_ulong	target_st_ctime_nsec;
+	abi_ulong	target_st_ctime;
+	abi_ulong	target_st_ctime_nsec;
 
 	unsigned long long	st_ino;
 };
@@ -1366,22 +1486,40 @@
 } target_fsid_t;
 
 #ifdef TARGET_MIPS
+#ifdef TARGET_MIPSN32
 struct target_statfs {
-	target_long		f_type;
-	target_long		f_bsize;
-	target_long		f_frsize;	/* Fragment size - unsupported */
-	target_long		f_blocks;
-	target_long		f_bfree;
-	target_long		f_files;
-	target_long		f_ffree;
-	target_long		f_bavail;
+	int32_t			f_type;
+	int32_t			f_bsize;
+	int32_t			f_frsize;	/* Fragment size - unsupported */
+	int32_t			f_blocks;
+	int32_t			f_bfree;
+	int32_t			f_files;
+	int32_t			f_ffree;
+	int32_t			f_bavail;
 
 	/* Linux specials */
 	target_fsid_t		f_fsid;
-	target_long		f_namelen;
-	target_long		f_spare[6];
+	int32_t			f_namelen;
+	int32_t			f_spare[6];
 };
+#else
+struct target_statfs {
+	abi_long		f_type;
+	abi_long		f_bsize;
+	abi_long		f_frsize;	/* Fragment size - unsupported */
+	abi_long		f_blocks;
+	abi_long		f_bfree;
+	abi_long		f_files;
+	abi_long		f_ffree;
+	abi_long		f_bavail;
 
+	/* Linux specials */
+	target_fsid_t		f_fsid;
+	abi_long		f_namelen;
+	abi_long		f_spare[6];
+};
+#endif
+
 struct target_statfs64 {
 	uint32_t	f_type;
 	uint32_t	f_bsize;
@@ -1550,8 +1688,8 @@
 struct target_flock {
 	short l_type;
 	short l_whence;
-	target_ulong l_start;
-	target_ulong l_len;
+	abi_ulong l_start;
+	abi_ulong l_len;
 	int l_pid;
 };
 
@@ -1718,20 +1856,20 @@
 #define TARGET_VFAT_IOCTL_READDIR_SHORT   TARGET_IORU('r', 2)
 
 struct target_sysinfo {
-    target_long uptime;             /* Seconds since boot */
-    target_ulong loads[3];          /* 1, 5, and 15 minute load averages */
-    target_ulong totalram;          /* Total usable main memory size */
-    target_ulong freeram;           /* Available memory size */
-    target_ulong sharedram;         /* Amount of shared memory */
-    target_ulong bufferram;         /* Memory used by buffers */
-    target_ulong totalswap;         /* Total swap space size */
-    target_ulong freeswap;          /* swap space still available */
+    abi_long uptime;                /* Seconds since boot */
+    abi_ulong loads[3];             /* 1, 5, and 15 minute load averages */
+    abi_ulong totalram;             /* Total usable main memory size */
+    abi_ulong freeram;              /* Available memory size */
+    abi_ulong sharedram;            /* Amount of shared memory */
+    abi_ulong bufferram;            /* Memory used by buffers */
+    abi_ulong totalswap;            /* Total swap space size */
+    abi_ulong freeswap;             /* swap space still available */
     unsigned short procs;           /* Number of current processes */
     unsigned short pad;             /* explicit padding for m68k */
-    target_ulong totalhigh;         /* Total high memory size */
-    target_ulong freehigh;          /* Available high memory size */
+    abi_ulong totalhigh;            /* Total high memory size */
+    abi_ulong freehigh;             /* Available high memory size */
     unsigned int mem_unit;          /* Memory unit size in bytes */
-    char _f[20-2*sizeof(target_long)-sizeof(int)]; /* Padding: libc5 uses this.. */
+    char _f[20-2*sizeof(abi_long)-sizeof(int)]; /* Padding: libc5 uses this.. */
 };
 
 #include "socket.h"

Modified: trunk/src/host/qemu-neo1973/linux-user/vm86.c
===================================================================
--- trunk/src/host/qemu-neo1973/linux-user/vm86.c	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/linux-user/vm86.c	2007-10-29 21:14:04 UTC (rev 3303)
@@ -381,7 +381,7 @@
     }
 }
 
-int do_vm86(CPUX86State *env, long subfunction, target_ulong vm86_addr)
+int do_vm86(CPUX86State *env, long subfunction, abi_ulong vm86_addr)
 {
     TaskState *ts = env->opaque;
     struct target_vm86plus_struct * target_v86;

Modified: trunk/src/host/qemu-neo1973/linux-user/x86_64/syscall.h
===================================================================
--- trunk/src/host/qemu-neo1973/linux-user/x86_64/syscall.h	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/linux-user/x86_64/syscall.h	2007-10-29 21:14:04 UTC (rev 3303)
@@ -2,30 +2,30 @@
 #define __USER_DS	(0x2B)
 
 struct target_pt_regs {
-	target_ulong r15;
-	target_ulong r14;
-	target_ulong r13;
-	target_ulong r12;
-	target_ulong rbp;
-	target_ulong rbx;
+	abi_ulong r15;
+	abi_ulong r14;
+	abi_ulong r13;
+	abi_ulong r12;
+	abi_ulong rbp;
+	abi_ulong rbx;
 /* arguments: non interrupts/non tracing syscalls only save upto here*/
- 	target_ulong r11;
-	target_ulong r10;
-	target_ulong r9;
-	target_ulong r8;
-	target_ulong rax;
-	target_ulong rcx;
-	target_ulong rdx;
-	target_ulong rsi;
-	target_ulong rdi;
-	target_ulong orig_rax;
+ 	abi_ulong r11;
+	abi_ulong r10;
+	abi_ulong r9;
+	abi_ulong r8;
+	abi_ulong rax;
+	abi_ulong rcx;
+	abi_ulong rdx;
+	abi_ulong rsi;
+	abi_ulong rdi;
+	abi_ulong orig_rax;
 /* end of arguments */
 /* cpu exception frame or undefined */
-	target_ulong rip;
-	target_ulong cs;
-	target_ulong eflags;
-	target_ulong rsp;
-	target_ulong ss;
+	abi_ulong rip;
+	abi_ulong cs;
+	abi_ulong eflags;
+	abi_ulong rsp;
+	abi_ulong ss;
 /* top of stack page */
 };
 
@@ -41,7 +41,7 @@
 #if 0 // Redefine this
 struct target_modify_ldt_ldt_s {
 	unsigned int  entry_number;
-	target_ulong  base_addr;
+        abi_ulong     base_addr;
 	unsigned int  limit;
 	unsigned int  seg_32bit:1;
 	unsigned int  contents:2;
@@ -54,7 +54,7 @@
 #else
 struct target_modify_ldt_ldt_s {
 	unsigned int  entry_number;
-	target_ulong  base_addr;
+        abi_ulong     base_addr;
 	unsigned int  limit;
         unsigned int flags;
 };
@@ -71,8 +71,8 @@
 	unsigned short		__pad1;
 	unsigned short		seq;
 	unsigned short		__pad2;
-	target_ulong		__unused1;
-	target_ulong		__unused2;
+	abi_ulong		__unused1;
+	abi_ulong		__unused2;
 };
 
 struct target_msqid64_ds {
@@ -80,13 +80,13 @@
 	unsigned int msg_stime;	/* last msgsnd time */
 	unsigned int msg_rtime;	/* last msgrcv time */
 	unsigned int msg_ctime;	/* last change time */
-	target_ulong  msg_cbytes;	/* current number of bytes on queue */
-	target_ulong  msg_qnum;	/* number of messages in queue */
-	target_ulong  msg_qbytes;	/* max number of bytes on queue */
+	abi_ulong  msg_cbytes;	/* current number of bytes on queue */
+	abi_ulong  msg_qnum;	/* number of messages in queue */
+	abi_ulong  msg_qbytes;	/* max number of bytes on queue */
 	unsigned int msg_lspid;	/* pid of last msgsnd */
 	unsigned int msg_lrpid;	/* last receive pid */
-	target_ulong  __unused4;
-	target_ulong  __unused5;
+	abi_ulong  __unused4;
+	abi_ulong  __unused5;
 };
 
 #define UNAME_MACHINE "x86_64"

Modified: trunk/src/host/qemu-neo1973/linux-user/x86_64/syscall_nr.h
===================================================================
--- trunk/src/host/qemu-neo1973/linux-user/x86_64/syscall_nr.h	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/linux-user/x86_64/syscall_nr.h	2007-10-29 21:14:04 UTC (rev 3303)
@@ -278,3 +278,9 @@
 #define TARGET_NR_sync_file_range	277
 #define TARGET_NR_vmsplice		278
 #define TARGET_NR_move_pages		279
+#define TARGET_NR_utimensat		280
+#define TARGET_NR_epoll_pwait	281
+#define TARGET_NR_signalfd		282
+#define TARGET_NR_timerfd		283
+#define TARGET_NR_eventfd		284
+#define TARGET_NR_fallocate		285

Added: trunk/src/host/qemu-neo1973/linux-user/x86_64/target_signal.h
===================================================================
--- trunk/src/host/qemu-neo1973/linux-user/x86_64/target_signal.h	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/linux-user/x86_64/target_signal.h	2007-10-29 21:14:04 UTC (rev 3303)
@@ -0,0 +1,29 @@
+#ifndef TARGET_SIGNAL_H
+#define TARGET_SIGNAL_H
+
+#include "cpu.h"
+
+/* this struct defines a stack used during syscall handling */
+
+typedef struct target_sigaltstack {
+	abi_ulong ss_sp;
+	abi_long ss_flags;
+	abi_ulong ss_size;
+} target_stack_t;
+
+
+/*
+ * sigaltstack controls
+ */
+#define TARGET_SS_ONSTACK	1
+#define TARGET_SS_DISABLE	2
+
+#define TARGET_MINSIGSTKSZ	2048
+#define TARGET_SIGSTKSZ		8192
+
+static inline abi_ulong get_sp_from_cpustate(CPUX86State *state)
+{
+    return state->regs[R_ESP];
+}
+
+#endif /* TARGET_SIGNAL_H */

Modified: trunk/src/host/qemu-neo1973/loader.c
===================================================================
--- trunk/src/host/qemu-neo1973/loader.c	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/loader.c	2007-10-29 21:14:04 UTC (rev 3303)
@@ -173,6 +173,7 @@
 
 #define SZ		32
 #define elf_word        uint32_t
+#define elf_sword        int32_t
 #define bswapSZs	bswap32s
 #include "elf_ops.h"
 
@@ -182,6 +183,7 @@
 #undef elf_sym
 #undef elf_note
 #undef elf_word
+#undef elf_sword
 #undef bswapSZs
 #undef SZ
 #define elfhdr		elf64_hdr
@@ -190,6 +192,7 @@
 #define elf_shdr	elf64_shdr
 #define elf_sym		elf64_sym
 #define elf_word        uint64_t
+#define elf_sword        int64_t
 #define bswapSZs	bswap64s
 #define SZ		64
 #include "elf_ops.h"

Modified: trunk/src/host/qemu-neo1973/monitor.c
===================================================================
--- trunk/src/host/qemu-neo1973/monitor.c	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/monitor.c	2007-10-29 21:14:04 UTC (rev 3303)
@@ -509,7 +509,7 @@
 }
 
 static void memory_dump(int count, int format, int wsize,
-                        target_ulong addr, int is_physical)
+                        target_phys_addr_t addr, int is_physical)
 {
     CPUState *env;
     int nb_per_line, l, line_size, i, max_digits, len;
@@ -572,7 +572,10 @@
     }
 
     while (len > 0) {
-        term_printf(TARGET_FMT_lx ":", addr);
+        if (is_physical)
+            term_printf(TARGET_FMT_plx ":", addr);
+        else
+            term_printf(TARGET_FMT_lx ":", (target_ulong)addr);
         l = len;
         if (l > line_size)
             l = line_size;
@@ -640,18 +643,24 @@
     memory_dump(count, format, size, addr, 0);
 }
 
+#if TARGET_PHYS_ADDR_BITS > 32
+#define GET_TPHYSADDR(h, l) (((uint64_t)(h) << 32) | (l))
+#else
+#define GET_TPHYSADDR(h, l) (l)
+#endif
+
 static void do_physical_memory_dump(int count, int format, int size,
                                     uint32_t addrh, uint32_t addrl)
 
 {
-    target_long addr = GET_TLONG(addrh, addrl);
+    target_phys_addr_t addr = GET_TPHYSADDR(addrh, addrl);
     memory_dump(count, format, size, addr, 1);
 }
 
 static void do_print(int count, int format, int size, unsigned int valh, unsigned int vall)
 {
-    target_long val = GET_TLONG(valh, vall);
-#if TARGET_LONG_BITS == 32
+    target_phys_addr_t val = GET_TPHYSADDR(valh, vall);
+#if TARGET_PHYS_ADDR_BITS == 32
     switch(format) {
     case 'o':
         term_printf("%#o", val);
@@ -1386,6 +1395,10 @@
     { "cpustats", "", do_info_cpu_stats,
       "", "show CPU statistics", },
 #endif
+#if defined(CONFIG_SLIRP)
+    { "slirp", "", do_info_slirp,
+      "", "show SLIRP statistics", },
+#endif
     { NULL, NULL, },
 };
 
@@ -1442,7 +1455,7 @@
     CPUState *env = mon_get_cpu();
     if (!env)
         return 0;
-    return do_load_msr(env);
+    return env->msr;
 }
 
 static target_long monitor_get_xer (struct MonitorDef *md, int val)
@@ -1788,11 +1801,11 @@
     }
 }
 
-static target_long expr_sum(void);
+static int64_t expr_sum(void);
 
-static target_long expr_unary(void)
+static int64_t expr_unary(void)
 {
-    target_long n;
+    int64_t n;
     char *p;
     int ret;
 
@@ -1830,6 +1843,7 @@
     case '$':
         {
             char buf[128], *q;
+            target_long reg;
 
             pch++;
             q = buf;
@@ -1844,11 +1858,12 @@
             while (isspace(*pch))
                 pch++;
             *q = 0;
-            ret = get_monitor_def(&n, buf);
+            ret = get_monitor_def(&reg, buf);
             if (ret == -1)
                 expr_error("unknown register");
             else if (ret == -2)
                 expr_error("no cpu defined");
+            n = reg;
         }
         break;
     case '\0':
@@ -1856,7 +1871,7 @@
         n = 0;
         break;
     default:
-#if TARGET_LONG_BITS == 64
+#if TARGET_PHYS_ADDR_BITS > 32
         n = strtoull(pch, &p, 0);
 #else
         n = strtoul(pch, &p, 0);
@@ -1873,9 +1888,9 @@
 }
 
 
-static target_long expr_prod(void)
+static int64_t expr_prod(void)
 {
-    target_long val, val2;
+    int64_t val, val2;
     int op;
 
     val = expr_unary();
@@ -1904,9 +1919,9 @@
     return val;
 }
 
-static target_long expr_logic(void)
+static int64_t expr_logic(void)
 {
-    target_long val, val2;
+    int64_t val, val2;
     int op;
 
     val = expr_prod();
@@ -1932,9 +1947,9 @@
     return val;
 }
 
-static target_long expr_sum(void)
+static int64_t expr_sum(void)
 {
-    target_long val, val2;
+    int64_t val, val2;
     int op;
 
     val = expr_logic();
@@ -1952,7 +1967,7 @@
     return val;
 }
 
-static int get_expr(target_long *pval, const char **pp)
+static int get_expr(int64_t *pval, const char **pp)
 {
     pch = *pp;
     if (setjmp(expr_env)) {
@@ -2215,7 +2230,8 @@
         case 'i':
         case 'l':
             {
-                target_long val;
+                int64_t val;
+
                 while (isspace(*p))
                     p++;
                 if (*typestr == '?' || *typestr == '.') {
@@ -2255,7 +2271,7 @@
                 } else {
                     if ((nb_args + 1) >= MAX_ARGS)
                         goto error_args;
-#if TARGET_LONG_BITS == 64
+#if TARGET_PHYS_ADDR_BITS > 32
                     args[nb_args++] = (void *)(long)((val >> 32) & 0xffffffff);
 #else
                     args[nb_args++] = (void *)0;

Modified: trunk/src/host/qemu-neo1973/pc-bios/README
===================================================================
--- trunk/src/host/qemu-neo1973/pc-bios/README	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/pc-bios/README	2007-10-29 21:14:04 UTC (rev 3303)
@@ -14,7 +14,8 @@
 - OpenBIOS (http://www.openbios.org/) is a free (GPL v2) portable
   firmware implementation. The goal is to implement a 100% IEEE
   1275-1994 (referred to as Open Firmware) compliant firmware.
-  The included Sparc32 and Sparc64 images are built from SVN revision 169.
+  The included Sparc32 image is built from SVN revision 171 and
+  Sparc64 image from revision 169.
 
 - The PXE roms come from Rom-o-Matic etherboot 5.4.2.
   pcnet32:pcnet32 -- [0x1022,0x2000]

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

Modified: trunk/src/host/qemu-neo1973/pc-bios/ppc_rom.bin
===================================================================
(Binary files differ)

Modified: trunk/src/host/qemu-neo1973/qemu-binfmt-conf.sh
===================================================================
--- trunk/src/host/qemu-neo1973/qemu-binfmt-conf.sh	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/qemu-binfmt-conf.sh	2007-10-29 21:14:04 UTC (rev 3303)
@@ -46,10 +46,14 @@
 fi
 if [ $cpu != "m68k" ] ; then
     echo   'Please check cpu value and header information for m68k!'
-    echo   ':m68k:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x08:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-m68k:' > /proc/sys/fs/binfmt_misc/register
+    echo   ':m68k:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x04:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-m68k:' > /proc/sys/fs/binfmt_misc/register
 fi
 if [ $cpu != "mips" ] ; then
     # FIXME: We could use the other endianness on a MIPS host.
     echo   ':mips:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-mips:' > /proc/sys/fs/binfmt_misc/register
     echo   ':mipsel:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-mipsel:' > /proc/sys/fs/binfmt_misc/register
+    echo   ':mipsn32:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-mipsn32:' > /proc/sys/fs/binfmt_misc/register
+    echo   ':mipsn32el:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-mipsn32el:' > /proc/sys/fs/binfmt_misc/register
+    echo   ':mips64:M::\x7fELF\x02\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-mips64:' > /proc/sys/fs/binfmt_misc/register
+    echo   ':mips64el:M::\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-mips64el:' > /proc/sys/fs/binfmt_misc/register
 fi

Modified: trunk/src/host/qemu-neo1973/qemu-doc.texi
===================================================================
--- trunk/src/host/qemu-neo1973/qemu-doc.texi	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/qemu-doc.texi	2007-10-29 21:14:04 UTC (rev 3303)
@@ -242,7 +242,8 @@
 
 @item -smp n
 Simulate an SMP system with @var{n} CPUs. On the PC target, up to 255
-CPUs are supported.
+CPUs are supported. On Sparc32 target, Linux limits the number of usable CPUs
+to 4.
 
 @item -audio-help
 
@@ -1942,6 +1943,8 @@
 
 Use the executable @file{qemu-system-sparc} to simulate a SparcStation 5
 or SparcStation 10 (sun4m architecture). The emulation is somewhat complete.
+SMP up to 16 CPUs is supported, but Linux limits the number of usable CPUs
+to 4.
 
 QEMU emulates the following sun4m peripherals:
 
@@ -1965,7 +1968,8 @@
 CS4231 sound device (only on SS-5, not working yet)
 @end itemize
 
-The number of peripherals is fixed in the architecture.
+The number of peripherals is fixed in the architecture.  Maximum memory size
+depends on the machine type, for SS-5 it is 256MB and for SS-10 2047MB.
 
 Since version 0.8.2, QEMU uses OpenBIOS
 @url{http://www.openbios.org/}. OpenBIOS is a free (GPL v2) portable
@@ -2036,6 +2040,8 @@
 The MIPS Malta prototype board "malta"
 @item
 An ACER Pica "pica61"
+ at item
+MIPS emulator pseudo board "mipssim"
 @end itemize
 
 The generic emulation is supported by Debian 'Etch' and is able to
@@ -2044,7 +2050,7 @@
 
 @itemize @minus
 @item
-MIPS 24Kf CPU
+A range of MIPS CPUs, default is the 24Kf
 @item
 PC style serial port
 @item
@@ -2083,6 +2089,19 @@
 IDE controller
 @end itemize
 
+The mipssim pseudo board emulation provides an environment similiar
+to what the proprietary MIPS emulator uses for running Linux.
+It supports:
+
+ at itemize @minus
+ at item
+A range of MIPS CPUs, default is the 24Kf
+ at item
+PC style serial port
+ at item
+MIPSnet network emulation
+ at end itemize
+
 @node ARM System emulator
 @section ARM System emulator
 
@@ -2367,6 +2386,12 @@
 
 The binary format is detected automatically.
 
+ at command{qemu-sparc32plus} can execute Sparc32 and SPARC32PLUS binaries
+(Sparc64 CPU, 32 bit ABI).
+
+ at command{qemu-sparc64} can execute some Sparc64 (Sparc64 CPU, 64 bit ABI) and
+SPARC32PLUS binaries (Sparc64 CPU, 32 bit ABI).
+
 @node Mac OS X/Darwin User space emulator
 @section Mac OS X/Darwin User space emulator
 

Modified: trunk/src/host/qemu-neo1973/qemu-img.c
===================================================================
--- trunk/src/host/qemu-neo1973/qemu-img.c	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/qemu-img.c	2007-10-29 21:14:04 UTC (rev 3303)
@@ -269,9 +269,9 @@
         case 'e':
             flags |= BLOCK_FLAG_ENCRYPT;
             break;
-		case '6':
+        case '6':
             flags |= BLOCK_FLAG_COMPAT6;
-			break;
+            break;
         }
     }
     if (optind >= argc)
@@ -471,7 +471,7 @@
         error("Compression not supported for this file format");
     if (flags & BLOCK_FLAG_ENCRYPT && drv != &bdrv_qcow && drv != &bdrv_qcow2)
         error("Encryption not supported for this file format");
-    if (flags & BLOCK_FLAG_COMPRESS && drv != &bdrv_vmdk)
+    if (flags & BLOCK_FLAG_COMPAT6 && drv != &bdrv_vmdk)
         error("Alternative compatibility level not supported for this file format");
     if (flags & BLOCK_FLAG_ENCRYPT && flags & BLOCK_FLAG_COMPRESS)
         error("Compression and encryption not supported at the same time");

Modified: trunk/src/host/qemu-neo1973/qemu-tech.texi
===================================================================
--- trunk/src/host/qemu-neo1973/qemu-tech.texi	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/qemu-tech.texi	2007-10-29 21:14:04 UTC (rev 3303)
@@ -199,9 +199,10 @@
 
 @item Full SPARC V8 emulation, including privileged
 instructions, FPU and MMU. SPARC V9 emulation includes most privileged
-instructions, FPU and I/D MMU, but misses most VIS instructions.
+and VIS instructions, FPU and I/D MMU. Alignment is fully enforced.
 
- at item Can run most 32-bit SPARC Linux binaries and some handcrafted 64-bit SPARC Linux binaries.
+ at item Can run most 32-bit SPARC Linux binaries, SPARC32PLUS Linux binaries and
+some 64-bit SPARC Linux binaries.
 
 @end itemize
 
@@ -212,11 +213,8 @@
 @item IPC syscalls are missing.
 
 @item 128-bit floating point operations are not supported, though none of the
-real CPUs implement them either. FCMPE[SD] are not correctly
-implemented.  Floating point exception support is untested.
+real CPUs implement them either.  Floating point exception support is untested.
 
- at item Alignment is not enforced at all.
-
 @item Atomic instructions are not correctly implemented.
 
 @item Sparc64 emulators are not usable for anything yet.

Modified: trunk/src/host/qemu-neo1973/readline.c
===================================================================
--- trunk/src/host/qemu-neo1973/readline.c	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/readline.c	2007-10-29 21:14:04 UTC (rev 3303)
@@ -301,7 +301,7 @@
 
 static void term_completion(void)
 {
-    int len, i, j, max_width, nb_cols;
+    int len, i, j, max_width, nb_cols, max_prefix;
     char *cmdline;
 
     nb_completions = 0;
@@ -328,11 +328,26 @@
     } else {
         term_printf("\n");
         max_width = 0;
+        max_prefix = 0;	
         for(i = 0; i < nb_completions; i++) {
             len = strlen(completions[i]);
+            if (i==0) {
+                max_prefix = len;
+            } else {
+                if (len < max_prefix)
+                    max_prefix = len;
+                for(j=0; j<max_prefix; j++) {
+                    if (completions[i][j] != completions[0][j])
+                        max_prefix = j;
+                }
+            }
             if (len > max_width)
                 max_width = len;
         }
+        if (max_prefix > 0) 
+            for(i = completion_index; i < max_prefix; i++) {
+                term_insert_char(completions[0][i]);
+            }
         max_width += 2;
         if (max_width < 10)
             max_width = 10;

Modified: trunk/src/host/qemu-neo1973/slirp/bootp.c
===================================================================
--- trunk/src/host/qemu-neo1973/slirp/bootp.c	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/slirp/bootp.c	2007-10-29 21:14:04 UTC (rev 3303)
@@ -149,7 +149,7 @@
 
     if ((m = m_get()) == NULL)
         return;
-    m->m_data += if_maxlinkhdr;
+    m->m_data += IF_MAXLINKHDR;
     rbp = (struct bootp_t *)m->m_data;
     m->m_data += sizeof(struct udpiphdr);
     memset(rbp, 0, sizeof(struct bootp_t));

Modified: trunk/src/host/qemu-neo1973/slirp/debug.c
===================================================================
--- trunk/src/host/qemu-neo1973/slirp/debug.c	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/slirp/debug.c	2007-10-29 21:14:04 UTC (rev 3303)
@@ -20,6 +20,7 @@
 
 /* Carry over one item from main.c so that the tty's restored.
  * Only done when the tty being used is /dev/tty --RedWolf */
+#ifndef CONFIG_QEMU
 extern struct termios slirp_tty_settings;
 extern int slirp_tty_restore;
 
@@ -70,7 +71,9 @@
 	}
 }
 #endif
+#endif
 
+#ifdef LOG_ENABLED
 #if 0
 /*
  * Statistic routines
@@ -80,7 +83,7 @@
  * the link as well.
  */
 
-void
+static void
 ttystats(ttyp)
 	struct ttys *ttyp;
 {
@@ -89,9 +92,9 @@
 
 	lprint(" \r\n");
 
-	if (if_comp & IF_COMPRESS)
+	if (IF_COMP & IF_COMPRESS)
 	   strcpy(buff, "on");
-	else if (if_comp & IF_NOCOMPRESS)
+	else if (IF_COMP & IF_NOCOMPRESS)
 	   strcpy(buff, "off");
 	else
 	   strcpy(buff, "off (for now)");
@@ -119,8 +122,8 @@
 	lprint("  %6d bad input packets\r\n", is->in_mbad);
 }
 
-void
-allttystats()
+static void
+allttystats(void)
 {
 	struct ttys *ttyp;
 
@@ -129,8 +132,8 @@
 }
 #endif
 
-void
-ipstats()
+static void
+ipstats(void)
 {
 	lprint(" \r\n");
 
@@ -153,9 +156,9 @@
 	lprint("  %6d total packets delivered\r\n", ipstat.ips_delivered);
 }
 
-#if 0
-void
-vjstats()
+#ifndef CONFIG_QEMU
+static void
+vjstats(void)
 {
 	lprint(" \r\n");
 
@@ -172,8 +175,8 @@
 }
 #endif
 
-void
-tcpstats()
+static void
+tcpstats(void)
 {
 	lprint(" \r\n");
 
@@ -240,8 +243,8 @@
 
 }
 
-void
-udpstats()
+static void
+udpstats(void)
 {
         lprint(" \r\n");
 
@@ -254,8 +257,8 @@
 	lprint("  %6d datagrams sent\r\n", udpstat.udps_opackets);
 }
 
-void
-icmpstats()
+static void
+icmpstats(void)
 {
 	lprint(" \r\n");
 	lprint("ICMP stats:\r\n");
@@ -267,8 +270,8 @@
 	lprint("  %6d ICMP packets sent in reply\r\n", icmpstat.icps_reflect);
 }
 
-void
-mbufstats()
+static void
+mbufstats(void)
 {
 	struct mbuf *m;
 	int i;
@@ -291,8 +294,8 @@
         lprint("  %6d mbufs queued as packets\r\n\r\n", if_queued);
 }
 
-void
-sockstats()
+static void
+sockstats(void)
 {
 	char buff[256];
 	int n;
@@ -331,8 +334,9 @@
 				so->so_rcv.sb_cc, so->so_snd.sb_cc);
 	}
 }
+#endif
 
-#if 0
+#ifndef CONFIG_QEMU
 void
 slirp_exit(exit_status)
 	int exit_status;
@@ -374,3 +378,18 @@
 	exit(exit_status);
 }
 #endif
+
+void
+slirp_stats(void)
+{
+#ifdef LOG_ENABLED
+    ipstats();
+    tcpstats();
+    udpstats();
+    icmpstats();
+    mbufstats();
+    sockstats();
+#else
+    lprint("SLIRP statistics code not compiled.\n");
+#endif
+}

Modified: trunk/src/host/qemu-neo1973/slirp/debug.h
===================================================================
--- trunk/src/host/qemu-neo1973/slirp/debug.h	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/slirp/debug.h	2007-10-29 21:14:04 UTC (rev 3303)
@@ -37,14 +37,4 @@
 #endif
 
 void debug_init _P((char *, int));
-//void ttystats _P((struct ttys *));
-void allttystats _P((void));
-void ipstats _P((void));
-void vjstats _P((void));
-void tcpstats _P((void));
-void udpstats _P((void));
-void icmpstats _P((void));
-void mbufstats _P((void));
-void sockstats _P((void));
-void slirp_exit _P((int));
 

Modified: trunk/src/host/qemu-neo1973/slirp/icmp_var.h
===================================================================
--- trunk/src/host/qemu-neo1973/slirp/icmp_var.h	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/slirp/icmp_var.h	2007-10-29 21:14:04 UTC (rev 3303)
@@ -64,6 +64,8 @@
 	{ "stats", CTLTYPE_STRUCT }, \
 }
 
+#ifdef LOG_ENABLED
 extern struct icmpstat icmpstat;
+#endif
 
 #endif

Modified: trunk/src/host/qemu-neo1973/slirp/if.c
===================================================================
--- trunk/src/host/qemu-neo1973/slirp/if.c	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/slirp/if.c	2007-10-29 21:14:04 UTC (rev 3303)
@@ -7,12 +7,7 @@
 
 #include <slirp.h>
 
-int if_mtu, if_mru;
-int if_comp;
-int if_maxlinkhdr;
 int     if_queued = 0;                  /* Number of packets queued so far */
-int     if_thresh = 10;                 /* Number of packets queued before we start sending
-					 * (to prevent allocing too many mbufs) */
 
 struct  mbuf if_fastq;                  /* fast queue (for interactive data) */
 struct  mbuf if_batchq;                 /* queue for non-interactive data */
@@ -41,23 +36,6 @@
 void
 if_init()
 {
-#if 0
-	/*
-	 * Set if_maxlinkhdr to 48 because it's 40 bytes for TCP/IP,
-	 * and 8 bytes for PPP, but need to have it on an 8byte boundary
-	 */
-#ifdef USE_PPP
-	if_maxlinkhdr = 48;
-#else
-	if_maxlinkhdr = 40;
-#endif
-#else
-        /* 2 for alignment, 14 for ethernet, 40 for TCP/IP */
-        if_maxlinkhdr = 2 + 14 + 40;
-#endif
-	if_mtu = 1500;
-	if_mru = 1500;
-	if_comp = IF_AUTOCOMP;
 	if_fastq.ifq_next = if_fastq.ifq_prev = &if_fastq;
 	if_batchq.ifq_next = if_batchq.ifq_prev = &if_batchq;
         //	sl_compress_init(&comp_s);

Modified: trunk/src/host/qemu-neo1973/slirp/if.h
===================================================================
--- trunk/src/host/qemu-neo1973/slirp/if.h	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/slirp/if.h	2007-10-29 21:14:04 UTC (rev 3303)
@@ -13,15 +13,26 @@
 #define IF_AUTOCOMP	0x04	/* Autodetect (default) */
 #define IF_NOCIDCOMP	0x08	/* CID compression */
 
-/* Needed for FreeBSD */
-#undef if_mtu
-extern int	if_mtu;
-extern int	if_mru;	/* MTU and MRU */
-extern int	if_comp;	/* Flags for compression */
-extern int	if_maxlinkhdr;
+#define IF_MTU 1500
+#define IF_MRU 1500
+#define	IF_COMP IF_AUTOCOMP	/* Flags for compression */
+
+#if 0
+/*
+ * Set if_maxlinkhdr to 48 because it's 40 bytes for TCP/IP,
+ * and 8 bytes for PPP, but need to have it on an 8byte boundary
+ */
+#ifdef USE_PPP
+#define IF_MAXLINKHDR 48
+#else
+#define IF_MAXLINKHDR 40
+#endif
+#else
+        /* 2 for alignment, 14 for ethernet, 40 for TCP/IP */
+#define IF_MAXLINKHDR (2 + 14 + 40)
+#endif
+
 extern int	if_queued;	/* Number of packets queued so far */
-extern int	if_thresh;	/* Number of packets queued before we start sending
-				 * (to prevent allocing too many mbufs) */
 
 extern	struct mbuf if_fastq;                  /* fast queue (for interactive data) */
 extern	struct mbuf if_batchq;                 /* queue for non-interactive data */
@@ -29,6 +40,7 @@
 
 #define ifs_init(ifm) ((ifm)->ifs_next = (ifm)->ifs_prev = (ifm))
 
+#ifdef LOG_ENABLED
 /* Interface statistics */
 struct slirp_ifstats {
 	u_int out_pkts;		/* Output packets */
@@ -46,5 +58,6 @@
 
 	u_int in_mbad;		/* Bad incoming packets */
 };
+#endif
 
 #endif

Modified: trunk/src/host/qemu-neo1973/slirp/ip.h
===================================================================
--- trunk/src/host/qemu-neo1973/slirp/ip.h	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/slirp/ip.h	2007-10-29 21:14:04 UTC (rev 3303)
@@ -272,6 +272,7 @@
 	int8_t	ipopt_list[MAX_IPOPTLEN];	/* options proper */
 };
 
+#ifdef LOG_ENABLED
 /*
  * Structure attached to inpcb.ip_moptions and
  * passed to ip_output when IP multicast options are in use.
@@ -306,8 +307,9 @@
 };
 
 extern struct	ipstat	ipstat;
+#endif
+
 extern struct	ipq	ipq;			/* ip reass. queue */
 extern u_int16_t	ip_id;				/* ip packet ctr, for ids */
-extern int	ip_defttl;			/* default IP ttl */
 
 #endif

Modified: trunk/src/host/qemu-neo1973/slirp/ip_icmp.c
===================================================================
--- trunk/src/host/qemu-neo1973/slirp/ip_icmp.c	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/slirp/ip_icmp.c	2007-10-29 21:14:04 UTC (rev 3303)
@@ -37,14 +37,16 @@
 #include "slirp.h"
 #include "ip_icmp.h"
 
+#ifdef LOG_ENABLED
 struct icmpstat icmpstat;
+#endif
 
 /* The message sent when emulating PING */
-/* Be nice and tell them it's just a psuedo-ping packet */
-char icmp_ping_msg[] = "This is a psuedo-PING packet used by Slirp to emulate ICMP ECHO-REQUEST packets.\n";
+/* Be nice and tell them it's just a pseudo-ping packet */
+const char icmp_ping_msg[] = "This is a pseudo-PING packet used by Slirp to emulate ICMP ECHO-REQUEST packets.\n";
 
 /* list of actions for icmp_error() on RX of an icmp message */
-static int icmp_flush[19] = {
+static const int icmp_flush[19] = {
 /*  ECHO REPLY (0)  */   0,
 		         1,
 		         1,
@@ -83,14 +85,14 @@
   DEBUG_ARG("m = %lx", (long )m);
   DEBUG_ARG("m_len = %d", m->m_len);
 
-  icmpstat.icps_received++;
+  STAT(icmpstat.icps_received++);
 
   /*
    * Locate icmp structure in mbuf, and check
    * that its not corrupted and of at least minimum length.
    */
   if (icmplen < ICMP_MINLEN) {          /* min 8 bytes payload */
-    icmpstat.icps_tooshort++;
+    STAT(icmpstat.icps_tooshort++);
   freeit:
     m_freem(m);
     goto end_error;
@@ -100,7 +102,7 @@
   m->m_data += hlen;
   icp = mtod(m, struct icmp *);
   if (cksum(m, icmplen)) {
-    icmpstat.icps_checksum++;
+    STAT(icmpstat.icps_checksum++);
     goto freeit;
   }
   m->m_len += hlen;
@@ -170,12 +172,12 @@
   case ICMP_TSTAMP:
   case ICMP_MASKREQ:
   case ICMP_REDIRECT:
-    icmpstat.icps_notsupp++;
+    STAT(icmpstat.icps_notsupp++);
     m_freem(m);
     break;
 
   default:
-    icmpstat.icps_badtype++;
+    STAT(icmpstat.icps_badtype++);
     m_freem(m);
   } /* swith */
 
@@ -314,7 +316,7 @@
 
   (void ) ip_output((struct socket *)NULL, m);
 
-  icmpstat.icps_reflect++;
+  STAT(icmpstat.icps_reflect++);
 
 end_error:
   return;
@@ -371,5 +373,5 @@
 
   (void ) ip_output((struct socket *)NULL, m);
 
-  icmpstat.icps_reflect++;
+  STAT(icmpstat.icps_reflect++);
 }

Modified: trunk/src/host/qemu-neo1973/slirp/ip_input.c
===================================================================
--- trunk/src/host/qemu-neo1973/slirp/ip_input.c	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/slirp/ip_input.c	2007-10-29 21:14:04 UTC (rev 3303)
@@ -45,10 +45,19 @@
 #include <slirp.h>
 #include "ip_icmp.h"
 
-int ip_defttl;
+#ifdef LOG_ENABLED
 struct ipstat ipstat;
+#endif
+
 struct ipq ipq;
 
+static struct ip *ip_reass(register struct ipasfrag *ip,
+                           register struct ipq *fp);
+static void ip_freef(struct ipq *fp);
+static void ip_enq(register struct ipasfrag *p,
+                   register struct ipasfrag *prev);
+static void ip_deq(register struct ipasfrag *p);
+
 /*
  * IP initialization: fill in IP protocol switch table.
  * All protocols not implemented in kernel go to raw IP protocol handler.
@@ -60,7 +69,6 @@
 	ip_id = tt.tv_sec & 0xffff;
 	udp_init();
 	tcp_init();
-	ip_defttl = IPDEFTTL;
 }
 
 /*
@@ -78,23 +86,23 @@
 	DEBUG_ARG("m = %lx", (long)m);
 	DEBUG_ARG("m_len = %d", m->m_len);
 
-	ipstat.ips_total++;
+	STAT(ipstat.ips_total++);
 
 	if (m->m_len < sizeof (struct ip)) {
-		ipstat.ips_toosmall++;
+		STAT(ipstat.ips_toosmall++);
 		return;
 	}
 
 	ip = mtod(m, struct ip *);
 
 	if (ip->ip_v != IPVERSION) {
-		ipstat.ips_badvers++;
+		STAT(ipstat.ips_badvers++);
 		goto bad;
 	}
 
 	hlen = ip->ip_hl << 2;
 	if (hlen<sizeof(struct ip ) || hlen>m->m_len) {/* min header length */
-	  ipstat.ips_badhlen++;                     /* or packet too short */
+	  STAT(ipstat.ips_badhlen++);                     /* or packet too short */
 	  goto bad;
 	}
 
@@ -103,7 +111,7 @@
 	 * if (ip->ip_sum) {
 	 */
 	if(cksum(m,hlen)) {
-	  ipstat.ips_badsum++;
+	  STAT(ipstat.ips_badsum++);
 	  goto bad;
 	}
 
@@ -112,7 +120,7 @@
 	 */
 	NTOHS(ip->ip_len);
 	if (ip->ip_len < hlen) {
-		ipstat.ips_badlen++;
+		STAT(ipstat.ips_badlen++);
 		goto bad;
 	}
 	NTOHS(ip->ip_id);
@@ -125,7 +133,7 @@
 	 * Drop packet if shorter than we expect.
 	 */
 	if (m->m_len < ip->ip_len) {
-		ipstat.ips_tooshort++;
+		STAT(ipstat.ips_tooshort++);
 		goto bad;
 	}
 	/* Should drop packet if mbuf too long? hmmm... */
@@ -192,11 +200,11 @@
 		 * attempt reassembly; if it succeeds, proceed.
 		 */
 		if (((struct ipasfrag *)ip)->ipf_mff & 1 || ip->ip_off) {
-			ipstat.ips_fragments++;
+			STAT(ipstat.ips_fragments++);
 			ip = ip_reass((struct ipasfrag *)ip, fp);
 			if (ip == 0)
 				return;
-			ipstat.ips_reassembled++;
+			STAT(ipstat.ips_reassembled++);
 			m = dtom(ip);
 		} else
 			if (fp)
@@ -208,7 +216,7 @@
 	/*
 	 * Switch out to protocol's input routine.
 	 */
-	ipstat.ips_delivered++;
+	STAT(ipstat.ips_delivered++);
 	switch (ip->ip_p) {
 	 case IPPROTO_TCP:
 		tcp_input(m, hlen, (struct socket *)NULL);
@@ -220,7 +228,7 @@
 		icmp_input(m, hlen);
 		break;
 	 default:
-		ipstat.ips_noproto++;
+		STAT(ipstat.ips_noproto++);
 		m_free(m);
 	}
 	return;
@@ -235,10 +243,8 @@
  * reassembly of this datagram already exists, then it
  * is given as fp; otherwise have to make a chain.
  */
-struct ip *
-ip_reass(ip, fp)
-	register struct ipasfrag *ip;
-	register struct ipq *fp;
+static struct ip *
+ip_reass(register struct ipasfrag *ip, register struct ipq *fp)
 {
 	register struct mbuf *m = dtom(ip);
 	register struct ipasfrag *q;
@@ -385,7 +391,7 @@
 	return ((struct ip *)ip);
 
 dropfrag:
-	ipstat.ips_fragdropped++;
+	STAT(ipstat.ips_fragdropped++);
 	m_freem(m);
 	return (0);
 }
@@ -394,9 +400,8 @@
  * Free a fragment reassembly header and all
  * associated datagrams.
  */
-void
-ip_freef(fp)
-	struct ipq *fp;
+static void
+ip_freef(struct ipq *fp)
 {
 	register struct ipasfrag *q, *p;
 
@@ -414,9 +419,8 @@
  * Put an ip fragment on a reassembly chain.
  * Like insque, but pointers in middle of structure.
  */
-void
-ip_enq(p, prev)
-	register struct ipasfrag *p, *prev;
+static void
+ip_enq(register struct ipasfrag *p, register struct ipasfrag *prev)
 {
 	DEBUG_CALL("ip_enq");
 	DEBUG_ARG("prev = %lx", (long)prev);
@@ -429,9 +433,8 @@
 /*
  * To ip_enq as remque is to insque.
  */
-void
-ip_deq(p)
-	register struct ipasfrag *p;
+static void
+ip_deq(register struct ipasfrag *p)
 {
 	((struct ipasfrag *)(p->ipf_prev))->ipf_next = p->ipf_next;
 	((struct ipasfrag *)(p->ipf_next))->ipf_prev = p->ipf_prev;
@@ -457,7 +460,7 @@
 		--fp->ipq_ttl;
 		fp = (struct ipq *) fp->next;
 		if (((struct ipq *)(fp->prev))->ipq_ttl == 0) {
-			ipstat.ips_fragtimeout++;
+			STAT(ipstat.ips_fragtimeout++);
 			ip_freef((struct ipq *) fp->prev);
 		}
 	}
@@ -664,7 +667,7 @@
 /* Not yet */
  	icmp_error(m, type, code, 0, 0);
 
-	ipstat.ips_badoptions++;
+	STAT(ipstat.ips_badoptions++);
 	return (1);
 }
 

Modified: trunk/src/host/qemu-neo1973/slirp/ip_output.c
===================================================================
--- trunk/src/host/qemu-neo1973/slirp/ip_output.c	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/slirp/ip_output.c	2007-10-29 21:14:04 UTC (rev 3303)
@@ -46,6 +46,10 @@
 
 u_int16_t ip_id;
 
+/* Number of packets queued before we start sending
+ * (to prevent allocing too many mbufs) */
+#define IF_THRESH 10
+
 /*
  * IP output.  The packet in mbuf chain m contains a skeletal IP
  * header (with len, off, ttl, proto, tos, src, dst).
@@ -80,14 +84,14 @@
 	ip->ip_off &= IP_DF;
 	ip->ip_id = htons(ip_id++);
 	ip->ip_hl = hlen >> 2;
-	ipstat.ips_localout++;
+	STAT(ipstat.ips_localout++);
 
 	/*
 	 * Verify that we have any chance at all of being able to queue
 	 *      the packet or packet fragments
 	 */
 	/* XXX Hmmm... */
-/*	if (if_queued > if_thresh && towrite <= 0) {
+/*	if (if_queued > IF_THRESH && towrite <= 0) {
  *		error = ENOBUFS;
  *		goto bad;
  *	}
@@ -96,7 +100,7 @@
 	/*
 	 * If small enough for interface, can just send directly.
 	 */
-	if ((u_int16_t)ip->ip_len <= if_mtu) {
+	if ((u_int16_t)ip->ip_len <= IF_MTU) {
 		ip->ip_len = htons((u_int16_t)ip->ip_len);
 		ip->ip_off = htons((u_int16_t)ip->ip_off);
 		ip->ip_sum = 0;
@@ -112,11 +116,11 @@
 	 */
 	if (ip->ip_off & IP_DF) {
 		error = -1;
-		ipstat.ips_cantfrag++;
+		STAT(ipstat.ips_cantfrag++);
 		goto bad;
 	}
 
-	len = (if_mtu - hlen) &~ 7;       /* ip databytes per packet */
+	len = (IF_MTU - hlen) &~ 7;       /* ip databytes per packet */
 	if (len < 8) {
 		error = -1;
 		goto bad;
@@ -137,10 +141,10 @@
 	  m = m_get();
 	  if (m == 0) {
 	    error = -1;
-	    ipstat.ips_odropped++;
+	    STAT(ipstat.ips_odropped++);
 	    goto sendorfree;
 	  }
-	  m->m_data += if_maxlinkhdr;
+	  m->m_data += IF_MAXLINKHDR;
 	  mhip = mtod(m, struct ip *);
 	  *mhip = *ip;
 
@@ -170,7 +174,7 @@
 	  mhip->ip_sum = cksum(m, mhlen);
 	  *mnext = m;
 	  mnext = &m->m_nextpkt;
-	  ipstat.ips_ofragments++;
+	  STAT(ipstat.ips_ofragments++);
 	}
 	/*
 	 * Update first fragment by trimming what's been copied out
@@ -193,7 +197,7 @@
 	}
 
 	if (error == 0)
-		ipstat.ips_fragmented++;
+		STAT(ipstat.ips_fragmented++);
     }
 
 done:

Modified: trunk/src/host/qemu-neo1973/slirp/libslirp.h
===================================================================
--- trunk/src/host/qemu-neo1973/slirp/libslirp.h	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/slirp/libslirp.h	2007-10-29 21:14:04 UTC (rev 3303)
@@ -26,6 +26,8 @@
 extern const char *tftp_prefix;
 extern char slirp_hostname[33];
 
+void slirp_stats(void);
+
 #ifdef __cplusplus
 }
 #endif

Modified: trunk/src/host/qemu-neo1973/slirp/main.h
===================================================================
--- trunk/src/host/qemu-neo1973/slirp/main.h	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/slirp/main.h	2007-10-29 21:14:04 UTC (rev 3303)
@@ -42,7 +42,6 @@
 extern char *socket_path;
 extern int towrite_max;
 extern int ppp_exit;
-extern int so_options;
 extern int tcp_keepintvl;
 extern uint8_t client_ethaddr[6];
 

Modified: trunk/src/host/qemu-neo1973/slirp/mbuf.c
===================================================================
--- trunk/src/host/qemu-neo1973/slirp/mbuf.c	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/slirp/mbuf.c	2007-10-29 21:14:04 UTC (rev 3303)
@@ -21,29 +21,22 @@
 char	*mclrefcnt;
 int mbuf_alloced = 0;
 struct mbuf m_freelist, m_usedlist;
-int mbuf_thresh = 30;
+#define MBUF_THRESH 30
 int mbuf_max = 0;
-int msize;
 
+/*
+ * Find a nice value for msize
+ * XXX if_maxlinkhdr already in mtu
+ */
+#define MSIZE (IF_MTU + IF_MAXLINKHDR + sizeof(struct m_hdr ) + 6)
+
 void
 m_init()
 {
 	m_freelist.m_next = m_freelist.m_prev = &m_freelist;
 	m_usedlist.m_next = m_usedlist.m_prev = &m_usedlist;
-	msize_init();
 }
 
-void
-msize_init()
-{
-	/*
-	 * Find a nice value for msize
-	 * XXX if_maxlinkhdr already in mtu
-	 */
-	msize = (if_mtu>if_mru?if_mtu:if_mru) +
-			if_maxlinkhdr + sizeof(struct m_hdr ) + 6;
-}
-
 /*
  * Get an mbuf from the free list, if there are none
  * malloc one
@@ -61,10 +54,10 @@
 	DEBUG_CALL("m_get");
 
 	if (m_freelist.m_next == &m_freelist) {
-		m = (struct mbuf *)malloc(msize);
+		m = (struct mbuf *)malloc(MSIZE);
 		if (m == NULL) goto end_error;
 		mbuf_alloced++;
-		if (mbuf_alloced > mbuf_thresh)
+		if (mbuf_alloced > MBUF_THRESH)
 			flags = M_DOFREE;
 		if (mbuf_alloced > mbuf_max)
 			mbuf_max = mbuf_alloced;
@@ -78,7 +71,7 @@
 	m->m_flags = (flags | M_USEDLIST);
 
 	/* Initialise it */
-	m->m_size = msize - sizeof(struct m_hdr);
+	m->m_size = MSIZE - sizeof(struct m_hdr);
 	m->m_data = m->m_dat;
 	m->m_len = 0;
 	m->m_nextpkt = 0;

Modified: trunk/src/host/qemu-neo1973/slirp/mbuf.h
===================================================================
--- trunk/src/host/qemu-neo1973/slirp/mbuf.h	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/slirp/mbuf.h	2007-10-29 21:14:04 UTC (rev 3303)
@@ -135,7 +135,6 @@
 extern int mbuf_max;
 
 void m_init _P((void));
-void msize_init _P((void));
 struct mbuf * m_get _P((void));
 void m_free _P((struct mbuf *));
 void m_cat _P((register struct mbuf *, register struct mbuf *));

Modified: trunk/src/host/qemu-neo1973/slirp/misc.c
===================================================================
--- trunk/src/host/qemu-neo1973/slirp/misc.c	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/slirp/misc.c	2007-10-29 21:14:04 UTC (rev 3303)
@@ -8,8 +8,7 @@
 #define WANT_SYS_IOCTL_H
 #include <slirp.h>
 
-u_int curtime, time_fasttimo, last_slowtimo, detach_time;
-u_int detach_wait = 600000;	/* 10 minutes */
+u_int curtime, time_fasttimo, last_slowtimo;
 
 #if 0
 int x_port = -1;
@@ -214,10 +213,7 @@
 #ifdef _WIN32
 
 int
-fork_exec(so, ex, do_pty)
-	struct socket *so;
-	char *ex;
-	int do_pty;
+fork_exec(struct socket *so, const char *ex, int do_pty)
 {
     /* not implemented */
     return 0;
@@ -225,6 +221,7 @@
 
 #else
 
+#ifndef CONFIG_QEMU
 int
 slirp_openpty(amaster, aslave)
      int *amaster, *aslave;
@@ -289,6 +286,7 @@
 	return (-1);
 #endif
 }
+#endif
 
 /*
  * XXX This is ugly
@@ -302,23 +300,20 @@
  * do_ptr = 2   Fork/exec using pty
  */
 int
-fork_exec(so, ex, do_pty)
-	struct socket *so;
-	char *ex;
-	int do_pty;
+fork_exec(struct socket *so, const char *ex, int do_pty)
 {
 	int s;
 	struct sockaddr_in addr;
 	int addrlen = sizeof(addr);
 	int opt;
-        int master;
+        int master = -1;
 	char *argv[256];
 #if 0
 	char buff[256];
 #endif
 	/* don't want to clobber the original */
 	char *bptr;
-	char *curarg;
+	const char *curarg;
 	int c, i, ret;
 
 	DEBUG_CALL("fork_exec");
@@ -327,10 +322,12 @@
 	DEBUG_ARG("do_pty = %lx", (long)do_pty);
 
 	if (do_pty == 2) {
+#if 0
 		if (slirp_openpty(&master, &s) == -1) {
 			lprint("Error: openpty failed: %s\n", strerror(errno));
 			return 0;
 		}
+#endif
 	} else {
 		addr.sin_family = AF_INET;
 		addr.sin_port = 0;
@@ -390,7 +387,7 @@
 		dup2(s, 0);
 		dup2(s, 1);
 		dup2(s, 2);
-		for (s = 3; s <= 255; s++)
+		for (s = getdtablesize() - 1; s >= 3; s--)
 		   close(s);
 
 		i = 0;
@@ -603,6 +600,16 @@
 }
 #endif
 
+#ifdef CONFIG_QEMU
+void lprint(const char *format, ...)
+{
+    va_list args;
+
+    va_start(args, format);
+    term_vprintf(format, args);
+    va_end(args);
+}
+#else
 int (*lprint_print) _P((void *, const char *, va_list));
 char *lprint_ptr, *lprint_ptr2, **lprint_arg;
 
@@ -754,6 +761,7 @@
 
 	lprint("Adding emulation for %s to port %d/%d\r\n", buff1, emup->lport, emup->fport);
 }
+#endif
 
 #ifdef BAD_SPRINTF
 

Modified: trunk/src/host/qemu-neo1973/slirp/misc.h
===================================================================
--- trunk/src/host/qemu-neo1973/slirp/misc.h	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/slirp/misc.h	2007-10-29 21:14:04 UTC (rev 3303)
@@ -12,12 +12,12 @@
 	int ex_pty;			/* Do we want a pty? */
 	int ex_addr;			/* The last byte of the address */
 	int ex_fport;                   /* Port to telnet to */
-	char *ex_exec;                  /* Command line of what to exec */
+	const char *ex_exec;            /* Command line of what to exec */
 	struct ex_list *ex_next;
 };
 
 extern struct ex_list *exec_list;
-extern u_int curtime, time_fasttimo, last_slowtimo, detach_time, detach_wait;
+extern u_int curtime, time_fasttimo, last_slowtimo;
 
 extern int (*lprint_print) _P((void *, const char *, va_list));
 extern char *lprint_ptr, *lprint_ptr2, **lprint_arg;
@@ -74,7 +74,7 @@
 inline  void slirp_remque  _P((void *));
 int add_exec _P((struct ex_list **, int, char *, int, int));
 int slirp_openpty _P((int *, int *));
-int fork_exec _P((struct socket *, char *, int));
+int fork_exec(struct socket *so, const char *ex, int do_pty);
 void snooze_hup _P((int));
 void snooze _P((void));
 void relay _P((int));

Modified: trunk/src/host/qemu-neo1973/slirp/sbuf.c
===================================================================
--- trunk/src/host/qemu-neo1973/slirp/sbuf.c	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/slirp/sbuf.c	2007-10-29 21:14:04 UTC (rev 3303)
@@ -7,6 +7,8 @@
 
 #include <slirp.h>
 
+static void sbappendsb(struct sbuf *sb, struct mbuf *m);
+
 /* Done as a macro in socket.h */
 /* int
  * sbspace(struct sockbuff *sb)
@@ -133,10 +135,8 @@
  * Copy the data from m into sb
  * The caller is responsible to make sure there's enough room
  */
-void
-sbappendsb(sb, m)
-	 struct sbuf *sb;
-	 struct mbuf *m;
+static void
+sbappendsb(struct sbuf *sb, struct mbuf *m)
 {
 	int len, n,  nn;
 

Modified: trunk/src/host/qemu-neo1973/slirp/sbuf.h
===================================================================
--- trunk/src/host/qemu-neo1973/slirp/sbuf.h	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/slirp/sbuf.h	2007-10-29 21:14:04 UTC (rev 3303)
@@ -25,7 +25,6 @@
 void sbdrop _P((struct sbuf *, int));
 void sbreserve _P((struct sbuf *, int));
 void sbappend _P((struct socket *, struct mbuf *));
-void sbappendsb _P((struct sbuf *, struct mbuf *));
 void sbcopy _P((struct sbuf *, int, int, char *));
 
 #endif

Modified: trunk/src/host/qemu-neo1973/slirp/slirp.c
===================================================================
--- trunk/src/host/qemu-neo1973/slirp/slirp.c	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/slirp/slirp.c	2007-10-29 21:14:04 UTC (rev 3303)
@@ -12,7 +12,7 @@
 /* virtual address alias for host */
 struct in_addr alias_addr;
 
-const uint8_t special_ethaddr[6] = {
+static const uint8_t special_ethaddr[6] = {
     0x52, 0x54, 0x00, 0x12, 0x35, 0x00
 };
 
@@ -93,7 +93,9 @@
     if (!f)
         return -1;
 
+#ifdef DEBUG
     lprint("IP address of your DNS(s): ");
+#endif
     while (fgets(buff, 512, f) != NULL) {
         if (sscanf(buff, "nameserver%*[ \t]%256s", buff2) == 1) {
             if (!inet_aton(buff2, &tmp_addr))
@@ -103,13 +105,20 @@
             /* If it's the first one, set it to dns_addr */
             if (!found)
                 *pdns_addr = tmp_addr;
+#ifdef DEBUG
             else
                 lprint(", ");
+#endif
             if (++found > 3) {
+#ifdef DEBUG
                 lprint("(more)");
+#endif
                 break;
-            } else
+            }
+#ifdef DEBUG
+            else
                 lprint("%s", inet_ntoa(tmp_addr));
+#endif
         }
     }
     fclose(f);
@@ -121,7 +130,7 @@
 #endif
 
 #ifdef _WIN32
-void slirp_cleanup(void)
+static void slirp_cleanup(void)
 {
     WSACleanup();
 }

Modified: trunk/src/host/qemu-neo1973/slirp/slirp.h
===================================================================
--- trunk/src/host/qemu-neo1973/slirp/slirp.h	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/slirp/slirp.h	2007-10-29 21:14:04 UTC (rev 3303)
@@ -3,8 +3,17 @@
 
 #define CONFIG_QEMU
 
-#define DEBUG 1
+//#define DEBUG 1
 
+// Uncomment the following line to enable SLIRP statistics printing in Qemu
+//#define LOG_ENABLED
+
+#ifdef LOG_ENABLED
+#define STAT(expr) expr
+#else
+#define STAT(expr) do { } while(0)
+#endif
+
 #ifndef CONFIG_QEMU
 #include "version.h"
 #endif
@@ -255,8 +264,6 @@
 
 void lprint _P((const char *, ...));
 
-extern int do_echo;
-
 #if SIZEOF_CHAR_P == 4
 # define insque_32 insque
 # define remque_32 remque
@@ -271,6 +278,9 @@
 
 #define DEFAULT_BAUD 115200
 
+#define SO_OPTIONS DO_KEEPALIVE
+#define TCP_MAXIDLE (TCPTV_KEEPCNT * TCPTV_KEEPINTVL)
+
 /* cksum.c */
 int cksum(struct mbuf *m, int len);
 
@@ -281,10 +291,6 @@
 /* ip_input.c */
 void ip_init _P((void));
 void ip_input _P((struct mbuf *));
-struct ip * ip_reass _P((register struct ipasfrag *, register struct ipq *));
-void ip_freef _P((struct ipq *));
-void ip_enq _P((register struct ipasfrag *, register struct ipasfrag *));
-void ip_deq _P((register struct ipasfrag *));
 void ip_slowtimo _P((void));
 void ip_stripoptions _P((register struct mbuf *, struct mbuf *));
 
@@ -292,10 +298,7 @@
 int ip_output _P((struct socket *, struct mbuf *));
 
 /* tcp_input.c */
-int tcp_reass _P((register struct tcpcb *, register struct tcpiphdr *, struct mbuf *));
 void tcp_input _P((register struct mbuf *, int, struct socket *));
-void tcp_dooptions _P((struct tcpcb *, u_char *, int, struct tcpiphdr *));
-void tcp_xmit_timer _P((register struct tcpcb *, int));
 int tcp_mss _P((register struct tcpcb *, u_int));
 
 /* tcp_output.c */
@@ -308,7 +311,6 @@
 void tcp_respond _P((struct tcpcb *, register struct tcpiphdr *, register struct mbuf *, tcp_seq, tcp_seq, int));
 struct tcpcb * tcp_newtcpcb _P((struct socket *));
 struct tcpcb * tcp_close _P((register struct tcpcb *));
-void tcp_drain _P((void));
 void tcp_sockclosed _P((struct tcpcb *));
 int tcp_fconnect _P((struct socket *));
 void tcp_connect _P((struct socket *));

Modified: trunk/src/host/qemu-neo1973/slirp/socket.c
===================================================================
--- trunk/src/host/qemu-neo1973/slirp/socket.c	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/slirp/socket.c	2007-10-29 21:14:04 UTC (rev 3303)
@@ -13,13 +13,17 @@
 #include <sys/filio.h>
 #endif
 
-void
+static void sofcantrcvmore(struct socket *so);
+static void sofcantsendmore(struct socket *so);
+
+#if 0
+static void
 so_init()
 {
 	/* Nothing yet */
 }
+#endif
 
-
 struct socket *
 solookup(head, laddr, lport, faddr, fport)
 	struct socket *head;
@@ -421,7 +425,7 @@
 	  int len, n;
 
 	  if (!(m = m_get())) return;
-	  m->m_data += if_maxlinkhdr;
+	  m->m_data += IF_MAXLINKHDR;
 
 	  /*
 	   * XXX Shouldn't FIONREAD packets destined for port 53,
@@ -604,12 +608,13 @@
 	return so;
 }
 
+#if 0
 /*
  * Data is available in so_rcv
  * Just write() the data to the socket
  * XXX not yet...
  */
-void
+static void
 sorwakeup(so)
 	struct socket *so;
 {
@@ -622,12 +627,13 @@
  * We have room for a read() if we want to
  * For now, don't read, it'll be done in the main loop
  */
-void
+static void
 sowwakeup(so)
 	struct socket *so;
 {
 	/* Nothing, yet */
 }
+#endif
 
 /*
  * Various session state calls
@@ -652,9 +658,8 @@
 	so->so_state |= SS_ISFCONNECTED; /* Clobber other states */
 }
 
-void
-sofcantrcvmore(so)
-	struct  socket *so;
+static void
+sofcantrcvmore(struct socket *so)
 {
 	if ((so->so_state & SS_NOFDREF) == 0) {
 		shutdown(so->s,0);
@@ -669,9 +674,8 @@
 	   so->so_state |= SS_FCANTRCVMORE;
 }
 
-void
-sofcantsendmore(so)
-	struct socket *so;
+static void
+sofcantsendmore(struct socket *so)
 {
 	if ((so->so_state & SS_NOFDREF) == 0) {
             shutdown(so->s,1);           /* send FIN to fhost */

Modified: trunk/src/host/qemu-neo1973/slirp/socket.h
===================================================================
--- trunk/src/host/qemu-neo1973/slirp/socket.h	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/slirp/socket.h	2007-10-29 21:14:04 UTC (rev 3303)
@@ -81,7 +81,6 @@
 };
 #endif
 
-void so_init _P((void));
 struct socket * solookup _P((struct socket *, struct in_addr, u_int, struct in_addr, u_int));
 struct socket * socreate _P((void));
 void sofree _P((struct socket *));
@@ -92,12 +91,8 @@
 void sorecvfrom _P((struct socket *));
 int sosendto _P((struct socket *, struct mbuf *));
 struct socket * solisten _P((u_int, u_int32_t, u_int, int));
-void sorwakeup _P((struct socket *));
-void sowwakeup _P((struct socket *));
 void soisfconnecting _P((register struct socket *));
 void soisfconnected _P((register struct socket *));
-void sofcantrcvmore _P((struct  socket *));
-void sofcantsendmore _P((struct socket *));
 void soisfdisconnected _P((struct socket *));
 void sofwdrain _P((struct socket *));
 

Modified: trunk/src/host/qemu-neo1973/slirp/tcp.h
===================================================================
--- trunk/src/host/qemu-neo1973/slirp/tcp.h	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/slirp/tcp.h	2007-10-29 21:14:04 UTC (rev 3303)
@@ -42,8 +42,6 @@
 #define      PR_SLOWHZ       2               /* 2 slow timeouts per second (approx) */
 #define      PR_FASTHZ       5               /* 5 fast timeouts per second (not important) */
 
-extern int tcp_rcvspace;
-extern int tcp_sndspace;
 extern struct socket *tcp_last_so;
 
 #define TCP_SNDSPACE 8192
@@ -172,6 +170,6 @@
 
 extern tcp_seq tcp_iss;                /* tcp initial send seq # */
 
-extern char *tcpstates[];
+extern const char * const tcpstates[];
 
 #endif

Modified: trunk/src/host/qemu-neo1973/slirp/tcp_input.c
===================================================================
--- trunk/src/host/qemu-neo1973/slirp/tcp_input.c	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/slirp/tcp_input.c	2007-10-29 21:14:04 UTC (rev 3303)
@@ -47,7 +47,7 @@
 
 struct socket tcb;
 
-int	tcprexmtthresh = 3;
+#define	TCPREXMTTHRESH 3
 struct	socket *tcp_last_so = &tcb;
 
 tcp_seq tcp_iss;                /* tcp initial send seq # */
@@ -79,8 +79,8 @@
                        tp->t_flags |= TF_DELACK; \
                (tp)->rcv_nxt += (ti)->ti_len; \
                flags = (ti)->ti_flags & TH_FIN; \
-               tcpstat.tcps_rcvpack++;\
-               tcpstat.tcps_rcvbyte += (ti)->ti_len;\
+               STAT(tcpstat.tcps_rcvpack++);         \
+               STAT(tcpstat.tcps_rcvbyte += (ti)->ti_len);   \
                if (so->so_emu) { \
 		       if (tcp_emu((so),(m))) sbappend((so), (m)); \
 	       } else \
@@ -99,8 +99,8 @@
 		tp->t_flags |= TF_DELACK; \
 		(tp)->rcv_nxt += (ti)->ti_len; \
 		flags = (ti)->ti_flags & TH_FIN; \
-		tcpstat.tcps_rcvpack++;\
-		tcpstat.tcps_rcvbyte += (ti)->ti_len;\
+		STAT(tcpstat.tcps_rcvpack++);        \
+		STAT(tcpstat.tcps_rcvbyte += (ti)->ti_len);  \
 		if (so->so_emu) { \
 			if (tcp_emu((so),(m))) sbappend(so, (m)); \
 		} else \
@@ -112,12 +112,13 @@
 	} \
 }
 #endif
+static void tcp_dooptions(struct tcpcb *tp, u_char *cp, int cnt,
+                          struct tcpiphdr *ti);
+static void tcp_xmit_timer(register struct tcpcb *tp, int rtt);
 
-int
-tcp_reass(tp, ti, m)
-	register struct tcpcb *tp;
-	register struct tcpiphdr *ti;
-	struct mbuf *m;
+static int
+tcp_reass(register struct tcpcb *tp, register struct tcpiphdr *ti,
+          struct mbuf *m)
 {
 	register struct tcpiphdr *q;
 	struct socket *so = tp->t_socket;
@@ -150,8 +151,8 @@
 		i = q->ti_seq + q->ti_len - ti->ti_seq;
 		if (i > 0) {
 			if (i >= ti->ti_len) {
-				tcpstat.tcps_rcvduppack++;
-				tcpstat.tcps_rcvdupbyte += ti->ti_len;
+				STAT(tcpstat.tcps_rcvduppack++);
+				STAT(tcpstat.tcps_rcvdupbyte += ti->ti_len);
 				m_freem(m);
 				/*
 				 * Try to present any queued data
@@ -167,8 +168,8 @@
 		}
 		q = (struct tcpiphdr *)(q->ti_next);
 	}
-	tcpstat.tcps_rcvoopack++;
-	tcpstat.tcps_rcvoobyte += ti->ti_len;
+	STAT(tcpstat.tcps_rcvoopack++);
+	STAT(tcpstat.tcps_rcvoobyte += ti->ti_len);
 	REASS_MBUF(ti) = (mbufp_32) m;		/* XXX */
 
 	/*
@@ -275,7 +276,7 @@
 	}
 
 
-	tcpstat.tcps_rcvtotal++;
+	STAT(tcpstat.tcps_rcvtotal++);
 	/*
 	 * Get IP and TCP header together in first mbuf.
 	 * Note: IP leaves IP header in first mbuf.
@@ -308,7 +309,7 @@
 	 * ti->ti_sum = cksum(m, len);
 	 * if (ti->ti_sum) { */
 	if(cksum(m, len)) {
-	  tcpstat.tcps_rcvbadsum++;
+	  STAT(tcpstat.tcps_rcvbadsum++);
 	  goto drop;
 	}
 
@@ -318,7 +319,7 @@
 	 */
 	off = ti->ti_off << 2;
 	if (off < sizeof (struct tcphdr) || off > tlen) {
-	  tcpstat.tcps_rcvbadoff++;
+	  STAT(tcpstat.tcps_rcvbadoff++);
 	  goto drop;
 	}
 	tlen -= off;
@@ -375,7 +376,7 @@
 			       ti->ti_dst, ti->ti_dport);
 		if (so)
 			tcp_last_so = so;
-		++tcpstat.tcps_socachemiss;
+		STAT(tcpstat.tcps_socachemiss++);
 	}
 
 	/*
@@ -402,8 +403,8 @@
 	    goto dropwithreset;
 	  }
 
-	  sbreserve(&so->so_snd, tcp_sndspace);
-	  sbreserve(&so->so_rcv, tcp_rcvspace);
+	  sbreserve(&so->so_snd, TCP_SNDSPACE);
+	  sbreserve(&so->so_rcv, TCP_RCVSPACE);
 
 	  /*		tcp_last_so = so; */  /* XXX ? */
 	  /*		tp = sototcpcb(so);    */
@@ -448,10 +449,10 @@
 	 * Reset idle time and keep-alive timer.
 	 */
 	tp->t_idle = 0;
-	if (so_options)
-	   tp->t_timer[TCPT_KEEP] = tcp_keepintvl;
+	if (SO_OPTIONS)
+	   tp->t_timer[TCPT_KEEP] = TCPTV_KEEPINTVL;
 	else
-	   tp->t_timer[TCPT_KEEP] = tcp_keepidle;
+	   tp->t_timer[TCPT_KEEP] = TCPTV_KEEP_IDLE;
 
 	/*
 	 * Process options if not in LISTEN state,
@@ -503,7 +504,7 @@
 				/*
 				 * this is a pure ack for outstanding data.
 				 */
-				++tcpstat.tcps_predack;
+				STAT(tcpstat.tcps_predack++);
 /*				if (ts_present)
  *					tcp_xmit_timer(tp, tcp_now-ts_ecr+1);
  *				else
@@ -511,8 +512,8 @@
 					    SEQ_GT(ti->ti_ack, tp->t_rtseq))
 					tcp_xmit_timer(tp, tp->t_rtt);
 				acked = ti->ti_ack - tp->snd_una;
-				tcpstat.tcps_rcvackpack++;
-				tcpstat.tcps_rcvackbyte += acked;
+				STAT(tcpstat.tcps_rcvackpack++);
+				STAT(tcpstat.tcps_rcvackbyte += acked);
 				sbdrop(&so->so_snd, acked);
 				tp->snd_una = ti->ti_ack;
 				m_freem(m);
@@ -556,10 +557,10 @@
 			 * with nothing on the reassembly queue and
 			 * we have enough buffer space to take it.
 			 */
-			++tcpstat.tcps_preddat;
+			STAT(tcpstat.tcps_preddat++);
 			tp->rcv_nxt += ti->ti_len;
-			tcpstat.tcps_rcvpack++;
-			tcpstat.tcps_rcvbyte += ti->ti_len;
+			STAT(tcpstat.tcps_rcvpack++);
+			STAT(tcpstat.tcps_rcvbyte += ti->ti_len);
 			/*
 			 * Add data to socket buffer.
 			 */
@@ -726,7 +727,7 @@
 	  tp->t_flags |= TF_ACKNOW;
 	  tp->t_state = TCPS_SYN_RECEIVED;
 	  tp->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT;
-	  tcpstat.tcps_accepts++;
+	  STAT(tcpstat.tcps_accepts++);
 	  goto trimthenstep6;
 	} /* case TCPS_LISTEN */
 
@@ -767,7 +768,7 @@
 		tcp_rcvseqinit(tp);
 		tp->t_flags |= TF_ACKNOW;
 		if (tiflags & TH_ACK && SEQ_GT(tp->snd_una, tp->iss)) {
-			tcpstat.tcps_connects++;
+			STAT(tcpstat.tcps_connects++);
 			soisfconnected(so);
 			tp->t_state = TCPS_ESTABLISHED;
 
@@ -801,8 +802,8 @@
 			m_adj(m, -todrop);
 			ti->ti_len = tp->rcv_wnd;
 			tiflags &= ~TH_FIN;
-			tcpstat.tcps_rcvpackafterwin++;
-			tcpstat.tcps_rcvbyteafterwin += todrop;
+			STAT(tcpstat.tcps_rcvpackafterwin++);
+			STAT(tcpstat.tcps_rcvbyteafterwin += todrop);
 		}
 		tp->snd_wl1 = ti->ti_seq - 1;
 		tp->rcv_up = ti->ti_seq;
@@ -873,11 +874,11 @@
 			 */
 			tp->t_flags |= TF_ACKNOW;
 			todrop = ti->ti_len;
-			tcpstat.tcps_rcvduppack++;
-			tcpstat.tcps_rcvdupbyte += todrop;
+			STAT(tcpstat.tcps_rcvduppack++);
+			STAT(tcpstat.tcps_rcvdupbyte += todrop);
 		} else {
-			tcpstat.tcps_rcvpartduppack++;
-			tcpstat.tcps_rcvpartdupbyte += todrop;
+			STAT(tcpstat.tcps_rcvpartduppack++);
+			STAT(tcpstat.tcps_rcvpartdupbyte += todrop);
 		}
 		m_adj(m, todrop);
 		ti->ti_seq += todrop;
@@ -896,7 +897,7 @@
 	if ((so->so_state & SS_NOFDREF) &&
 	    tp->t_state > TCPS_CLOSE_WAIT && ti->ti_len) {
 		tp = tcp_close(tp);
-		tcpstat.tcps_rcvafterclose++;
+		STAT(tcpstat.tcps_rcvafterclose++);
 		goto dropwithreset;
 	}
 
@@ -906,9 +907,9 @@
 	 */
 	todrop = (ti->ti_seq+ti->ti_len) - (tp->rcv_nxt+tp->rcv_wnd);
 	if (todrop > 0) {
-		tcpstat.tcps_rcvpackafterwin++;
+		STAT(tcpstat.tcps_rcvpackafterwin++);
 		if (todrop >= ti->ti_len) {
-			tcpstat.tcps_rcvbyteafterwin += ti->ti_len;
+			STAT(tcpstat.tcps_rcvbyteafterwin += ti->ti_len);
 			/*
 			 * If a new connection request is received
 			 * while in TIME_WAIT, drop the old connection
@@ -931,11 +932,11 @@
 			 */
 			if (tp->rcv_wnd == 0 && ti->ti_seq == tp->rcv_nxt) {
 				tp->t_flags |= TF_ACKNOW;
-				tcpstat.tcps_rcvwinprobe++;
+				STAT(tcpstat.tcps_rcvwinprobe++);
 			} else
 				goto dropafterack;
 		} else
-			tcpstat.tcps_rcvbyteafterwin += todrop;
+			STAT(tcpstat.tcps_rcvbyteafterwin += todrop);
 		m_adj(m, -todrop);
 		ti->ti_len -= todrop;
 		tiflags &= ~(TH_PUSH|TH_FIN);
@@ -976,7 +977,7 @@
 /*		so->so_error = ECONNRESET; */
 	close:
 		tp->t_state = TCPS_CLOSED;
-		tcpstat.tcps_drops++;
+		STAT(tcpstat.tcps_drops++);
 		tp = tcp_close(tp);
 		goto drop;
 
@@ -1015,7 +1016,7 @@
 		if (SEQ_GT(tp->snd_una, ti->ti_ack) ||
 		    SEQ_GT(ti->ti_ack, tp->snd_max))
 			goto dropwithreset;
-		tcpstat.tcps_connects++;
+		STAT(tcpstat.tcps_connects++);
 		tp->t_state = TCPS_ESTABLISHED;
 		/*
 		 * The sent SYN is ack'ed with our sequence number +1
@@ -1072,7 +1073,7 @@
 
 		if (SEQ_LEQ(ti->ti_ack, tp->snd_una)) {
 			if (ti->ti_len == 0 && tiwin == tp->snd_wnd) {
-			  tcpstat.tcps_rcvdupack++;
+			  STAT(tcpstat.tcps_rcvdupack++);
 			  DEBUG_MISC((dfd," dup ack  m = %lx  so = %lx \n",
 				      (long )m, (long )so));
 				/*
@@ -1102,7 +1103,7 @@
 				if (tp->t_timer[TCPT_REXMT] == 0 ||
 				    ti->ti_ack != tp->snd_una)
 					tp->t_dupacks = 0;
-				else if (++tp->t_dupacks == tcprexmtthresh) {
+				else if (++tp->t_dupacks == TCPREXMTTHRESH) {
 					tcp_seq onxt = tp->snd_nxt;
 					u_int win =
 					    min(tp->snd_wnd, tp->snd_cwnd) / 2 /
@@ -1121,7 +1122,7 @@
 					if (SEQ_GT(onxt, tp->snd_nxt))
 						tp->snd_nxt = onxt;
 					goto drop;
-				} else if (tp->t_dupacks > tcprexmtthresh) {
+				} else if (tp->t_dupacks > TCPREXMTTHRESH) {
 					tp->snd_cwnd += tp->t_maxseg;
 					(void) tcp_output(tp);
 					goto drop;
@@ -1135,17 +1136,17 @@
 		 * If the congestion window was inflated to account
 		 * for the other side's cached packets, retract it.
 		 */
-		if (tp->t_dupacks > tcprexmtthresh &&
+		if (tp->t_dupacks > TCPREXMTTHRESH &&
 		    tp->snd_cwnd > tp->snd_ssthresh)
 			tp->snd_cwnd = tp->snd_ssthresh;
 		tp->t_dupacks = 0;
 		if (SEQ_GT(ti->ti_ack, tp->snd_max)) {
-			tcpstat.tcps_rcvacktoomuch++;
+			STAT(tcpstat.tcps_rcvacktoomuch++);
 			goto dropafterack;
 		}
 		acked = ti->ti_ack - tp->snd_una;
-		tcpstat.tcps_rcvackpack++;
-		tcpstat.tcps_rcvackbyte += acked;
+		STAT(tcpstat.tcps_rcvackpack++);
+		STAT(tcpstat.tcps_rcvackbyte += acked);
 
 		/*
 		 * If we have a timestamp reply, update smoothed
@@ -1227,7 +1228,7 @@
 				 */
 				if (so->so_state & SS_FCANTRCVMORE) {
 					soisfdisconnected(so);
-					tp->t_timer[TCPT_2MSL] = tcp_maxidle;
+					tp->t_timer[TCPT_2MSL] = TCP_MAXIDLE;
 				}
 				tp->t_state = TCPS_FIN_WAIT_2;
 			}
@@ -1284,7 +1285,7 @@
 		/* keep track of pure window updates */
 		if (ti->ti_len == 0 &&
 		    tp->snd_wl2 == ti->ti_ack && tiwin > tp->snd_wnd)
-			tcpstat.tcps_rcvwinupd++;
+			STAT(tcpstat.tcps_rcvwinupd++);
 		tp->snd_wnd = tiwin;
 		tp->snd_wl1 = ti->ti_seq;
 		tp->snd_wl2 = ti->ti_ack;
@@ -1490,12 +1491,8 @@
 /*	int *ts_present;
  *	u_int32_t *ts_val, *ts_ecr;
  */
-void
-tcp_dooptions(tp, cp, cnt, ti)
-	struct tcpcb *tp;
-	u_char *cp;
-	int cnt;
-	struct tcpiphdr *ti;
+static void
+tcp_dooptions(struct tcpcb *tp, u_char *cp, int cnt, struct tcpiphdr *ti)
 {
 	u_int16_t mss;
 	int opt, optlen;
@@ -1605,10 +1602,8 @@
  * and update averages and current timeout.
  */
 
-void
-tcp_xmit_timer(tp, rtt)
-	register struct tcpcb *tp;
-	int rtt;
+static void
+tcp_xmit_timer(register struct tcpcb *tp, int rtt)
 {
 	register short delta;
 
@@ -1616,7 +1611,7 @@
 	DEBUG_ARG("tp = %lx", (long)tp);
 	DEBUG_ARG("rtt = %d", rtt);
 
-	tcpstat.tcps_rttupdated++;
+	STAT(tcpstat.tcps_rttupdated++);
 	if (tp->t_srtt != 0) {
 		/*
 		 * srtt is stored as fixed point with 3 bits after the
@@ -1707,7 +1702,7 @@
 	DEBUG_ARG("tp = %lx", (long)tp);
 	DEBUG_ARG("offer = %d", offer);
 
-	mss = min(if_mtu, if_mru) - sizeof(struct tcpiphdr);
+	mss = min(IF_MTU, IF_MRU) - sizeof(struct tcpiphdr);
 	if (offer)
 		mss = min(mss, offer);
 	mss = max(mss, 32);
@@ -1716,8 +1711,12 @@
 
 	tp->snd_cwnd = mss;
 
-	sbreserve(&so->so_snd, tcp_sndspace+((tcp_sndspace%mss)?(mss-(tcp_sndspace%mss)):0));
-	sbreserve(&so->so_rcv, tcp_rcvspace+((tcp_rcvspace%mss)?(mss-(tcp_rcvspace%mss)):0));
+	sbreserve(&so->so_snd, TCP_SNDSPACE + ((TCP_SNDSPACE % mss) ?
+                                               (mss - (TCP_SNDSPACE % mss)) :
+                                               0));
+	sbreserve(&so->so_rcv, TCP_RCVSPACE + ((TCP_RCVSPACE % mss) ?
+                                               (mss - (TCP_RCVSPACE % mss)) :
+                                               0));
 
 	DEBUG_MISC((dfd, " returning mss = %d\n", mss));
 

Modified: trunk/src/host/qemu-neo1973/slirp/tcp_output.c
===================================================================
--- trunk/src/host/qemu-neo1973/slirp/tcp_output.c	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/slirp/tcp_output.c	2007-10-29 21:14:04 UTC (rev 3303)
@@ -48,14 +48,14 @@
  * Since this is only used in "stats socket", we give meaning
  * names instead of the REAL names
  */
-char *tcpstates[] = {
+const char * const tcpstates[] = {
 /*	"CLOSED",       "LISTEN",       "SYN_SENT",     "SYN_RCVD", */
 	"REDIRECT",	"LISTEN",	"SYN_SENT",     "SYN_RCVD",
 	"ESTABLISHED",  "CLOSE_WAIT",   "FIN_WAIT_1",   "CLOSING",
 	"LAST_ACK",     "FIN_WAIT_2",   "TIME_WAIT",
 };
 
-u_char  tcp_outflags[TCP_NSTATES] = {
+static const u_char  tcp_outflags[TCP_NSTATES] = {
 	TH_RST|TH_ACK, 0,      TH_SYN,        TH_SYN|TH_ACK,
 	TH_ACK,        TH_ACK, TH_FIN|TH_ACK, TH_FIN|TH_ACK,
 	TH_FIN|TH_ACK, TH_ACK, TH_ACK,
@@ -263,7 +263,7 @@
 	/*
 	 * No reason to send a segment, just return.
 	 */
-	tcpstat.tcps_didnuttin++;
+	STAT(tcpstat.tcps_didnuttin++);
 
 	return (0);
 
@@ -339,13 +339,13 @@
 	 */
 	if (len) {
 		if (tp->t_force && len == 1)
-			tcpstat.tcps_sndprobe++;
+			STAT(tcpstat.tcps_sndprobe++);
 		else if (SEQ_LT(tp->snd_nxt, tp->snd_max)) {
-			tcpstat.tcps_sndrexmitpack++;
-			tcpstat.tcps_sndrexmitbyte += len;
+			STAT(tcpstat.tcps_sndrexmitpack++);
+			STAT(tcpstat.tcps_sndrexmitbyte += len);
 		} else {
-			tcpstat.tcps_sndpack++;
-			tcpstat.tcps_sndbyte += len;
+			STAT(tcpstat.tcps_sndpack++);
+			STAT(tcpstat.tcps_sndbyte += len);
 		}
 
 		m = m_get();
@@ -354,7 +354,7 @@
 			error = 1;
 			goto out;
 		}
-		m->m_data += if_maxlinkhdr;
+		m->m_data += IF_MAXLINKHDR;
 		m->m_len = hdrlen;
 
 		/*
@@ -382,13 +382,13 @@
 			flags |= TH_PUSH;
 	} else {
 		if (tp->t_flags & TF_ACKNOW)
-			tcpstat.tcps_sndacks++;
+			STAT(tcpstat.tcps_sndacks++);
 		else if (flags & (TH_SYN|TH_FIN|TH_RST))
-			tcpstat.tcps_sndctrl++;
+			STAT(tcpstat.tcps_sndctrl++);
 		else if (SEQ_GT(tp->snd_up, tp->snd_una))
-			tcpstat.tcps_sndurg++;
+			STAT(tcpstat.tcps_sndurg++);
 		else
-			tcpstat.tcps_sndwinup++;
+			STAT(tcpstat.tcps_sndwinup++);
 
 		m = m_get();
 		if (m == NULL) {
@@ -396,7 +396,7 @@
 			error = 1;
 			goto out;
 		}
-		m->m_data += if_maxlinkhdr;
+		m->m_data += IF_MAXLINKHDR;
 		m->m_len = hdrlen;
 	}
 
@@ -500,7 +500,7 @@
 			if (tp->t_rtt == 0) {
 				tp->t_rtt = 1;
 				tp->t_rtseq = startseq;
-				tcpstat.tcps_segstimed++;
+				STAT(tcpstat.tcps_segstimed++);
 			}
 		}
 
@@ -536,7 +536,7 @@
 
 	((struct ip *)ti)->ip_len = m->m_len;
 
-	((struct ip *)ti)->ip_ttl = ip_defttl;
+	((struct ip *)ti)->ip_ttl = IPDEFTTL;
 	((struct ip *)ti)->ip_tos = so->so_iptos;
 
 /* #if BSD >= 43 */
@@ -567,7 +567,7 @@
  */
 		return (error);
 	}
-	tcpstat.tcps_sndtotal++;
+	STAT(tcpstat.tcps_sndtotal++);
 
 	/*
 	 * Data sent (as far as we can tell).

Modified: trunk/src/host/qemu-neo1973/slirp/tcp_subr.c
===================================================================
--- trunk/src/host/qemu-neo1973/slirp/tcp_subr.c	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/slirp/tcp_subr.c	2007-10-29 21:14:04 UTC (rev 3303)
@@ -46,11 +46,8 @@
 #include <slirp.h>
 
 /* patchable/settable parameters for tcp */
-int 	tcp_mssdflt = TCP_MSS;
-int 	tcp_rttdflt = TCPTV_SRTTDFLT / PR_SLOWHZ;
-int	tcp_do_rfc1323 = 0;	/* Don't do rfc1323 performance enhancements */
-int	tcp_rcvspace;	/* You may want to change this */
-int	tcp_sndspace;	/* Keep small if you have an error prone link */
+/* Don't do rfc1323 performance enhancements */
+#define TCP_DO_RFC1323 0
 
 /*
  * Tcp initialization
@@ -60,14 +57,6 @@
 {
 	tcp_iss = 1;		/* wrong */
 	tcb.so_next = tcb.so_prev = &tcb;
-
-	/* tcp_rcvspace = our Window we advertise to the remote */
-	tcp_rcvspace = TCP_RCVSPACE;
-	tcp_sndspace = TCP_SNDSPACE;
-
-	/* Make sure tcp_sndspace is at least 2*MSS */
-	if (tcp_sndspace < 2*(min(if_mtu, if_mru) - sizeof(struct tcpiphdr)))
-		tcp_sndspace = 2*(min(if_mtu, if_mru) - sizeof(struct tcpiphdr));
 }
 
 /*
@@ -145,7 +134,7 @@
 #else
 		tlen = 0;
 #endif
-		m->m_data += if_maxlinkhdr;
+		m->m_data += IF_MAXLINKHDR;
 		*mtod(m, struct tcpiphdr *) = *ti;
 		ti = mtod(m, struct tcpiphdr *);
 		flags = TH_ACK;
@@ -186,7 +175,7 @@
 	if(flags & TH_RST)
 	  ((struct ip *)ti)->ip_ttl = MAXTTL;
 	else
-	  ((struct ip *)ti)->ip_ttl = ip_defttl;
+	  ((struct ip *)ti)->ip_ttl = IPDEFTTL;
 
 	(void) ip_output((struct socket *)0, m);
 }
@@ -208,9 +197,9 @@
 
 	memset((char *) tp, 0, sizeof(struct tcpcb));
 	tp->seg_next = tp->seg_prev = (tcpiphdrp_32)tp;
-	tp->t_maxseg = tcp_mssdflt;
+	tp->t_maxseg = TCP_MSS;
 
-	tp->t_flags = tcp_do_rfc1323 ? (TF_REQ_SCALE|TF_REQ_TSTMP) : 0;
+	tp->t_flags = TCP_DO_RFC1323 ? (TF_REQ_SCALE|TF_REQ_TSTMP) : 0;
 	tp->t_socket = so;
 
 	/*
@@ -219,7 +208,7 @@
 	 * reasonable initial retransmit time.
 	 */
 	tp->t_srtt = TCPTV_SRTTBASE;
-	tp->t_rttvar = tcp_rttdflt * PR_SLOWHZ << 2;
+	tp->t_rttvar = TCPTV_SRTTDFLT << 2;
 	tp->t_rttmin = TCPTV_MIN;
 
 	TCPT_RANGESET(tp->t_rxtcur,
@@ -255,9 +244,9 @@
 	if (TCPS_HAVERCVDSYN(tp->t_state)) {
 		tp->t_state = TCPS_CLOSED;
 		(void) tcp_output(tp);
-		tcpstat.tcps_drops++;
+		STAT(tcpstat.tcps_drops++);
 	} else
-		tcpstat.tcps_conndrops++;
+		STAT(tcpstat.tcps_conndrops++);
 /*	if (errno == ETIMEDOUT && tp->t_softerror)
  *		errno = tp->t_softerror;
  */
@@ -305,10 +294,11 @@
 	sbfree(&so->so_rcv);
 	sbfree(&so->so_snd);
 	sofree(so);
-	tcpstat.tcps_closed++;
+	STAT(tcpstat.tcps_closed++);
 	return ((struct tcpcb *)0);
 }
 
+#ifdef notdef
 void
 tcp_drain()
 {
@@ -319,9 +309,6 @@
  * When a source quench is received, close congestion window
  * to one segment.  We will gradually open it again as we proceed.
  */
-
-#ifdef notdef
-
 void
 tcp_quench(i, errno)
 
@@ -528,7 +515,7 @@
  */
 
 /*	soisconnecting(so); */ /* NOFDREF used instead */
-	tcpstat.tcps_connattempt++;
+	STAT(tcpstat.tcps_connattempt++);
 
 	tp->t_state = TCPS_SYN_SENT;
 	tp->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT;
@@ -556,7 +543,7 @@
 /*
  * Set the socket's type of service field
  */
-struct tos_t tcptos[] = {
+static const struct tos_t tcptos[] = {
 	  {0, 20, IPTOS_THROUGHPUT, 0},	/* ftp data */
 	  {21, 21, IPTOS_LOWDELAY,  EMU_FTP},	/* ftp control */
 	  {0, 23, IPTOS_LOWDELAY, 0},	/* telnet */
@@ -572,7 +559,7 @@
 	  {0, 0, 0, 0}
 };
 
-struct emu_t *tcpemu = 0;
+static struct emu_t *tcpemu = 0;
 
 /*
  * Return TOS according to the above table
@@ -605,7 +592,9 @@
 	return 0;
 }
 
+#if 0
 int do_echo = -1;
+#endif
 
 /*
  * Emulate programs that try and connect to us
@@ -665,7 +654,7 @@
 			so_rcv->sb_rptr += m->m_len;
 			m->m_data[m->m_len] = 0; /* NULL terminate */
 			if (strchr(m->m_data, '\r') || strchr(m->m_data, '\n')) {
-				if (sscanf(so_rcv->sb_data, "%d%*[ ,]%d", &n1, &n2) == 2) {
+				if (sscanf(so_rcv->sb_data, "%u%*[ ,]%u", &n1, &n2) == 2) {
 					HTONS(n1);
 					HTONS(n2);
 					/* n2 is the one on our host */
@@ -857,7 +846,7 @@
 
                 /*soisfconnecting(ns);*/
 
-				tcpstat.tcps_connattempt++;
+				STAT(tcpstat.tcps_connattempt++);
 
 				tp->t_state = TCPS_SYN_SENT;
 				tp->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT;
@@ -991,7 +980,7 @@
 			/*
 			 * Need to emulate the PORT command
 			 */
-			x = sscanf(bptr, "ORT %d,%d,%d,%d,%d,%d\r\n%256[^\177]",
+			x = sscanf(bptr, "ORT %u,%u,%u,%u,%u,%u\r\n%256[^\177]",
 				   &n1, &n2, &n3, &n4, &n5, &n6, buff);
 			if (x < 6)
 			   return 1;
@@ -1022,7 +1011,7 @@
 			/*
 			 * Need to emulate the PASV response
 			 */
-			x = sscanf(bptr, "27 Entering Passive Mode (%d,%d,%d,%d,%d,%d)\r\n%256[^\177]",
+			x = sscanf(bptr, "27 Entering Passive Mode (%u,%u,%u,%u,%u,%u)\r\n%256[^\177]",
 				   &n1, &n2, &n3, &n4, &n5, &n6, buff);
 			if (x < 6)
 			   return 1;

Modified: trunk/src/host/qemu-neo1973/slirp/tcp_timer.c
===================================================================
--- trunk/src/host/qemu-neo1973/slirp/tcp_timer.c	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/slirp/tcp_timer.c	2007-10-29 21:14:04 UTC (rev 3303)
@@ -36,14 +36,14 @@
 
 #include <slirp.h>
 
-int	tcp_keepidle = TCPTV_KEEP_IDLE;
-int	tcp_keepintvl = TCPTV_KEEPINTVL;
-int	tcp_maxidle;
-int	so_options = DO_KEEPALIVE;
-
+#ifdef LOG_ENABLED
 struct   tcpstat tcpstat;        /* tcp statistics */
+#endif
+
 u_int32_t        tcp_now;                /* for RFC 1323 timestamps */
 
+static struct tcpcb *tcp_timers(register struct tcpcb *tp, int timer);
+
 /*
  * Fast timeout routine for processing delayed acks
  */
@@ -62,7 +62,7 @@
 		    (tp->t_flags & TF_DELACK)) {
 			tp->t_flags &= ~TF_DELACK;
 			tp->t_flags |= TF_ACKNOW;
-			tcpstat.tcps_delack++;
+			STAT(tcpstat.tcps_delack++);
 			(void) tcp_output(tp);
 		}
 }
@@ -81,7 +81,6 @@
 
 	DEBUG_CALL("tcp_slowtimo");
 
-	tcp_maxidle = TCPTV_KEEPCNT * tcp_keepintvl;
 	/*
 	 * Search through tcb's and update active timers.
 	 */
@@ -127,16 +126,14 @@
 		tp->t_timer[i] = 0;
 }
 
-int	tcp_backoff[TCP_MAXRXTSHIFT + 1] =
+const int tcp_backoff[TCP_MAXRXTSHIFT + 1] =
    { 1, 2, 4, 8, 16, 32, 64, 64, 64, 64, 64, 64, 64 };
 
 /*
  * TCP timer processing.
  */
-struct tcpcb *
-tcp_timers(tp, timer)
-	register struct tcpcb *tp;
-	int timer;
+static struct tcpcb *
+tcp_timers(register struct tcpcb *tp, int timer)
 {
 	register int rexmt;
 
@@ -152,8 +149,8 @@
 	 */
 	case TCPT_2MSL:
 		if (tp->t_state != TCPS_TIME_WAIT &&
-		    tp->t_idle <= tcp_maxidle)
-			tp->t_timer[TCPT_2MSL] = tcp_keepintvl;
+		    tp->t_idle <= TCP_MAXIDLE)
+			tp->t_timer[TCPT_2MSL] = TCPTV_KEEPINTVL;
 		else
 			tp = tcp_close(tp);
 		break;
@@ -192,7 +189,7 @@
 				 * We tried our best, now the connection must die!
 				 */
 				tp->t_rxtshift = TCP_MAXRXTSHIFT;
-				tcpstat.tcps_timeoutdrop++;
+				STAT(tcpstat.tcps_timeoutdrop++);
 				tp = tcp_drop(tp, tp->t_softerror);
 				/* tp->t_softerror : ETIMEDOUT); */ /* XXX */
 				return (tp); /* XXX */
@@ -204,7 +201,7 @@
 			 */
 			tp->t_rxtshift = 6;
 		}
-		tcpstat.tcps_rexmttimeo++;
+		STAT(tcpstat.tcps_rexmttimeo++);
 		rexmt = TCP_REXMTVAL(tp) * tcp_backoff[tp->t_rxtshift];
 		TCPT_RANGESET(tp->t_rxtcur, rexmt,
 		    (short)tp->t_rttmin, TCPTV_REXMTMAX); /* XXX */
@@ -267,7 +264,7 @@
 	 * Force a byte to be output, if possible.
 	 */
 	case TCPT_PERSIST:
-		tcpstat.tcps_persisttimeo++;
+		STAT(tcpstat.tcps_persisttimeo++);
 		tcp_setpersist(tp);
 		tp->t_force = 1;
 		(void) tcp_output(tp);
@@ -279,13 +276,13 @@
 	 * or drop connection if idle for too long.
 	 */
 	case TCPT_KEEP:
-		tcpstat.tcps_keeptimeo++;
+		STAT(tcpstat.tcps_keeptimeo++);
 		if (tp->t_state < TCPS_ESTABLISHED)
 			goto dropit;
 
 /*		if (tp->t_socket->so_options & SO_KEEPALIVE && */
-		if ((so_options) && tp->t_state <= TCPS_CLOSE_WAIT) {
-		    	if (tp->t_idle >= tcp_keepidle + tcp_maxidle)
+		if ((SO_OPTIONS) && tp->t_state <= TCPS_CLOSE_WAIT) {
+		    	if (tp->t_idle >= TCPTV_KEEP_IDLE + TCP_MAXIDLE)
 				goto dropit;
 			/*
 			 * Send a packet designed to force a response
@@ -299,7 +296,7 @@
 			 * by the protocol spec, this requires the
 			 * correspondent TCP to respond.
 			 */
-			tcpstat.tcps_keepprobe++;
+			STAT(tcpstat.tcps_keepprobe++);
 #ifdef TCP_COMPAT_42
 			/*
 			 * The keepalive packet must have nonzero length
@@ -311,13 +308,13 @@
 			tcp_respond(tp, &tp->t_template, (struct mbuf *)NULL,
 			    tp->rcv_nxt, tp->snd_una - 1, 0);
 #endif
-			tp->t_timer[TCPT_KEEP] = tcp_keepintvl;
+			tp->t_timer[TCPT_KEEP] = TCPTV_KEEPINTVL;
 		} else
-			tp->t_timer[TCPT_KEEP] = tcp_keepidle;
+			tp->t_timer[TCPT_KEEP] = TCPTV_KEEP_IDLE;
 		break;
 
 	dropit:
-		tcpstat.tcps_keepdrops++;
+		STAT(tcpstat.tcps_keepdrops++);
 		tp = tcp_drop(tp, 0); /* ETIMEDOUT); */
 		break;
 	}

Modified: trunk/src/host/qemu-neo1973/slirp/tcp_timer.h
===================================================================
--- trunk/src/host/qemu-neo1973/slirp/tcp_timer.h	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/slirp/tcp_timer.h	2007-10-29 21:14:04 UTC (rev 3303)
@@ -126,17 +126,12 @@
 		(tv) = (tvmax); \
 }
 
-extern int tcp_keepidle;		/* time before keepalive probes begin */
-extern int tcp_keepintvl;		/* time between keepalive probes */
-extern int tcp_maxidle;			/* time to drop after starting probes */
-extern int tcp_ttl;			/* time to live for TCP segs */
-extern int tcp_backoff[];
+extern const int tcp_backoff[];
 
 struct tcpcb;
 
 void tcp_fasttimo _P((void));
 void tcp_slowtimo _P((void));
 void tcp_canceltimers _P((struct tcpcb *));
-struct tcpcb * tcp_timers _P((register struct tcpcb *, int));
 
 #endif

Modified: trunk/src/host/qemu-neo1973/slirp/tcp_var.h
===================================================================
--- trunk/src/host/qemu-neo1973/slirp/tcp_var.h	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/slirp/tcp_var.h	2007-10-29 21:14:04 UTC (rev 3303)
@@ -185,6 +185,7 @@
 #endif
 #define REASS_MBUF(ti) (*(mbufp_32 *)&((ti)->ti_t))
 
+#ifdef LOG_ENABLED
 /*
  * TCP statistics.
  * Many of these should be kept per connection,
@@ -247,6 +248,8 @@
 };
 
 extern struct	tcpstat tcpstat;	/* tcp statistics */
+#endif
+
 extern u_int32_t	tcp_now;		/* for RFC 1323 timestamps */
 
 #endif

Modified: trunk/src/host/qemu-neo1973/slirp/tftp.c
===================================================================
--- trunk/src/host/qemu-neo1973/slirp/tftp.c	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/slirp/tftp.c	2007-10-29 21:14:04 UTC (rev 3303)
@@ -34,7 +34,7 @@
     int timestamp;
 };
 
-struct tftp_session tftp_sessions[TFTP_SESSIONS_MAX];
+static struct tftp_session tftp_sessions[TFTP_SESSIONS_MAX];
 
 const char *tftp_prefix;
 
@@ -143,7 +143,7 @@
 
     memset(m->m_data, 0, m->m_size);
 
-    m->m_data += if_maxlinkhdr;
+    m->m_data += IF_MAXLINKHDR;
     tp = (void *)m->m_data;
     m->m_data += sizeof(struct udpiphdr);
 
@@ -183,7 +183,7 @@
 
   memset(m->m_data, 0, m->m_size);
 
-  m->m_data += if_maxlinkhdr;
+  m->m_data += IF_MAXLINKHDR;
   tp = (void *)m->m_data;
   m->m_data += sizeof(struct udpiphdr);
 
@@ -230,7 +230,7 @@
 
   memset(m->m_data, 0, m->m_size);
 
-  m->m_data += if_maxlinkhdr;
+  m->m_data += IF_MAXLINKHDR;
   tp = (void *)m->m_data;
   m->m_data += sizeof(struct udpiphdr);
 

Modified: trunk/src/host/qemu-neo1973/slirp/udp.c
===================================================================
--- trunk/src/host/qemu-neo1973/slirp/udp.c	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/slirp/udp.c	2007-10-29 21:14:04 UTC (rev 3303)
@@ -45,18 +45,23 @@
 #include <slirp.h>
 #include "ip_icmp.h"
 
+#ifdef LOG_ENABLED
 struct udpstat udpstat;
+#endif
 
 struct socket udb;
 
+static u_int8_t udp_tos(struct socket *so);
+static void udp_emu(struct socket *so, struct mbuf *m);
+
 /*
  * UDP protocol implementation.
  * Per RFC 768, August, 1980.
  */
 #ifndef	COMPAT_42
-int	udpcksum = 1;
+#define UDPCKSUM 1
 #else
-int	udpcksum = 0;		/* XXX */
+#define UDPCKSUM 0 /* XXX */
 #endif
 
 struct	socket *udp_last_so = &udb;
@@ -86,7 +91,7 @@
 	DEBUG_ARG("m = %lx", (long)m);
 	DEBUG_ARG("iphlen = %d", iphlen);
 
-	udpstat.udps_ipackets++;
+	STAT(udpstat.udps_ipackets++);
 
 	/*
 	 * Strip IP options, if any; should skip this,
@@ -113,7 +118,7 @@
 
 	if (ip->ip_len != len) {
 		if (len > ip->ip_len) {
-			udpstat.udps_badlen++;
+			STAT(udpstat.udps_badlen++);
 			goto bad;
 		}
 		m_adj(m, len - ip->ip_len);
@@ -130,7 +135,7 @@
 	/*
 	 * Checksum extended UDP header and data.
 	 */
-	if (udpcksum && uh->uh_sum) {
+	if (UDPCKSUM && uh->uh_sum) {
 	  ((struct ipovly *)ip)->ih_next = 0;
 	  ((struct ipovly *)ip)->ih_prev = 0;
 	  ((struct ipovly *)ip)->ih_x1 = 0;
@@ -140,7 +145,7 @@
 	   * if (uh->uh_sum) {
 	   */
 	  if(cksum(m, len + sizeof(struct ip))) {
-	    udpstat.udps_badsum++;
+	    STAT(udpstat.udps_badsum++);
 	    goto bad;
 	  }
 	}
@@ -181,7 +186,7 @@
 		if (tmp == &udb) {
 		  so = NULL;
 		} else {
-		  udpstat.udpps_pcbcachemiss++;
+		  STAT(udpstat.udpps_pcbcachemiss++);
 		  udp_last_so = so;
 		}
 	}
@@ -290,16 +295,16 @@
 	 * Stuff checksum and output datagram.
 	 */
 	ui->ui_sum = 0;
-	if (udpcksum) {
+	if (UDPCKSUM) {
 	    if ((ui->ui_sum = cksum(m, /* sizeof (struct udpiphdr) + */ m->m_len)) == 0)
 		ui->ui_sum = 0xffff;
 	}
 	((struct ip *)ui)->ip_len = m->m_len;
 
-	((struct ip *)ui)->ip_ttl = ip_defttl;
+	((struct ip *)ui)->ip_ttl = IPDEFTTL;
 	((struct ip *)ui)->ip_tos = iptos;
 
-	udpstat.udps_opackets++;
+	STAT(udpstat.udps_opackets++);
 
 	error = ip_output(so, m);
 
@@ -367,7 +372,7 @@
 	sofree(so);
 }
 
-struct tos_t udptos[] = {
+static const struct tos_t udptos[] = {
 	{0, 53, IPTOS_LOWDELAY, 0},			/* DNS */
 	{517, 517, IPTOS_LOWDELAY, EMU_TALK},	/* talk */
 	{518, 518, IPTOS_LOWDELAY, EMU_NTALK},	/* ntalk */
@@ -375,9 +380,8 @@
 	{0, 0, 0, 0}
 };
 
-u_int8_t
-udp_tos(so)
-	struct socket *so;
+static u_int8_t
+udp_tos(struct socket *so)
 {
 	int i = 0;
 
@@ -400,10 +404,8 @@
 /*
  * Here, talk/ytalk/ntalk requests must be emulated
  */
-void
-udp_emu(so, m)
-	struct socket *so;
-	struct mbuf *m;
+static void
+udp_emu(struct socket *so, struct mbuf *m)
 {
 	struct sockaddr_in addr;
         int addrlen = sizeof(addr);

Modified: trunk/src/host/qemu-neo1973/slirp/udp.h
===================================================================
--- trunk/src/host/qemu-neo1973/slirp/udp.h	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/slirp/udp.h	2007-10-29 21:14:04 UTC (rev 3303)
@@ -72,6 +72,7 @@
 #define ui_ulen         ui_u.uh_ulen
 #define ui_sum          ui_u.uh_sum
 
+#ifdef LOG_ENABLED
 struct udpstat {
 	                                /* input statistics: */
 	        u_long  udps_ipackets;          /* total input packets */
@@ -85,6 +86,7 @@
 	                                /* output statistics: */
 	        u_long  udps_opackets;          /* total output packets */
 };
+#endif
 
 /*
  * Names for UDP sysctl objects
@@ -92,7 +94,10 @@
 #define UDPCTL_CHECKSUM         1       /* checksum UDP packets */
 #define UDPCTL_MAXID            2
 
+#ifdef LOG_ENABLED
 extern struct udpstat udpstat;
+#endif
+
 extern struct socket udb;
 struct mbuf;
 
@@ -101,8 +106,6 @@
 int udp_output _P((struct socket *, struct mbuf *, struct sockaddr_in *));
 int udp_attach _P((struct socket *));
 void udp_detach _P((struct socket *));
-u_int8_t udp_tos _P((struct socket *));
-void udp_emu _P((struct socket *, struct mbuf *));
 struct socket * udp_listen _P((u_int, u_int32_t, u_int, int));
 int udp_output2(struct socket *so, struct mbuf *m,
                 struct sockaddr_in *saddr, struct sockaddr_in *daddr,

Modified: trunk/src/host/qemu-neo1973/softmmu_exec.h
===================================================================
--- trunk/src/host/qemu-neo1973/softmmu_exec.h	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/softmmu_exec.h	2007-10-29 21:14:04 UTC (rev 3303)
@@ -1,10 +1,16 @@
 /* Common softmmu definitions and inline routines.  */
 
-#define ldul_user ldl_user
-#define ldul_kernel ldl_kernel
+/* XXX: find something cleaner.
+ * Furthermore, this is false for 64 bits targets
+ */
+#define ldul_user       ldl_user
+#define ldul_kernel     ldl_kernel
+#define ldul_hypv       ldl_hypv
+#define ldul_executive  ldl_executive
+#define ldul_supervisor ldl_supervisor
 
 #define ACCESS_TYPE 0
-#define MEMSUFFIX _kernel
+#define MEMSUFFIX MMU_MODE0_SUFFIX
 #define DATA_SIZE 1
 #include "softmmu_header.h"
 
@@ -20,7 +26,7 @@
 #undef MEMSUFFIX
 
 #define ACCESS_TYPE 1
-#define MEMSUFFIX _user
+#define MEMSUFFIX MMU_MODE1_SUFFIX
 #define DATA_SIZE 1
 #include "softmmu_header.h"
 
@@ -35,8 +41,50 @@
 #undef ACCESS_TYPE
 #undef MEMSUFFIX
 
+#if (NB_MMU_MODES >= 3)
+
+#define ACCESS_TYPE 2
+#define MEMSUFFIX MMU_MODE2_SUFFIX
+#define DATA_SIZE 1
+#include "softmmu_header.h"
+
+#define DATA_SIZE 2
+#include "softmmu_header.h"
+
+#define DATA_SIZE 4
+#include "softmmu_header.h"
+
+#define DATA_SIZE 8
+#include "softmmu_header.h"
+#undef ACCESS_TYPE
+#undef MEMSUFFIX
+
+#if (NB_MMU_MODES >= 4)
+
+#define ACCESS_TYPE 3
+#define MEMSUFFIX MMU_MODE3_SUFFIX
+#define DATA_SIZE 1
+#include "softmmu_header.h"
+
+#define DATA_SIZE 2
+#include "softmmu_header.h"
+
+#define DATA_SIZE 4
+#include "softmmu_header.h"
+
+#define DATA_SIZE 8
+#include "softmmu_header.h"
+#undef ACCESS_TYPE
+#undef MEMSUFFIX
+
+#if (NB_MMU_MODES > 4)
+#error "NB_MMU_MODES > 4 is not supported for now"
+#endif /* (NB_MMU_MODES > 4) */
+#endif /* (NB_MMU_MODES == 4) */
+#endif /* (NB_MMU_MODES >= 3) */
+
 /* these access are slower, they must be as rare as possible */
-#define ACCESS_TYPE 2
+#define ACCESS_TYPE (NB_MMU_MODES)
 #define MEMSUFFIX _data
 #define DATA_SIZE 1
 #include "softmmu_header.h"

Modified: trunk/src/host/qemu-neo1973/softmmu_header.h
===================================================================
--- trunk/src/host/qemu-neo1973/softmmu_header.h	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/softmmu_header.h	2007-10-29 21:14:04 UTC (rev 3303)
@@ -39,60 +39,19 @@
 #error unsupported data size
 #endif
 
-#if ACCESS_TYPE == 0
+#if ACCESS_TYPE < (NB_MMU_MODES)
 
-#define CPU_MEM_INDEX 0
+#define CPU_MMU_INDEX ACCESS_TYPE
 #define MMUSUFFIX _mmu
 
-#elif ACCESS_TYPE == 1
+#elif ACCESS_TYPE == (NB_MMU_MODES)
 
-#define CPU_MEM_INDEX 1
+#define CPU_MMU_INDEX (cpu_mmu_index(env))
 #define MMUSUFFIX _mmu
 
-#elif ACCESS_TYPE == 2
+#elif ACCESS_TYPE == (NB_MMU_MODES + 1)
 
-#ifdef TARGET_I386
-#define CPU_MEM_INDEX ((env->hflags & HF_CPL_MASK) == 3)
-#elif defined (TARGET_PPC)
-#define CPU_MEM_INDEX (msr_pr)
-#elif defined (TARGET_MIPS)
-#define CPU_MEM_INDEX ((env->hflags & MIPS_HFLAG_MODE) == MIPS_HFLAG_UM)
-#elif defined (TARGET_SPARC)
-#define CPU_MEM_INDEX ((env->psrs) == 0)
-#elif defined (TARGET_ARM)
-#define CPU_MEM_INDEX ((env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_USR)
-#elif defined (TARGET_SH4)
-#define CPU_MEM_INDEX ((env->sr & SR_MD) == 0)
-#elif defined (TARGET_ALPHA)
-#define CPU_MEM_INDEX ((env->ps >> 3) & 3)
-#elif defined (TARGET_M68K)
-#define CPU_MEM_INDEX ((env->sr & SR_S) == 0)
-#else
-#error unsupported CPU
-#endif
-#define MMUSUFFIX _mmu
-
-#elif ACCESS_TYPE == 3
-
-#ifdef TARGET_I386
-#define CPU_MEM_INDEX ((env->hflags & HF_CPL_MASK) == 3)
-#elif defined (TARGET_PPC)
-#define CPU_MEM_INDEX (msr_pr)
-#elif defined (TARGET_MIPS)
-#define CPU_MEM_INDEX ((env->hflags & MIPS_HFLAG_MODE) == MIPS_HFLAG_UM)
-#elif defined (TARGET_SPARC)
-#define CPU_MEM_INDEX ((env->psrs) == 0)
-#elif defined (TARGET_ARM)
-#define CPU_MEM_INDEX ((env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_USR)
-#elif defined (TARGET_SH4)
-#define CPU_MEM_INDEX ((env->sr & SR_MD) == 0)
-#elif defined (TARGET_ALPHA)
-#define CPU_MEM_INDEX ((env->ps >> 3) & 3)
-#elif defined (TARGET_M68K)
-#define CPU_MEM_INDEX ((env->sr & SR_S) == 0)
-#else
-#error unsupported CPU
-#endif
+#define CPU_MMU_INDEX (cpu_mmu_index(env))
 #define MMUSUFFIX _cmmu
 
 #else
@@ -105,18 +64,18 @@
 #define RES_TYPE int
 #endif
 
-#if ACCESS_TYPE == 3
+#if ACCESS_TYPE == (NB_MMU_MODES + 1)
 #define ADDR_READ addr_code
 #else
 #define ADDR_READ addr_read
 #endif
 
 DATA_TYPE REGPARM(1) glue(glue(__ld, SUFFIX), MMUSUFFIX)(target_ulong addr,
-                                                         int is_user);
-void REGPARM(2) glue(glue(__st, SUFFIX), MMUSUFFIX)(target_ulong addr, DATA_TYPE v, int is_user);
+                                                         int mmu_idx);
+void REGPARM(2) glue(glue(__st, SUFFIX), MMUSUFFIX)(target_ulong addr, DATA_TYPE v, int mmu_idx);
 
 #if (DATA_SIZE <= 4) && (TARGET_LONG_BITS == 32) && defined(__i386__) && \
-    (ACCESS_TYPE <= 1) && defined(ASM_SOFTMMU)
+    (ACCESS_TYPE < NB_MMU_MODES) && defined(ASM_SOFTMMU)
 
 #define CPU_TLB_ENTRY_BITS 4
 
@@ -155,8 +114,8 @@
                   "i" ((CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS),
                   "i" (TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS),
                   "i" (TARGET_PAGE_MASK | (DATA_SIZE - 1)),
-                  "m" (*(uint32_t *)offsetof(CPUState, tlb_table[CPU_MEM_INDEX][0].addr_read)),
-                  "i" (CPU_MEM_INDEX),
+                  "m" (*(uint32_t *)offsetof(CPUState, tlb_table[CPU_MMU_INDEX][0].addr_read)),
+                  "i" (CPU_MMU_INDEX),
                   "m" (*(uint8_t *)&glue(glue(__ld, SUFFIX), MMUSUFFIX))
                   : "%eax", "%ecx", "%edx", "memory", "cc");
     return res;
@@ -202,8 +161,8 @@
                   "i" ((CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS),
                   "i" (TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS),
                   "i" (TARGET_PAGE_MASK | (DATA_SIZE - 1)),
-                  "m" (*(uint32_t *)offsetof(CPUState, tlb_table[CPU_MEM_INDEX][0].addr_read)),
-                  "i" (CPU_MEM_INDEX),
+                  "m" (*(uint32_t *)offsetof(CPUState, tlb_table[CPU_MMU_INDEX][0].addr_read)),
+                  "i" (CPU_MMU_INDEX),
                   "m" (*(uint8_t *)&glue(glue(__ld, SUFFIX), MMUSUFFIX))
                   : "%eax", "%ecx", "%edx", "memory", "cc");
     return res;
@@ -254,8 +213,8 @@
                   "i" ((CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS),
                   "i" (TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS),
                   "i" (TARGET_PAGE_MASK | (DATA_SIZE - 1)),
-                  "m" (*(uint32_t *)offsetof(CPUState, tlb_table[CPU_MEM_INDEX][0].addr_write)),
-                  "i" (CPU_MEM_INDEX),
+                  "m" (*(uint32_t *)offsetof(CPUState, tlb_table[CPU_MMU_INDEX][0].addr_write)),
+                  "i" (CPU_MMU_INDEX),
                   "m" (*(uint8_t *)&glue(glue(__st, SUFFIX), MMUSUFFIX))
                   : "%eax", "%ecx", "%edx", "memory", "cc");
 }
@@ -270,16 +229,16 @@
     RES_TYPE res;
     target_ulong addr;
     unsigned long physaddr;
-    int is_user;
+    int mmu_idx;
 
     addr = ptr;
     index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
-    is_user = CPU_MEM_INDEX;
-    if (__builtin_expect(env->tlb_table[is_user][index].ADDR_READ !=
+    mmu_idx = CPU_MMU_INDEX;
+    if (__builtin_expect(env->tlb_table[mmu_idx][index].ADDR_READ !=
                          (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))), 0)) {
-        res = glue(glue(__ld, SUFFIX), MMUSUFFIX)(addr, is_user);
+        res = glue(glue(__ld, SUFFIX), MMUSUFFIX)(addr, mmu_idx);
     } else {
-        physaddr = addr + env->tlb_table[is_user][index].addend;
+        physaddr = addr + env->tlb_table[mmu_idx][index].addend;
         res = glue(glue(ld, USUFFIX), _raw)((uint8_t *)physaddr);
     }
     return res;
@@ -291,23 +250,23 @@
     int res, index;
     target_ulong addr;
     unsigned long physaddr;
-    int is_user;
+    int mmu_idx;
 
     addr = ptr;
     index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
-    is_user = CPU_MEM_INDEX;
-    if (__builtin_expect(env->tlb_table[is_user][index].ADDR_READ !=
+    mmu_idx = CPU_MMU_INDEX;
+    if (__builtin_expect(env->tlb_table[mmu_idx][index].ADDR_READ !=
                          (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))), 0)) {
-        res = (DATA_STYPE)glue(glue(__ld, SUFFIX), MMUSUFFIX)(addr, is_user);
+        res = (DATA_STYPE)glue(glue(__ld, SUFFIX), MMUSUFFIX)(addr, mmu_idx);
     } else {
-        physaddr = addr + env->tlb_table[is_user][index].addend;
+        physaddr = addr + env->tlb_table[mmu_idx][index].addend;
         res = glue(glue(lds, SUFFIX), _raw)((uint8_t *)physaddr);
     }
     return res;
 }
 #endif
 
-#if ACCESS_TYPE != 3
+#if ACCESS_TYPE != (NB_MMU_MODES + 1)
 
 /* generic store macro */
 
@@ -316,25 +275,25 @@
     int index;
     target_ulong addr;
     unsigned long physaddr;
-    int is_user;
+    int mmu_idx;
 
     addr = ptr;
     index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
-    is_user = CPU_MEM_INDEX;
-    if (__builtin_expect(env->tlb_table[is_user][index].addr_write !=
+    mmu_idx = CPU_MMU_INDEX;
+    if (__builtin_expect(env->tlb_table[mmu_idx][index].addr_write !=
                          (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))), 0)) {
-        glue(glue(__st, SUFFIX), MMUSUFFIX)(addr, v, is_user);
+        glue(glue(__st, SUFFIX), MMUSUFFIX)(addr, v, mmu_idx);
     } else {
-        physaddr = addr + env->tlb_table[is_user][index].addend;
+        physaddr = addr + env->tlb_table[mmu_idx][index].addend;
         glue(glue(st, SUFFIX), _raw)((uint8_t *)physaddr, v);
     }
 }
 
-#endif /* ACCESS_TYPE != 3 */
+#endif /* ACCESS_TYPE != (NB_MMU_MODES + 1) */
 
 #endif /* !asm */
 
-#if ACCESS_TYPE != 3
+#if ACCESS_TYPE != (NB_MMU_MODES + 1)
 
 #if DATA_SIZE == 8
 static inline float64 glue(ldfq, MEMSUFFIX)(target_ulong ptr)
@@ -380,7 +339,7 @@
 }
 #endif /* DATA_SIZE == 4 */
 
-#endif /* ACCESS_TYPE != 3 */
+#endif /* ACCESS_TYPE != (NB_MMU_MODES + 1) */
 
 #undef RES_TYPE
 #undef DATA_TYPE
@@ -388,6 +347,6 @@
 #undef SUFFIX
 #undef USUFFIX
 #undef DATA_SIZE
-#undef CPU_MEM_INDEX
+#undef CPU_MMU_INDEX
 #undef MMUSUFFIX
 #undef ADDR_READ

Modified: trunk/src/host/qemu-neo1973/softmmu_template.h
===================================================================
--- trunk/src/host/qemu-neo1973/softmmu_template.h	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/softmmu_template.h	2007-10-29 21:14:04 UTC (rev 3303)
@@ -48,7 +48,7 @@
 #endif
 
 static DATA_TYPE glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(target_ulong addr,
-                                                        int is_user,
+                                                        int mmu_idx,
                                                         void *retaddr);
 static inline DATA_TYPE glue(io_read, SUFFIX)(target_phys_addr_t physaddr,
                                               target_ulong tlb_addr)
@@ -76,7 +76,7 @@
 
 /* handle all cases except unaligned access which span two pages */
 DATA_TYPE REGPARM(1) glue(glue(__ld, SUFFIX), MMUSUFFIX)(target_ulong addr,
-                                                         int is_user)
+                                                         int mmu_idx)
 {
     DATA_TYPE res;
     int index;
@@ -88,9 +88,9 @@
     /* XXX: could done more in memory macro in a non portable way */
     index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
  redo:
-    tlb_addr = env->tlb_table[is_user][index].ADDR_READ;
+    tlb_addr = env->tlb_table[mmu_idx][index].ADDR_READ;
     if ((addr & TARGET_PAGE_MASK) == (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
-        physaddr = addr + env->tlb_table[is_user][index].addend;
+        physaddr = addr + env->tlb_table[mmu_idx][index].addend;
         if (tlb_addr & ~TARGET_PAGE_MASK) {
             /* IO access */
             if ((addr & (DATA_SIZE - 1)) != 0)
@@ -101,16 +101,16 @@
         do_unaligned_access:
             retaddr = GETPC();
 #ifdef ALIGNED_ONLY
-            do_unaligned_access(addr, READ_ACCESS_TYPE, is_user, retaddr);
+            do_unaligned_access(addr, READ_ACCESS_TYPE, mmu_idx, retaddr);
 #endif
             res = glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(addr,
-                                                         is_user, retaddr);
+                                                         mmu_idx, retaddr);
         } else {
             /* unaligned/aligned access in the same page */
 #ifdef ALIGNED_ONLY
             if ((addr & (DATA_SIZE - 1)) != 0) {
                 retaddr = GETPC();
-                do_unaligned_access(addr, READ_ACCESS_TYPE, is_user, retaddr);
+                do_unaligned_access(addr, READ_ACCESS_TYPE, mmu_idx, retaddr);
             }
 #endif
             res = glue(glue(ld, USUFFIX), _raw)((uint8_t *)(long)physaddr);
@@ -120,9 +120,9 @@
         retaddr = GETPC();
 #ifdef ALIGNED_ONLY
         if ((addr & (DATA_SIZE - 1)) != 0)
-            do_unaligned_access(addr, READ_ACCESS_TYPE, is_user, retaddr);
+            do_unaligned_access(addr, READ_ACCESS_TYPE, mmu_idx, retaddr);
 #endif
-        tlb_fill(addr, READ_ACCESS_TYPE, is_user, retaddr);
+        tlb_fill(addr, READ_ACCESS_TYPE, mmu_idx, retaddr);
         goto redo;
     }
     return res;
@@ -130,7 +130,7 @@
 
 /* handle all unaligned cases */
 static DATA_TYPE glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(target_ulong addr,
-                                                        int is_user,
+                                                        int mmu_idx,
                                                         void *retaddr)
 {
     DATA_TYPE res, res1, res2;
@@ -140,9 +140,9 @@
 
     index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
  redo:
-    tlb_addr = env->tlb_table[is_user][index].ADDR_READ;
+    tlb_addr = env->tlb_table[mmu_idx][index].ADDR_READ;
     if ((addr & TARGET_PAGE_MASK) == (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
-        physaddr = addr + env->tlb_table[is_user][index].addend;
+        physaddr = addr + env->tlb_table[mmu_idx][index].addend;
         if (tlb_addr & ~TARGET_PAGE_MASK) {
             /* IO access */
             if ((addr & (DATA_SIZE - 1)) != 0)
@@ -154,9 +154,9 @@
             addr1 = addr & ~(DATA_SIZE - 1);
             addr2 = addr1 + DATA_SIZE;
             res1 = glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(addr1,
-                                                          is_user, retaddr);
+                                                          mmu_idx, retaddr);
             res2 = glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(addr2,
-                                                          is_user, retaddr);
+                                                          mmu_idx, retaddr);
             shift = (addr & (DATA_SIZE - 1)) * 8;
 #ifdef TARGET_WORDS_BIGENDIAN
             res = (res1 << shift) | (res2 >> ((DATA_SIZE * 8) - shift));
@@ -170,7 +170,7 @@
         }
     } else {
         /* the page is not in the TLB : fill it */
-        tlb_fill(addr, READ_ACCESS_TYPE, is_user, retaddr);
+        tlb_fill(addr, READ_ACCESS_TYPE, mmu_idx, retaddr);
         goto redo;
     }
     return res;
@@ -180,7 +180,7 @@
 
 static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(target_ulong addr,
                                                    DATA_TYPE val,
-                                                   int is_user,
+                                                   int mmu_idx,
                                                    void *retaddr);
 
 static inline void glue(io_write, SUFFIX)(target_phys_addr_t physaddr,
@@ -211,7 +211,7 @@
 
 void REGPARM(2) glue(glue(__st, SUFFIX), MMUSUFFIX)(target_ulong addr,
                                                     DATA_TYPE val,
-                                                    int is_user)
+                                                    int mmu_idx)
 {
     target_phys_addr_t physaddr;
     target_ulong tlb_addr;
@@ -220,9 +220,9 @@
 
     index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
  redo:
-    tlb_addr = env->tlb_table[is_user][index].addr_write;
+    tlb_addr = env->tlb_table[mmu_idx][index].addr_write;
     if ((addr & TARGET_PAGE_MASK) == (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
-        physaddr = addr + env->tlb_table[is_user][index].addend;
+        physaddr = addr + env->tlb_table[mmu_idx][index].addend;
         if (tlb_addr & ~TARGET_PAGE_MASK) {
             /* IO access */
             if ((addr & (DATA_SIZE - 1)) != 0)
@@ -233,16 +233,16 @@
         do_unaligned_access:
             retaddr = GETPC();
 #ifdef ALIGNED_ONLY
-            do_unaligned_access(addr, 1, is_user, retaddr);
+            do_unaligned_access(addr, 1, mmu_idx, retaddr);
 #endif
             glue(glue(slow_st, SUFFIX), MMUSUFFIX)(addr, val,
-                                                   is_user, retaddr);
+                                                   mmu_idx, retaddr);
         } else {
             /* aligned/unaligned access in the same page */
 #ifdef ALIGNED_ONLY
             if ((addr & (DATA_SIZE - 1)) != 0) {
                 retaddr = GETPC();
-                do_unaligned_access(addr, 1, is_user, retaddr);
+                do_unaligned_access(addr, 1, mmu_idx, retaddr);
             }
 #endif
             glue(glue(st, SUFFIX), _raw)((uint8_t *)(long)physaddr, val);
@@ -252,9 +252,9 @@
         retaddr = GETPC();
 #ifdef ALIGNED_ONLY
         if ((addr & (DATA_SIZE - 1)) != 0)
-            do_unaligned_access(addr, 1, is_user, retaddr);
+            do_unaligned_access(addr, 1, mmu_idx, retaddr);
 #endif
-        tlb_fill(addr, 1, is_user, retaddr);
+        tlb_fill(addr, 1, mmu_idx, retaddr);
         goto redo;
     }
 }
@@ -262,7 +262,7 @@
 /* handles all unaligned cases */
 static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(target_ulong addr,
                                                    DATA_TYPE val,
-                                                   int is_user,
+                                                   int mmu_idx,
                                                    void *retaddr)
 {
     target_phys_addr_t physaddr;
@@ -271,9 +271,9 @@
 
     index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
  redo:
-    tlb_addr = env->tlb_table[is_user][index].addr_write;
+    tlb_addr = env->tlb_table[mmu_idx][index].addr_write;
     if ((addr & TARGET_PAGE_MASK) == (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
-        physaddr = addr + env->tlb_table[is_user][index].addend;
+        physaddr = addr + env->tlb_table[mmu_idx][index].addend;
         if (tlb_addr & ~TARGET_PAGE_MASK) {
             /* IO access */
             if ((addr & (DATA_SIZE - 1)) != 0)
@@ -285,10 +285,10 @@
             for(i = 0;i < DATA_SIZE; i++) {
 #ifdef TARGET_WORDS_BIGENDIAN
                 glue(slow_stb, MMUSUFFIX)(addr + i, val >> (((DATA_SIZE - 1) * 8) - (i * 8)),
-                                          is_user, retaddr);
+                                          mmu_idx, retaddr);
 #else
                 glue(slow_stb, MMUSUFFIX)(addr + i, val >> (i * 8),
-                                          is_user, retaddr);
+                                          mmu_idx, retaddr);
 #endif
             }
         } else {
@@ -297,7 +297,7 @@
         }
     } else {
         /* the page is not in the TLB : fill it */
-        tlb_fill(addr, 1, is_user, retaddr);
+        tlb_fill(addr, 1, mmu_idx, retaddr);
         goto redo;
     }
 }

Modified: trunk/src/host/qemu-neo1973/sparc-dis.c
===================================================================
--- trunk/src/host/qemu-neo1973/sparc-dis.c	2007-10-29 20:40:05 UTC (rev 3302)
+++ trunk/src/host/qemu-neo1973/sparc-dis.c	2007-10-29 21:14:04 UTC (rev 3303)
@@ -88,21 +88,21 @@
 
 struct sparc_opcode {
   const char *name;
-  unsigned long match;	/* Bits that must be set. */
-  unsigned long lose;	/* Bits that must not be set. */
+  unsigned long match;  /* Bits that must be set. */
+  unsigned long lose;   /* Bits that must not be set. */
   const char *args;
   /* This was called "delayed" in versions before the flags. */
   char flags;
-  short architecture;	/* Bitmask of sparc_opcode_arch_val's.  */
+  short architecture;   /* Bitmask of sparc_opcode_arch_val's.  */
 };
 
-#define	F_DELAYED	1	/* Delayed branch */
-#define	F_ALIAS		2	/* Alias for a "real" instruction */
-#define	F_UNBR		4	/* Unconditional branch */
-#define	F_CONDBR	8	/* Conditional branch */
-#define	F_JSR		16	/* Subroutine call */
-#define F_FLOAT		32	/* Floating point instruction (not a branch) */
-#define F_FBR		64	/* Floating point branch */
+#define F_DELAYED       1       /* Delayed branch */
+#define F_ALIAS         2       /* Alias for a "real" instruction */
+#define F_UNBR          4       /* Unconditional branch */
+#define F_CONDBR        8       /* Conditional branch */
+#define F_JSR           16      /* Subroutine call */
+#define F_FLOAT         32      /* Floating point instruction (not a branch) */
+#define F_FBR           64      /* Floating point branch */
 /* FIXME: Add F_ANACHRONISTIC flag for v9.  */
 
 /*
@@ -117,104 +117,104 @@
 instruction.
 
 Kinds of operands:
-	#	Number used by optimizer.	It is ignored.
-	1	rs1 register.
-	2	rs2 register.
-	d	rd register.
-	e	frs1 floating point register.
-	v	frs1 floating point register (double/even).
-	V	frs1 floating point register (quad/multiple of 4).
-	f	frs2 floating point register.
-	B	frs2 floating point register (double/even).
-	R	frs2 floating point register (quad/multiple of 4).
-	g	frsd floating point register.
-	H	frsd floating point register (double/even).
-	J	frsd floating point register (quad/multiple of 4).
-	b	crs1 coprocessor register
-	c	crs2 coprocessor register
-	D	crsd coprocessor register
-	m	alternate space register (asr) in rd
-	M	alternate space register (asr) in rs1
-	h	22 high bits.
-	X	5 bit unsigned immediate
-	Y	6 bit unsigned immediate
-	3	SIAM mode (3 bits). (v9b)
-	K	MEMBAR mask (7 bits). (v9)
-	j	10 bit Immediate. (v9)
-	I	11 bit Immediate. (v9)
-	i	13 bit Immediate.
-	n	22 bit immediate.
-	k	2+14 bit PC relative immediate. (v9)
-	G	19 bit PC relative immediate. (v9)
-	l	22 bit PC relative immediate.
-	L	30 bit PC relative immediate.
-	a	Annul.	The annul bit is set.
-	A	Alternate address space. Stored as 8 bits.
-	C	Coprocessor state register.
-	F	floating point state register.
-	p	Processor state register.
-	N	Branch predict clear ",pn" (v9)
-	T	Branch predict set ",pt" (v9)
-	z	%icc. (v9)
-	Z	%xcc. (v9)
-	q	Floating point queue.
-	r	Single register that is both rs1 and rd.
-	O	Single register that is both rs2 and rd.
-	Q	Coprocessor queue.
-	S	Special case.
-	t	Trap base register.
-	w	Window invalid mask register.
-	y	Y register.
-	u	sparclet coprocessor registers in rd position
-	U	sparclet coprocessor registers in rs1 position
-	E	%ccr. (v9)
-	s	%fprs. (v9)
-	P	%pc.  (v9)
-	W	%tick.	(v9)
-	o	%asi. (v9)
-	6	%fcc0. (v9)
-	7	%fcc1. (v9)
-	8	%fcc2. (v9)
-	9	%fcc3. (v9)
-	!	Privileged Register in rd (v9)
-	?	Privileged Register in rs1 (v9)
-	*	Prefetch function constant. (v9)
-	x	OPF field (v9 impdep).
-	0	32/64 bit immediate for set or setx (v9) insns
-	_	Ancillary state register in rd (v9a)
-	/	Ancillary state register in rs1 (v9a)
+        #       Number used by optimizer.       It is ignored.
+        1       rs1 register.
+        2       rs2 register.
+        d       rd register.
+        e       frs1 floating point register.
+        v       frs1 floating point register (double/even).
+        V       frs1 floating point register (quad/multiple of 4).
+        f       frs2 floating point register.
+        B       frs2 floating point register (double/even).
+        R       frs2 floating point register (quad/multiple of 4).
+        g       frsd floating point register.
+        H       frsd floating point register (double/even).
+        J       frsd floating point register (quad/multiple of 4).
+        b       crs1 coprocessor register
+        c       crs2 coprocessor register
+        D       crsd coprocessor register
+        m       alternate space register (asr) in rd
+        M       alternate space register (asr) in rs1
+        h       22 high bits.
+        X       5 bit unsigned immediate
+        Y       6 bit unsigned immediate
+        3       SIAM mode (3 bits). (v9b)
+        K       MEMBAR mask (7 bits). (v9)
+        j       10 bit Immediate. (v9)
+        I       11 bit Immediate. (v9)
+        i       13 bit Immediate.
+        n       22 bit immediate.
+        k       2+14 bit PC relative immediate. (v9)
+        G       19 bit PC relative immediate. (v9)
+        l       22 bit PC relative immediate.
+        L       30 bit PC relative immediate.
+        a       Annul.  The annul bit is set.
+        A       Alternate address space. Stored as 8 bits.
+        C       Coprocessor state register.
+        F       floating point state register.
+        p       Processor state register.
+        N       Branch predict clear ",pn" (v9)
+        T       Branch predict set ",pt" (v9)
+        z       %icc. (v9)
+        Z       %xcc. (v9)
+        q       Floating point queue.
+        r       Single register that is both rs1 and rd.
+        O       Single register that is both rs2 and rd.
+        Q       Coprocessor queue.
+        S       Special case.
+        t       Trap base register.
+        w       Window invalid mask register.
+        y       Y register.
+        u       sparclet coprocessor registers in rd position
+        U       sparclet coprocessor registers in rs1 position
+        E       %ccr. (v9)
+        s       %fprs. (v9)
+        P       %pc.  (v9)
+        W       %tick.  (v9)
+        o       %asi. (v9)
+        6       %fcc0. (v9)
+        7       %fcc1. (v9)
+        8       %fcc2. (v9)
+        9       %fcc3. (v9)
+        !       Privileged Register in rd (v9)
+        ?       Privileged Register in rs1 (v9)
+        *       Prefetch function constant. (v9)
+        x       OPF field (v9 impdep).
+        0       32/64 bit immediate for set or setx (v9) insns
+        _       Ancillary state register in rd (v9a)
+        /       Ancillary state register in rs1 (v9a)
 
 The following chars are unused: (note: ,[] are used as punctuation)
 [45]
 
 */
 
-#define OP2(x)		(((x)&0x7) << 22) /* op2 field of format2 insns */
-#define OP3(x)		(((x)&0x3f) << 19) /* op3 field of format3 insns */
-#define OP(x)		((unsigned)((x)&0x3) << 30) /* op field of all insns */
-#define OPF(x)		(((x)&0x1ff) << 5) /* opf field of float insns */
-#define OPF_LOW5(x)	OPF((x)&0x1f) /* v9 */
-#define F3F(x, y, z)	(OP(x) | OP3(y) | OPF(z)) /* format3 float insns */
-#define F3I(x)		(((x)&0x1) << 13) /* immediate field of format 3 insns */
-#define F2(x, y)	(OP(x) | OP2(y)) /* format 2 insns */
-#define F3(x, y, z)	(OP(x) | OP3(y) | F3I(z)) /* format3 insns */
-#define F1(x)		(OP(x))
-#define DISP30(x)	((x)&0x3fffffff)
-#define ASI(x)		(((x)&0xff) << 5) /* asi field of format3 insns */
-#define RS2(x)		((x)&0x1f) /* rs2 field */
-#define SIMM13(x)	((x)&0x1fff) /* simm13 field */
-#define RD(x)		(((x)&0x1f) << 25) /* destination register field */
-#define RS1(x)		(((x)&0x1f) << 14) /* rs1 field */
-#define ASI_RS2(x)	(SIMM13(x))
-#define MEMBAR(x)	((x)&0x7f)
-#define SLCPOP(x)	(((x)&0x7f) << 6) /* sparclet cpop */
+#define OP2(x)          (((x)&0x7) << 22) /* op2 field of format2 insns */
+#define OP3(x)          (((x)&0x3f) << 19) /* op3 field of format3 insns */
+#define OP(x)           ((unsigned)((x)&0x3) << 30) /* op field of all insns */
+#define OPF(x)          (((x)&0x1ff) << 5) /* opf field of float insns */
+#define OPF_LOW5(x)     OPF((x)&0x1f) /* v9 */
+#define F3F(x, y, z)    (OP(x) | OP3(y) | OPF(z)) /* format3 float insns */
+#define F3I(x)          (((x)&0x1) << 13) /* immediate field of format 3 insns */
+#define F2(x, y)        (OP(x) | OP2(y)) /* format 2 insns */
+#define F3(x, y, z)     (OP(x) | OP3(y) | F3I(z)) /* format3 insns */
+#define F1(x)           (OP(x))
+#define DISP30(x)       ((x)&0x3fffffff)
+#define ASI(x)          (((x)&0xff) << 5) /* asi field of format3 insns */
+#define RS2(x)          ((x)&0x1f) /* rs2 field */
+#define SIMM13(x)       ((x)&0x1fff) /* simm13 field */
+#define RD(x)           (((x)&0x1f) << 25) /* destination register field */
+#define RS1(x)          (((x)&0x1f) << 14) /* rs1 field */
+#define ASI_RS2(x)      (SIMM13(x))
+#define MEMBAR(x)       ((x)&0x7f)
+#define SLCPOP(x)       (((x)&0x7f) << 6) /* sparclet cpop */
 
-#define ANNUL	(1<<29)
-#define BPRED	(1<<19)	/* v9 */
-#define	IMMED	F3I(1)
-#define RD_G0	RD(~0)
-#define	RS1_G0	RS1(~0)
-#define	RS2_G0	RS2(~0)
+#define ANNUL   (1<<29)
+#define BPRED   (1<<19) /* v9 */
+#define IMMED   F3I(1)
+#define RD_G0   RD(~0)
+#define RS1_G0  RS1(~0)
+#define RS2_G0  RS2(~0)
 
 extern const struct sparc_opcode sparc_opcodes[];
 extern const int sparc_num_opcodes;
@@ -229,43 +229,43 @@
 extern const char *sparc_decode_sparclet_cpreg PARAMS ((int));
 
 /* Some defines to make life easy.  */
-#define MASK_V6		SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V6)
-#define MASK_V7		SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V7)
-#define MASK_V8		SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V8)
-#define MASK_SPARCLET	SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_SPARCLET)
-#define MASK_SPARCLITE	SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_SPARCLITE)
-#define MASK_V9		SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V9)
-#define MASK_V9A	SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V9A)
-#define MASK_V9B	SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V9B)
+#define MASK_V6         SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V6)
+#define MASK_V7         SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V7)
+#define MASK_V8         SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V8)
+#define MASK_SPARCLET   SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_SPARCLET)
+#define MASK_SPARCLITE  SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_SPARCLITE)
+#define MASK_V9         SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V9)
+#define MASK_V9A        SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V9A)
+#define MASK_V9B        SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V9B)
 
 /* Bit masks of architectures supporting the insn.  */
 
-#define v6		(MASK_V6 | MASK_V7 | MASK_V8 | MASK_SPARCLET \
-			 | MASK_SPARCLITE | MASK_V9 | MASK_V9A | MASK_V9B)
+#define v6              (MASK_V6 | MASK_V7 | MASK_V8 | MASK_SPARCLET \
+                         | MASK_SPARCLITE | MASK_V9 | MASK_V9A | MASK_V9B)
 /* v6 insns not supported on the sparclet */
-#define v6notlet	(MASK_V6 | MASK_V7 | MASK_V8 \
-			 | MASK_SPARCLITE | MASK_V9 | MASK_V9A | MASK_V9B)
-#define v7		(MASK_V7 | MASK_V8 | MASK_SPARCLET \
-			 | MASK_SPARCLITE | MASK_V9 | MASK_V9A | MASK_V9B)
+#define v6notlet        (MASK_V6 | MASK_V7 | MASK_V8 \
+                         | MASK_SPARCLITE | MASK_V9 | MASK_V9A | MASK_V9B)
+#define v7              (MASK_V7 | MASK_V8 | MASK_SPARCLET \
+                         | MASK_SPARCLITE | MASK_V9 | MASK_V9A | MASK_V9B)
 /* Although not all insns are implemented in hardware, sparclite is defined
    to be a superset of v8.  Unimplemented insns trap and are then theoretically
    implemented in software.
    It's not clear that the same is true for sparclet, although the docs
    suggest it is.  Rather than complicating things, the sparclet assembler
    recognizes all v8 insns.  */
-#define v8		(MASK_V8 | MASK_SPARCLET | MASK_SPARCLITE \
-			 | MASK_V9 | MASK_V9A | MASK_V9B)
-#define sparclet	(MASK_SPARCLET)
-#define sparclite	(MASK_SPARCLITE)
-#define v9		(MASK_V9 | MASK_V9A | MASK_V9B)
-#define v9a		(MASK_V9A | MASK_V9B)
-#define v9b		(MASK_V9B)
+#define v8              (MASK_V8 | MASK_SPARCLET | MASK_SPARCLITE \
+                         | MASK_V9 | MASK_V9A | MASK_V9B)
+#define sparclet        (MASK_SPARCLET)
+#define sparclite       (MASK_SPARCLITE)
+#define v9              (MASK_V9 | MASK_V9A | MASK_V9B)
+#define v9a             (MASK_V9A | MASK_V9B)
+#define v9b             (MASK_V9B)
 /* v6 insns not supported by v9 */
-#define v6notv9		(MASK_V6 | MASK_V7 | MASK_V8 \
-			 | MASK_SPARCLET | MASK_SPARCLITE)
+#define v6notv9         (MASK_V6 | MASK_V7 | MASK_V8 \
+                         | MASK_SPARCLET | MASK_SPARCLITE)
 /* v9a instructions which would appear to be aliases to v9's impdep's
    otherwise */
-#define v9notv9a	(MASK_V9)
+#define v9notv9a        (MASK_V9)
 
 /* Table of opcode architectures.
    The order is defined in opcode/sparc.h.  */
@@ -296,959 +296,959 @@
   for (p = &sparc_opcode_archs[0]; p->name; ++p)
     {
       if (strcmp (name, p->name) == 0)
-	return (enum sparc_opcode_arch_val) (p - &sparc_opcode_archs[0]);
+        return (enum sparc_opcode_arch_val) (p - &sparc_opcode_archs[0]);
     }
 
   return SPARC_OPCODE_ARCH_BAD;
 }
 
 /* Branch condition field.  */
-#define COND(x)		(((x)&0xf)<<25)
+#define COND(x)         (((x)&0xf)<<25)
 
 /* v9: Move (MOVcc and FMOVcc) condition field.  */
-#define MCOND(x,i_or_f)	((((i_or_f)&1)<<18)|(((x)>>11)&(0xf<<14))) /* v9 */
+#define MCOND(x,i_or_f) ((((i_or_f)&1)<<18)|(((x)>>11)&(0xf<<14))) /* v9 */
 
 /* v9: Move register (MOVRcc and FMOVRcc) condition field.  */
-#define RCOND(x)	(((x)&0x7)<<10)	/* v9 */
+#define RCOND(x)        (((x)&0x7)<<10) /* v9 */
 
-#define CONDA	(COND(0x8))
-#define CONDCC	(COND(0xd))
-#define CONDCS	(COND(0x5))
-#define CONDE	(COND(0x1))
-#define CONDG	(COND(0xa))
-#define CONDGE	(COND(0xb))
-#define CONDGU	(COND(0xc))
-#define CONDL	(COND(0x3))
-#define CONDLE	(COND(0x2))
-#define CONDLEU	(COND(0x4))
-#define CONDN	(COND(0x0))
-#define CONDNE	(COND(0x9))
-#define CONDNEG	(COND(0x6))
-#define CONDPOS	(COND(0xe))
-#define CONDVC	(COND(0xf))
-#define CONDVS	(COND(0x7))
+#define CONDA   (COND(0x8))
+#define CONDCC  (COND(0xd))
+#define CONDCS  (COND(0x5))
+#define CONDE   (COND(0x1))
+#define CONDG   (COND(0xa))
+#define CONDGE  (COND(0xb))
+#define CONDGU  (COND(0xc))
+#define CONDL   (COND(0x3))
+#define CONDLE  (COND(0x2))
+#define CONDLEU (COND(0x4))
+#define CONDN   (COND(0x0))
+#define CONDNE  (COND(0x9))
+#define CONDNEG (COND(0x6))
+#define CONDPOS (COND(0xe))
+#define CONDVC  (COND(0xf))
+#define CONDVS  (COND(0x7))
 
-#define CONDNZ	CONDNE
-#define CONDZ	CONDE
-#define CONDGEU	CONDCC
-#define CONDLU	CONDCS
+#define CONDNZ  CONDNE
+#define CONDZ   CONDE
+#define CONDGEU CONDCC
+#define CONDLU  CONDCS
 
-#define FCONDA		(COND(0x8))
-#define FCONDE		(COND(0x9))
-#define FCONDG		(COND(0x6))
-#define FCONDGE		(COND(0xb))
-#define FCONDL		(COND(0x4))
-#define FCONDLE		(COND(0xd))
-#define FCONDLG		(COND(0x2))
-#define FCONDN		(COND(0x0))
-#define FCONDNE		(COND(0x1))
-#define FCONDO		(COND(0xf))
-#define FCONDU		(COND(0x7))
-#define FCONDUE		(COND(0xa))
-#define FCONDUG		(COND(0x5))
-#define FCONDUGE	(COND(0xc))
-#define FCONDUL		(COND(0x3))
-#define FCONDULE	(COND(0xe))
+#define FCONDA          (COND(0x8))
+#define FCONDE          (COND(0x9))
+#define FCONDG          (COND(0x6))
+#define FCONDGE         (COND(0xb))
+#define FCONDL          (COND(0x4))
+#define FCONDLE         (COND(0xd))
+#define FCONDLG         (COND(0x2))
+#define FCONDN          (COND(0x0))
+#define FCONDNE         (COND(0x1))
+#define FCONDO          (COND(0xf))
+#define FCONDU          (COND(0x7))
+#define FCONDUE         (COND(0xa))
+#define FCONDUG         (COND(0x5))
+#define FCONDUGE        (COND(0xc))
+#define FCONDUL         (COND(0x3))
+#define FCONDULE        (COND(0xe))
 
-#define FCONDNZ	FCONDNE
-#define FCONDZ	FCONDE
+#define FCONDNZ FCONDNE
+#define FCONDZ  FCONDE
 
-#define ICC (0)	/* v9 */
+#define ICC (0) /* v9 */
 #define XCC (1<<12) /* v9 */
-#define FCC(x)	(((x)&0x3)<<11) /* v9 */
-#define FBFCC(x)	(((x)&0x3)<<20)	/* v9 */
+#define FCC(x)  (((x)&0x3)<<11) /* v9 */
+#define FBFCC(x)        (((x)&0x3)<<20) /* v9 */
 
 /* The order of the opcodes in the table is significant:
 
-	* The assembler requires that all instances of the same mnemonic must
-	be consecutive.	If they aren't, the assembler will bomb at runtime.
+        * The assembler requires that all instances of the same mnemonic must
+        be consecutive. If they aren't, the assembler will bomb at runtime.
 
-	* The disassembler should not care about the order of the opcodes.
+        * The disassembler should not care about the order of the opcodes.
 
 */
 
 /* Entries for commutative arithmetic operations.  */
 /* ??? More entries can make use of this.  */
 #define COMMUTEOP(opcode, op3, arch_mask) \
-{ opcode,	F3(2, op3, 0), F3(~2, ~op3, ~0)|ASI(~0),	"1,2,d", 0, arch_mask }, \
-{ opcode,	F3(2, op3, 1), F3(~2, ~op3, ~1),		"1,i,d", 0, arch_mask }, \
-{ opcode,	F3(2, op3, 1), F3(~2, ~op3, ~1),		"i,1,d", 0, arch_mask }
+{ opcode,       F3(2, op3, 0), F3(~2, ~op3, ~0)|ASI(~0),        "1,2,d", 0, arch_mask }, \
+{ opcode,       F3(2, op3, 1), F3(~2, ~op3, ~1),                "1,i,d", 0, arch_mask }, \
+{ opcode,       F3(2, op3, 1), F3(~2, ~op3, ~1),                "i,1,d", 0, arch_mask }
 
 const struct sparc_opcode sparc_opcodes[] = {
 
-{ "ld",	F3(3, 0x00, 0), F3(~3, ~0x00, ~0),		"[1+2],d", 0, v6 },
-{ "ld",	F3(3, 0x00, 0), F3(~3, ~0x00, ~0)|RS2_G0,	"[1],d", 0, v6 }, /* ld [rs1+%g0],d */
-{ "ld",	F3(3, 0x00, 1), F3(~3, ~0x00, ~1),		"[1+i],d", 0, v6 },
-{ "ld",	F3(3, 0x00, 1), F3(~3, ~0x00, ~1),		"[i+1],d", 0, v6 },
-{ "ld",	F3(3, 0x00, 1), F3(~3, ~0x00, ~1)|RS1_G0,	"[i],d", 0, v6 },
-{ "ld",	F3(3, 0x00, 1), F3(~3, ~0x00, ~1)|SIMM13(~0),	"[1],d", 0, v6 }, /* ld [rs1+0],d */
-{ "ld",	F3(3, 0x20, 0), F3(~3, ~0x20, ~0),		"[1+2],g", 0, v6 },
-{ "ld",	F3(3, 0x20, 0), F3(~3, ~0x20, ~0)|RS2_G0,	"[1],g", 0, v6 }, /* ld [rs1+%g0],d */
-{ "ld",	F3(3, 0x20, 1), F3(~3, ~0x20, ~1),		"[1+i],g", 0, v6 },
-{ "ld",	F3(3, 0x20, 1), F3(~3, ~0x20, ~1),		"[i+1],g", 0, v6 },
-{ "ld",	F3(3, 0x20, 1), F3(~3, ~0x20, ~1)|RS1_G0,	"[i],g", 0, v6 },
-{ "ld",	F3(3, 0x20, 1), F3(~3, ~0x20, ~1)|SIMM13(~0),	"[1],g", 0, v6 }, /* ld [rs1+0],d */
+{ "ld", F3(3, 0x00, 0), F3(~3, ~0x00, ~0),              "[1+2],d", 0, v6 },
+{ "ld", F3(3, 0x00, 0), F3(~3, ~0x00, ~0)|RS2_G0,       "[1],d", 0, v6 }, /* ld [rs1+%g0],d */
+{ "ld", F3(3, 0x00, 1), F3(~3, ~0x00, ~1),              "[1+i],d", 0, v6 },
+{ "ld", F3(3, 0x00, 1), F3(~3, ~0x00, ~1),              "[i+1],d", 0, v6 },
+{ "ld", F3(3, 0x00, 1), F3(~3, ~0x00, ~1)|RS1_G0,       "[i],d", 0, v6 },
+{ "ld", F3(3, 0x00, 1), F3(~3, ~0x00, ~1)|SIMM13(~0),   "[1],d", 0, v6 }, /* ld [rs1+0],d */
+{ "ld", F3(3, 0x20, 0), F3(~3, ~0x20, ~0),              "[1+2],g", 0, v6 },
+{ "ld", F3(3, 0x20, 0), F3(~3, ~0x20, ~0)|RS2_G0,       "[1],g", 0, v6 }, /* ld [rs1+%g0],d */
+{ "ld", F3(3, 0x20, 1), F3(~3, ~0x20, ~1),              "[1+i],g", 0, v6 },
+{ "ld", F3(3, 0x20, 1), F3(~3, ~0x20, ~1),              "[i+1],g", 0, v6 },
+{ "ld", F3(3, 0x20, 1), F3(~3, ~0x20, ~1)|RS1_G0,       "[i],g", 0, v6 },
+{ "ld", F3(3, 0x20, 1), F3(~3, ~0x20, ~1)|SIMM13(~0),   "[1],g", 0, v6 }, /* ld [rs1+0],d */
 
-{ "ld",	F3(3, 0x21, 0), F3(~3, ~0x21, ~0)|RD(~0),	"[1+2],F", 0, v6 },
-{ "ld",	F3(3, 0x21, 0), F3(~3, ~0x21, ~0)|RS2_G0|RD(~0),"[1],F", 0, v6 }, /* ld [rs1+%g0],d */
-{ "ld",	F3(3, 0x21, 1), F3(~3, ~0x21, ~1)|RD(~0),	"[1+i],F", 0, v6 },
-{ "ld",	F3(3, 0x21, 1), F3(~3, ~0x21, ~1)|RD(~0),	"[i+1],F", 0, v6 },
-{ "ld",	F3(3, 0x21, 1), F3(~3, ~0x21, ~1)|RS1_G0|RD(~0),"[i],F", 0, v6 },
-{ "ld",	F3(3, 0x21, 1), F3(~3, ~0x21, ~1)|SIMM13(~0)|RD(~0),"[1],F", 0, v6 }, /* ld [rs1+0],d */
+{ "ld", F3(3, 0x21, 0), F3(~3, ~0x21, ~0)|RD(~0),       "[1+2],F", 0, v6 },
+{ "ld", F3(3, 0x21, 0), F3(~3, ~0x21, ~0)|RS2_G0|RD(~0),"[1],F", 0, v6 }, /* ld [rs1+%g0],d */
+{ "ld", F3(3, 0x21, 1), F3(~3, ~0x21, ~1)|RD(~0),       "[1+i],F", 0, v6 },
+{ "ld", F3(3, 0x21, 1), F3(~3, ~0x21, ~1)|RD(~0),       "[i+1],F", 0, v6 },
+{ "ld", F3(3, 0x21, 1), F3(~3, ~0x21, ~1)|RS1_G0|RD(~0),"[i],F", 0, v6 },
+{ "ld", F3(3, 0x21, 1), F3(~3, ~0x21, ~1)|SIMM13(~0)|RD(~0),"[1],F", 0, v6 }, /* ld [rs1+0],d */
 
-{ "ld",	F3(3, 0x30, 0), F3(~3, ~0x30, ~0),		"[1+2],D", 0, v6notv9 },
-{ "ld",	F3(3, 0x30, 0), F3(~3, ~0x30, ~0)|RS2_G0,	"[1],D", 0, v6notv9 }, /* ld [rs1+%g0],d */
-{ "ld",	F3(3, 0x30, 1), F3(~3, ~0x30, ~1),		"[1+i],D", 0, v6notv9 },
-{ "ld",	F3(3, 0x30, 1), F3(~3, ~0x30, ~1),		"[i+1],D", 0, v6notv9 },
-{ "ld",	F3(3, 0x30, 1), F3(~3, ~0x30, ~1)|RS1_G0,	"[i],D", 0, v6notv9 },
-{ "ld",	F3(3, 0x30, 1), F3(~3, ~0x30, ~1)|SIMM13(~0),	"[1],D", 0, v6notv9 }, /* ld [rs1+0],d */
-{ "ld",	F3(3, 0x31, 0), F3(~3, ~0x31, ~0),		"[1+2],C", 0, v6notv9 },
-{ "ld",	F3(3, 0x31, 0), F3(~3, ~0x31, ~0)|RS2_G0,	"[1],C", 0, v6notv9 }, /* ld [rs1+%g0],d */
-{ "ld",	F3(3, 0x31, 1), F3(~3, ~0x31, ~1),		"[1+i],C", 0, v6notv9 },
-{ "ld",	F3(3, 0x31, 1), F3(~3, ~0x31, ~1),		"[i+1],C", 0, v6notv9 },
-{ "ld",	F3(3, 0x31, 1), F3(~3, ~0x31, ~1)|RS1_G0,	"[i],C", 0, v6notv9 },
-{ "ld",	F3(3, 0x31, 1), F3(~3, ~0x31, ~1)|SIMM13(~0),	"[1],C", 0, v6notv9 }, /* ld [rs1+0],d */
+{ "ld", F3(3, 0x30, 0), F3(~3, ~0x30, ~0),              "[1+2],D", 0, v6notv9 },
+{ "ld", F3(3, 0x30, 0), F3(~3, ~0x30, ~0)|RS2_G0,       "[1],D", 0, v6notv9 }, /* ld [rs1+%g0],d */
+{ "ld", F3(3, 0x30, 1), F3(~3, ~0x30, ~1),              "[1+i],D", 0, v6notv9 },
+{ "ld", F3(3, 0x30, 1), F3(~3, ~0x30, ~1),              "[i+1],D", 0, v6notv9 },
+{ "ld", F3(3, 0x30, 1), F3(~3, ~0x30, ~1)|RS1_G0,       "[i],D", 0, v6notv9 },
+{ "ld", F3(3, 0x30, 1), F3(~3, ~0x30, ~1)|SIMM13(~0),   "[1],D", 0, v6notv9 }, /* ld [rs1+0],d */
+{ "ld", F3(3, 0x31, 0), F3(~3, ~0x31, ~0),              "[1+2],C", 0, v6notv9 },
+{ "ld", F3(3, 0x31, 0), F3(~3, ~0x31, ~0)|RS2_G0,       "[1],C", 0, v6notv9 }, /* ld [rs1+%g0],d */
+{ "ld", F3(3, 0x31, 1), F3(~3, ~0x31, ~1),              "[1+i],C", 0, v6notv9 },
+{ "ld", F3(3, 0x31, 1), F3(~3, ~0x31, ~1),              "[i+1],C", 0, v6notv9 },
+{ "ld", F3(3, 0x31, 1), F3(~3, ~0x31, ~1)|RS1_G0,       "[i],C", 0, v6notv9 },
+{ "ld", F3(3, 0x31, 1), F3(~3, ~0x31, ~1)|SIMM13(~0),   "[1],C", 0, v6notv9 }, /* ld [rs1+0],d */
 
 /* The v9 LDUW is the same as the old 'ld' opcode, it is not the same as the
    'ld' pseudo-op in v9.  */
-{ "lduw",	F3(3, 0x00, 0), F3(~3, ~0x00, ~0),		"[1+2],d", F_ALIAS, v9 },
-{ "lduw",	F3(3, 0x00, 0), F3(~3, ~0x00, ~0)|RS2_G0,	"[1],d", F_ALIAS, v9 }, /* ld [rs1+%g0],d */
-{ "lduw",	F3(3, 0x00, 1), F3(~3, ~0x00, ~1),		"[1+i],d", F_ALIAS, v9 },
-{ "lduw",	F3(3, 0x00, 1), F3(~3, ~0x00, ~1),		"[i+1],d", F_ALIAS, v9 },
-{ "lduw",	F3(3, 0x00, 1), F3(~3, ~0x00, ~1)|RS1_G0,	"[i],d", F_ALIAS, v9 },
-{ "lduw",	F3(3, 0x00, 1), F3(~3, ~0x00, ~1)|SIMM13(~0),	"[1],d", F_ALIAS, v9 }, /* ld [rs1+0],d */
+{ "lduw",       F3(3, 0x00, 0), F3(~3, ~0x00, ~0),              "[1+2],d", F_ALIAS, v9 },
+{ "lduw",       F3(3, 0x00, 0), F3(~3, ~0x00, ~0)|RS2_G0,       "[1],d", F_ALIAS, v9 }, /* ld [rs1+%g0],d */
+{ "lduw",       F3(3, 0x00, 1), F3(~3, ~0x00, ~1),              "[1+i],d", F_ALIAS, v9 },
+{ "lduw",       F3(3, 0x00, 1), F3(~3, ~0x00, ~1),              "[i+1],d", F_ALIAS, v9 },
+{ "lduw",       F3(3, 0x00, 1), F3(~3, ~0x00, ~1)|RS1_G0,       "[i],d", F_ALIAS, v9 },
+{ "lduw",       F3(3, 0x00, 1), F3(~3, ~0x00, ~1)|SIMM13(~0),   "[1],d", F_ALIAS, v9 }, /* ld [rs1+0],d */
 
-{ "ldd",	F3(3, 0x03, 0), F3(~3, ~0x03, ~0)|ASI(~0),	"[1+2],d", 0, v6 },
-{ "ldd",	F3(3, 0x03, 0), F3(~3, ~0x03, ~0)|ASI_RS2(~0),	"[1],d", 0, v6 }, /* ldd [rs1+%g0],d */
-{ "ldd",	F3(3, 0x03, 1), F3(~3, ~0x03, ~1),		"[1+i],d", 0, v6 },
-{ "ldd",	F3(3, 0x03, 1), F3(~3, ~0x03, ~1),		"[i+1],d", 0, v6 },
-{ "ldd",	F3(3, 0x03, 1), F3(~3, ~0x03, ~1)|RS1_G0,	"[i],d", 0, v6 },
-{ "ldd",	F3(3, 0x03, 1), F3(~3, ~0x03, ~1)|SIMM13(~0),	"[1],d", 0, v6 }, /* ldd [rs1+0],d */
-{ "ldd",	F3(3, 0x23, 0), F3(~3, ~0x23, ~0)|ASI(~0),	"[1+2],H", 0, v6 },
-{ "ldd",	F3(3, 0x23, 0), F3(~3, ~0x23, ~0)|ASI_RS2(~0),	"[1],H", 0, v6 }, /* ldd [rs1+%g0],d */
-{ "ldd",	F3(3, 0x23, 1), F3(~3, ~0x23, ~1),		"[1+i],H", 0, v6 },
-{ "ldd",	F3(3, 0x23, 1), F3(~3, ~0x23, ~1),		"[i+1],H", 0, v6 },
-{ "ldd",	F3(3, 0x23, 1), F3(~3, ~0x23, ~1)|RS1_G0,	"[i],H", 0, v6 },
-{ "ldd",	F3(3, 0x23, 1), F3(~3, ~0x23, ~1)|SIMM13(~0),	"[1],H", 0, v6 }, /* ldd [rs1+0],d */
+{ "ldd",        F3(3, 0x03, 0), F3(~3, ~0x03, ~0)|ASI(~0),      "[1+2],d"