ia64/xen-unstable

changeset 10985:08a11694b109

[qemu] Update ioemu to qemu 0.8.2.

Signed-off-by: Christian Limpach <Christian.Limpach@xensource.com>
author chris@kneesaa.uk.xensource.com
date Mon Aug 07 18:25:30 2006 +0100 (2006-08-07)
parents fd59667e5365
children 98fc8b05193c
files tools/ioemu/Changelog tools/ioemu/Makefile tools/ioemu/Makefile.target tools/ioemu/TODO tools/ioemu/VERSION tools/ioemu/audio/alsaaudio.c tools/ioemu/audio/audio.c tools/ioemu/audio/audio.h tools/ioemu/audio/audio_int.h tools/ioemu/audio/audio_template.h tools/ioemu/audio/coreaudio.c tools/ioemu/audio/dsound_template.h tools/ioemu/audio/dsoundaudio.c tools/ioemu/audio/fmodaudio.c tools/ioemu/audio/noaudio.c tools/ioemu/audio/ossaudio.c tools/ioemu/audio/rate_template.h tools/ioemu/audio/sdlaudio.c tools/ioemu/audio/wavaudio.c tools/ioemu/audio/wavcapture.c tools/ioemu/block-cow.c tools/ioemu/block-qcow.c tools/ioemu/block-vmdk.c tools/ioemu/block-vpc.c tools/ioemu/block-vvfat.c tools/ioemu/block.c tools/ioemu/block_int.h tools/ioemu/cocoa.m tools/ioemu/configure tools/ioemu/console.c tools/ioemu/cpu-all.h tools/ioemu/cpu-defs.h tools/ioemu/cpu-exec.c tools/ioemu/disas.c tools/ioemu/dyngen-exec.h tools/ioemu/dyngen.c tools/ioemu/dyngen.h tools/ioemu/elf.h tools/ioemu/exec-all.h tools/ioemu/exec.c tools/ioemu/fpu/softfloat-native.c tools/ioemu/gdbstub.c tools/ioemu/hw/acpi-dsdt.dsl tools/ioemu/hw/acpi-dsdt.hex tools/ioemu/hw/acpi.c tools/ioemu/hw/adlib.c tools/ioemu/hw/apb_pci.c tools/ioemu/hw/apic.c tools/ioemu/hw/cdrom.c tools/ioemu/hw/cuda.c tools/ioemu/hw/es1370.c tools/ioemu/hw/esp.c tools/ioemu/hw/grackle_pci.c tools/ioemu/hw/i8259.c tools/ioemu/hw/ide.c tools/ioemu/hw/lsi53c895a.c tools/ioemu/hw/m48t59.c tools/ioemu/hw/mips_r4k.c tools/ioemu/hw/ne2000.c tools/ioemu/hw/pc.c tools/ioemu/hw/pci.c tools/ioemu/hw/pci_host.h tools/ioemu/hw/pcnet.c tools/ioemu/hw/pcspk.c tools/ioemu/hw/pflash_cfi02.c tools/ioemu/hw/piix4acpi.c tools/ioemu/hw/piix_pci.c tools/ioemu/hw/pl050.c tools/ioemu/hw/ppc_chrp.c tools/ioemu/hw/ppc_prep.c tools/ioemu/hw/prep_pci.c tools/ioemu/hw/rtl8139.c tools/ioemu/hw/sb16.c tools/ioemu/hw/scsi-disk.c tools/ioemu/hw/sh7750.c tools/ioemu/hw/slavio_intctl.c tools/ioemu/hw/slavio_timer.c tools/ioemu/hw/sun4m.c tools/ioemu/hw/sun4u.c tools/ioemu/hw/unin_pci.c tools/ioemu/hw/usb-hid.c tools/ioemu/hw/usb-hub.c tools/ioemu/hw/usb-msd.c tools/ioemu/hw/usb-ohci.c tools/ioemu/hw/usb-uhci.c tools/ioemu/hw/usb.h tools/ioemu/hw/versatile_pci.c tools/ioemu/hw/versatilepb.c tools/ioemu/hw/vga.c tools/ioemu/hw/vga_int.h tools/ioemu/hw/vga_template.h tools/ioemu/kqemu.c tools/ioemu/loader.c tools/ioemu/monitor.c tools/ioemu/osdep.c tools/ioemu/osdep.h tools/ioemu/pc-bios/README tools/ioemu/pc-bios/bios.diff tools/ioemu/pc-bios/vgabios.diff tools/ioemu/pc-bios/video.x tools/ioemu/qemu-doc.texi tools/ioemu/qemu-img.c tools/ioemu/sdl.c tools/ioemu/tap-win32.c tools/ioemu/target-i386/exec.h tools/ioemu/target-i386/helper.c tools/ioemu/target-i386/helper2.c tools/ioemu/target-i386/op.c tools/ioemu/target-i386/translate.c tools/ioemu/tests/Makefile tools/ioemu/tests/test-i386.c tools/ioemu/usb-linux.c tools/ioemu/vl.c tools/ioemu/vl.h tools/ioemu/vnc.c tools/ioemu/vnchextile.h
line diff
     1.1 --- a/tools/ioemu/Changelog	Mon Aug 07 18:11:59 2006 +0100
     1.2 +++ b/tools/ioemu/Changelog	Mon Aug 07 18:25:30 2006 +0100
     1.3 @@ -1,3 +1,22 @@
     1.4 +version 0.8.2:
     1.5 +
     1.6 +  - ACPI support
     1.7 +  - PC VGA BIOS fixes
     1.8 +  - switch to OpenBios for SPARC targets (Blue Swirl)
     1.9 +  - VNC server fixes
    1.10 +  - MIPS FPU support (Marius Groeger)
    1.11 +  - Solaris/SPARC host support (Ben Taylor)
    1.12 +  - PPC breakpoints and single stepping (Jason Wessel)
    1.13 +  - USB updates (Paul Brook)
    1.14 +  - UDP/TCP/telnet character devices (Jason Wessel)
    1.15 +  - Windows sparse file support (Frediano Ziglio)
    1.16 +  - RTL8139 NIC TCP segmentation offloading (Igor Kovalenko)
    1.17 +  - PCNET NIC support (Antony T Curtis)
    1.18 +  - Support for variable frequency host CPUs
    1.19 +  - Workaround for win32 SMP hosts
    1.20 +  - Support for AMD Flash memories (Jocelyn Mayer)
    1.21 +  - Audio capture to WAV files support (malc)
    1.22 +
    1.23  version 0.8.1:
    1.24  
    1.25    - USB tablet support (Brad Campbell, Anthony Liguori)
     2.1 --- a/tools/ioemu/Makefile	Mon Aug 07 18:11:59 2006 +0100
     2.2 +++ b/tools/ioemu/Makefile	Mon Aug 07 18:25:30 2006 +0100
     2.3 @@ -1,12 +1,20 @@
     2.4 +# Makefile for QEMU.
     2.5 +
     2.6  XEN_ROOT=../..
     2.7  include $(XEN_ROOT)/tools/Rules.mk
     2.8  
     2.9  -include config-host.mak
    2.10  
    2.11 +.PHONY: all clean distclean dvi info install install-doc tar tarbin \
    2.12 +	speed test test2 html dvi info
    2.13 +
    2.14  CFLAGS+=-Wall -O2 -g -fno-strict-aliasing -I.
    2.15  ifdef CONFIG_DARWIN
    2.16  CFLAGS+= -mdynamic-no-pic
    2.17  endif
    2.18 +ifeq ($(ARCH),sparc)
    2.19 +CFLAGS+=-mcpu=ultrasparc
    2.20 +endif
    2.21  LDFLAGS=-g
    2.22  LIBS=
    2.23  DEFINES+=-D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE
    2.24 @@ -20,11 +28,15 @@ else
    2.25  DOCS=
    2.26  endif
    2.27  
    2.28 -all: $(DOCS)
    2.29 -	for d in $(TARGET_DIRS); do \
    2.30 -	$(MAKE) -C $$d $@ || exit 1 ; \
    2.31 -        done
    2.32 +TOOLS=
    2.33  
    2.34 +all: $(TOOLS) $(DOCS) recurse-all
    2.35 +
    2.36 +subdir-%:
    2.37 +	$(MAKE) -C $(subst subdir-,,$@) all
    2.38 +
    2.39 +recurse-all: $(patsubst %,subdir-%, $(TARGET_DIRS))
    2.40 +        
    2.41  qemu-img$(EXESUF): qemu-img.c block.c block-cow.c block-qcow.c aes.c block-vmdk.c block-cloop.c block-dmg.c block-bochs.c block-vpc.c block-vvfat.c
    2.42  	$(CC) -DQEMU_TOOL $(CFLAGS) $(LDFLAGS) $(DEFINES) -o $@ $^ -lz $(LIBS)
    2.43  
    2.44 @@ -42,6 +54,7 @@ clean:
    2.45  
    2.46  distclean: clean
    2.47  	rm -f config-host.mak config-host.h $(DOCS)
    2.48 +	rm -f qemu-{doc,tech}.{info,aux,cp,dvi,fn,info,ky,log,pg,toc,tp,vr}
    2.49  	for d in $(TARGET_DIRS); do \
    2.50  	rm -rf $$d || exit 1 ; \
    2.51          done
    2.52 @@ -63,7 +76,7 @@ install: all $(if $(BUILD_DOCS),install-
    2.53  #	$(INSTALL) -m 755 -s $(TOOLS) "$(DESTDIR)$(bindir)"
    2.54  #	mkdir -p "$(DESTDIR)$(datadir)"
    2.55  #	for x in bios.bin vgabios.bin vgabios-cirrus.bin ppc_rom.bin \
    2.56 -#			video.x proll.elf linux_boot.bin; do \
    2.57 +#			video.x openbios-sparc32 linux_boot.bin; do \
    2.58  #		$(INSTALL) -m 644 $(SRC_PATH)/pc-bios/$$x "$(DESTDIR)$(datadir)"; \
    2.59  #	done
    2.60  ifndef CONFIG_WIN32
    2.61 @@ -106,6 +119,12 @@ qemu-img.1: qemu-img.texi
    2.62  	perl -w $(SRC_PATH)/texi2pod.pl $< qemu-img.pod
    2.63  	pod2man --section=1 --center=" " --release=" " qemu-img.pod > $@
    2.64  
    2.65 +info: qemu-doc.info qemu-tech.info
    2.66 +
    2.67 +dvi: qemu-doc.dvi qemu-tech.dvi
    2.68 +
    2.69 +html: qemu-doc.html qemu-tech.html
    2.70 +
    2.71  FILE=qemu-$(shell cat VERSION)
    2.72  
    2.73  # tar release (use 'make -k tar' on a checkouted tree)
    2.74 @@ -138,7 +157,7 @@ tarbin:
    2.75  	$(datadir)/vgabios-cirrus.bin \
    2.76  	$(datadir)/ppc_rom.bin \
    2.77  	$(datadir)/video.x \
    2.78 -	$(datadir)/proll.elf \
    2.79 +	$(datadir)/openbios-sparc32 \
    2.80  	$(datadir)/linux_boot.bin \
    2.81  	$(docdir)/qemu-doc.html \
    2.82  	$(docdir)/qemu-tech.html \
     3.1 --- a/tools/ioemu/Makefile.target	Mon Aug 07 18:11:59 2006 +0100
     3.2 +++ b/tools/ioemu/Makefile.target	Mon Aug 07 18:25:30 2006 +0100
     3.3 @@ -40,6 +40,11 @@ ifeq ($(TARGET_ARCH),arm)
     3.4      TARGET_ARCH2=armeb
     3.5    endif
     3.6  endif
     3.7 +ifeq ($(TARGET_ARCH),sh4)
     3.8 +  ifeq ($(TARGET_WORDS_BIGENDIAN),yes)
     3.9 +    TARGET_ARCH2=sh4eb
    3.10 +  endif
    3.11 +endif
    3.12  ifeq ($(TARGET_ARCH),mips)
    3.13    ifneq ($(TARGET_WORDS_BIGENDIAN),yes)
    3.14      TARGET_ARCH2=mipsel
    3.15 @@ -114,17 +119,24 @@ LDFLAGS+=-Wl,-T,$(SRC_PATH)/s390.ld
    3.16  endif
    3.17  
    3.18  ifeq ($(ARCH),sparc)
    3.19 -CFLAGS+=-m32 -ffixed-g1 -ffixed-g2 -ffixed-g3 -ffixed-g6
    3.20 +ifeq ($(CONFIG_SOLARIS),yes)
    3.21 +CFLAGS+=-mcpu=ultrasparc -m32 -ffixed-g2 -ffixed-g3
    3.22 +LDFLAGS+=-m32
    3.23 +OP_CFLAGS=$(CFLAGS) -fno-delayed-branch -fno-omit-frame-pointer -ffixed-i0
    3.24 +else
    3.25 +CFLAGS+=-mcpu=ultrasparc -m32 -ffixed-g1 -ffixed-g2 -ffixed-g3 -ffixed-g6
    3.26  LDFLAGS+=-m32
    3.27  OP_CFLAGS=$(CFLAGS) -fno-delayed-branch -ffixed-i0
    3.28  HELPER_CFLAGS=$(CFLAGS) -ffixed-i0 -mflat
    3.29  # -static is used to avoid g1/g3 usage by the dynamic linker
    3.30  LDFLAGS+=-Wl,-T,$(SRC_PATH)/sparc.ld -static
    3.31  endif
    3.32 +endif
    3.33  
    3.34  ifeq ($(ARCH),sparc64)
    3.35 -CFLAGS+=-m64 -ffixed-g1 -ffixed-g2 -ffixed-g3 -ffixed-g6
    3.36 +CFLAGS+=-mcpu=ultrasparc -m64 -ffixed-g1 -ffixed-g4 -ffixed-g5 -ffixed-g7
    3.37  LDFLAGS+=-m64
    3.38 +LDFLAGS+=-Wl,-T,$(SRC_PATH)/sparc64.ld
    3.39  OP_CFLAGS=$(CFLAGS) -fno-delayed-branch -ffixed-i0
    3.40  endif
    3.41  
    3.42 @@ -186,7 +198,12 @@ LDFLAGS+=-p
    3.43  main.o: CFLAGS+=-p
    3.44  endif
    3.45  
    3.46 -OBJS= elfload.o main.o syscall.o mmap.o signal.o path.o osdep.o thunk.o 
    3.47 +OBJS= main.o syscall.o mmap.o signal.o path.o osdep.o thunk.o \
    3.48 +      elfload.o linuxload.o
    3.49 +ifdef TARGET_HAS_BFLT
    3.50 +OBJS+= flatload.o
    3.51 +endif
    3.52 +
    3.53  ifeq ($(TARGET_ARCH), i386)
    3.54  OBJS+= vm86.o
    3.55  endif
    3.56 @@ -323,18 +340,23 @@ endif
    3.57  ifdef CONFIG_ADLIB
    3.58  SOUND_HW += fmopl.o adlib.o
    3.59  endif
    3.60 +AUDIODRV+= wavcapture.o
    3.61 +
    3.62 +# SCSI layer
    3.63 +VL_OBJS+= scsi-disk.o cdrom.o lsi53c895a.o
    3.64  
    3.65  # USB layer
    3.66 -VL_OBJS+= usb.o usb-hub.o usb-uhci.o usb-linux.o usb-hid.o
    3.67 +VL_OBJS+= usb.o usb-hub.o usb-linux.o usb-hid.o usb-ohci.o usb-msd.o
    3.68  
    3.69  # PCI network cards
    3.70 -VL_OBJS+= ne2000.o rtl8139.o
    3.71 +VL_OBJS+= ne2000.o rtl8139.o pcnet.o
    3.72  
    3.73  ifeq ($(TARGET_BASE_ARCH), i386)
    3.74  # Hardware support
    3.75  VL_OBJS+= ide.o pckbd.o ps2.o vga.o $(SOUND_HW) dma.o $(AUDIODRV)
    3.76  VL_OBJS+= fdc.o mc146818rtc.o serial.o pc.o
    3.77 -VL_OBJS+= cirrus_vga.o mixeng.o parallel.o
    3.78 +VL_OBJS+= cirrus_vga.o mixeng.o parallel.o acpi.o piix_pci.o
    3.79 +VL_OBJS+= usb-uhci.o
    3.80  VL_OBJS+= piix4acpi.o
    3.81  VL_OBJS+= xenstore.o
    3.82  DEFINES += -DHAS_AUDIO
    3.83 @@ -343,6 +365,7 @@ ifeq ($(TARGET_BASE_ARCH), ppc)
    3.84  VL_OBJS+= ppc.o ide.o pckbd.o ps2.o vga.o $(SOUND_HW) dma.o $(AUDIODRV)
    3.85  VL_OBJS+= mc146818rtc.o serial.o i8259.o i8254.o fdc.o m48t59.o
    3.86  VL_OBJS+= ppc_prep.o ppc_chrp.o cuda.o adb.o openpic.o heathrow_pic.o mixeng.o
    3.87 +VL_OBJS+= grackle_pci.o prep_pci.o unin_pci.o
    3.88  DEFINES += -DHAS_AUDIO
    3.89  endif
    3.90  ifeq ($(TARGET_ARCH), mips)
    3.91 @@ -351,7 +374,7 @@ VL_OBJS+= mips_r4k.o dma.o vga.o serial.
    3.92  endif
    3.93  ifeq ($(TARGET_BASE_ARCH), sparc)
    3.94  ifeq ($(TARGET_ARCH), sparc64)
    3.95 -VL_OBJS+= sun4u.o ide.o pckbd.o ps2.o vga.o
    3.96 +VL_OBJS+= sun4u.o ide.o pckbd.o ps2.o vga.o apb_pci.o
    3.97  VL_OBJS+= fdc.o mc146818rtc.o serial.o m48t59.o
    3.98  VL_OBJS+= cirrus_vga.o parallel.o
    3.99  else
   3.100 @@ -362,6 +385,7 @@ endif
   3.101  ifeq ($(TARGET_BASE_ARCH), arm)
   3.102  VL_OBJS+= integratorcp.o versatilepb.o ps2.o smc91c111.o arm_pic.o arm_timer.o
   3.103  VL_OBJS+= arm_boot.o pl011.o pl050.o pl080.o pl110.o pl190.o
   3.104 +VL_OBJS+= versatile_pci.o
   3.105  endif
   3.106  ifeq ($(TARGET_BASE_ARCH), sh4)
   3.107  VL_OBJS+= shix.o sh7750.o sh7750_regnames.o tc58128.o
   3.108 @@ -399,7 +423,7 @@ endif
   3.109  ifndef CONFIG_DARWIN
   3.110  ifndef CONFIG_WIN32
   3.111  ifndef CONFIG_SOLARIS
   3.112 -VL_LIBS=-lutil
   3.113 +VL_LIBS=-lutil -lrt
   3.114  endif
   3.115  endif
   3.116  endif
   3.117 @@ -412,6 +436,11 @@ ifeq ($(ARCH),ia64)
   3.118  VL_LDFLAGS+=-Wl,-G0 -Wl,-T,$(SRC_PATH)/ia64.ld
   3.119  endif
   3.120  
   3.121 +ifeq ($(ARCH),sparc64)
   3.122 +VL_LDFLAGS+=-m64
   3.123 +VL_LDFLAGS+=-Wl,-T,$(SRC_PATH)/sparc64.ld
   3.124 +endif
   3.125 +
   3.126  ifdef CONFIG_WIN32
   3.127  SDL_LIBS := $(filter-out -mwindows, $(SDL_LIBS)) -mconsole
   3.128  endif
   3.129 @@ -491,6 +520,13 @@ endif
   3.130  
   3.131  loader.o: loader.c elf_ops.h
   3.132  
   3.133 +acpi.o: acpi.c acpi-dsdt.hex
   3.134 +
   3.135 +ifdef BUILD_ACPI_TABLES
   3.136 +$(SRC_PATH)/hw/acpi-dsdt.hex: acpi-dsdt.dsl
   3.137 +	iasl -tc -p $@ $<
   3.138 +endif
   3.139 +
   3.140  ifeq ($(TARGET_ARCH), sh4)
   3.141  op.o: op.c op_mem.c cpu.h
   3.142  op_helper.o: op_helper.c exec.h cpu.h
   3.143 @@ -501,6 +537,8 @@ sh7750_regnames.o: sh7750_regnames.c sh7
   3.144  tc58128.o: tc58128.c
   3.145  endif
   3.146  
   3.147 +$(OBJS) $(LIBOBJS) $(VL_OBJS): config.h ../config-host.h
   3.148 +
   3.149  %.o: %.c
   3.150  	$(CC) $(CFLAGS) $(DEFINES) -c -o $@ $<
   3.151  
     4.1 --- a/tools/ioemu/TODO	Mon Aug 07 18:11:59 2006 +0100
     4.2 +++ b/tools/ioemu/TODO	Mon Aug 07 18:25:30 2006 +0100
     4.3 @@ -1,24 +1,20 @@
     4.4  short term:
     4.5  ----------
     4.6 +- cycle counter for all archs
     4.7 +- cpu_interrupt() win32/SMP fix
     4.8  - support variable tsc freq
     4.9 -- cpu_interrupt() win32/SMP fix
    4.10  - USB host async
    4.11  - IDE async
    4.12  - debug option in 'configure' script + disable -fomit-frame-pointer
    4.13  - Precise VGA timings for old games/demos (malc patch)
    4.14  - merge PIC spurious interrupt patch
    4.15 -- merge Solaris patch
    4.16  - warning for OS/2: must not use 128 MB memory (merge bochs cmos patch ?)
    4.17  - config file (at least for windows/Mac OS X)
    4.18 -- commit message if execution of code in IO memory
    4.19  - update doc: PCI infos.
    4.20 -- VNC patch + Synaptic patch.
    4.21  - basic VGA optimizations
    4.22 -- physical memory cache (reduce qemu-fast address space size to about 32 MB)
    4.23  - better code fetch (different exception handling + CS.limit support)
    4.24  - do not resize vga if invalid size.
    4.25  - avoid looping if only exceptions
    4.26 -- cycle counter for all archs
    4.27  - TLB code protection support for PPC
    4.28  - see openMosix Doc 
    4.29  - disable SMC handling for ARM/SPARC/PPC (not finished)
    4.30 @@ -31,12 +27,10 @@ short term:
    4.31  - fix CCOP optimisation
    4.32  - fix all remaining thread lock issues (must put TBs in a specific invalid
    4.33    state, find a solution for tb_flush()).
    4.34 -- fix arm fpu rounding (at least for float->integer conversions)
    4.35  
    4.36  ppc specific:
    4.37  ------------
    4.38  - TLB invalidate not needed if msr_pr changes
    4.39 -- SPR_ENCODE() not useful
    4.40  - enable shift optimizations ?
    4.41  
    4.42  linux-user specific:
     5.1 --- a/tools/ioemu/VERSION	Mon Aug 07 18:11:59 2006 +0100
     5.2 +++ b/tools/ioemu/VERSION	Mon Aug 07 18:25:30 2006 +0100
     5.3 @@ -1,1 +1,1 @@
     5.4 -0.8.1
     5.5 \ No newline at end of file
     5.6 +0.8.2
     5.7 \ No newline at end of file
     6.1 --- a/tools/ioemu/audio/alsaaudio.c	Mon Aug 07 18:11:59 2006 +0100
     6.2 +++ b/tools/ioemu/audio/alsaaudio.c	Mon Aug 07 18:25:30 2006 +0100
     6.3 @@ -61,8 +61,8 @@ static struct {
     6.4      .size_in_usec_in = 1,
     6.5      .size_in_usec_out = 1,
     6.6  #endif
     6.7 -    .pcm_name_out = "hw:0,0",
     6.8 -    .pcm_name_in = "hw:0,0",
     6.9 +    .pcm_name_out = "default",
    6.10 +    .pcm_name_in = "default",
    6.11  #ifdef HIGH_LATENCY
    6.12      .buffer_size_in = 400000,
    6.13      .period_size_in = 400000 / 4,
    6.14 @@ -606,7 +606,6 @@ static int alsa_run_out (HWVoiceOut *hw)
    6.15                  }
    6.16              }
    6.17  
    6.18 -            mixeng_clear (src, written);
    6.19              rpos = (rpos + written) % hw->samples;
    6.20              samples -= written;
    6.21              len -= written;
    6.22 @@ -663,12 +662,9 @@ static int alsa_init_out (HWVoiceOut *hw
    6.23      obt_as.freq = obt.freq;
    6.24      obt_as.nchannels = obt.nchannels;
    6.25      obt_as.fmt = effective_fmt;
    6.26 +    obt_as.endianness = endianness;
    6.27  
    6.28 -    audio_pcm_init_info (
    6.29 -        &hw->info,
    6.30 -        &obt_as,
    6.31 -        audio_need_to_swap_endian (endianness)
    6.32 -        );
    6.33 +    audio_pcm_init_info (&hw->info, &obt_as);
    6.34      hw->samples = obt.samples;
    6.35  
    6.36      alsa->pcm_buf = audio_calloc (AUDIO_FUNC, obt.samples, 1 << hw->info.shift);
    6.37 @@ -752,12 +748,9 @@ static int alsa_init_in (HWVoiceIn *hw, 
    6.38      obt_as.freq = obt.freq;
    6.39      obt_as.nchannels = obt.nchannels;
    6.40      obt_as.fmt = effective_fmt;
    6.41 +    obt_as.endianness = endianness;
    6.42  
    6.43 -    audio_pcm_init_info (
    6.44 -        &hw->info,
    6.45 -        &obt_as,
    6.46 -        audio_need_to_swap_endian (endianness)
    6.47 -        );
    6.48 +    audio_pcm_init_info (&hw->info, &obt_as);
    6.49      hw->samples = obt.samples;
    6.50  
    6.51      alsa->pcm_buf = audio_calloc (AUDIO_FUNC, hw->samples, 1 << hw->info.shift);
     7.1 --- a/tools/ioemu/audio/audio.c	Mon Aug 07 18:11:59 2006 +0100
     7.2 +++ b/tools/ioemu/audio/audio.c	Mon Aug 07 18:25:30 2006 +0100
     7.3 @@ -29,6 +29,7 @@
     7.4  /* #define DEBUG_PLIVE */
     7.5  /* #define DEBUG_LIVE */
     7.6  /* #define DEBUG_OUT */
     7.7 +/* #define DEBUG_CAPTURE */
     7.8  
     7.9  #define SW_NAME(sw) (sw)->name ? (sw)->name : "unknown"
    7.10  
    7.11 @@ -137,7 +138,7 @@ int audio_bug (const char *funcname, int
    7.12      if (cond) {
    7.13          static int shown;
    7.14  
    7.15 -        AUD_log (NULL, "Error a bug that was just triggered in %s\n", funcname);
    7.16 +        AUD_log (NULL, "A bug was just triggered in %s\n", funcname);
    7.17          if (!shown) {
    7.18              shown = 1;
    7.19              AUD_log (NULL, "Save all your work and restart without audio\n");
    7.20 @@ -509,14 +510,28 @@ static void audio_print_settings (audset
    7.21          AUD_log (NULL, "invalid(%d)", as->fmt);
    7.22          break;
    7.23      }
    7.24 +
    7.25 +    AUD_log (NULL, " endianness=");
    7.26 +    switch (as->endianness) {
    7.27 +    case 0:
    7.28 +        AUD_log (NULL, "little");
    7.29 +        break;
    7.30 +    case 1:
    7.31 +        AUD_log (NULL, "big");
    7.32 +        break;
    7.33 +    default:
    7.34 +        AUD_log (NULL, "invalid");
    7.35 +        break;
    7.36 +    }
    7.37      AUD_log (NULL, "\n");
    7.38  }
    7.39  
    7.40 -static int audio_validate_settigs (audsettings_t *as)
    7.41 +static int audio_validate_settings (audsettings_t *as)
    7.42  {
    7.43      int invalid;
    7.44  
    7.45      invalid = as->nchannels != 1 && as->nchannels != 2;
    7.46 +    invalid |= as->endianness != 0 && as->endianness != 1;
    7.47  
    7.48      switch (as->fmt) {
    7.49      case AUD_FMT_S8:
    7.50 @@ -530,11 +545,7 @@ static int audio_validate_settigs (audse
    7.51      }
    7.52  
    7.53      invalid |= as->freq <= 0;
    7.54 -
    7.55 -    if (invalid) {
    7.56 -        return -1;
    7.57 -    }
    7.58 -    return 0;
    7.59 +    return invalid ? -1 : 0;
    7.60  }
    7.61  
    7.62  static int audio_pcm_info_eq (struct audio_pcm_info *info, audsettings_t *as)
    7.63 @@ -556,14 +567,11 @@ static int audio_pcm_info_eq (struct aud
    7.64      return info->freq == as->freq
    7.65          && info->nchannels == as->nchannels
    7.66          && info->sign == sign
    7.67 -        && info->bits == bits;
    7.68 +        && info->bits == bits
    7.69 +        && info->swap_endianness == (as->endianness != AUDIO_HOST_ENDIANNESS);
    7.70  }
    7.71  
    7.72 -void audio_pcm_init_info (
    7.73 -    struct audio_pcm_info *info,
    7.74 -    audsettings_t *as,
    7.75 -    int swap_endian
    7.76 -    )
    7.77 +void audio_pcm_init_info (struct audio_pcm_info *info, audsettings_t *as)
    7.78  {
    7.79      int bits = 8, sign = 0;
    7.80  
    7.81 @@ -587,7 +595,7 @@ void audio_pcm_init_info (
    7.82      info->shift = (as->nchannels == 2) + (bits == 16);
    7.83      info->align = (1 << info->shift) - 1;
    7.84      info->bytes_per_second = info->freq << info->shift;
    7.85 -    info->swap_endian = swap_endian;
    7.86 +    info->swap_endianness = (as->endianness != AUDIO_HOST_ENDIANNESS);
    7.87  }
    7.88  
    7.89  void audio_pcm_info_clear_buf (struct audio_pcm_info *info, void *buf, int len)
    7.90 @@ -609,7 +617,7 @@ void audio_pcm_info_clear_buf (struct au
    7.91              int shift = info->nchannels - 1;
    7.92              short s = INT16_MAX;
    7.93  
    7.94 -            if (info->swap_endian) {
    7.95 +            if (info->swap_endianness) {
    7.96                  s = bswap16 (s);
    7.97              }
    7.98  
    7.99 @@ -621,6 +629,143 @@ void audio_pcm_info_clear_buf (struct au
   7.100  }
   7.101  
   7.102  /*
   7.103 + * Capture
   7.104 + */
   7.105 +static void noop_conv (st_sample_t *dst, const void *src,
   7.106 +                       int samples, volume_t *vol)
   7.107 +{
   7.108 +    (void) src;
   7.109 +    (void) dst;
   7.110 +    (void) samples;
   7.111 +    (void) vol;
   7.112 +}
   7.113 +
   7.114 +static CaptureVoiceOut *audio_pcm_capture_find_specific (
   7.115 +    AudioState *s,
   7.116 +    audsettings_t *as
   7.117 +    )
   7.118 +{
   7.119 +    CaptureVoiceOut *cap;
   7.120 +
   7.121 +    for (cap = s->cap_head.lh_first; cap; cap = cap->entries.le_next) {
   7.122 +        if (audio_pcm_info_eq (&cap->hw.info, as)) {
   7.123 +            return cap;
   7.124 +        }
   7.125 +    }
   7.126 +    return NULL;
   7.127 +}
   7.128 +
   7.129 +static void audio_notify_capture (CaptureVoiceOut *cap, audcnotification_e cmd)
   7.130 +{
   7.131 +    struct capture_callback *cb;
   7.132 +
   7.133 +#ifdef DEBUG_CAPTURE
   7.134 +    dolog ("notification %d sent\n", cmd);
   7.135 +#endif
   7.136 +    for (cb = cap->cb_head.lh_first; cb; cb = cb->entries.le_next) {
   7.137 +        cb->ops.notify (cb->opaque, cmd);
   7.138 +    }
   7.139 +}
   7.140 +
   7.141 +static void audio_capture_maybe_changed (CaptureVoiceOut *cap, int enabled)
   7.142 +{
   7.143 +    if (cap->hw.enabled != enabled) {
   7.144 +        audcnotification_e cmd;
   7.145 +        cap->hw.enabled = enabled;
   7.146 +        cmd = enabled ? AUD_CNOTIFY_ENABLE : AUD_CNOTIFY_DISABLE;
   7.147 +        audio_notify_capture (cap, cmd);
   7.148 +    }
   7.149 +}
   7.150 +
   7.151 +static void audio_recalc_and_notify_capture (CaptureVoiceOut *cap)
   7.152 +{
   7.153 +    HWVoiceOut *hw = &cap->hw;
   7.154 +    SWVoiceOut *sw;
   7.155 +    int enabled = 0;
   7.156 +
   7.157 +    for (sw = hw->sw_head.lh_first; sw; sw = sw->entries.le_next) {
   7.158 +        if (sw->active) {
   7.159 +            enabled = 1;
   7.160 +            break;
   7.161 +        }
   7.162 +    }
   7.163 +    audio_capture_maybe_changed (cap, enabled);
   7.164 +}
   7.165 +
   7.166 +static void audio_detach_capture (HWVoiceOut *hw)
   7.167 +{
   7.168 +    SWVoiceCap *sc = hw->cap_head.lh_first;
   7.169 +
   7.170 +    while (sc) {
   7.171 +        SWVoiceCap *sc1 = sc->entries.le_next;
   7.172 +        SWVoiceOut *sw = &sc->sw;
   7.173 +        CaptureVoiceOut *cap = sc->cap;
   7.174 +        int was_active = sw->active;
   7.175 +
   7.176 +        if (sw->rate) {
   7.177 +            st_rate_stop (sw->rate);
   7.178 +            sw->rate = NULL;
   7.179 +        }
   7.180 +
   7.181 +        LIST_REMOVE (sw, entries);
   7.182 +        LIST_REMOVE (sc, entries);
   7.183 +        qemu_free (sc);
   7.184 +        if (was_active) {
   7.185 +            /* We have removed soft voice from the capture:
   7.186 +               this might have changed the overall status of the capture
   7.187 +               since this might have been the only active voice */
   7.188 +            audio_recalc_and_notify_capture (cap);
   7.189 +        }
   7.190 +        sc = sc1;
   7.191 +    }
   7.192 +}
   7.193 +
   7.194 +static int audio_attach_capture (AudioState *s, HWVoiceOut *hw)
   7.195 +{
   7.196 +    CaptureVoiceOut *cap;
   7.197 +
   7.198 +    audio_detach_capture (hw);
   7.199 +    for (cap = s->cap_head.lh_first; cap; cap = cap->entries.le_next) {
   7.200 +        SWVoiceCap *sc;
   7.201 +        SWVoiceOut *sw;
   7.202 +        HWVoiceOut *hw_cap = &cap->hw;
   7.203 +
   7.204 +        sc = audio_calloc (AUDIO_FUNC, 1, sizeof (*sc));
   7.205 +        if (!sc) {
   7.206 +            dolog ("Could not allocate soft capture voice (%zu bytes)\n",
   7.207 +                   sizeof (*sc));
   7.208 +            return -1;
   7.209 +        }
   7.210 +
   7.211 +        sc->cap = cap;
   7.212 +        sw = &sc->sw;
   7.213 +        sw->hw = hw_cap;
   7.214 +        sw->info = hw->info;
   7.215 +        sw->empty = 1;
   7.216 +        sw->active = hw->enabled;
   7.217 +        sw->conv = noop_conv;
   7.218 +        sw->ratio = ((int64_t) hw_cap->info.freq << 32) / sw->info.freq;
   7.219 +        sw->rate = st_rate_start (sw->info.freq, hw_cap->info.freq);
   7.220 +        if (!sw->rate) {
   7.221 +            dolog ("Could not start rate conversion for `%s'\n", SW_NAME (sw));
   7.222 +            qemu_free (sw);
   7.223 +            return -1;
   7.224 +        }
   7.225 +        LIST_INSERT_HEAD (&hw_cap->sw_head, sw, entries);
   7.226 +        LIST_INSERT_HEAD (&hw->cap_head, sc, entries);
   7.227 +#ifdef DEBUG_CAPTURE
   7.228 +        asprintf (&sw->name, "for %p %d,%d,%d",
   7.229 +                  hw, sw->info.freq, sw->info.bits, sw->info.nchannels);
   7.230 +        dolog ("Added %s active = %d\n", sw->name, sw->active);
   7.231 +#endif
   7.232 +        if (sw->active) {
   7.233 +            audio_capture_maybe_changed (cap, 1);
   7.234 +        }
   7.235 +    }
   7.236 +    return 0;
   7.237 +}
   7.238 +
   7.239 +/*
   7.240   * Hard voice (capture)
   7.241   */
   7.242  static int audio_pcm_hw_find_min_in (HWVoiceIn *hw)
   7.243 @@ -796,6 +941,9 @@ int audio_pcm_sw_write (SWVoiceOut *sw, 
   7.244      }
   7.245  
   7.246      if (live == hwsamples) {
   7.247 +#ifdef DEBUG_OUT
   7.248 +        dolog ("%s is full %d\n", sw->name, live);
   7.249 +#endif
   7.250          return 0;
   7.251      }
   7.252  
   7.253 @@ -914,19 +1062,14 @@ void AUD_set_active_out (SWVoiceOut *sw,
   7.254      hw = sw->hw;
   7.255      if (sw->active != on) {
   7.256          SWVoiceOut *temp_sw;
   7.257 +        SWVoiceCap *sc;
   7.258  
   7.259          if (on) {
   7.260 -            int total;
   7.261 -
   7.262              hw->pending_disable = 0;
   7.263              if (!hw->enabled) {
   7.264                  hw->enabled = 1;
   7.265                  hw->pcm_ops->ctl_out (hw, VOICE_ENABLE);
   7.266              }
   7.267 -
   7.268 -            if (sw->empty) {
   7.269 -                total = 0;
   7.270 -            }
   7.271          }
   7.272          else {
   7.273              if (hw->enabled) {
   7.274 @@ -940,6 +1083,13 @@ void AUD_set_active_out (SWVoiceOut *sw,
   7.275                  hw->pending_disable = nb_active == 1;
   7.276              }
   7.277          }
   7.278 +
   7.279 +        for (sc = hw->cap_head.lh_first; sc; sc = sc->entries.le_next) {
   7.280 +            sc->sw.active = hw->enabled;
   7.281 +            if (hw->enabled) {
   7.282 +                audio_capture_maybe_changed (sc->cap, 1);
   7.283 +            }
   7.284 +        }
   7.285          sw->active = on;
   7.286      }
   7.287  }
   7.288 @@ -997,7 +1147,7 @@ static int audio_get_avail (SWVoiceIn *s
   7.289      }
   7.290  
   7.291      ldebug (
   7.292 -        "%s: get_avail live %d ret %lld\n",
   7.293 +        "%s: get_avail live %d ret %" PRId64 "\n",
   7.294          SW_NAME (sw),
   7.295          live, (((int64_t) live << 32) / sw->ratio) << sw->info.shift
   7.296          );
   7.297 @@ -1023,7 +1173,7 @@ static int audio_get_free (SWVoiceOut *s
   7.298      dead = sw->hw->samples - live;
   7.299  
   7.300  #ifdef DEBUG_OUT
   7.301 -    dolog ("%s: get_free live %d dead %d ret %lld\n",
   7.302 +    dolog ("%s: get_free live %d dead %d ret %" PRId64 "\n",
   7.303             SW_NAME (sw),
   7.304             live, dead, (((int64_t) dead << 32) / sw->ratio) << sw->info.shift);
   7.305  #endif
   7.306 @@ -1031,6 +1181,43 @@ static int audio_get_free (SWVoiceOut *s
   7.307      return (((int64_t) dead << 32) / sw->ratio) << sw->info.shift;
   7.308  }
   7.309  
   7.310 +static void audio_capture_mix_and_clear (HWVoiceOut *hw, int rpos, int samples)
   7.311 +{
   7.312 +    int n;
   7.313 +
   7.314 +    if (hw->enabled) {
   7.315 +        SWVoiceCap *sc;
   7.316 +
   7.317 +        for (sc = hw->cap_head.lh_first; sc; sc = sc->entries.le_next) {
   7.318 +            SWVoiceOut *sw = &sc->sw;
   7.319 +            int rpos2 = rpos;
   7.320 +
   7.321 +            n = samples;
   7.322 +            while (n) {
   7.323 +                int till_end_of_hw = hw->samples - rpos2;
   7.324 +                int to_write = audio_MIN (till_end_of_hw, n);
   7.325 +                int bytes = to_write << hw->info.shift;
   7.326 +                int written;
   7.327 +
   7.328 +                sw->buf = hw->mix_buf + rpos2;
   7.329 +                written = audio_pcm_sw_write (sw, NULL, bytes);
   7.330 +                if (written - bytes) {
   7.331 +                    dolog ("Could not mix %d bytes into a capture "
   7.332 +                           "buffer, mixed %d\n",
   7.333 +                           bytes, written);
   7.334 +                    break;
   7.335 +                }
   7.336 +                n -= to_write;
   7.337 +                rpos2 = (rpos2 + to_write) % hw->samples;
   7.338 +            }
   7.339 +        }
   7.340 +    }
   7.341 +
   7.342 +    n = audio_MIN (samples, hw->samples - rpos);
   7.343 +    mixeng_clear (hw->mix_buf + rpos, n);
   7.344 +    mixeng_clear (hw->mix_buf, samples - n);
   7.345 +}
   7.346 +
   7.347  static void audio_run_out (AudioState *s)
   7.348  {
   7.349      HWVoiceOut *hw = NULL;
   7.350 @@ -1038,7 +1225,7 @@ static void audio_run_out (AudioState *s
   7.351  
   7.352      while ((hw = audio_pcm_hw_find_any_enabled_out (s, hw))) {
   7.353          int played;
   7.354 -        int live, free, nb_live, cleanup_required;
   7.355 +        int live, free, nb_live, cleanup_required, prev_rpos;
   7.356  
   7.357          live = audio_pcm_hw_get_live_out2 (hw, &nb_live);
   7.358          if (!nb_live) {
   7.359 @@ -1051,12 +1238,17 @@ static void audio_run_out (AudioState *s
   7.360          }
   7.361  
   7.362          if (hw->pending_disable && !nb_live) {
   7.363 +            SWVoiceCap *sc;
   7.364  #ifdef DEBUG_OUT
   7.365              dolog ("Disabling voice\n");
   7.366  #endif
   7.367              hw->enabled = 0;
   7.368              hw->pending_disable = 0;
   7.369              hw->pcm_ops->ctl_out (hw, VOICE_DISABLE);
   7.370 +            for (sc = hw->cap_head.lh_first; sc; sc = sc->entries.le_next) {
   7.371 +                sc->sw.active = 0;
   7.372 +                audio_recalc_and_notify_capture (sc->cap);
   7.373 +            }
   7.374              continue;
   7.375          }
   7.376  
   7.377 @@ -1072,6 +1264,7 @@ static void audio_run_out (AudioState *s
   7.378              continue;
   7.379          }
   7.380  
   7.381 +        prev_rpos = hw->rpos;
   7.382          played = hw->pcm_ops->run_out (hw);
   7.383          if (audio_bug (AUDIO_FUNC, hw->rpos >= hw->samples)) {
   7.384              dolog ("hw->rpos=%d hw->samples=%d played=%d\n",
   7.385 @@ -1085,6 +1278,7 @@ static void audio_run_out (AudioState *s
   7.386  
   7.387          if (played) {
   7.388              hw->ts_helper += played;
   7.389 +            audio_capture_mix_and_clear (hw, prev_rpos, played);
   7.390          }
   7.391  
   7.392          cleanup_required = 0;
   7.393 @@ -1115,15 +1309,18 @@ static void audio_run_out (AudioState *s
   7.394          }
   7.395  
   7.396          if (cleanup_required) {
   7.397 -        restart:
   7.398 -            for (sw = hw->sw_head.lh_first; sw; sw = sw->entries.le_next) {
   7.399 +            SWVoiceOut *sw1;
   7.400 +
   7.401 +            sw = hw->sw_head.lh_first;
   7.402 +            while (sw) {
   7.403 +                sw1 = sw->entries.le_next;
   7.404                  if (!sw->active && !sw->callback.fn) {
   7.405  #ifdef DEBUG_PLIVE
   7.406                      dolog ("Finishing with old voice\n");
   7.407  #endif
   7.408                      audio_close_out (s, sw);
   7.409 -                    goto restart; /* play it safe */
   7.410                  }
   7.411 +                sw = sw1;
   7.412              }
   7.413          }
   7.414      }
   7.415 @@ -1158,12 +1355,60 @@ static void audio_run_in (AudioState *s)
   7.416      }
   7.417  }
   7.418  
   7.419 +static void audio_run_capture (AudioState *s)
   7.420 +{
   7.421 +    CaptureVoiceOut *cap;
   7.422 +
   7.423 +    for (cap = s->cap_head.lh_first; cap; cap = cap->entries.le_next) {
   7.424 +        int live, rpos, captured;
   7.425 +        HWVoiceOut *hw = &cap->hw;
   7.426 +        SWVoiceOut *sw;
   7.427 +
   7.428 +        captured = live = audio_pcm_hw_get_live_out (hw);
   7.429 +        rpos = hw->rpos;
   7.430 +        while (live) {
   7.431 +            int left = hw->samples - rpos;
   7.432 +            int to_capture = audio_MIN (live, left);
   7.433 +            st_sample_t *src;
   7.434 +            struct capture_callback *cb;
   7.435 +
   7.436 +            src = hw->mix_buf + rpos;
   7.437 +            hw->clip (cap->buf, src, to_capture);
   7.438 +            mixeng_clear (src, to_capture);
   7.439 +
   7.440 +            for (cb = cap->cb_head.lh_first; cb; cb = cb->entries.le_next) {
   7.441 +                cb->ops.capture (cb->opaque, cap->buf,
   7.442 +                                 to_capture << hw->info.shift);
   7.443 +            }
   7.444 +            rpos = (rpos + to_capture) % hw->samples;
   7.445 +            live -= to_capture;
   7.446 +        }
   7.447 +        hw->rpos = rpos;
   7.448 +
   7.449 +        for (sw = hw->sw_head.lh_first; sw; sw = sw->entries.le_next) {
   7.450 +            if (!sw->active && sw->empty) {
   7.451 +                continue;
   7.452 +            }
   7.453 +
   7.454 +            if (audio_bug (AUDIO_FUNC, captured > sw->total_hw_samples_mixed)) {
   7.455 +                dolog ("captured=%d sw->total_hw_samples_mixed=%d\n",
   7.456 +                       captured, sw->total_hw_samples_mixed);
   7.457 +                captured = sw->total_hw_samples_mixed;
   7.458 +            }
   7.459 +
   7.460 +            sw->total_hw_samples_mixed -= captured;
   7.461 +            sw->empty = sw->total_hw_samples_mixed == 0;
   7.462 +        }
   7.463 +    }
   7.464 +}
   7.465 +
   7.466  static void audio_timer (void *opaque)
   7.467  {
   7.468      AudioState *s = opaque;
   7.469  
   7.470      audio_run_out (s);
   7.471      audio_run_in (s);
   7.472 +    audio_run_capture (s);
   7.473  
   7.474      qemu_mod_timer (s->ts, qemu_get_clock (vm_clock) + conf.period.ticks);
   7.475  }
   7.476 @@ -1327,8 +1572,19 @@ static void audio_atexit (void)
   7.477      HWVoiceIn *hwi = NULL;
   7.478  
   7.479      while ((hwo = audio_pcm_hw_find_any_enabled_out (s, hwo))) {
   7.480 +        SWVoiceCap *sc;
   7.481 +
   7.482          hwo->pcm_ops->ctl_out (hwo, VOICE_DISABLE);
   7.483          hwo->pcm_ops->fini_out (hwo);
   7.484 +
   7.485 +        for (sc = hwo->cap_head.lh_first; sc; sc = sc->entries.le_next) {
   7.486 +            CaptureVoiceOut *cap = sc->cap;
   7.487 +            struct capture_callback *cb;
   7.488 +
   7.489 +            for (cb = cap->cb_head.lh_first; cb; cb = cb->entries.le_next) {
   7.490 +                cb->ops.destroy (cb->opaque);
   7.491 +            }
   7.492 +        }
   7.493      }
   7.494  
   7.495      while ((hwi = audio_pcm_hw_find_any_enabled_in (s, hwi))) {
   7.496 @@ -1383,6 +1639,7 @@ AudioState *AUD_init (void)
   7.497  
   7.498      LIST_INIT (&s->hw_head_out);
   7.499      LIST_INIT (&s->hw_head_in);
   7.500 +    LIST_INIT (&s->cap_head);
   7.501      atexit (audio_atexit);
   7.502  
   7.503      s->ts = qemu_new_timer (vm_clock, audio_timer, s);
   7.504 @@ -1479,3 +1736,136 @@ AudioState *AUD_init (void)
   7.505      qemu_mod_timer (s->ts, qemu_get_clock (vm_clock) + conf.period.ticks);
   7.506      return s;
   7.507  }
   7.508 +
   7.509 +CaptureVoiceOut *AUD_add_capture (
   7.510 +    AudioState *s,
   7.511 +    audsettings_t *as,
   7.512 +    struct audio_capture_ops *ops,
   7.513 +    void *cb_opaque
   7.514 +    )
   7.515 +{
   7.516 +    CaptureVoiceOut *cap;
   7.517 +    struct capture_callback *cb;
   7.518 +
   7.519 +    if (!s) {
   7.520 +        /* XXX suppress */
   7.521 +        s = &glob_audio_state;
   7.522 +    }
   7.523 +
   7.524 +    if (audio_validate_settings (as)) {
   7.525 +        dolog ("Invalid settings were passed when trying to add capture\n");
   7.526 +        audio_print_settings (as);
   7.527 +        goto err0;
   7.528 +    }
   7.529 +
   7.530 +    cb = audio_calloc (AUDIO_FUNC, 1, sizeof (*cb));
   7.531 +    if (!cb) {
   7.532 +        dolog ("Could not allocate capture callback information, size %zu\n",
   7.533 +               sizeof (*cb));
   7.534 +        goto err0;
   7.535 +    }
   7.536 +    cb->ops = *ops;
   7.537 +    cb->opaque = cb_opaque;
   7.538 +
   7.539 +    cap = audio_pcm_capture_find_specific (s, as);
   7.540 +    if (cap) {
   7.541 +        LIST_INSERT_HEAD (&cap->cb_head, cb, entries);
   7.542 +        return cap;
   7.543 +    }
   7.544 +    else {
   7.545 +        HWVoiceOut *hw;
   7.546 +        CaptureVoiceOut *cap;
   7.547 +
   7.548 +        cap = audio_calloc (AUDIO_FUNC, 1, sizeof (*cap));
   7.549 +        if (!cap) {
   7.550 +            dolog ("Could not allocate capture voice, size %zu\n",
   7.551 +                   sizeof (*cap));
   7.552 +            goto err1;
   7.553 +        }
   7.554 +
   7.555 +        hw = &cap->hw;
   7.556 +        LIST_INIT (&hw->sw_head);
   7.557 +        LIST_INIT (&cap->cb_head);
   7.558 +
   7.559 +        /* XXX find a more elegant way */
   7.560 +        hw->samples = 4096 * 4;
   7.561 +        hw->mix_buf = audio_calloc (AUDIO_FUNC, hw->samples,
   7.562 +                                    sizeof (st_sample_t));
   7.563 +        if (!hw->mix_buf) {
   7.564 +            dolog ("Could not allocate capture mix buffer (%d samples)\n",
   7.565 +                   hw->samples);
   7.566 +            goto err2;
   7.567 +        }
   7.568 +
   7.569 +        audio_pcm_init_info (&hw->info, as);
   7.570 +
   7.571 +        cap->buf = audio_calloc (AUDIO_FUNC, hw->samples, 1 << hw->info.shift);
   7.572 +        if (!cap->buf) {
   7.573 +            dolog ("Could not allocate capture buffer "
   7.574 +                   "(%d samples, each %d bytes)\n",
   7.575 +                   hw->samples, 1 << hw->info.shift);
   7.576 +            goto err3;
   7.577 +        }
   7.578 +
   7.579 +        hw->clip = mixeng_clip
   7.580 +            [hw->info.nchannels == 2]
   7.581 +            [hw->info.sign]
   7.582 +            [hw->info.swap_endianness]
   7.583 +            [hw->info.bits == 16];
   7.584 +
   7.585 +        LIST_INSERT_HEAD (&s->cap_head, cap, entries);
   7.586 +        LIST_INSERT_HEAD (&cap->cb_head, cb, entries);
   7.587 +
   7.588 +        hw = NULL;
   7.589 +        while ((hw = audio_pcm_hw_find_any_out (s, hw))) {
   7.590 +            audio_attach_capture (s, hw);
   7.591 +        }
   7.592 +        return cap;
   7.593 +
   7.594 +    err3:
   7.595 +        qemu_free (cap->hw.mix_buf);
   7.596 +    err2:
   7.597 +        qemu_free (cap);
   7.598 +    err1:
   7.599 +        qemu_free (cb);
   7.600 +    err0:
   7.601 +        return NULL;
   7.602 +    }
   7.603 +}
   7.604 +
   7.605 +void AUD_del_capture (CaptureVoiceOut *cap, void *cb_opaque)
   7.606 +{
   7.607 +    struct capture_callback *cb;
   7.608 +
   7.609 +    for (cb = cap->cb_head.lh_first; cb; cb = cb->entries.le_next) {
   7.610 +        if (cb->opaque == cb_opaque) {
   7.611 +            cb->ops.destroy (cb_opaque);
   7.612 +            LIST_REMOVE (cb, entries);
   7.613 +            qemu_free (cb);
   7.614 +
   7.615 +            if (!cap->cb_head.lh_first) {
   7.616 +                SWVoiceOut *sw = cap->hw.sw_head.lh_first, *sw1;
   7.617 +
   7.618 +                while (sw) {
   7.619 +                    SWVoiceCap *sc = (SWVoiceCap *) sw;
   7.620 +#ifdef DEBUG_CAPTURE
   7.621 +                    dolog ("freeing %s\n", sw->name);
   7.622 +#endif
   7.623 +
   7.624 +                    sw1 = sw->entries.le_next;
   7.625 +                    if (sw->rate) {
   7.626 +                        st_rate_stop (sw->rate);
   7.627 +                        sw->rate = NULL;
   7.628 +                    }
   7.629 +                    LIST_REMOVE (sw, entries);
   7.630 +                    LIST_REMOVE (sc, entries);
   7.631 +                    qemu_free (sc);
   7.632 +                    sw = sw1;
   7.633 +                }
   7.634 +                LIST_REMOVE (cap, entries);
   7.635 +                qemu_free (cap);
   7.636 +            }
   7.637 +            return;
   7.638 +        }
   7.639 +    }
   7.640 +}
     8.1 --- a/tools/ioemu/audio/audio.h	Mon Aug 07 18:11:59 2006 +0100
     8.2 +++ b/tools/ioemu/audio/audio.h	Mon Aug 07 18:25:30 2006 +0100
     8.3 @@ -24,6 +24,7 @@
     8.4  #ifndef QEMU_AUDIO_H
     8.5  #define QEMU_AUDIO_H
     8.6  
     8.7 +#include "config.h"
     8.8  #include "sys-queue.h"
     8.9  
    8.10  typedef void (*audio_callback_fn_t) (void *opaque, int avail);
    8.11 @@ -35,14 +36,44 @@ typedef enum {
    8.12      AUD_FMT_S16
    8.13  } audfmt_e;
    8.14  
    8.15 +#ifdef WORDS_BIGENDIAN
    8.16 +#define AUDIO_HOST_ENDIANNESS 1
    8.17 +#else
    8.18 +#define AUDIO_HOST_ENDIANNESS 0
    8.19 +#endif
    8.20 +
    8.21  typedef struct {
    8.22      int freq;
    8.23      int nchannels;
    8.24      audfmt_e fmt;
    8.25 +    int endianness;
    8.26  } audsettings_t;
    8.27  
    8.28 +typedef enum {
    8.29 +    AUD_CNOTIFY_ENABLE,
    8.30 +    AUD_CNOTIFY_DISABLE
    8.31 +} audcnotification_e;
    8.32 +
    8.33 +struct audio_capture_ops {
    8.34 +    void (*notify) (void *opaque, audcnotification_e cmd);
    8.35 +    void (*capture) (void *opaque, void *buf, int size);
    8.36 +    void (*destroy) (void *opaque);
    8.37 +};
    8.38 +
    8.39 +struct capture_ops {
    8.40 +    void (*info) (void *opaque);
    8.41 +    void (*destroy) (void *opaque);
    8.42 +};
    8.43 +
    8.44 +typedef struct CaptureState {
    8.45 +    void *opaque;
    8.46 +    struct capture_ops ops;
    8.47 +    LIST_ENTRY (CaptureState) entries;
    8.48 +} CaptureState;
    8.49 +
    8.50  typedef struct AudioState AudioState;
    8.51  typedef struct SWVoiceOut SWVoiceOut;
    8.52 +typedef struct CaptureVoiceOut CaptureVoiceOut;
    8.53  typedef struct SWVoiceIn SWVoiceIn;
    8.54  
    8.55  typedef struct QEMUSoundCard {
    8.56 @@ -66,6 +97,13 @@ AudioState *AUD_init (void);
    8.57  void AUD_help (void);
    8.58  void AUD_register_card (AudioState *s, const char *name, QEMUSoundCard *card);
    8.59  void AUD_remove_card (QEMUSoundCard *card);
    8.60 +CaptureVoiceOut *AUD_add_capture (
    8.61 +    AudioState *s,
    8.62 +    audsettings_t *as,
    8.63 +    struct audio_capture_ops *ops,
    8.64 +    void *opaque
    8.65 +    );
    8.66 +void AUD_del_capture (CaptureVoiceOut *cap, void *cb_opaque);
    8.67  
    8.68  SWVoiceOut *AUD_open_out (
    8.69      QEMUSoundCard *card,
    8.70 @@ -73,8 +111,7 @@ SWVoiceOut *AUD_open_out (
    8.71      const char *name,
    8.72      void *callback_opaque,
    8.73      audio_callback_fn_t callback_fn,
    8.74 -    audsettings_t *settings,
    8.75 -    int sw_endian
    8.76 +    audsettings_t *settings
    8.77      );
    8.78  
    8.79  void AUD_close_out (QEMUSoundCard *card, SWVoiceOut *sw);
    8.80 @@ -92,8 +129,7 @@ SWVoiceIn *AUD_open_in (
    8.81      const char *name,
    8.82      void *callback_opaque,
    8.83      audio_callback_fn_t callback_fn,
    8.84 -    audsettings_t *settings,
    8.85 -    int sw_endian
    8.86 +    audsettings_t *settings
    8.87      );
    8.88  
    8.89  void AUD_close_in (QEMUSoundCard *card, SWVoiceIn *sw);
    8.90 @@ -111,7 +147,7 @@ static inline void *advance (void *p, in
    8.91  }
    8.92  
    8.93  uint32_t popcount (uint32_t u);
    8.94 -inline uint32_t lsbindex (uint32_t u);
    8.95 +uint32_t lsbindex (uint32_t u);
    8.96  
    8.97  #ifdef __GNUC__
    8.98  #define audio_MIN(a, b) ( __extension__ ({      \
     9.1 --- a/tools/ioemu/audio/audio_int.h	Mon Aug 07 18:11:59 2006 +0100
     9.2 +++ b/tools/ioemu/audio/audio_int.h	Mon Aug 07 18:25:30 2006 +0100
     9.3 @@ -61,13 +61,14 @@ struct audio_pcm_info {
     9.4      int align;
     9.5      int shift;
     9.6      int bytes_per_second;
     9.7 -    int swap_endian;
     9.8 +    int swap_endianness;
     9.9  };
    9.10  
    9.11 +typedef struct SWVoiceCap SWVoiceCap;
    9.12 +
    9.13  typedef struct HWVoiceOut {
    9.14      int enabled;
    9.15      int pending_disable;
    9.16 -    int valid;
    9.17      struct audio_pcm_info info;
    9.18  
    9.19      f_sample *clip;
    9.20 @@ -79,6 +80,7 @@ typedef struct HWVoiceOut {
    9.21  
    9.22      int samples;
    9.23      LIST_HEAD (sw_out_listhead, SWVoiceOut) sw_head;
    9.24 +    LIST_HEAD (sw_cap_listhead, SWVoiceCap) cap_head;
    9.25      struct audio_pcm_ops *pcm_ops;
    9.26      LIST_ENTRY (HWVoiceOut) entries;
    9.27  } HWVoiceOut;
    9.28 @@ -160,14 +162,34 @@ struct audio_pcm_ops {
    9.29      int  (*ctl_in)  (HWVoiceIn *hw, int cmd, ...);
    9.30  };
    9.31  
    9.32 +struct capture_callback {
    9.33 +    struct audio_capture_ops ops;
    9.34 +    void *opaque;
    9.35 +    LIST_ENTRY (capture_callback) entries;
    9.36 +};
    9.37 +
    9.38 +struct CaptureVoiceOut {
    9.39 +    HWVoiceOut hw;
    9.40 +    void *buf;
    9.41 +    LIST_HEAD (cb_listhead, capture_callback) cb_head;
    9.42 +    LIST_ENTRY (CaptureVoiceOut) entries;
    9.43 +};
    9.44 +
    9.45 +struct SWVoiceCap {
    9.46 +    SWVoiceOut sw;
    9.47 +    CaptureVoiceOut *cap;
    9.48 +    LIST_ENTRY (SWVoiceCap) entries;
    9.49 +};
    9.50 +
    9.51  struct AudioState {
    9.52      struct audio_driver *drv;
    9.53      void *drv_opaque;
    9.54  
    9.55      QEMUTimer *ts;
    9.56 -    LIST_HEAD (card_head, QEMUSoundCard) card_head;
    9.57 +    LIST_HEAD (card_listhead, QEMUSoundCard) card_head;
    9.58      LIST_HEAD (hw_in_listhead, HWVoiceIn) hw_head_in;
    9.59      LIST_HEAD (hw_out_listhead, HWVoiceOut) hw_head_out;
    9.60 +    LIST_HEAD (cap_listhead, CaptureVoiceOut) cap_head;
    9.61      int nb_hw_voices_out;
    9.62      int nb_hw_voices_in;
    9.63  };
    9.64 @@ -182,8 +204,7 @@ extern struct audio_driver coreaudio_aud
    9.65  extern struct audio_driver dsound_audio_driver;
    9.66  extern volume_t nominal_volume;
    9.67  
    9.68 -void audio_pcm_init_info (struct audio_pcm_info *info, audsettings_t *as,
    9.69 -                          int swap_endian);
    9.70 +void audio_pcm_init_info (struct audio_pcm_info *info, audsettings_t *as);
    9.71  void audio_pcm_info_clear_buf (struct audio_pcm_info *info, void *buf, int len);
    9.72  
    9.73  int  audio_pcm_sw_write (SWVoiceOut *sw, void *buf, int len);
    9.74 @@ -204,15 +225,6 @@ static inline int audio_ring_dist (int d
    9.75      return (dst >= src) ? (dst - src) : (len - src + dst);
    9.76  }
    9.77  
    9.78 -static inline int audio_need_to_swap_endian (int endianness)
    9.79 -{
    9.80 -#ifdef WORDS_BIGENDIAN
    9.81 -    return endianness != 1;
    9.82 -#else
    9.83 -    return endianness != 0;
    9.84 -#endif
    9.85 -}
    9.86 -
    9.87  #if defined __GNUC__
    9.88  #define GCC_ATTR __attribute__ ((__unused__, __format__ (__printf__, 1, 2)))
    9.89  #define INIT_FIELD(f) . f
    10.1 --- a/tools/ioemu/audio/audio_template.h	Mon Aug 07 18:11:59 2006 +0100
    10.2 +++ b/tools/ioemu/audio/audio_template.h	Mon Aug 07 18:25:30 2006 +0100
    10.3 @@ -140,13 +140,12 @@ static int glue (audio_pcm_sw_init_, TYP
    10.4      SW *sw,
    10.5      HW *hw,
    10.6      const char *name,
    10.7 -    audsettings_t *as,
    10.8 -    int endian
    10.9 +    audsettings_t *as
   10.10      )
   10.11  {
   10.12      int err;
   10.13  
   10.14 -    audio_pcm_init_info (&sw->info, as, audio_need_to_swap_endian (endian));
   10.15 +    audio_pcm_init_info (&sw->info, as);
   10.16      sw->hw = hw;
   10.17      sw->active = 0;
   10.18  #ifdef DAC
   10.19 @@ -164,7 +163,7 @@ static int glue (audio_pcm_sw_init_, TYP
   10.20  #endif
   10.21          [sw->info.nchannels == 2]
   10.22          [sw->info.sign]
   10.23 -        [sw->info.swap_endian]
   10.24 +        [sw->info.swap_endianness]
   10.25          [sw->info.bits == 16];
   10.26  
   10.27      sw->name = qemu_strdup (name);
   10.28 @@ -200,6 +199,9 @@ static void glue (audio_pcm_hw_gc_, TYPE
   10.29      HW *hw = *hwp;
   10.30  
   10.31      if (!hw->sw_head.lh_first) {
   10.32 +#ifdef DAC
   10.33 +        audio_detach_capture (hw);
   10.34 +#endif
   10.35          LIST_REMOVE (hw, entries);
   10.36          glue (s->nb_hw_voices_, TYPE) += 1;
   10.37          glue (audio_pcm_hw_free_resources_ ,TYPE) (hw);
   10.38 @@ -266,7 +268,9 @@ static HW *glue (audio_pcm_hw_add_new_, 
   10.39  
   10.40      hw->pcm_ops = drv->pcm_ops;
   10.41      LIST_INIT (&hw->sw_head);
   10.42 -
   10.43 +#ifdef DAC
   10.44 +    LIST_INIT (&hw->cap_head);
   10.45 +#endif
   10.46      if (glue (hw->pcm_ops->init_, TYPE) (hw, as)) {
   10.47          goto err0;
   10.48      }
   10.49 @@ -283,7 +287,7 @@ static HW *glue (audio_pcm_hw_add_new_, 
   10.50  #endif
   10.51          [hw->info.nchannels == 2]
   10.52          [hw->info.sign]
   10.53 -        [hw->info.swap_endian]
   10.54 +        [hw->info.swap_endianness]
   10.55          [hw->info.bits == 16];
   10.56  
   10.57      if (glue (audio_pcm_hw_alloc_resources_, TYPE) (hw)) {
   10.58 @@ -292,6 +296,9 @@ static HW *glue (audio_pcm_hw_add_new_, 
   10.59  
   10.60      LIST_INSERT_HEAD (&s->glue (hw_head_, TYPE), hw, entries);
   10.61      glue (s->nb_hw_voices_, TYPE) -= 1;
   10.62 +#ifdef DAC
   10.63 +    audio_attach_capture (s, hw);
   10.64 +#endif
   10.65      return hw;
   10.66  
   10.67   err1:
   10.68 @@ -328,8 +335,7 @@ static HW *glue (audio_pcm_hw_add_, TYPE
   10.69  static SW *glue (audio_pcm_create_voice_pair_, TYPE) (
   10.70      AudioState *s,
   10.71      const char *sw_name,
   10.72 -    audsettings_t *as,
   10.73 -    int sw_endian
   10.74 +    audsettings_t *as
   10.75      )
   10.76  {
   10.77      SW *sw;
   10.78 @@ -357,7 +363,7 @@ static SW *glue (audio_pcm_create_voice_
   10.79  
   10.80      glue (audio_pcm_hw_add_sw_, TYPE) (hw, sw);
   10.81  
   10.82 -    if (glue (audio_pcm_sw_init_, TYPE) (sw, hw, sw_name, as, sw_endian)) {
   10.83 +    if (glue (audio_pcm_sw_init_, TYPE) (sw, hw, sw_name, as)) {
   10.84          goto err3;
   10.85      }
   10.86  
   10.87 @@ -399,8 +405,7 @@ SW *glue (AUD_open_, TYPE) (
   10.88      const char *name,
   10.89      void *callback_opaque ,
   10.90      audio_callback_fn_t callback_fn,
   10.91 -    audsettings_t *as,
   10.92 -    int sw_endian
   10.93 +    audsettings_t *as
   10.94      )
   10.95  {
   10.96      AudioState *s;
   10.97 @@ -421,7 +426,7 @@ SW *glue (AUD_open_, TYPE) (
   10.98  
   10.99      s = card->audio;
  10.100  
  10.101 -    if (audio_bug (AUDIO_FUNC, audio_validate_settigs (as))) {
  10.102 +    if (audio_bug (AUDIO_FUNC, audio_validate_settings (as))) {
  10.103          audio_print_settings (as);
  10.104          goto fail;
  10.105      }
  10.106 @@ -473,12 +478,12 @@ SW *glue (AUD_open_, TYPE) (
  10.107          }
  10.108  
  10.109          glue (audio_pcm_sw_fini_, TYPE) (sw);
  10.110 -        if (glue (audio_pcm_sw_init_, TYPE) (sw, hw, name, as, sw_endian)) {
  10.111 +        if (glue (audio_pcm_sw_init_, TYPE) (sw, hw, name, as)) {
  10.112              goto fail;
  10.113          }
  10.114      }
  10.115      else {
  10.116 -        sw = glue (audio_pcm_create_voice_pair_, TYPE) (s, name, as, sw_endian);
  10.117 +        sw = glue (audio_pcm_create_voice_pair_, TYPE) (s, name, as);
  10.118          if (!sw) {
  10.119              dolog ("Failed to create voice `%s'\n", name);
  10.120              return NULL;
    11.1 --- a/tools/ioemu/audio/coreaudio.c	Mon Aug 07 18:11:59 2006 +0100
    11.2 +++ b/tools/ioemu/audio/coreaudio.c	Mon Aug 07 18:25:30 2006 +0100
    11.3 @@ -275,8 +275,6 @@ static OSStatus audioDeviceIOProc(
    11.4  #endif
    11.5      }
    11.6  
    11.7 -    /* cleanup */
    11.8 -    mixeng_clear (src, frameCount);
    11.9      rpos = (rpos + frameCount) % hw->samples;
   11.10      core->decr += frameCount;
   11.11      core->rpos = rpos;
   11.12 @@ -297,7 +295,6 @@ static int coreaudio_init_out (HWVoiceOu
   11.13      UInt32 propertySize;
   11.14      int err;
   11.15      int bits = 8;
   11.16 -    int endianess = 0;
   11.17      const char *typ = "playback";
   11.18      AudioValueRange frameRange;
   11.19  
   11.20 @@ -310,16 +307,9 @@ static int coreaudio_init_out (HWVoiceOu
   11.21  
   11.22      if (as->fmt == AUD_FMT_S16 || as->fmt == AUD_FMT_U16) {
   11.23          bits = 16;
   11.24 -        endianess = 1;
   11.25      }
   11.26  
   11.27 -    audio_pcm_init_info (
   11.28 -        &hw->info,
   11.29 -        as,
   11.30 -        /* Following is irrelevant actually since we do not use
   11.31 -           mixengs clipping routines */
   11.32 -        audio_need_to_swap_endian (endianess)
   11.33 -        );
   11.34 +    audio_pcm_init_info (&hw->info, as);
   11.35  
   11.36      /* open default output device */
   11.37      propertySize = sizeof(core->outputDeviceID);
    12.1 --- a/tools/ioemu/audio/dsound_template.h	Mon Aug 07 18:11:59 2006 +0100
    12.2 +++ b/tools/ioemu/audio/dsound_template.h	Mon Aug 07 18:25:30 2006 +0100
    12.3 @@ -70,7 +70,13 @@ static int glue (dsound_lock_, TYPE) (
    12.4      int i;
    12.5      LPVOID p1 = NULL, p2 = NULL;
    12.6      DWORD blen1 = 0, blen2 = 0;
    12.7 +    DWORD flag;
    12.8  
    12.9 +#ifdef DSBTYPE_IN
   12.10 +    flag = entire ? DSCBLOCK_ENTIREBUFFER : 0;
   12.11 +#else
   12.12 +    flag = entire ? DSBLOCK_ENTIREBUFFER : 0;
   12.13 +#endif
   12.14      for (i = 0; i < conf.lock_retries; ++i) {
   12.15          hr = glue (IFACE, _Lock) (
   12.16              buf,
   12.17 @@ -80,13 +86,7 @@ static int glue (dsound_lock_, TYPE) (
   12.18              &blen1,
   12.19              &p2,
   12.20              &blen2,
   12.21 -            (entire
   12.22 -#ifdef DSBTYPE_IN
   12.23 -             ? DSCBLOCK_ENTIREBUFFER
   12.24 -#else
   12.25 -             ? DSBLOCK_ENTIREBUFFER
   12.26 -#endif
   12.27 -             : 0)
   12.28 +            flag
   12.29              );
   12.30  
   12.31          if (FAILED (hr)) {
   12.32 @@ -250,8 +250,8 @@ static int dsound_init_out (HWVoiceOut *
   12.33      }
   12.34  
   12.35      ds->first_time = 1;
   12.36 -
   12.37 -    audio_pcm_init_info (&hw->info, &obt_as, audio_need_to_swap_endian (0));
   12.38 +    obt_as.endianness = 0;
   12.39 +    audio_pcm_init_info (&hw->info, &obt_as);
   12.40  
   12.41      if (bc.dwBufferBytes & hw->info.align) {
   12.42          dolog (
    13.1 --- a/tools/ioemu/audio/dsoundaudio.c	Mon Aug 07 18:11:59 2006 +0100
    13.2 +++ b/tools/ioemu/audio/dsoundaudio.c	Mon Aug 07 18:25:30 2006 +0100
    13.3 @@ -453,13 +453,11 @@ static void dsound_write_sample (HWVoice
    13.4  
    13.5      if (src_len1) {
    13.6          hw->clip (dst, src1, src_len1);
    13.7 -        mixeng_clear (src1, src_len1);
    13.8      }
    13.9  
   13.10      if (src_len2) {
   13.11          dst = advance (dst, src_len1 << hw->info.shift);
   13.12          hw->clip (dst, src2, src_len2);
   13.13 -        mixeng_clear (src2, src_len2);
   13.14      }
   13.15  
   13.16      hw->rpos = pos % hw->samples;
   13.17 @@ -987,6 +985,12 @@ static void *dsound_audio_init (void)
   13.18      hr = IDirectSound_Initialize (s->dsound, NULL);
   13.19      if (FAILED (hr)) {
   13.20          dsound_logerr (hr, "Could not initialize DirectSound\n");
   13.21 +
   13.22 +        hr = IDirectSound_Release (s->dsound);
   13.23 +        if (FAILED (hr)) {
   13.24 +            dsound_logerr (hr, "Could not release DirectSound\n");
   13.25 +        }
   13.26 +        s->dsound = NULL;
   13.27          return NULL;
   13.28      }
   13.29  
    14.1 --- a/tools/ioemu/audio/fmodaudio.c	Mon Aug 07 18:11:59 2006 +0100
    14.2 +++ b/tools/ioemu/audio/fmodaudio.c	Mon Aug 07 18:25:30 2006 +0100
    14.3 @@ -153,13 +153,11 @@ static void fmod_write_sample (HWVoiceOu
    14.4  
    14.5      if (src_len1) {
    14.6          hw->clip (dst, src1, src_len1);
    14.7 -        mixeng_clear (src1, src_len1);
    14.8      }
    14.9  
   14.10      if (src_len2) {
   14.11          dst = advance (dst, src_len1 << hw->info.shift);
   14.12          hw->clip (dst, src2, src_len2);
   14.13 -        mixeng_clear (src2, src_len2);
   14.14      }
   14.15  
   14.16      hw->rpos = pos % hw->samples;
   14.17 @@ -360,6 +358,7 @@ static int fmod_init_out (HWVoiceOut *hw
   14.18  {
   14.19      int bits16, mode, channel;
   14.20      FMODVoiceOut *fmd = (FMODVoiceOut *) hw;
   14.21 +    audsettings_t obt_as = *as;
   14.22  
   14.23      mode = aud_to_fmodfmt (as->fmt, as->nchannels == 2 ? 1 : 0);
   14.24      fmd->fmod_sample = FSOUND_Sample_Alloc (
   14.25 @@ -386,7 +385,8 @@ static int fmod_init_out (HWVoiceOut *hw
   14.26      fmd->channel = channel;
   14.27  
   14.28      /* FMOD always operates on little endian frames? */
   14.29 -    audio_pcm_init_info (&hw->info, as, audio_need_to_swap_endian (0));
   14.30 +    obt_as.endianness = 0;
   14.31 +    audio_pcm_init_info (&hw->info, &obt_as);
   14.32      bits16 = (mode & FSOUND_16BITS) != 0;
   14.33      hw->samples = conf.nb_samples;
   14.34      return 0;
   14.35 @@ -420,6 +420,7 @@ static int fmod_init_in (HWVoiceIn *hw, 
   14.36  {
   14.37      int bits16, mode;
   14.38      FMODVoiceIn *fmd = (FMODVoiceIn *) hw;
   14.39 +    audsettings_t obt_as = *as;
   14.40  
   14.41      if (conf.broken_adc) {
   14.42          return -1;
   14.43 @@ -442,7 +443,8 @@ static int fmod_init_in (HWVoiceIn *hw, 
   14.44      }
   14.45  
   14.46      /* FMOD always operates on little endian frames? */
   14.47 -    audio_pcm_init_info (&hw->info, as, audio_need_to_swap_endian (0));
   14.48 +    obt_as.endianness = 0;
   14.49 +    audio_pcm_init_info (&hw->info, &obt_as);
   14.50      bits16 = (mode & FSOUND_16BITS) != 0;
   14.51      hw->samples = conf.nb_samples;
   14.52      return 0;
    15.1 --- a/tools/ioemu/audio/noaudio.c	Mon Aug 07 18:11:59 2006 +0100
    15.2 +++ b/tools/ioemu/audio/noaudio.c	Mon Aug 07 18:25:30 2006 +0100
    15.3 @@ -40,22 +40,21 @@ static int no_run_out (HWVoiceOut *hw)
    15.4  {
    15.5      NoVoiceOut *no = (NoVoiceOut *) hw;
    15.6      int live, decr, samples;
    15.7 -    int64_t now = qemu_get_clock (vm_clock);
    15.8 -    int64_t ticks = now - no->old_ticks;
    15.9 -    int64_t bytes = (ticks * hw->info.bytes_per_second) / ticks_per_sec;
   15.10 -
   15.11 -    if (bytes > INT_MAX) {
   15.12 -        samples = INT_MAX >> hw->info.shift;
   15.13 -    }
   15.14 -    else {
   15.15 -        samples = bytes >> hw->info.shift;
   15.16 -    }
   15.17 +    int64_t now;
   15.18 +    int64_t ticks;
   15.19 +    int64_t bytes;
   15.20  
   15.21      live = audio_pcm_hw_get_live_out (&no->hw);
   15.22      if (!live) {
   15.23          return 0;
   15.24      }
   15.25  
   15.26 +    now = qemu_get_clock (vm_clock);
   15.27 +    ticks = now - no->old_ticks;
   15.28 +    bytes = (ticks * hw->info.bytes_per_second) / ticks_per_sec;
   15.29 +    bytes = audio_MIN (bytes, INT_MAX);
   15.30 +    samples = bytes >> hw->info.shift;
   15.31 +
   15.32      no->old_ticks = now;
   15.33      decr = audio_MIN (live, samples);
   15.34      hw->rpos = (hw->rpos + decr) % hw->samples;
   15.35 @@ -69,7 +68,7 @@ static int no_write (SWVoiceOut *sw, voi
   15.36  
   15.37  static int no_init_out (HWVoiceOut *hw, audsettings_t *as)
   15.38  {
   15.39 -    audio_pcm_init_info (&hw->info, as, 0);
   15.40 +    audio_pcm_init_info (&hw->info, as);
   15.41      hw->samples = 1024;
   15.42      return 0;
   15.43  }
   15.44 @@ -88,7 +87,7 @@ static int no_ctl_out (HWVoiceOut *hw, i
   15.45  
   15.46  static int no_init_in (HWVoiceIn *hw, audsettings_t *as)
   15.47  {
   15.48 -    audio_pcm_init_info (&hw->info, as, 0);
   15.49 +    audio_pcm_init_info (&hw->info, as);
   15.50      hw->samples = 1024;
   15.51      return 0;
   15.52  }
   15.53 @@ -101,17 +100,20 @@ static void no_fini_in (HWVoiceIn *hw)
   15.54  static int no_run_in (HWVoiceIn *hw)
   15.55  {
   15.56      NoVoiceIn *no = (NoVoiceIn *) hw;
   15.57 -    int64_t now = qemu_get_clock (vm_clock);
   15.58 -    int64_t ticks = now - no->old_ticks;
   15.59 -    int64_t bytes = (ticks * hw->info.bytes_per_second) / ticks_per_sec;
   15.60      int live = audio_pcm_hw_get_live_in (hw);
   15.61      int dead = hw->samples - live;
   15.62 -    int samples;
   15.63 +    int samples = 0;
   15.64  
   15.65 -    bytes = audio_MIN (bytes, INT_MAX);
   15.66 -    samples = bytes >> hw->info.shift;
   15.67 -    samples = audio_MIN (samples, dead);
   15.68 +    if (dead) {
   15.69 +        int64_t now = qemu_get_clock (vm_clock);
   15.70 +        int64_t ticks = now - no->old_ticks;
   15.71 +        int64_t bytes = (ticks * hw->info.bytes_per_second) / ticks_per_sec;
   15.72  
   15.73 +        no->old_ticks = now;
   15.74 +        bytes = audio_MIN (bytes, INT_MAX);
   15.75 +        samples = bytes >> hw->info.shift;
   15.76 +        samples = audio_MIN (samples, dead);
   15.77 +    }
   15.78      return samples;
   15.79  }
   15.80  
    16.1 --- a/tools/ioemu/audio/ossaudio.c	Mon Aug 07 18:11:59 2006 +0100
    16.2 +++ b/tools/ioemu/audio/ossaudio.c	Mon Aug 07 18:25:30 2006 +0100
    16.3 @@ -55,12 +55,14 @@ static struct {
    16.4      int fragsize;
    16.5      const char *devpath_out;
    16.6      const char *devpath_in;
    16.7 +    int debug;
    16.8  } conf = {
    16.9      .try_mmap = 0,
   16.10      .nfrags = 4,
   16.11      .fragsize = 4096,
   16.12      .devpath_out = "/dev/dsp",
   16.13 -    .devpath_in = "/dev/dsp"
   16.14 +    .devpath_in = "/dev/dsp",
   16.15 +    .debug = 0
   16.16  };
   16.17  
   16.18  struct oss_params {
   16.19 @@ -324,9 +326,20 @@ static int oss_run_out (HWVoiceOut *hw)
   16.20              return 0;
   16.21          }
   16.22  
   16.23 -        if (abinfo.bytes < 0 || abinfo.bytes > bufsize) {
   16.24 -            ldebug ("warning: Invalid available size, size=%d bufsize=%d\n",
   16.25 -                    abinfo.bytes, bufsize);
   16.26 +        if (abinfo.bytes > bufsize) {
   16.27 +            if (conf.debug) {
   16.28 +                dolog ("warning: Invalid available size, size=%d bufsize=%d\n"
   16.29 +                       "please report your OS/audio hw to malc@pulsesoft.com\n",
   16.30 +                       abinfo.bytes, bufsize);
   16.31 +            }
   16.32 +            abinfo.bytes = bufsize;
   16.33 +        }
   16.34 +
   16.35 +        if (abinfo.bytes < 0) {
   16.36 +            if (conf.debug) {
   16.37 +                dolog ("warning: Invalid available size, size=%d bufsize=%d\n",
   16.38 +                       abinfo.bytes, bufsize);
   16.39 +            }
   16.40              return 0;
   16.41          }
   16.42  
   16.43 @@ -369,15 +382,12 @@ static int oss_run_out (HWVoiceOut *hw)
   16.44                             "alignment %d\n",
   16.45                             wbytes, written, hw->info.align + 1);
   16.46                  }
   16.47 -                mixeng_clear (src, wsamples);
   16.48                  decr -= wsamples;
   16.49                  rpos = (rpos + wsamples) % hw->samples;
   16.50                  break;
   16.51              }
   16.52          }
   16.53  
   16.54 -        mixeng_clear (src, convert_samples);
   16.55 -
   16.56          rpos = (rpos + convert_samples) % hw->samples;
   16.57          samples -= convert_samples;
   16.58      }
   16.59 @@ -443,12 +453,9 @@ static int oss_init_out (HWVoiceOut *hw,
   16.60      obt_as.freq = obt.freq;
   16.61      obt_as.nchannels = obt.nchannels;
   16.62      obt_as.fmt = effective_fmt;
   16.63 +    obt_as.endianness = endianness;
   16.64  
   16.65 -    audio_pcm_init_info (
   16.66 -        &hw->info,
   16.67 -        &obt_as,
   16.68 -        audio_need_to_swap_endian (endianness)
   16.69 -        );
   16.70 +    audio_pcm_init_info (&hw->info, &obt_as);
   16.71      oss->nfrags = obt.nfrags;
   16.72      oss->fragsize = obt.fragsize;
   16.73  
   16.74 @@ -587,12 +594,9 @@ static int oss_init_in (HWVoiceIn *hw, a
   16.75      obt_as.freq = obt.freq;
   16.76      obt_as.nchannels = obt.nchannels;
   16.77      obt_as.fmt = effective_fmt;
   16.78 +    obt_as.endianness = endianness;
   16.79  
   16.80 -    audio_pcm_init_info (
   16.81 -        &hw->info,
   16.82 -        &obt_as,
   16.83 -        audio_need_to_swap_endian (endianness)
   16.84 -        );
   16.85 +    audio_pcm_init_info (&hw->info, &obt_as);
   16.86      oss->nfrags = obt.nfrags;
   16.87      oss->fragsize = obt.fragsize;
   16.88  
   16.89 @@ -730,6 +734,8 @@ static struct audio_option oss_options[]
   16.90       "Path to DAC device", NULL, 0},
   16.91      {"ADC_DEV", AUD_OPT_STR, &conf.devpath_in,
   16.92       "Path to ADC device", NULL, 0},
   16.93 +    {"DEBUG", AUD_OPT_BOOL, &conf.debug,
   16.94 +     "Turn on some debugging messages", NULL, 0},
   16.95      {NULL, 0, NULL, NULL, NULL, 0}
   16.96  };
   16.97  
    17.1 --- a/tools/ioemu/audio/rate_template.h	Mon Aug 07 18:11:59 2006 +0100
    17.2 +++ b/tools/ioemu/audio/rate_template.h	Mon Aug 07 18:25:30 2006 +0100
    17.3 @@ -51,7 +51,7 @@ void NAME (void *opaque, st_sample_t *ib
    17.4      if (rate->opos_inc == (1ULL + UINT_MAX)) {
    17.5          int i, n = *isamp > *osamp ? *osamp : *isamp;
    17.6          for (i = 0; i < n; i++) {
    17.7 -            OP (obuf[i].l, ibuf[i].r);
    17.8 +            OP (obuf[i].l, ibuf[i].l);
    17.9              OP (obuf[i].r, ibuf[i].r);
   17.10          }
   17.11          *isamp = n;
    18.1 --- a/tools/ioemu/audio/sdlaudio.c	Mon Aug 07 18:11:59 2006 +0100
    18.2 +++ b/tools/ioemu/audio/sdlaudio.c	Mon Aug 07 18:25:30 2006 +0100
    18.3 @@ -240,7 +240,6 @@ static void sdl_callback (void *opaque, 
    18.4  
    18.5              /* dolog ("in callback to_mix %d, chunk %d\n", to_mix, chunk); */
    18.6              hw->clip (buf, src, chunk);
    18.7 -            mixeng_clear (src, chunk);
    18.8              sdl->rpos = (sdl->rpos + chunk) % hw->samples;
    18.9              to_mix -= chunk;
   18.10              buf += chunk << hw->info.shift;
   18.11 @@ -336,12 +335,9 @@ static int sdl_init_out (HWVoiceOut *hw,
   18.12      obt_as.freq = obt.freq;
   18.13      obt_as.nchannels = obt.channels;
   18.14      obt_as.fmt = effective_fmt;
   18.15 +    obt_as.endianness = endianess;
   18.16  
   18.17 -    audio_pcm_init_info (
   18.18 -        &hw->info,
   18.19 -        &obt_as,
   18.20 -        audio_need_to_swap_endian (endianess)
   18.21 -        );
   18.22 +    audio_pcm_init_info (&hw->info, &obt_as);
   18.23      hw->samples = obt.samples;
   18.24  
   18.25      s->initialized = 1;
    19.1 --- a/tools/ioemu/audio/wavaudio.c	Mon Aug 07 18:11:59 2006 +0100
    19.2 +++ b/tools/ioemu/audio/wavaudio.c	Mon Aug 07 18:25:30 2006 +0100
    19.3 @@ -81,7 +81,6 @@ static int wav_run_out (HWVoiceOut *hw)
    19.4  
    19.5          hw->clip (dst, src, convert_samples);
    19.6          qemu_put_buffer (wav->f, dst, convert_samples << hw->info.shift);
    19.7 -        mixeng_clear (src, convert_samples);
    19.8  
    19.9          rpos = (rpos + convert_samples) % hw->samples;
   19.10          samples -= convert_samples;
   19.11 @@ -136,7 +135,8 @@ static int wav_init_out (HWVoiceOut *hw,
   19.12  
   19.13      hdr[34] = bits16 ? 0x10 : 0x08;
   19.14  
   19.15 -    audio_pcm_init_info (&hw->info, &wav_as, audio_need_to_swap_endian (0));
   19.16 +    wav_as.endianness = 0;
   19.17 +    audio_pcm_init_info (&hw->info, &wav_as);
   19.18  
   19.19      hw->samples = 1024;
   19.20      wav->pcm_buf = audio_calloc (AUDIO_FUNC, hw->samples, 1 << hw->info.shift);
    20.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    20.2 +++ b/tools/ioemu/audio/wavcapture.c	Mon Aug 07 18:25:30 2006 +0100
    20.3 @@ -0,0 +1,164 @@
    20.4 +#include "vl.h"
    20.5 +
    20.6 +typedef struct {
    20.7 +    QEMUFile *f;
    20.8 +    int bytes;
    20.9 +    char *path;
   20.10 +    int freq;
   20.11 +    int bits;
   20.12 +    int nchannels;
   20.13 +    CaptureVoiceOut *cap;
   20.14 +} WAVState;
   20.15 +
   20.16 +/* VICE code: Store number as little endian. */
   20.17 +static void le_store (uint8_t *buf, uint32_t val, int len)
   20.18 +{
   20.19 +    int i;
   20.20 +    for (i = 0; i < len; i++) {
   20.21 +        buf[i] = (uint8_t) (val & 0xff);
   20.22 +        val >>= 8;
   20.23 +    }
   20.24 +}
   20.25 +
   20.26 +static void wav_notify (void *opaque, audcnotification_e cmd)
   20.27 +{
   20.28 +    (void) opaque;
   20.29 +    (void) cmd;
   20.30 +}
   20.31 +
   20.32 +static void wav_destroy (void *opaque)
   20.33 +{
   20.34 +    WAVState *wav = opaque;
   20.35 +    uint8_t rlen[4];
   20.36 +    uint8_t dlen[4];
   20.37 +    uint32_t datalen = wav->bytes;
   20.38 +    uint32_t rifflen = datalen + 36;
   20.39 +
   20.40 +    if (!wav->f) {
   20.41 +        return;
   20.42 +    }
   20.43 +
   20.44 +    le_store (rlen, rifflen, 4);
   20.45 +    le_store (dlen, datalen, 4);
   20.46 +
   20.47 +    qemu_fseek (wav->f, 4, SEEK_SET);
   20.48 +    qemu_put_buffer (wav->f, rlen, 4);
   20.49 +
   20.50 +    qemu_fseek (wav->f, 32, SEEK_CUR);
   20.51 +    qemu_put_buffer (wav->f, dlen, 4);
   20.52 +    fclose (wav->f);
   20.53 +    if (wav->path) {
   20.54 +        qemu_free (wav->path);
   20.55 +    }
   20.56 +}
   20.57 +
   20.58 +static void wav_capture (void *opaque, void *buf, int size)
   20.59 +{
   20.60 +    WAVState *wav = opaque;
   20.61 +
   20.62 +    qemu_put_buffer (wav->f, buf, size);
   20.63 +    wav->bytes += size;
   20.64 +}
   20.65 +
   20.66 +static void wav_capture_destroy (void *opaque)
   20.67 +{
   20.68 +    WAVState *wav = opaque;
   20.69 +
   20.70 +    AUD_del_capture (wav->cap, wav);
   20.71 +}
   20.72 +
   20.73 +static void wav_capture_info (void *opaque)
   20.74 +{
   20.75 +    WAVState *wav = opaque;
   20.76 +    char *path = wav->path;
   20.77 +
   20.78 +    term_printf ("Capturing audio(%d,%d,%d) to %s: %d bytes\n",
   20.79 +                 wav->freq, wav->bits, wav->nchannels,
   20.80 +                 path ? path : "<not available>", wav->bytes);
   20.81 +}
   20.82 +
   20.83 +static struct capture_ops wav_capture_ops = {
   20.84 +    .destroy = wav_capture_destroy,
   20.85 +    .info = wav_capture_info
   20.86 +};
   20.87 +
   20.88 +int wav_start_capture (CaptureState *s, const char *path, int freq,
   20.89 +                       int bits, int nchannels)
   20.90 +{
   20.91 +    WAVState *wav;
   20.92 +    uint8_t hdr[] = {
   20.93 +        0x52, 0x49, 0x46, 0x46, 0x00, 0x00, 0x00, 0x00, 0x57, 0x41, 0x56,
   20.94 +        0x45, 0x66, 0x6d, 0x74, 0x20, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00,
   20.95 +        0x02, 0x00, 0x44, 0xac, 0x00, 0x00, 0x10, 0xb1, 0x02, 0x00, 0x04,
   20.96 +        0x00, 0x10, 0x00, 0x64, 0x61, 0x74, 0x61, 0x00, 0x00, 0x00, 0x00
   20.97 +    };
   20.98 +    audsettings_t as;
   20.99 +    struct audio_capture_ops ops;
  20.100 +    int stereo, bits16, shift;
  20.101 +    CaptureVoiceOut *cap;
  20.102 +
  20.103 +    if (bits != 8 && bits != 16) {
  20.104 +        term_printf ("incorrect bit count %d, must be 8 or 16\n", bits);
  20.105 +        return -1;
  20.106 +    }
  20.107 +
  20.108 +    if (nchannels != 1 && nchannels != 2) {
  20.109 +        term_printf ("incorrect channel count %d, must be 1 or 2\n",
  20.110 +                     nchannels);
  20.111 +        return -1;
  20.112 +    }
  20.113 +
  20.114 +    stereo = nchannels == 2;
  20.115 +    bits16 = bits == 16;
  20.116 +
  20.117 +    as.freq = freq;
  20.118 +    as.nchannels = 1 << stereo;
  20.119 +    as.fmt = bits16 ? AUD_FMT_S16 : AUD_FMT_U8;
  20.120 +    as.endianness = 0;
  20.121 +
  20.122 +    ops.notify = wav_notify;
  20.123 +    ops.capture = wav_capture;
  20.124 +    ops.destroy = wav_destroy;
  20.125 +
  20.126 +    wav = qemu_mallocz (sizeof (*wav));
  20.127 +    if (!wav) {
  20.128 +        term_printf ("Could not allocate memory for wav capture (%zu bytes)",
  20.129 +                     sizeof (*wav));
  20.130 +        return -1;
  20.131 +    }
  20.132 +
  20.133 +    shift = bits16 + stereo;
  20.134 +    hdr[34] = bits16 ? 0x10 : 0x08;
  20.135 +
  20.136 +    le_store (hdr + 22, as.nchannels, 2);
  20.137 +    le_store (hdr + 24, freq, 4);
  20.138 +    le_store (hdr + 28, freq << shift, 4);
  20.139 +    le_store (hdr + 32, 1 << shift, 2);
  20.140 +
  20.141 +    wav->f = fopen (path, "wb");
  20.142 +    if (!wav->f) {
  20.143 +        term_printf ("Failed to open wave file `%s'\nReason: %s\n",
  20.144 +                     path, strerror (errno));
  20.145 +        qemu_free (wav);
  20.146 +        return -1;
  20.147 +    }
  20.148 +
  20.149 +    wav->path = qemu_strdup (path);
  20.150 +    wav->bits = bits;
  20.151 +    wav->nchannels = nchannels;
  20.152 +    wav->freq = freq;
  20.153 +
  20.154 +    qemu_put_buffer (wav->f, hdr, sizeof (hdr));
  20.155 +
  20.156 +    cap = AUD_add_capture (NULL, &as, &ops, wav);
  20.157 +    if (!cap) {
  20.158 +        term_printf ("Failed to add audio capture\n");
  20.159 +        qemu_free (wav);
  20.160 +        return -1;
  20.161 +    }
  20.162 +
  20.163 +    wav->cap = cap;
  20.164 +    s->opaque = wav;
  20.165 +    s->ops = wav_capture_ops;
  20.166 +    return 0;
  20.167 +}
    21.1 --- a/tools/ioemu/block-cow.c	Mon Aug 07 18:11:59 2006 +0100
    21.2 +++ b/tools/ioemu/block-cow.c	Mon Aug 07 18:25:30 2006 +0100
    21.3 @@ -250,6 +250,12 @@ static int cow_create(const char *filena
    21.4      return 0;
    21.5  }
    21.6  
    21.7 +static void cow_flush(BlockDriverState *bs)
    21.8 +{
    21.9 +    BDRVCowState *s = bs->opaque;
   21.10 +    fsync(s->fd);
   21.11 +}
   21.12 +
   21.13  BlockDriver bdrv_cow = {
   21.14      "cow",
   21.15      sizeof(BDRVCowState),
   21.16 @@ -259,6 +265,7 @@ BlockDriver bdrv_cow = {
   21.17      cow_write,
   21.18      cow_close,
   21.19      cow_create,
   21.20 +    cow_flush,
   21.21      cow_is_allocated,
   21.22  };
   21.23  #endif
    22.1 --- a/tools/ioemu/block-qcow.c	Mon Aug 07 18:11:59 2006 +0100
    22.2 +++ b/tools/ioemu/block-qcow.c	Mon Aug 07 18:25:30 2006 +0100
    22.3 @@ -693,6 +693,12 @@ int qcow_compress_cluster(BlockDriverSta
    22.4      return 0;
    22.5  }
    22.6  
    22.7 +static void qcow_flush(BlockDriverState *bs)
    22.8 +{
    22.9 +    BDRVQcowState *s = bs->opaque;
   22.10 +    fsync(s->fd);
   22.11 +}
   22.12 +
   22.13  BlockDriver bdrv_qcow = {
   22.14      "qcow",
   22.15      sizeof(BDRVQcowState),
   22.16 @@ -702,6 +708,7 @@ BlockDriver bdrv_qcow = {
   22.17      qcow_write,
   22.18      qcow_close,
   22.19      qcow_create,
   22.20 +    qcow_flush,
   22.21      qcow_is_allocated,
   22.22      qcow_set_key,
   22.23      qcow_make_empty
    23.1 --- a/tools/ioemu/block-vmdk.c	Mon Aug 07 18:11:59 2006 +0100
    23.2 +++ b/tools/ioemu/block-vmdk.c	Mon Aug 07 18:25:30 2006 +0100
    23.3 @@ -426,6 +426,12 @@ static void vmdk_close(BlockDriverState 
    23.4      close(s->fd);
    23.5  }
    23.6  
    23.7 +static void vmdk_flush(BlockDriverState *bs)
    23.8 +{
    23.9 +    BDRVVmdkState *s = bs->opaque;
   23.10 +    fsync(s->fd);
   23.11 +}
   23.12 +
   23.13  BlockDriver bdrv_vmdk = {
   23.14      "vmdk",
   23.15      sizeof(BDRVVmdkState),
   23.16 @@ -435,5 +441,6 @@ BlockDriver bdrv_vmdk = {
   23.17      vmdk_write,
   23.18      vmdk_close,
   23.19      vmdk_create,
   23.20 +    vmdk_flush,
   23.21      vmdk_is_allocated,
   23.22  };
    24.1 --- a/tools/ioemu/block-vpc.c	Mon Aug 07 18:11:59 2006 +0100
    24.2 +++ b/tools/ioemu/block-vpc.c	Mon Aug 07 18:25:30 2006 +0100
    24.3 @@ -163,7 +163,7 @@ static inline int seek_to_sector(BlockDr
    24.4      bitmap_offset = 512 * s->pagetable[pagetable_index];
    24.5      block_offset = bitmap_offset + 512 + (512 * pageentry_index);
    24.6      
    24.7 -//    printf("sector: %llx, index: %x, offset: %x, bioff: %llx, bloff: %llx\n",
    24.8 +//    printf("sector: %" PRIx64 ", index: %x, offset: %x, bioff: %" PRIx64 ", bloff: %" PRIx64 "\n",
    24.9  //	sector_num, pagetable_index, pageentry_index,
   24.10  //	bitmap_offset, block_offset);
   24.11  
    25.1 --- a/tools/ioemu/block-vvfat.c	Mon Aug 07 18:11:59 2006 +0100
    25.2 +++ b/tools/ioemu/block-vvfat.c	Mon Aug 07 18:25:30 2006 +0100
    25.3 @@ -2772,6 +2772,7 @@ BlockDriver bdrv_vvfat = {
    25.4      vvfat_read,
    25.5      vvfat_write,
    25.6      vvfat_close,
    25.7 +    NULL, /* ??? Not sure if we can do any meaningful flushing.  */
    25.8      NULL,
    25.9      vvfat_is_allocated
   25.10  };
    26.1 --- a/tools/ioemu/block.c	Mon Aug 07 18:11:59 2006 +0100
    26.2 +++ b/tools/ioemu/block.c	Mon Aug 07 18:25:30 2006 +0100
    26.3 @@ -615,6 +615,14 @@ const char *bdrv_get_device_name(BlockDr
    26.4      return bs->device_name;
    26.5  }
    26.6  
    26.7 +void bdrv_flush(BlockDriverState *bs)
    26.8 +{
    26.9 +    if (bs->drv->bdrv_flush)
   26.10 +        bs->drv->bdrv_flush(bs);
   26.11 +    if (bs->backing_hd)
   26.12 +        bdrv_flush(bs->backing_hd);
   26.13 +}
   26.14 +
   26.15  void bdrv_info(void)
   26.16  {
   26.17      BlockDriverState *bs;
   26.18 @@ -754,6 +762,51 @@ static void raw_close(BlockDriverState *
   26.19      close(s->fd);
   26.20  }
   26.21  
   26.22 +#ifdef _WIN32
   26.23 +#include <windows.h>
   26.24 +#include <winioctl.h>
   26.25 +
   26.26 +int qemu_ftruncate64(int fd, int64_t length)
   26.27 +{
   26.28 +    LARGE_INTEGER li;
   26.29 +    LONG high;
   26.30 +    HANDLE h;
   26.31 +    BOOL res;
   26.32 +
   26.33 +    if ((GetVersion() & 0x80000000UL) && (length >> 32) != 0)
   26.34 +	return -1;
   26.35 +
   26.36 +    h = (HANDLE)_get_osfhandle(fd);
   26.37 +
   26.38 +    /* get current position, ftruncate do not change position */
   26.39 +    li.HighPart = 0;
   26.40 +    li.LowPart = SetFilePointer (h, 0, &li.HighPart, FILE_CURRENT);
   26.41 +    if (li.LowPart == 0xffffffffUL && GetLastError() != NO_ERROR)
   26.42 +	return -1;
   26.43 +
   26.44 +    high = length >> 32;
   26.45 +    if (!SetFilePointer(h, (DWORD) length, &high, FILE_BEGIN))
   26.46 +	return -1;
   26.47 +    res = SetEndOfFile(h);
   26.48 +
   26.49 +    /* back to old position */
   26.50 +    SetFilePointer(h, li.LowPart, &li.HighPart, FILE_BEGIN);
   26.51 +    return res ? 0 : -1;
   26.52 +}
   26.53 +
   26.54 +static int set_sparse(int fd)
   26.55 +{
   26.56 +    DWORD returned;
   26.57 +    return (int) DeviceIoControl((HANDLE)_get_osfhandle(fd), FSCTL_SET_SPARSE,
   26.58 +				 NULL, 0, NULL, 0, &returned, NULL);
   26.59 +}
   26.60 +#else
   26.61 +static inline int set_sparse(int fd)
   26.62 +{
   26.63 +    return 1;
   26.64 +}
   26.65 +#endif
   26.66 +
   26.67  static int raw_create(const char *filename, int64_t total_size,
   26.68                        const char *backing_file, int flags)
   26.69  {
   26.70 @@ -766,11 +819,18 @@ static int raw_create(const char *filena
   26.71                0644);
   26.72      if (fd < 0)
   26.73          return -EIO;
   26.74 +    set_sparse(fd);
   26.75      ftruncate(fd, total_size * 512);
   26.76      close(fd);
   26.77      return 0;
   26.78  }
   26.79  
   26.80 +static void raw_flush(BlockDriverState *bs)
   26.81 +{
   26.82 +    BDRVRawState *s = bs->opaque;
   26.83 +    fsync(s->fd);
   26.84 +}
   26.85 +
   26.86  BlockDriver bdrv_raw = {
   26.87      "raw",
   26.88      sizeof(BDRVRawState),
   26.89 @@ -780,6 +840,7 @@ BlockDriver bdrv_raw = {
   26.90      raw_write,
   26.91      raw_close,
   26.92      raw_create,
   26.93 +    raw_flush,
   26.94  };
   26.95  
   26.96  void bdrv_init(void)
    27.1 --- a/tools/ioemu/block_int.h	Mon Aug 07 18:11:59 2006 +0100
    27.2 +++ b/tools/ioemu/block_int.h	Mon Aug 07 18:25:30 2006 +0100
    27.3 @@ -36,6 +36,7 @@ struct BlockDriver {
    27.4      void (*bdrv_close)(BlockDriverState *bs);
    27.5      int (*bdrv_create)(const char *filename, int64_t total_sectors, 
    27.6                         const char *backing_file, int flags);
    27.7 +    void (*bdrv_flush)(BlockDriverState *bs);
    27.8      int (*bdrv_is_allocated)(BlockDriverState *bs, int64_t sector_num,
    27.9                               int nb_sectors, int *pnum);
   27.10      int (*bdrv_set_key)(BlockDriverState *bs, const char *key);
    28.1 --- a/tools/ioemu/cocoa.m	Mon Aug 07 18:11:59 2006 +0100
    28.2 +++ b/tools/ioemu/cocoa.m	Mon Aug 07 18:25:30 2006 +0100
    28.3 @@ -439,23 +439,40 @@ static void cocoa_refresh(DisplayState *
    28.4                                  kbd_put_keycode(keycode & 0x7f); //remove e0 bit in front
    28.5                              /* handle monitor key events */
    28.6                              } else {
    28.7 +                                int keysym = 0;
    28.8 +
    28.9                                  switch([event keyCode]) {
   28.10 -                                    case 123:
   28.11 -                                        kbd_put_keysym(QEMU_KEY_LEFT);
   28.12 -                                        break;
   28.13 -                                    case 124:
   28.14 -                                        kbd_put_keysym(QEMU_KEY_RIGHT);
   28.15 -                                        break;
   28.16 -                                    case 125:
   28.17 -                                        kbd_put_keysym(QEMU_KEY_DOWN);
   28.18 -                                        break;
   28.19 -                                    case 126:
   28.20 -                                        kbd_put_keysym(QEMU_KEY_UP);
   28.21 -                                        break;
   28.22 -                                    default:
   28.23 -                                        kbd_put_keysym([[event characters] characterAtIndex:0]);
   28.24 -                                        break;
   28.25 +                                case 115:
   28.26 +                                    keysym = QEMU_KEY_HOME;
   28.27 +                                    break;
   28.28 +                                case 117:
   28.29 +                                    keysym = QEMU_KEY_DELETE;
   28.30 +                                    break;
   28.31 +                                case 119:
   28.32 +                                    keysym = QEMU_KEY_END;
   28.33 +                                    break;
   28.34 +                                case 123:
   28.35 +                                    keysym = QEMU_KEY_LEFT;
   28.36 +                                    break;
   28.37 +                                case 124:
   28.38 +                                    keysym = QEMU_KEY_RIGHT;
   28.39 +                                    break;
   28.40 +                                case 125:
   28.41 +                                    keysym = QEMU_KEY_DOWN;
   28.42 +                                    break;
   28.43 +                                case 126:
   28.44 +                                    keysym = QEMU_KEY_UP;
   28.45 +                                    break;
   28.46 +                                default:
   28.47 +                                    {
   28.48 +                                        NSString *ks = [event characters];
   28.49 +
   28.50 +                                        if ([ks length] > 0)
   28.51 +                                            keysym = [ks characterAtIndex:0];
   28.52 +                                    }
   28.53                                  }
   28.54 +                                if (keysym)
   28.55 +                                    kbd_put_keysym(keysym);
   28.56                              }
   28.57                          }
   28.58                      }
   28.59 @@ -867,10 +884,9 @@ static void setupWindowMenu(void)
   28.60      /* Finally give up our references to the objects */
   28.61      [windowMenu release];
   28.62      [windowMenuItem release];
   28.63 - 
   28.64  }
   28.65  
   28.66 -static void CustomApplicationMain (argc, argv)
   28.67 +static void CustomApplicationMain(void)
   28.68  {
   28.69      NSAutoreleasePool   *pool = [[NSAutoreleasePool alloc] init];
   28.70      QemuCocoaGUIController *gui_controller;
   28.71 @@ -904,8 +920,8 @@ int main(int argc, char **argv)
   28.72  {
   28.73      gArgc = argc;
   28.74      gArgv = argv;
   28.75 -    
   28.76 -    CustomApplicationMain (argc, argv);
   28.77 -    
   28.78 +
   28.79 +    CustomApplicationMain();
   28.80 +
   28.81      return 0;
   28.82  }
    29.1 --- a/tools/ioemu/configure	Mon Aug 07 18:11:59 2006 +0100
    29.2 +++ b/tools/ioemu/configure	Mon Aug 07 18:25:30 2006 +0100
    29.3 @@ -96,6 +96,8 @@ check_gcc="no"
    29.4  softmmu="yes"
    29.5  user="no"
    29.6  build_docs="no"
    29.7 +build_acpi_tables="no"
    29.8 +uname_release=""
    29.9  
   29.10  # OS specific
   29.11  targetos=`uname -s`
   29.12 @@ -212,7 +214,7 @@ for opt do
   29.13    ;;
   29.14    --fmod-inc=*) fmod_inc="$optarg"
   29.15    ;;
   29.16 -  --enable-mingw32) mingw32="yes" ; cross_prefix="i386-mingw32-"
   29.17 +  --enable-mingw32) mingw32="yes" ; cross_prefix="i386-mingw32-" ; user="no"
   29.18    ;;
   29.19    --disable-slirp) slirp="no"
   29.20    ;;
   29.21 @@ -236,6 +238,10 @@ for opt do
   29.22    ;;
   29.23    --enable-user) user="yes"
   29.24    ;;
   29.25 +  --enable-uname-release=*) uname_release="$optarg"
   29.26 +  ;;
   29.27 +  --enable-iasl) build_acpi_tables="yes"
   29.28 +  ;;
   29.29    esac
   29.30  done
   29.31  
   29.32 @@ -283,6 +289,8 @@ echo "  --enable-user            enable 
   29.33  echo "  --disable-user           disable all linux usermode emulation targets"
   29.34  echo "  --fmod-lib               path to FMOD library"
   29.35  echo "  --fmod-inc               path to FMOD includes"
   29.36 +echo "  --enable-uname-release=R Return R for uname -r in usermode emulation"
   29.37 +echo "  --enable-iasl            compilation of ACPI tables with the IASL compiler"
   29.38  echo ""
   29.39  echo "NOTE: The object files are build at the place where configure is launched"
   29.40  exit 1
   29.41 @@ -292,15 +300,21 @@ cc="${cross_prefix}${cc}"
   29.42  ar="${cross_prefix}${ar}"
   29.43  strip="${cross_prefix}${strip}"
   29.44  
   29.45 -if [ ! -x "`which $cc`" ] ; then
   29.46 -    echo "Compiler $cc could not be found"
   29.47 -    exit
   29.48 +# check that the C compiler works.
   29.49 +cat > $TMPC <<EOF
   29.50 +int main(void) {}
   29.51 +EOF
   29.52 +
   29.53 +if $cc -c -o $TMPO $TMPC 2>/dev/null ; then
   29.54 +  : C compiler works ok
   29.55 +else
   29.56 +    echo "ERROR: \"$cc\" either does not exist or does not work"
   29.57 +    exit 1
   29.58  fi
   29.59  
   29.60  if test "$mingw32" = "yes" ; then
   29.61      linux="no"
   29.62      EXESUF=".exe"
   29.63 -    gdbstub="no"
   29.64      oss="no"
   29.65      if [ "$cpu" = "i386" ] ; then
   29.66          kqemu="yes"
   29.67 @@ -551,6 +565,8 @@ fi
   29.68  echo "FMOD support      $fmod $fmod_support"
   29.69  echo "kqemu support     $kqemu"
   29.70  echo "Documentation     $build_docs"
   29.71 +[ ! -z "$uname_release" ] && \
   29.72 +echo "uname -r          $uname_release"
   29.73  
   29.74  if test $sdl_too_old = "yes"; then
   29.75  echo "-> Your SDL version is too old - please upgrade to have SDL support"
   29.76 @@ -703,6 +719,9 @@ echo "TARGET_DIRS=$target_list" >> $conf
   29.77  if [ "$build_docs" = "yes" ] ; then
   29.78    echo "BUILD_DOCS=yes" >> $config_mak
   29.79  fi
   29.80 +if [ "$build_acpi_tables" = "yes" ] ; then
   29.81 +  echo "BUILD_ACPI_TABLES=yes" >> $config_mak
   29.82 +fi
   29.83  
   29.84  # XXX: suppress that
   29.85  if [ "$bsd" = "yes" ] ; then
   29.86 @@ -711,6 +730,8 @@ if [ "$bsd" = "yes" ] ; then
   29.87    echo "#define _BSD 1" >> $config_h
   29.88  fi
   29.89  
   29.90 +echo "#define CONFIG_UNAME_RELEASE \"$uname_release\"" >> $config_h
   29.91 +
   29.92  for target in $target_list; do
   29.93  target_dir="$target"
   29.94  config_mak=$target_dir/config.mak
   29.95 @@ -723,6 +744,7 @@ target_bigendian="no"
   29.96  [ "$target_cpu" = "ppc" ] && target_bigendian=yes
   29.97  [ "$target_cpu" = "ppc64" ] && target_bigendian=yes
   29.98  [ "$target_cpu" = "mips" ] && target_bigendian=yes
   29.99 +[ "$target_cpu" = "sh4eb" ] && target_bigendian=yes
  29.100  target_softmmu="no"
  29.101  if expr $target : '.*-softmmu' > /dev/null ; then
  29.102    target_softmmu="yes"
  29.103 @@ -759,6 +781,7 @@ echo "/* Automatically generated by conf
  29.104  echo "include ../config-host.mak" >> $config_mak
  29.105  echo "#include \"../config-host.h\"" >> $config_h
  29.106  
  29.107 +bflt="no"
  29.108  interp_prefix1=`echo "$interp_prefix" | sed "s/%M/$target_cpu/g"`
  29.109  echo "#define CONFIG_QEMU_PREFIX \"$interp_prefix1\"" >> $config_h
  29.110  
  29.111 @@ -779,6 +802,7 @@ elif test "$target_cpu" = "arm" -o "$tar
  29.112    echo "TARGET_ARCH=arm" >> $config_mak
  29.113    echo "#define TARGET_ARCH \"arm\"" >> $config_h
  29.114    echo "#define TARGET_ARM 1" >> $config_h
  29.115 +  bflt="yes"
  29.116  elif test "$target_cpu" = "sparc" ; then
  29.117    echo "TARGET_ARCH=sparc" >> $config_mak
  29.118    echo "#define TARGET_ARCH \"sparc\"" >> $config_h
  29.119 @@ -809,10 +833,13 @@ elif test "$target_cpu" = "mips" -o "$ta
  29.120    echo "TARGET_ARCH=mips" >> $config_mak
  29.121    echo "#define TARGET_ARCH \"mips\"" >> $config_h
  29.122    echo "#define TARGET_MIPS 1" >> $config_h
  29.123 -elif test "$target_cpu" = "sh4" ; then
  29.124 +  echo "CONFIG_SOFTFLOAT=yes" >> $config_mak
  29.125 +  echo "#define CONFIG_SOFTFLOAT 1" >> $config_h
  29.126 +elif test "$target_cpu" = "sh4" -o "$target_cpu" = "sh4eb" ; then
  29.127    echo "TARGET_ARCH=sh4" >> $config_mak
  29.128    echo "#define TARGET_ARCH \"sh4\"" >> $config_h
  29.129    echo "#define TARGET_SH4 1" >> $config_h
  29.130 +  bflt="yes"
  29.131  else
  29.132    echo "Unsupported target CPU"
  29.133    exit 1
  29.134 @@ -834,10 +861,14 @@ if expr $target : '.*-dm' > /dev/null ; 
  29.135    echo "#define CONFIG_DM 1" >> $config_h
  29.136  fi
  29.137  
  29.138 -if test "$target_cpu" = "arm" -o "$target_cpu" = "armeb" ; then
  29.139 +if test "$target_cpu" = "arm" -o "$target_cpu" = "armeb" -o "$target_cpu" = "sparc" -o "$target_cpu" = "sparc64"; then
  29.140    echo "CONFIG_SOFTFLOAT=yes" >> $config_mak
  29.141    echo "#define CONFIG_SOFTFLOAT 1" >> $config_h
  29.142  fi
  29.143 +if test "$target_user_only" = "yes" -a "$bflt" = "yes"; then
  29.144 +  echo "TARGET_HAS_BFLT=yes" >> $config_mak
  29.145 +  echo "#define TARGET_HAS_BFLT 1" >> $config_h
  29.146 +fi
  29.147  # sdl defines
  29.148  
  29.149  if test "$target_user_only" = "no"; then
    30.1 --- a/tools/ioemu/console.c	Mon Aug 07 18:11:59 2006 +0100
    30.2 +++ b/tools/ioemu/console.c	Mon Aug 07 18:25:30 2006 +0100
    30.3 @@ -27,8 +27,8 @@
    30.4  #define DEFAULT_BACKSCROLL 512
    30.5  #define MAX_CONSOLES 12
    30.6  
    30.7 -#define RGBA(r, g, b, a) (((a) << 24) | ((r) << 16) | ((g) << 8) | (b))
    30.8 -#define RGB(r, g, b) RGBA(r, g, b, 0xff)
    30.9 +#define QEMU_RGBA(r, g, b, a) (((a) << 24) | ((r) << 16) | ((g) << 8) | (b))
   30.10 +#define QEMU_RGB(r, g, b) QEMU_RGBA(r, g, b, 0xff)
   30.11  
   30.12  typedef struct TextAttributes {
   30.13      uint8_t fgcol:4;
   30.14 @@ -53,6 +53,57 @@ enum TTYState {
   30.15      TTY_STATE_CSI,
   30.16  };
   30.17  
   30.18 +typedef struct QEMUFIFO {
   30.19 +    uint8_t *buf;
   30.20 +    int buf_size;
   30.21 +    int count, wptr, rptr;
   30.22 +} QEMUFIFO;
   30.23 +
   30.24 +int qemu_fifo_write(QEMUFIFO *f, const uint8_t *buf, int len1)
   30.25 +{
   30.26 +    int l, len;
   30.27 +
   30.28 +    l = f->buf_size - f->count;
   30.29 +    if (len1 > l)
   30.30 +        len1 = l;
   30.31 +    len = len1;
   30.32 +    while (len > 0) {
   30.33 +        l = f->buf_size - f->wptr;
   30.34 +        if (l > len)
   30.35 +            l = len;
   30.36 +        memcpy(f->buf + f->wptr, buf, l);
   30.37 +        f->wptr += l;
   30.38 +        if (f->wptr >= f->buf_size)
   30.39 +            f->wptr = 0;
   30.40 +        buf += l;
   30.41 +        len -= l;
   30.42 +    }
   30.43 +    f->count += len1;
   30.44 +    return len1;
   30.45 +}
   30.46 +
   30.47 +int qemu_fifo_read(QEMUFIFO *f, uint8_t *buf, int len1)
   30.48 +{
   30.49 +    int l, len;
   30.50 +
   30.51 +    if (len1 > f->count)
   30.52 +        len1 = f->count;
   30.53 +    len = len1;
   30.54 +    while (len > 0) {
   30.55 +        l = f->buf_size - f->rptr;
   30.56 +        if (l > len)
   30.57 +            l = len;
   30.58 +        memcpy(buf, f->buf + f->rptr, l);
   30.59 +        f->rptr += l;
   30.60 +        if (f->rptr >= f->buf_size)
   30.61 +            f->rptr = 0;
   30.62 +        buf += l;
   30.63 +        len -= l;
   30.64 +    }
   30.65 +    f->count -= len1;
   30.66 +    return len1;
   30.67 +}
   30.68 +
   30.69  /* ??? This is mis-named.
   30.70     It is used for both text and graphical consoles.  */
   30.71  struct TextConsole {
   30.72 @@ -81,8 +132,13 @@ struct TextConsole {
   30.73      int nb_esc_params;
   30.74  
   30.75      /* kbd read handler */
   30.76 +    IOCanRWHandler *fd_can_read; 
   30.77      IOReadHandler *fd_read;
   30.78      void *fd_opaque;
   30.79 +    /* fifo for key pressed */
   30.80 +    QEMUFIFO out_fifo;
   30.81 +    uint8_t out_fifo_buf[16];
   30.82 +    QEMUTimer *kbd_timer;
   30.83  };
   30.84  
   30.85  static TextConsole *active_console;
   30.86 @@ -274,24 +330,24 @@ enum color_names {
   30.87  
   30.88  static const uint32_t color_table_rgb[2][8] = {
   30.89      {   /* dark */
   30.90 -        RGB(0x00, 0x00, 0x00),  /* black */
   30.91 -        RGB(0xaa, 0x00, 0x00),  /* red */
   30.92 -        RGB(0x00, 0xaa, 0x00),  /* green */
   30.93 -        RGB(0xaa, 0xaa, 0x00),  /* yellow */
   30.94 -        RGB(0x00, 0x00, 0xaa),  /* blue */
   30.95 -        RGB(0xaa, 0x00, 0xaa),  /* magenta */
   30.96 -        RGB(0x00, 0xaa, 0xaa),  /* cyan */
   30.97 -        RGB(0xaa, 0xaa, 0xaa),  /* white */
   30.98 +        QEMU_RGB(0x00, 0x00, 0x00),  /* black */
   30.99 +        QEMU_RGB(0xaa, 0x00, 0x00),  /* red */
  30.100 +        QEMU_RGB(0x00, 0xaa, 0x00),  /* green */
  30.101 +        QEMU_RGB(0xaa, 0xaa, 0x00),  /* yellow */
  30.102 +        QEMU_RGB(0x00, 0x00, 0xaa),  /* blue */
  30.103 +        QEMU_RGB(0xaa, 0x00, 0xaa),  /* magenta */
  30.104 +        QEMU_RGB(0x00, 0xaa, 0xaa),  /* cyan */
  30.105 +        QEMU_RGB(0xaa, 0xaa, 0xaa),  /* white */
  30.106      },
  30.107      {   /* bright */
  30.108 -        RGB(0x00, 0x00, 0x00),  /* black */
  30.109 -        RGB(0xff, 0x00, 0x00),  /* red */
  30.110 -        RGB(0x00, 0xff, 0x00),  /* green */
  30.111 -        RGB(0xff, 0xff, 0x00),  /* yellow */
  30.112 -        RGB(0x00, 0x00, 0xff),  /* blue */
  30.113 -        RGB(0xff, 0x00, 0xff),  /* magenta */
  30.114 -        RGB(0x00, 0xff, 0xff),  /* cyan */
  30.115 -        RGB(0xff, 0xff, 0xff),  /* white */
  30.116 +        QEMU_RGB(0x00, 0x00, 0x00),  /* black */
  30.117 +        QEMU_RGB(0xff, 0x00, 0x00),  /* red */
  30.118 +        QEMU_RGB(0x00, 0xff, 0x00),  /* green */
  30.119 +        QEMU_RGB(0xff, 0xff, 0x00),  /* yellow */
  30.120 +        QEMU_RGB(0x00, 0x00, 0xff),  /* blue */
  30.121 +        QEMU_RGB(0xff, 0x00, 0xff),  /* magenta */
  30.122 +        QEMU_RGB(0x00, 0xff, 0xff),  /* cyan */
  30.123 +        QEMU_RGB(0xff, 0xff, 0xff),  /* white */
  30.124      }
  30.125  };
  30.126  
  30.127 @@ -563,7 +619,6 @@ static void console_put_lf(TextConsole *
  30.128      TextCell *c;
  30.129      int x, y1;
  30.130  
  30.131 -    s->x = 0;
  30.132      s->y++;
  30.133      if (s->y >= s->height) {
  30.134          s->y = s->height - 1;
  30.135 @@ -712,15 +767,12 @@ static void console_putchar(TextConsole 
  30.136              console_put_lf(s);
  30.137              break;
  30.138          case '\b':  /* backspace */
  30.139 -            if(s->x > 0) s->x--;
  30.140 -            y1 = (s->y_base + s->y) % s->total_height;
  30.141 -            c = &s->cells[y1 * s->width + s->x];
  30.142 -            c->ch = ' ';
  30.143 -            c->t_attrib = s->t_attrib;
  30.144 -            update_xy(s, s->x, s->y);
  30.145 +            if (s->x > 0) 
  30.146 +                s->x--;
  30.147              break;
  30.148          case '\t':  /* tabspace */
  30.149              if (s->x + (8 - (s->x % 8)) > s->width) {
  30.150 +                s->x = 0;
  30.151                  console_put_lf(s);
  30.152              } else {
  30.153                  s->x = s->x + (8 - (s->x % 8));
  30.154 @@ -739,8 +791,10 @@ static void console_putchar(TextConsole 
  30.155              c->t_attrib = s->t_attrib;
  30.156              update_xy(s, s->x, s->y);
  30.157              s->x++;
  30.158 -            if (s->x >= s->width)
  30.159 +            if (s->x >= s->width) {
  30.160 +                s->x = 0;
  30.161                  console_put_lf(s);
  30.162 +            }
  30.163              break;
  30.164          }
  30.165          break;
  30.166 @@ -835,6 +889,7 @@ static void console_chr_add_read_handler
  30.167                                           IOReadHandler *fd_read, void *opaque)
  30.168  {
  30.169      TextConsole *s = chr->opaque;
  30.170 +    s->fd_can_read = fd_can_read;
  30.171      s->fd_read = fd_read;
  30.172      s->fd_opaque = opaque;
  30.173  }
  30.174 @@ -854,6 +909,28 @@ static void console_send_event(CharDrive
  30.175      }
  30.176  }
  30.177  
  30.178 +static void kbd_send_chars(void *opaque)
  30.179 +{
  30.180 +    TextConsole *s = opaque;
  30.181 +    int len;
  30.182 +    uint8_t buf[16];
  30.183 +    
  30.184 +    len = s->fd_can_read(s->fd_opaque);
  30.185 +    if (len > s->out_fifo.count)
  30.186 +        len = s->out_fifo.count;
  30.187 +    if (len > 0) {
  30.188 +        if (len > sizeof(buf))
  30.189 +            len = sizeof(buf);
  30.190 +        qemu_fifo_read(&s->out_fifo, buf, len);
  30.191 +        s->fd_read(s->fd_opaque, buf, len);
  30.192 +    }
  30.193 +    /* characters are pending: we send them a bit later (XXX:
  30.194 +       horrible, should change char device API) */
  30.195 +    if (s->out_fifo.count > 0) {
  30.196 +        qemu_mod_timer(s->kbd_timer, qemu_get_clock(rt_clock) + 1);
  30.197 +    }
  30.198 +}
  30.199 +
  30.200  /* called when an ascii key is pressed */
  30.201  void kbd_put_keysym(int keysym)
  30.202  {
  30.203 @@ -879,25 +956,26 @@ void kbd_put_keysym(int keysym)
  30.204          console_scroll(10);
  30.205          break;
  30.206      default:
  30.207 +        /* convert the QEMU keysym to VT100 key string */
  30.208 +        q = buf;
  30.209 +        if (keysym >= 0xe100 && keysym <= 0xe11f) {
  30.210 +            *q++ = '\033';
  30.211 +            *q++ = '[';
  30.212 +            c = keysym - 0xe100;
  30.213 +            if (c >= 10)
  30.214 +                *q++ = '0' + (c / 10);
  30.215 +            *q++ = '0' + (c % 10);
  30.216 +            *q++ = '~';
  30.217 +        } else if (keysym >= 0xe120 && keysym <= 0xe17f) {
  30.218 +            *q++ = '\033';
  30.219 +            *q++ = '[';
  30.220 +            *q++ = keysym & 0xff;
  30.221 +        } else {
  30.222 +                *q++ = keysym;
  30.223 +        }
  30.224          if (s->fd_read) {
  30.225 -            /* convert the QEMU keysym to VT100 key string */
  30.226 -            q = buf;
  30.227 -            if (keysym >= 0xe100 && keysym <= 0xe11f) {
  30.228 -                *q++ = '\033';
  30.229 -                *q++ = '[';
  30.230 -                c = keysym - 0xe100;
  30.231 -                if (c >= 10)
  30.232 -                    *q++ = '0' + (c / 10);
  30.233 -                *q++ = '0' + (c % 10);
  30.234 -                *q++ = '~';
  30.235 -            } else if (keysym >= 0xe120 && keysym <= 0xe17f) {
  30.236 -                *q++ = '\033';
  30.237 -                *q++ = '[';
  30.238 -                *q++ = keysym & 0xff;
  30.239 -            } else {
  30.240 -                *q++ = keysym;
  30.241 -            }
  30.242 -            s->fd_read(s->fd_opaque, buf, q - buf);
  30.243 +            qemu_fifo_write(&s->out_fifo, buf, q - buf);
  30.244 +            kbd_send_chars(s);
  30.245          }
  30.246          break;
  30.247      }
  30.248 @@ -984,6 +1062,10 @@ CharDriverState *text_console_init(Displ
  30.249      chr->chr_add_read_handler = console_chr_add_read_handler;
  30.250      chr->chr_send_event = console_send_event;
  30.251  
  30.252 +    s->out_fifo.buf = s->out_fifo_buf;
  30.253 +    s->out_fifo.buf_size = sizeof(s->out_fifo_buf);
  30.254 +    s->kbd_timer = qemu_new_timer(rt_clock, kbd_send_chars, s);
  30.255 +    
  30.256      if (!color_inited) {
  30.257          color_inited = 1;
  30.258          set_color_table(ds);
    31.1 --- a/tools/ioemu/cpu-all.h	Mon Aug 07 18:11:59 2006 +0100
    31.2 +++ b/tools/ioemu/cpu-all.h	Mon Aug 07 18:25:30 2006 +0100
    31.3 @@ -878,6 +878,10 @@ extern uint8_t *phys_ram_dirty;
    31.4  #define IO_MEM_ROM         (1 << IO_MEM_SHIFT) /* hardcoded offset */
    31.5  #define IO_MEM_UNASSIGNED  (2 << IO_MEM_SHIFT)
    31.6  #define IO_MEM_NOTDIRTY    (4 << IO_MEM_SHIFT) /* used internally, never use directly */
    31.7 +/* acts like a ROM when read and like a device when written. As an
    31.8 +   exception, the write memory callback gets the ram offset instead of
    31.9 +   the physical address */
   31.10 +#define IO_MEM_ROMD        (1)
   31.11  
   31.12  typedef void CPUWriteMemoryFunc(void *opaque, target_phys_addr_t addr, uint32_t value);
   31.13  typedef uint32_t CPUReadMemoryFunc(void *opaque, target_phys_addr_t addr);
   31.14 @@ -946,13 +950,105 @@ void cpu_tlb_update_dirty(CPUState *env)
   31.15  void dump_exec_info(FILE *f,
   31.16                      int (*cpu_fprintf)(FILE *f, const char *fmt, ...));
   31.17  
   31.18 +/*******************************************/
   31.19 +/* host CPU ticks (if available) */
   31.20 +
   31.21 +#if defined(__powerpc__)
   31.22 +
   31.23 +static inline uint32_t get_tbl(void) 
   31.24 +{
   31.25 +    uint32_t tbl;
   31.26 +    asm volatile("mftb %0" : "=r" (tbl));
   31.27 +    return tbl;
   31.28 +}
   31.29 +
   31.30 +static inline uint32_t get_tbu(void) 
   31.31 +{
   31.32 +	uint32_t tbl;
   31.33 +	asm volatile("mftbu %0" : "=r" (tbl));
   31.34 +	return tbl;
   31.35 +}
   31.36 +
   31.37 +static inline int64_t cpu_get_real_ticks(void)
   31.38 +{
   31.39 +    uint32_t l, h, h1;
   31.40 +    /* NOTE: we test if wrapping has occurred */
   31.41 +    do {
   31.42 +        h = get_tbu();
   31.43 +        l = get_tbl();
   31.44 +        h1 = get_tbu();
   31.45 +    } while (h != h1);
   31.46 +    return ((int64_t)h << 32) | l;
   31.47 +}
   31.48 +
   31.49 +#elif defined(__i386__)
   31.50 +
   31.51 +static inline int64_t cpu_get_real_ticks(void)
   31.52 +{
   31.53 +    int64_t val;
   31.54 +    asm volatile ("rdtsc" : "=A" (val));
   31.55 +    return val;
   31.56 +}
   31.57 +
   31.58 +#elif defined(__x86_64__)
   31.59 +
   31.60 +static inline int64_t cpu_get_real_ticks(void)
   31.61 +{
   31.62 +    uint32_t low,high;
   31.63 +    int64_t val;
   31.64 +    asm volatile("rdtsc" : "=a" (low), "=d" (high));
   31.65 +    val = high;
   31.66 +    val <<= 32;
   31.67 +    val |= low;
   31.68 +    return val;
   31.69 +}
   31.70 +
   31.71 +#elif defined(__ia64)
   31.72 +
   31.73 +static inline int64_t cpu_get_real_ticks(void)
   31.74 +{
   31.75 +	int64_t val;
   31.76 +	asm volatile ("mov %0 = ar.itc" : "=r"(val) :: "memory");
   31.77 +	return val;
   31.78 +}
   31.79 +
   31.80 +#elif defined(__s390__)
   31.81 +
   31.82 +static inline int64_t cpu_get_real_ticks(void)
   31.83 +{
   31.84 +    int64_t val;
   31.85 +    asm volatile("stck 0(%1)" : "=m" (val) : "a" (&val) : "cc");
   31.86 +    return val;
   31.87 +}
   31.88 +
   31.89 +#elif defined(__sparc_v9__)
   31.90 +
   31.91 +static inline int64_t cpu_get_real_ticks (void)
   31.92 +{
   31.93 +#if     defined(_LP64)
   31.94 +        uint64_t        rval;
   31.95 +        asm volatile("rd %%tick,%0" : "=r"(rval));
   31.96 +        return rval;
   31.97 +#else
   31.98 +        union {
   31.99 +                uint64_t i64;
  31.100 +                struct {
  31.101 +                        uint32_t high;
  31.102 +                        uint32_t low;
  31.103 +                }       i32;
  31.104 +        } rval;
  31.105 +        asm volatile("rd %%tick,%1; srlx %1,32,%0"
  31.106 +                : "=r"(rval.i32.high), "=r"(rval.i32.low));
  31.107 +        return rval.i64;
  31.108 +#endif
  31.109 +}
  31.110 +#endif
  31.111 +
  31.112  /* profiling */
  31.113  #ifdef CONFIG_PROFILER
  31.114  static inline int64_t profile_getclock(void)
  31.115  {
  31.116 -    int64_t val;
  31.117 -    asm volatile ("rdtsc" : "=A" (val));
  31.118 -    return val;
  31.119 +    return cpu_get_real_ticks();
  31.120  }
  31.121  
  31.122  extern int64_t kqemu_time, kqemu_time_start;
    32.1 --- a/tools/ioemu/cpu-defs.h	Mon Aug 07 18:11:59 2006 +0100
    32.2 +++ b/tools/ioemu/cpu-defs.h	Mon Aug 07 18:25:30 2006 +0100
    32.3 @@ -47,7 +47,7 @@ typedef uint32_t target_ulong;
    32.4  #elif TARGET_LONG_SIZE == 8
    32.5  typedef int64_t target_long;
    32.6  typedef uint64_t target_ulong;
    32.7 -#define TARGET_FMT_lx "%016llx"
    32.8 +#define TARGET_FMT_lx "%016" PRIx64
    32.9  #else
   32.10  #error TARGET_LONG_SIZE undefined
   32.11  #endif
    33.1 --- a/tools/ioemu/cpu-exec.c	Mon Aug 07 18:11:59 2006 +0100
    33.2 +++ b/tools/ioemu/cpu-exec.c	Mon Aug 07 18:25:30 2006 +0100
    33.3 @@ -47,7 +47,7 @@ void cpu_loop_exit(void)
    33.4      longjmp(env->jmp_env, 1);
    33.5  }
    33.6  #endif
    33.7 -#ifndef TARGET_SPARC
    33.8 +#if !(defined(TARGET_SPARC) || defined(TARGET_SH4))
    33.9  #define reg_T2
   33.10  #endif
   33.11  
   33.12 @@ -175,9 +175,13 @@ static inline TranslationBlock *tb_find_
   33.13      pc = env->regs[15];
   33.14  #elif defined(TARGET_SPARC)
   33.15  #ifdef TARGET_SPARC64
   33.16 -    flags = (env->pstate << 2) | ((env->lsu & (DMMU_E | IMMU_E)) >> 2);
   33.17 +    // Combined FPU enable bits . PRIV . DMMU enabled . IMMU enabled
   33.18 +    flags = (((env->pstate & PS_PEF) >> 1) | ((env->fprs & FPRS_FEF) << 2))
   33.19 +        | (env->pstate & PS_PRIV) | ((env->lsu & (DMMU_E | IMMU_E)) >> 2);
   33.20  #else
   33.21 -    flags = env->psrs | ((env->mmuregs[0] & (MMU_E | MMU_NF)) << 1);
   33.22 +    // FPU enable . MMU enabled . MMU no-fault . Supervisor
   33.23 +    flags = (env->psref << 3) | ((env->mmuregs[0] & (MMU_E | MMU_NF)) << 1)
   33.24 +        | env->psrs;
   33.25  #endif
   33.26      cs_base = env->npc;
   33.27      pc = env->pc;
   33.28 @@ -253,7 +257,7 @@ int cpu_exec(CPUState *env1)
   33.29      uint32_t *saved_regwptr;
   33.30  #endif
   33.31  #endif
   33.32 -#ifdef __sparc__
   33.33 +#if defined(__sparc__) && !defined(HOST_SOLARIS)
   33.34      int saved_i7, tmp_T0;
   33.35  #endif
   33.36      int ret, interrupt_request;
   33.37 @@ -323,7 +327,7 @@ int cpu_exec(CPUState *env1)
   33.38  #if defined(reg_T2)
   33.39      saved_T2 = T2;
   33.40  #endif
   33.41 -#ifdef __sparc__
   33.42 +#if defined(__sparc__) && !defined(HOST_SOLARIS)
   33.43      /* we also save i7 because longjmp may not restore it */
   33.44      asm volatile ("mov %%i7, %0" : "=r" (saved_i7));
   33.45  #endif
   33.46 @@ -447,7 +451,7 @@ int cpu_exec(CPUState *env1)
   33.47  
   33.48              T0 = 0; /* force lookup of first TB */
   33.49              for(;;) {
   33.50 -#ifdef __sparc__
   33.51 +#if defined(__sparc__) && !defined(HOST_SOLARIS)
   33.52                  /* g1 can be modified by some libc? functions */ 
   33.53                  tmp_T0 = T0;
   33.54  #endif	    
   33.55 @@ -467,7 +471,7 @@ int cpu_exec(CPUState *env1)
   33.56                          do_interrupt(intno, 0, 0, 0, 1);
   33.57                          /* ensure that no TB jump will be modified as
   33.58                             the program flow was changed */
   33.59 -#ifdef __sparc__
   33.60 +#if defined(__sparc__) && !defined(HOST_SOLARIS)
   33.61                          tmp_T0 = 0;
   33.62  #else
   33.63                          T0 = 0;
   33.64 @@ -486,7 +490,7 @@ int cpu_exec(CPUState *env1)
   33.65  			    env->error_code = 0;
   33.66                              do_interrupt(env);
   33.67                              env->interrupt_request &= ~CPU_INTERRUPT_HARD;
   33.68 -#ifdef __sparc__
   33.69 +#if defined(__sparc__) && !defined(HOST_SOLARIS)
   33.70                              tmp_T0 = 0;
   33.71  #else
   33.72                              T0 = 0;
   33.73 @@ -497,7 +501,7 @@ int cpu_exec(CPUState *env1)
   33.74                              env->error_code = 0;
   33.75                              do_interrupt(env);
   33.76                              env->interrupt_request &= ~CPU_INTERRUPT_TIMER;
   33.77 -#ifdef __sparc__
   33.78 +#if defined(__sparc__) && !defined(HOST_SOLARIS)
   33.79                              tmp_T0 = 0;
   33.80  #else
   33.81                              T0 = 0;
   33.82 @@ -516,7 +520,7 @@ int cpu_exec(CPUState *env1)
   33.83                          env->error_code = 0;
   33.84                          do_interrupt(env);
   33.85                          env->interrupt_request &= ~CPU_INTERRUPT_HARD;
   33.86 -#ifdef __sparc__
   33.87 +#if defined(__sparc__) && !defined(HOST_SOLARIS)
   33.88                          tmp_T0 = 0;
   33.89  #else
   33.90                          T0 = 0;
   33.91 @@ -534,7 +538,7 @@ int cpu_exec(CPUState *env1)
   33.92  			    env->interrupt_request &= ~CPU_INTERRUPT_HARD;
   33.93  			    do_interrupt(env->interrupt_index);
   33.94  			    env->interrupt_index = 0;
   33.95 -#ifdef __sparc__
   33.96 +#if defined(__sparc__) && !defined(HOST_SOLARIS)
   33.97                              tmp_T0 = 0;
   33.98  #else
   33.99                              T0 = 0;
  33.100 @@ -561,11 +565,13 @@ int cpu_exec(CPUState *env1)
  33.101  #elif defined(TARGET_SH4)
  33.102  		    /* XXXXX */
  33.103  #endif
  33.104 +                   /* Don't use the cached interupt_request value,
  33.105 +                      do_interrupt may have updated the EXITTB flag. */
  33.106                      if (env->interrupt_request & CPU_INTERRUPT_EXITTB) {
  33.107                          env->interrupt_request &= ~CPU_INTERRUPT_EXITTB;
  33.108                          /* ensure that no TB jump will be modified as
  33.109                             the program flow was changed */
  33.110 -#ifdef __sparc__
  33.111 +#if defined(__sparc__) && !defined(HOST_SOLARIS)
  33.112                          tmp_T0 = 0;
  33.113  #else
  33.114                          T0 = 0;
  33.115 @@ -633,7 +639,7 @@ int cpu_exec(CPUState *env1)
  33.116                              lookup_symbol(tb->pc));
  33.117                  }
  33.118  #endif
  33.119 -#ifdef __sparc__
  33.120 +#if defined(__sparc__) && !defined(HOST_SOLARIS)
  33.121                  T0 = tmp_T0;
  33.122  #endif	    
  33.123                  /* see if we can patch the calling TB. When the TB
  33.124 @@ -669,7 +675,9 @@ int cpu_exec(CPUState *env1)
  33.125                                       "mov	%%o7,%%i0"
  33.126                                       : /* no outputs */
  33.127                                       : "r" (gen_func) 
  33.128 -                                     : "i0", "i1", "i2", "i3", "i4", "i5");
  33.129 +                                     : "i0", "i1", "i2", "i3", "i4", "i5",
  33.130 +                                       "l0", "l1", "l2", "l3", "l4", "l5",
  33.131 +                                       "l6", "l7");
  33.132  #elif defined(__arm__)
  33.133                  asm volatile ("mov pc, %0\n\t"
  33.134                                ".global exec_loop\n\t"
  33.135 @@ -834,7 +842,7 @@ int cpu_exec(CPUState *env1)
  33.136  #else
  33.137  #error unsupported target CPU
  33.138  #endif
  33.139 -#ifdef __sparc__
  33.140 +#if defined(__sparc__) && !defined(HOST_SOLARIS)
  33.141      asm volatile ("mov %0, %%i7" : : "r" (saved_i7));
  33.142  #endif
  33.143      T0 = saved_T0;
  33.144 @@ -1168,19 +1176,14 @@ static inline int handle_cpu_signal(unsi
  33.145             a virtual CPU fault */
  33.146          cpu_restore_state(tb, env, pc, puc);
  33.147      }
  33.148 -    if (ret == 1) {
  33.149  #if 0
  33.150          printf("PF exception: NIP=0x%08x error=0x%x %p\n", 
  33.151                 env->nip, env->error_code, tb);
  33.152  #endif
  33.153      /* we restore the process signal mask as the sigreturn should
  33.154         do it (XXX: use sigsetjmp) */
  33.155 -        sigprocmask(SIG_SETMASK, old_set, NULL);
  33.156 -        //        do_raise_exception_err(env->exception_index, env->error_code);
  33.157 -    } else {
  33.158 -        /* activate soft MMU for this block */
  33.159 -        cpu_resume_from_signal(env, puc);
  33.160 -    }
  33.161 +    sigprocmask(SIG_SETMASK, old_set, NULL);
  33.162 +    cpu_loop_exit();
  33.163      /* never comes here */
  33.164      return 1;
  33.165  }
    34.1 --- a/tools/ioemu/disas.c	Mon Aug 07 18:11:59 2006 +0100
    34.2 +++ b/tools/ioemu/disas.c	Mon Aug 07 18:25:30 2006 +0100
    34.3 @@ -58,7 +58,7 @@ perror_memory (status, memaddr, info)
    34.4      /* Actually, address between memaddr and memaddr + len was
    34.5         out of bounds.  */
    34.6      (*info->fprintf_func) (info->stream,
    34.7 -			   "Address 0x%llx is out of bounds.\n", memaddr);
    34.8 +			   "Address 0x%" PRIx64 " is out of bounds.\n", memaddr);
    34.9  }
   34.10  
   34.11  /* This could be in a separate file, to save miniscule amounts of space
   34.12 @@ -73,7 +73,7 @@ generic_print_address (addr, info)
   34.13       bfd_vma addr;
   34.14       struct disassemble_info *info;
   34.15  {
   34.16 -    (*info->fprintf_func) (info->stream, "0x%llx", addr);
   34.17 +    (*info->fprintf_func) (info->stream, "0x%" PRIx64, addr);
   34.18  }
   34.19  
   34.20  /* Just return the given address.  */
    35.1 --- a/tools/ioemu/dyngen-exec.h	Mon Aug 07 18:11:59 2006 +0100
    35.2 +++ b/tools/ioemu/dyngen-exec.h	Mon Aug 07 18:25:30 2006 +0100
    35.3 @@ -35,12 +35,15 @@
    35.4  typedef unsigned char uint8_t;
    35.5  typedef unsigned short uint16_t;
    35.6  typedef unsigned int uint32_t;
    35.7 +// Linux/Sparc64 defines uint64_t
    35.8 +#if !(defined (__sparc_v9__) && defined(__linux__))
    35.9  /* XXX may be done for all 64 bits targets ? */
   35.10  #if defined (__x86_64__) || defined(__ia64)
   35.11  typedef unsigned long uint64_t;
   35.12  #else
   35.13  typedef unsigned long long uint64_t;
   35.14  #endif
   35.15 +#endif
   35.16  
   35.17  /* if Solaris/__sun__, don't typedef int8_t, as it will be typedef'd
   35.18     prior to this and will cause an error in compliation, conflicting
   35.19 @@ -50,11 +53,14 @@ typedef signed char int8_t;
   35.20  #endif
   35.21  typedef signed short int16_t;
   35.22  typedef signed int int32_t;
   35.23 +// Linux/Sparc64 defines int64_t
   35.24 +#if !(defined (__sparc_v9__) && defined(__linux__))
   35.25  #if defined (__x86_64__) || defined(__ia64)
   35.26  typedef signed long int64_t;
   35.27  #else
   35.28  typedef signed long long int64_t;
   35.29  #endif
   35.30 +#endif
   35.31  
   35.32  #define INT8_MIN		(-128)
   35.33  #define INT16_MIN		(-32767-1)
   35.34 @@ -121,6 +127,19 @@ extern int printf(const char *, ...);
   35.35  #define AREG3 "s2"
   35.36  #endif
   35.37  #ifdef __sparc__
   35.38 +#ifdef HOST_SOLARIS
   35.39 +#define AREG0 "g2"
   35.40 +#define AREG1 "g3"
   35.41 +#define AREG2 "g4"
   35.42 +#define AREG3 "g5"
   35.43 +#define AREG4 "g6"
   35.44 +#else
   35.45 +#ifdef __sparc_v9__
   35.46 +#define AREG0 "g1"
   35.47 +#define AREG1 "g4"
   35.48 +#define AREG2 "g5"
   35.49 +#define AREG3 "g7"
   35.50 +#else
   35.51  #define AREG0 "g6"
   35.52  #define AREG1 "g1"
   35.53  #define AREG2 "g2"
   35.54 @@ -133,6 +152,8 @@ extern int printf(const char *, ...);
   35.55  #define AREG9 "l5"
   35.56  #define AREG10 "l6"
   35.57  #define AREG11 "l7"
   35.58 +#endif
   35.59 +#endif
   35.60  #define USE_FP_CONVERT
   35.61  #endif
   35.62  #ifdef __s390__
   35.63 @@ -241,10 +262,8 @@ extern int __op_jmp0, __op_jmp1, __op_jm
   35.64  					  ASM_NAME(__op_gen_label) #n)
   35.65  #endif
   35.66  #ifdef __sparc__
   35.67 -#define EXIT_TB() asm volatile ("jmpl %i0 + 8, %g0\n" \
   35.68 -                                "nop")
   35.69 -#define        GOTO_LABEL_PARAM(n) asm volatile ( \
   35.70 -               "set " ASM_NAME(__op_gen_label) #n ", %g1; jmp %g1; nop")
   35.71 +#define EXIT_TB() asm volatile ("jmpl %i0 + 8, %g0; nop")
   35.72 +#define GOTO_LABEL_PARAM(n) asm volatile ("ba " ASM_NAME(__op_gen_label) #n ";nop")
   35.73  #endif
   35.74  #ifdef __arm__
   35.75  #define EXIT_TB() asm volatile ("b exec_loop")
    36.1 --- a/tools/ioemu/dyngen.c	Mon Aug 07 18:11:59 2006 +0100
    36.2 +++ b/tools/ioemu/dyngen.c	Mon Aug 07 18:25:30 2006 +0100
    36.3 @@ -1196,7 +1196,7 @@ void get_reloc_expr(char *name, int name
    36.4      } else {
    36.5  #ifdef HOST_SPARC
    36.6          if (sym_name[0] == '.')
    36.7 -            snprintf(name, sizeof(name),
    36.8 +            snprintf(name, name_size,
    36.9                       "(long)(&__dot_%s)",
   36.10                       sym_name + 1);
   36.11          else
   36.12 @@ -1440,6 +1440,15 @@ void gen_code(const char *name, host_ulo
   36.13      }
   36.14  #elif defined(HOST_SPARC)
   36.15      {
   36.16 +#define INSN_SAVE       0x9de3a000
   36.17 +#define INSN_RET        0x81c7e008
   36.18 +#define INSN_RETL       0x81c3e008
   36.19 +#define INSN_RESTORE    0x81e80000
   36.20 +#define INSN_RETURN     0x81cfe008
   36.21 +#define INSN_NOP        0x01000000
   36.22 +#define INSN_ADD_SP     0x9c03a000 // add %sp, nn, %sp
   36.23 +#define INSN_SUB_SP     0x9c23a000 // sub %sp, nn, %sp
   36.24 +
   36.25          uint32_t start_insn, end_insn1, end_insn2;
   36.26          uint8_t *p;
   36.27          p = (void *)(p_end - 8);
   36.28 @@ -1448,13 +1457,21 @@ void gen_code(const char *name, host_ulo
   36.29          start_insn = get32((uint32_t *)(p_start + 0x0));
   36.30          end_insn1 = get32((uint32_t *)(p + 0x0));
   36.31          end_insn2 = get32((uint32_t *)(p + 0x4));
   36.32 -        if ((start_insn & ~0x1fff) == 0x9de3a000) {
   36.33 +        if (((start_insn & ~0x1fff) == INSN_SAVE) ||
   36.34 +            (start_insn & ~0x1fff) == INSN_ADD_SP) {
   36.35              p_start += 0x4;
   36.36              start_offset += 0x4;
   36.37 -            if ((int)(start_insn | ~0x1fff) < -128)
   36.38 -                error("Found bogus save at the start of %s", name);
   36.39 -            if (end_insn1 != 0x81c7e008 || end_insn2 != 0x81e80000)
   36.40 +            if (end_insn1 == INSN_RET && end_insn2 == INSN_RESTORE)
   36.41 +                /* SPARC v7: ret; restore; */ ;
   36.42 +            else if (end_insn1 == INSN_RETURN && end_insn2 == INSN_NOP)
   36.43 +                /* SPARC v9: return; nop; */ ;
   36.44 +            else if (end_insn1 == INSN_RETL && (end_insn2 & ~0x1fff) == INSN_SUB_SP)
   36.45 +                /* SPARC v7: retl; sub %sp, nn, %sp; */ ;
   36.46 +            else
   36.47 +
   36.48                  error("ret; restore; not found at end of %s", name);
   36.49 +        } else if (end_insn1 == INSN_RETL && end_insn2 == INSN_NOP) {
   36.50 +            ;
   36.51          } else {
   36.52              error("No save at the beginning of %s", name);
   36.53          }
   36.54 @@ -1462,7 +1479,7 @@ void gen_code(const char *name, host_ulo
   36.55          /* Skip a preceeding nop, if present.  */
   36.56          if (p > p_start) {
   36.57              skip_insn = get32((uint32_t *)(p - 0x4));
   36.58 -            if (skip_insn == 0x01000000)
   36.59 +            if (skip_insn == INSN_NOP)
   36.60                  p -= 4;
   36.61          }
   36.62  #endif
   36.63 @@ -1470,21 +1487,41 @@ void gen_code(const char *name, host_ulo
   36.64      }
   36.65  #elif defined(HOST_SPARC64)
   36.66      {
   36.67 +#define INSN_SAVE       0x9de3a000
   36.68 +#define INSN_RET        0x81c7e008
   36.69 +#define INSN_RETL       0x81c3e008
   36.70 +#define INSN_RESTORE    0x81e80000
   36.71 +#define INSN_RETURN     0x81cfe008
   36.72 +#define INSN_NOP        0x01000000
   36.73 +#define INSN_ADD_SP     0x9c03a000 // add %sp, nn, %sp
   36.74 +#define INSN_SUB_SP     0x9c23a000 // sub %sp, nn, %sp
   36.75 +
   36.76          uint32_t start_insn, end_insn1, end_insn2, skip_insn;
   36.77          uint8_t *p;
   36.78          p = (void *)(p_end - 8);
   36.79 +#if 0
   36.80 +        /* XXX: check why it occurs */
   36.81          if (p <= p_start)
   36.82              error("empty code for %s", name);
   36.83 +#endif
   36.84          start_insn = get32((uint32_t *)(p_start + 0x0));
   36.85          end_insn1 = get32((uint32_t *)(p + 0x0));
   36.86          end_insn2 = get32((uint32_t *)(p + 0x4));
   36.87 -        if ((start_insn & ~0x1fff) == 0x9de3a000) {
   36.88 +        if (((start_insn & ~0x1fff) == INSN_SAVE) ||
   36.89 +            (start_insn & ~0x1fff) == INSN_ADD_SP) {
   36.90              p_start += 0x4;
   36.91              start_offset += 0x4;
   36.92 -            if ((int)(start_insn | ~0x1fff) < -256)
   36.93 -                error("Found bogus save at the start of %s", name);
   36.94 -            if (end_insn1 != 0x81c7e008 || end_insn2 != 0x81e80000)
   36.95 +            if (end_insn1 == INSN_RET && end_insn2 == INSN_RESTORE)
   36.96 +                /* SPARC v7: ret; restore; */ ;
   36.97 +            else if (end_insn1 == INSN_RETURN && end_insn2 == INSN_NOP)
   36.98 +                /* SPARC v9: return; nop; */ ;
   36.99 +            else if (end_insn1 == INSN_RETL && (end_insn2 & ~0x1fff) == INSN_SUB_SP)
  36.100 +                /* SPARC v7: retl; sub %sp, nn, %sp; */ ;
  36.101 +            else
  36.102 +
  36.103                  error("ret; restore; not found at end of %s", name);
  36.104 +        } else if (end_insn1 == INSN_RETL && end_insn2 == INSN_NOP) {
  36.105 +            ;
  36.106          } else {
  36.107              error("No save at the beginning of %s", name);
  36.108          }
  36.109 @@ -2151,6 +2188,18 @@ void gen_code(const char *name, host_ulo
  36.110  				    reloc_offset, reloc_offset, name, addend,
  36.111  				    reloc_offset);
  36.112  			    break;
  36.113 +                        case R_SPARC_WDISP22:
  36.114 +                            fprintf(outfile,
  36.115 +                                    "    *(uint32_t *)(gen_code_ptr + %d) = "
  36.116 +                                    "((*(uint32_t *)(gen_code_ptr + %d)) "
  36.117 +                                    " & ~0x3fffff) "
  36.118 +                                    " | ((((%s + %d) - (long)(gen_code_ptr + %d))>>2) "
  36.119 +                                    "    & 0x3fffff);\n",
  36.120 +                                    rel->r_offset - start_offset,
  36.121 +                                    rel->r_offset - start_offset,
  36.122 +                                    name, addend,
  36.123 +                                    rel->r_offset - start_offset);
  36.124 +                            break;
  36.125                          default:
  36.126                              error("unsupported sparc relocation (%d)", type);
  36.127                          }
  36.128 @@ -2168,7 +2217,7 @@ void gen_code(const char *name, host_ulo
  36.129  			rel->r_offset < start_offset + copy_size) {
  36.130                          sym_name = strtab + symtab[ELF64_R_SYM(rel->r_info)].st_name;
  36.131                          get_reloc_expr(name, sizeof(name), sym_name);
  36.132 -                        type = ELF64_R_TYPE(rel->r_info);
  36.133 +                        type = ELF32_R_TYPE(rel->r_info);
  36.134                          addend = rel->r_addend;
  36.135                          reloc_offset = rel->r_offset - start_offset;
  36.136                          switch(type) {
  36.137 @@ -2192,6 +2241,15 @@ void gen_code(const char *name, host_ulo
  36.138  				    " | ((%s + %d) & 0x3ff);\n",
  36.139                                      reloc_offset, reloc_offset, name, addend);
  36.140  			    break;
  36.141 +                        case R_SPARC_OLO10:
  36.142 +                            addend += ELF64_R_TYPE_DATA (rel->r_info);
  36.143 +                            fprintf(outfile,
  36.144 +				    "    *(uint32_t *)(gen_code_ptr + %d) = "
  36.145 +				    "((*(uint32_t *)(gen_code_ptr + %d)) "
  36.146 +				    " & ~0x3ff) "
  36.147 +				    " | ((%s + %d) & 0x3ff);\n",
  36.148 +                                    reloc_offset, reloc_offset, name, addend);
  36.149 +			    break;
  36.150  			case R_SPARC_WDISP30:
  36.151  			    fprintf(outfile,
  36.152  				    "    *(uint32_t *)(gen_code_ptr + %d) = "
  36.153 @@ -2202,8 +2260,18 @@ void gen_code(const char *name, host_ulo
  36.154  				    reloc_offset, reloc_offset, name, addend,
  36.155  				    reloc_offset);
  36.156  			    break;
  36.157 +                        case R_SPARC_WDISP22:
  36.158 +                            fprintf(outfile,
  36.159 +                                    "    *(uint32_t *)(gen_code_ptr + %d) = "
  36.160 +                                    "((*(uint32_t *)(gen_code_ptr + %d)) "
  36.161 +                                    " & ~0x3fffff) "
  36.162 +                                    " | ((((%s + %d) - (long)(gen_code_ptr + %d))>>2) "
  36.163 +                                    "    & 0x3fffff);\n",
  36.164 +                                    reloc_offset, reloc_offset, name, addend,
  36.165 +				    reloc_offset);
  36.166 +                            break;
  36.167                          default:
  36.168 -			    error("unsupported sparc64 relocation (%d)", type);
  36.169 +			    error("unsupported sparc64 relocation (%d) for symbol %s", type, name);
  36.170                          }
  36.171                      }
  36.172                  }
    37.1 --- a/tools/ioemu/dyngen.h	Mon Aug 07 18:11:59 2006 +0100
    37.2 +++ b/tools/ioemu/dyngen.h	Mon Aug 07 18:25:30 2006 +0100
    37.3 @@ -19,7 +19,13 @@
    37.4   */
    37.5  
    37.6  int __op_param1, __op_param2, __op_param3;
    37.7 -int __op_gen_label1, __op_gen_label2, __op_gen_label3;
    37.8 +#ifdef __sparc__
    37.9 +  void __op_gen_label1(){}
   37.10 +  void __op_gen_label2(){}
   37.11 +  void __op_gen_label3(){}
   37.12 +#else
   37.13 +  int __op_gen_label1, __op_gen_label2, __op_gen_label3;
   37.14 +#endif
   37.15  int __op_jmp0, __op_jmp1, __op_jmp2, __op_jmp3;
   37.16  
   37.17  #ifdef __i386__
    38.1 --- a/tools/ioemu/elf.h	Mon Aug 07 18:11:59 2006 +0100
    38.2 +++ b/tools/ioemu/elf.h	Mon Aug 07 18:25:30 2006 +0100
    38.3 @@ -227,6 +227,7 @@ typedef struct {
    38.4  
    38.5  #define ELF64_R_SYM(i)			((i) >> 32)
    38.6  #define ELF64_R_TYPE(i)			((i) & 0xffffffff)
    38.7 +#define ELF64_R_TYPE_DATA(i)            (((ELF64_R_TYPE(i) >> 8) ^ 0x00800000) - 0x00800000)
    38.8  
    38.9  #define R_386_NONE	0
   38.10  #define R_386_32	1
   38.11 @@ -326,6 +327,7 @@ typedef struct {
   38.12  #define R_SPARC_10		30
   38.13  #define R_SPARC_11		31
   38.14  #define R_SPARC_64		32
   38.15 +#define R_SPARC_OLO10           33
   38.16  #define R_SPARC_WDISP16		40
   38.17  #define R_SPARC_WDISP19		41
   38.18  #define R_SPARC_7		43
    39.1 --- a/tools/ioemu/exec-all.h	Mon Aug 07 18:11:59 2006 +0100
    39.2 +++ b/tools/ioemu/exec-all.h	Mon Aug 07 18:25:30 2006 +0100
    39.3 @@ -571,7 +571,7 @@ static inline target_ulong get_phys_addr
    39.4          ldub_code(addr);
    39.5      }
    39.6      pd = env->tlb_table[is_user][index].addr_code & ~TARGET_PAGE_MASK;
    39.7 -    if (pd > IO_MEM_ROM) {
    39.8 +    if (pd > IO_MEM_ROM && !(pd & IO_MEM_ROMD)) {
    39.9          cpu_abort(env, "Trying to execute code outside RAM or ROM at 0x%08lx\n", addr);
   39.10      }
   39.11      return addr + env->tlb_table[is_user][index].addend - (unsigned long)phys_ram_base;
    40.1 --- a/tools/ioemu/exec.c	Mon Aug 07 18:11:59 2006 +0100
    40.2 +++ b/tools/ioemu/exec.c	Mon Aug 07 18:25:30 2006 +0100
    40.3 @@ -1488,7 +1488,7 @@ int tlb_set_page_exec(CPUState *env, tar
    40.4      if (is_softmmu) 
    40.5  #endif
    40.6      {
    40.7 -        if ((pd & ~TARGET_PAGE_MASK) > IO_MEM_ROM) {
    40.8 +        if ((pd & ~TARGET_PAGE_MASK) > IO_MEM_ROM && !(pd & IO_MEM_ROMD)) {
    40.9              /* IO memory case */
   40.10              address = vaddr | pd;
   40.11              addend = paddr;
   40.12 @@ -1513,9 +1513,11 @@ int tlb_set_page_exec(CPUState *env, tar
   40.13              te->addr_code = -1;
   40.14          }
   40.15          if (prot & PAGE_WRITE) {
   40.16 -            if ((pd & ~TARGET_PAGE_MASK) == IO_MEM_ROM) {
   40.17 -                /* ROM: access is ignored (same as unassigned) */
   40.18 -                te->addr_write = vaddr | IO_MEM_ROM;
   40.19 +            if ((pd & ~TARGET_PAGE_MASK) == IO_MEM_ROM || 
   40.20 +                (pd & IO_MEM_ROMD)) {
   40.21 +                /* write access calls the I/O callback */
   40.22 +                te->addr_write = vaddr | 
   40.23 +                    (pd & ~(TARGET_PAGE_MASK | IO_MEM_ROMD));
   40.24              } else if ((pd & ~TARGET_PAGE_MASK) == IO_MEM_RAM && 
   40.25                         !cpu_physical_memory_is_dirty(pd)) {
   40.26                  te->addr_write = vaddr | IO_MEM_NOTDIRTY;
   40.27 @@ -1779,15 +1781,24 @@ void cpu_register_physical_memory(target
   40.28  {
   40.29      target_phys_addr_t addr, end_addr;
   40.30      PhysPageDesc *p;
   40.31 +    CPUState *env;
   40.32  
   40.33      size = (size + TARGET_PAGE_SIZE - 1) & TARGET_PAGE_MASK;
   40.34      end_addr = start_addr + size;
   40.35      for(addr = start_addr; addr != end_addr; addr += TARGET_PAGE_SIZE) {
   40.36          p = phys_page_find_alloc(addr >> TARGET_PAGE_BITS, 1);
   40.37          p->phys_offset = phys_offset;
   40.38 -        if ((phys_offset & ~TARGET_PAGE_MASK) <= IO_MEM_ROM)
   40.39 +        if ((phys_offset & ~TARGET_PAGE_MASK) <= IO_MEM_ROM ||
   40.40 +            (phys_offset & IO_MEM_ROMD))
   40.41              phys_offset += TARGET_PAGE_SIZE;
   40.42      }
   40.43 +    
   40.44 +    /* since each CPU stores ram addresses in its TLB cache, we must
   40.45 +       reset the modified entries */
   40.46 +    /* XXX: slow ! */
   40.47 +    for(env = first_cpu; env != NULL; env = env->next_cpu) {
   40.48 +        tlb_flush(env, 1);
   40.49 +    }
   40.50  }
   40.51  
   40.52  static uint32_t unassigned_mem_readb(void *opaque, target_phys_addr_t addr)
   40.53 @@ -2048,7 +2059,8 @@ void cpu_physical_memory_rw(target_phys_
   40.54                  }
   40.55              }
   40.56          } else {
   40.57 -            if ((pd & ~TARGET_PAGE_MASK) > IO_MEM_ROM) {
   40.58 +            if ((pd & ~TARGET_PAGE_MASK) > IO_MEM_ROM && 
   40.59 +                !(pd & IO_MEM_ROMD)) {
   40.60                  /* I/O case */
   40.61                  io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
   40.62                  if (l >= 4 && ((addr & 3) == 0)) {
   40.63 @@ -2103,7 +2115,8 @@ void cpu_physical_memory_write_rom(targe
   40.64          }
   40.65          
   40.66          if ((pd & ~TARGET_PAGE_MASK) != IO_MEM_RAM &&
   40.67 -            (pd & ~TARGET_PAGE_MASK) != IO_MEM_ROM) {
   40.68 +            (pd & ~TARGET_PAGE_MASK) != IO_MEM_ROM &&
   40.69 +            !(pd & IO_MEM_ROMD)) {
   40.70              /* do nothing */
   40.71          } else {
   40.72              unsigned long addr1;
   40.73 @@ -2135,7 +2148,8 @@ uint32_t ldl_phys(target_phys_addr_t add
   40.74          pd = p->phys_offset;
   40.75      }
   40.76          
   40.77 -    if ((pd & ~TARGET_PAGE_MASK) > IO_MEM_ROM) {
   40.78 +    if ((pd & ~TARGET_PAGE_MASK) > IO_MEM_ROM && 
   40.79 +        !(pd & IO_MEM_ROMD)) {
   40.80          /* I/O case */
   40.81          io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
   40.82          val = io_mem_read[io_index][2](io_mem_opaque[io_index], addr);
   40.83 @@ -2164,7 +2178,8 @@ uint64_t ldq_phys(target_phys_addr_t add
   40.84          pd = p->phys_offset;
   40.85      }
   40.86          
   40.87 -    if ((pd & ~TARGET_PAGE_MASK) > IO_MEM_ROM) {
   40.88 +    if ((pd & ~TARGET_PAGE_MASK) > IO_MEM_ROM &&
   40.89 +        !(pd & IO_MEM_ROMD)) {
   40.90          /* I/O case */
   40.91          io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
   40.92  #ifdef TARGET_WORDS_BIGENDIAN
    41.1 --- a/tools/ioemu/fpu/softfloat-native.c	Mon Aug 07 18:11:59 2006 +0100
    41.2 +++ b/tools/ioemu/fpu/softfloat-native.c	Mon Aug 07 18:25:30 2006 +0100
    41.3 @@ -6,7 +6,7 @@
    41.4  void set_float_rounding_mode(int val STATUS_PARAM)
    41.5  {
    41.6      STATUS(float_rounding_mode) = val;
    41.7 -#if defined(_BSD) && !defined(__APPLE__)
    41.8 +#if defined(_BSD) && !defined(__APPLE__) || (defined(HOST_SOLARIS) && HOST_SOLARIS < 10)
    41.9      fpsetround(val);
   41.10  #elif defined(__arm__)
   41.11      /* nothing to do */
   41.12 @@ -22,9 +22,14 @@ void set_floatx80_rounding_precision(int
   41.13  }
   41.14  #endif
   41.15  
   41.16 -#if defined(_BSD)
   41.17 -#define lrint(d)		((long)rint(d))
   41.18 -#define llrint(d)		((long long)rint(d))
   41.19 +#if defined(_BSD) || (defined(HOST_SOLARIS) && HOST_SOLARIS < 10)
   41.20 +#define lrint(d)		((int32_t)rint(d))
   41.21 +#define llrint(d)		((int64_t)rint(d))
   41.22 +#define lrintf(f)		((int32_t)rint(f))
   41.23 +#define llrintf(f)		((int64_t)rint(f))
   41.24 +#define sqrtf(f)		((float)sqrt(f))
   41.25 +#define remainderf(fa, fb)	((float)remainder(fa, fb))
   41.26 +#define rintf(f)		((float)rint(f))
   41.27  #endif
   41.28  
   41.29  #if defined(__powerpc__)
    42.1 --- a/tools/ioemu/gdbstub.c	Mon Aug 07 18:11:59 2006 +0100
    42.2 +++ b/tools/ioemu/gdbstub.c	Mon Aug 07 18:25:30 2006 +0100
    42.3 @@ -17,6 +17,7 @@
    42.4   * License along with this library; if not, write to the Free Software
    42.5   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    42.6   */
    42.7 +#include "config.h"
    42.8  #ifdef CONFIG_USER_ONLY
    42.9  #include <stdlib.h>
   42.10  #include <stdio.h>
   42.11 @@ -24,16 +25,25 @@
   42.12  #include <string.h>
   42.13  #include <errno.h>
   42.14  #include <unistd.h>
   42.15 +#include <fcntl.h>
   42.16  
   42.17  #include "qemu.h"
   42.18  #else
   42.19  #include "vl.h"
   42.20  #endif
   42.21  
   42.22 -#include <sys/socket.h>
   42.23 -#include <netinet/in.h>
   42.24 -#include <netinet/tcp.h>
   42.25 +#include "qemu_socket.h"
   42.26 +#ifdef _WIN32
   42.27 +/* XXX: these constants may be independent of the host ones even for Unix */
   42.28 +#ifndef SIGTRAP
   42.29 +#define SIGTRAP 5
   42.30 +#endif
   42.31 +#ifndef SIGINT
   42.32 +#define SIGINT 2
   42.33 +#endif
   42.34 +#else
   42.35  #include <signal.h>
   42.36 +#endif
   42.37  
   42.38  //#define DEBUG_GDB
   42.39  
   42.40 @@ -69,7 +79,7 @@ static int get_char(GDBState *s)
   42.41      int ret;
   42.42  
   42.43      for(;;) {
   42.44 -        ret = read(s->fd, &ch, 1);
   42.45 +        ret = recv(s->fd, &ch, 1, 0);
   42.46          if (ret < 0) {
   42.47              if (errno != EINTR && errno != EAGAIN)
   42.48                  return -1;
   42.49 @@ -87,7 +97,7 @@ static void put_buffer(GDBState *s, cons
   42.50      int ret;
   42.51  
   42.52      while (len > 0) {
   42.53 -        ret = write(s->fd, buf, len);
   42.54 +        ret = send(s->fd, buf, len, 0);
   42.55          if (ret < 0) {
   42.56              if (errno != EINTR && errno != EAGAIN)
   42.57                  return;
   42.58 @@ -305,11 +315,11 @@ static int cpu_gdb_read_registers(CPUSta
   42.59      for(i = 0; i < 24; i++) {
   42.60          registers[i + 8] = tswapl(env->regwptr[i]);
   42.61      }
   42.62 +#ifndef TARGET_SPARC64
   42.63      /* fill in fprs */
   42.64      for (i = 0; i < 32; i++) {
   42.65          registers[i + 32] = tswapl(*((uint32_t *)&env->fpr[i]));
   42.66      }
   42.67 -#ifndef TARGET_SPARC64
   42.68      /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */
   42.69      registers[64] = tswapl(env->y);
   42.70      {
   42.71 @@ -327,16 +337,21 @@ static int cpu_gdb_read_registers(CPUSta
   42.72      registers[72] = 0;
   42.73      return 73 * sizeof(target_ulong);
   42.74  #else
   42.75 -    for (i = 0; i < 32; i += 2) {
   42.76 -        registers[i/2 + 64] = tswapl(*((uint64_t *)&env->fpr[i]));
   42.77 +    /* fill in fprs */
   42.78 +    for (i = 0; i < 64; i += 2) {
   42.79 +	uint64_t tmp;
   42.80 +
   42.81 +        tmp = (uint64_t)tswap32(*((uint32_t *)&env->fpr[i])) << 32;
   42.82 +        tmp |= tswap32(*((uint32_t *)&env->fpr[i + 1]));
   42.83 +        registers[i/2 + 32] = tmp;
   42.84      }
   42.85 -    registers[81] = tswapl(env->pc);
   42.86 -    registers[82] = tswapl(env->npc);
   42.87 -    registers[83] = tswapl(env->tstate[env->tl]);
   42.88 -    registers[84] = tswapl(env->fsr);
   42.89 -    registers[85] = tswapl(env->fprs);
   42.90 -    registers[86] = tswapl(env->y);
   42.91 -    return 87 * sizeof(target_ulong);
   42.92 +    registers[64] = tswapl(env->pc);
   42.93 +    registers[65] = tswapl(env->npc);
   42.94 +    registers[66] = tswapl(env->tstate[env->tl]);
   42.95 +    registers[67] = tswapl(env->fsr);
   42.96 +    registers[68] = tswapl(env->fprs);
   42.97 +    registers[69] = tswapl(env->y);
   42.98 +    return 70 * sizeof(target_ulong);
   42.99  #endif
  42.100  }
  42.101  
  42.102 @@ -353,11 +368,11 @@ static void cpu_gdb_write_registers(CPUS
  42.103      for(i = 0; i < 24; i++) {
  42.104          env->regwptr[i] = tswapl(registers[i + 8]);
  42.105      }
  42.106 +#ifndef TARGET_SPARC64
  42.107      /* fill in fprs */
  42.108      for (i = 0; i < 32; i++) {
  42.109          *((uint32_t *)&env->fpr[i]) = tswapl(registers[i + 32]);
  42.110      }
  42.111 -#ifndef TARGET_SPARC64
  42.112      /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */
  42.113      env->y = tswapl(registers[64]);
  42.114      PUT_PSR(env, tswapl(registers[65]));
  42.115 @@ -367,18 +382,16 @@ static void cpu_gdb_write_registers(CPUS
  42.116      env->npc = tswapl(registers[69]);
  42.117      env->fsr = tswapl(registers[70]);
  42.118  #else
  42.119 -    for (i = 0; i < 32; i += 2) {
  42.120 -	uint64_t tmp;
  42.121 -	tmp = tswapl(registers[i/2 + 64]) << 32;
  42.122 -	tmp |= tswapl(registers[i/2 + 64 + 1]);
  42.123 -        *((uint64_t *)&env->fpr[i]) = tmp;
  42.124 +    for (i = 0; i < 64; i += 2) {
  42.125 +	*((uint32_t *)&env->fpr[i]) = tswap32(registers[i/2 + 32] >> 32);
  42.126 +	*((uint32_t *)&env->fpr[i + 1]) = tswap32(registers[i/2 + 32] & 0xffffffff);
  42.127      }
  42.128 -    env->pc = tswapl(registers[81]);
  42.129 -    env->npc = tswapl(registers[82]);
  42.130 -    env->tstate[env->tl] = tswapl(registers[83]);
  42.131 -    env->fsr = tswapl(registers[84]);
  42.132 -    env->fprs = tswapl(registers[85]);
  42.133 -    env->y = tswapl(registers[86]);
  42.134 +    env->pc = tswapl(registers[64]);
  42.135 +    env->npc = tswapl(registers[65]);
  42.136 +    env->tstate[env->tl] = tswapl(registers[66]);
  42.137 +    env->fsr = tswapl(registers[67]);
  42.138 +    env->fprs = tswapl(registers[68]);
  42.139 +    env->y = tswapl(registers[69]);
  42.140  #endif
  42.141  }
  42.142  #elif defined (TARGET_ARM)
  42.143 @@ -494,7 +507,12 @@ static int cpu_gdb_read_registers(CPUSta
  42.144    int i;
  42.145  
  42.146  #define SAVE(x) *ptr++=tswapl(x)
  42.147 -  for (i = 0; i < 16; i++) SAVE(env->gregs[i]);
  42.148 +  if ((env->sr & (SR_MD | SR_RB)) == (SR_MD | SR_RB)) {
  42.149 +      for (i = 0; i < 8; i++) SAVE(env->gregs[i + 16]);
  42.150 +  } else {
  42.151 +      for (i = 0; i < 8; i++) SAVE(env->gregs[i]);
  42.152 +  }
  42.153 +  for (i = 8; i < 16; i++) SAVE(env->gregs[i]);
  42.154    SAVE (env->pc);
  42.155    SAVE (env->pr);
  42.156    SAVE (env->gbr);
  42.157 @@ -517,7 +535,12 @@ static void cpu_gdb_write_registers(CPUS
  42.158    int i;
  42.159  
  42.160  #define LOAD(x) (x)=*ptr++;
  42.161 -  for (i = 0; i < 16; i++) LOAD(env->gregs[i]);
  42.162 +  if ((env->sr & (SR_MD | SR_RB)) == (SR_MD | SR_RB)) {
  42.163 +      for (i = 0; i < 8; i++) LOAD(env->gregs[i + 16]);
  42.164 +  } else {
  42.165 +      for (i = 0; i < 8; i++) LOAD(env->gregs[i]);
  42.166 +  }
  42.167 +  for (i = 8; i < 16; i++) LOAD(env->gregs[i]);
  42.168    LOAD (env->pc);
  42.169    LOAD (env->pr);
  42.170    LOAD (env->gbr);
  42.171 @@ -545,7 +568,7 @@ static int gdb_handle_packet(GDBState *s
  42.172      char buf[4096];
  42.173      uint8_t mem_buf[2000];
  42.174      uint32_t *registers;
  42.175 -    uint32_t addr, len;
  42.176 +    target_ulong addr, len;
  42.177      
  42.178  #ifdef DEBUG_GDB
  42.179      printf("command='%s'\n", line_buf);
  42.180 @@ -560,7 +583,7 @@ static int gdb_handle_packet(GDBState *s
  42.181          break;
  42.182      case 'c':
  42.183          if (*p != '\0') {
  42.184 -            addr = strtoul(p, (char **)&p, 16);
  42.185 +            addr = strtoull(p, (char **)&p, 16);
  42.186  #if defined(TARGET_I386)
  42.187              env->eip = addr;
  42.188  #elif defined (TARGET_PPC)
  42.189 @@ -616,10 +639,10 @@ static int gdb_handle_packet(GDBState *s
  42.190          put_packet(s, "OK");
  42.191          break;
  42.192      case 'm':
  42.193 -        addr = strtoul(p, (char **)&p, 16);
  42.194 +        addr = strtoull(p, (char **)&p, 16);
  42.195          if (*p == ',')
  42.196              p++;
  42.197 -        len = strtoul(p, NULL, 16);
  42.198 +        len = strtoull(p, NULL, 16);
  42.199          if (cpu_memory_rw_debug(env, addr, mem_buf, len, 0) != 0) {
  42.200              put_packet (s, "E14");
  42.201          } else {
  42.202 @@ -628,10 +651,10 @@ static int gdb_handle_packet(GDBState *s
  42.203          }
  42.204          break;
  42.205      case 'M':
  42.206 -        addr = strtoul(p, (char **)&p, 16);
  42.207 +        addr = strtoull(p, (char **)&p, 16);
  42.208          if (*p == ',')
  42.209              p++;
  42.210 -        len = strtoul(p, (char **)&p, 16);
  42.211 +        len = strtoull(p, (char **)&p, 16);
  42.212          if (*p == ':')
  42.213              p++;
  42.214          hextomem(mem_buf, p, len);
  42.215 @@ -644,10 +667,10 @@ static int gdb_handle_packet(GDBState *s
  42.216          type = strtoul(p, (char **)&p, 16);
  42.217          if (*p == ',')
  42.218              p++;
  42.219 -        addr = strtoul(p, (char **)&p, 16);
  42.220 +        addr = strtoull(p, (char **)&p, 16);
  42.221          if (*p == ',')
  42.222              p++;
  42.223 -        len = strtoul(p, (char **)&p, 16);
  42.224 +        len = strtoull(p, (char **)&p, 16);
  42.225          if (type == 0 || type == 1) {
  42.226              if (cpu_breakpoint_insert(env, addr) < 0)
  42.227                  goto breakpoint_error;
  42.228 @@ -661,10 +684,10 @@ static int gdb_handle_packet(GDBState *s
  42.229          type = strtoul(p, (char **)&p, 16);
  42.230          if (*p == ',')
  42.231              p++;
  42.232 -        addr = strtoul(p, (char **)&p, 16);
  42.233 +        addr = strtoull(p, (char **)&p, 16);
  42.234          if (*p == ',')
  42.235              p++;
  42.236 -        len = strtoul(p, (char **)&p, 16);
  42.237 +        len = strtoull(p, (char **)&p, 16);
  42.238          if (type == 0 || type == 1) {
  42.239              cpu_breakpoint_remove(env, addr);
  42.240              put_packet(s, "OK");
  42.241 @@ -672,6 +695,18 @@ static int gdb_handle_packet(GDBState *s
  42.242              goto breakpoint_error;
  42.243          }
  42.244          break;
  42.245 +#ifdef CONFIG_USER_ONLY
  42.246 +    case 'q':
  42.247 +        if (strncmp(p, "Offsets", 7) == 0) {
  42.248 +            TaskState *ts = env->opaque;
  42.249 +
  42.250 +            sprintf(buf, "Text=%x;Data=%x;Bss=%x", ts->info->code_offset,
  42.251 +                ts->info->data_offset, ts->info->data_offset);
  42.252 +            put_packet(s, buf);
  42.253 +            break;
  42.254 +        }
  42.255 +        /* Fall through.  */
  42.256 +#endif
  42.257      default:
  42.258          //        unknown_command:
  42.259          /* put empty packet */
  42.260 @@ -829,7 +864,7 @@ static void gdb_read(void *opaque)
  42.261      int i, size;
  42.262      uint8_t buf[4096];
  42.263  
  42.264 -    size = read(s->fd, buf, sizeof(buf));
  42.265 +    size = recv(s->fd, buf, sizeof(buf), 0);
  42.266      if (size < 0)
  42.267          return;
  42.268      if (size == 0) {
  42.269 @@ -866,7 +901,7 @@ static void gdb_accept(void *opaque)
  42.270  
  42.271      /* set short latency */
  42.272      val = 1;
  42.273 -    setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &val, sizeof(val));
  42.274 +    setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *)&val, sizeof(val));
  42.275      
  42.276  #ifdef CONFIG_USER_ONLY
  42.277      s = &gdbserver_state;
  42.278 @@ -881,9 +916,11 @@ static void gdb_accept(void *opaque)
  42.279      s->env = first_cpu; /* XXX: allow to change CPU */
  42.280      s->fd = fd;
  42.281  
  42.282 +#ifdef CONFIG_USER_ONLY
  42.283      fcntl(fd, F_SETFL, O_NONBLOCK);
  42.284 +#else
  42.285 +    socket_set_nonblock(fd);
  42.286  
  42.287 -#ifndef CONFIG_USER_ONLY
  42.288      /* stop the VM */
  42.289      vm_stop(EXCP_INTERRUPT);
  42.290  
  42.291 @@ -907,7 +944,7 @@ static int gdbserver_open(int port)
  42.292  
  42.293      /* allow fast reuse */
  42.294      val = 1;
  42.295 -    setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));
  42.296 +    setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *)&val, sizeof(val));
  42.297  
  42.298      sockaddr.sin_family = AF_INET;
  42.299      sockaddr.sin_port = htons(port);
  42.300 @@ -923,7 +960,7 @@ static int gdbserver_open(int port)
  42.301          return -1;
  42.302      }
  42.303  #ifndef CONFIG_USER_ONLY
  42.304 -    fcntl(fd, F_SETFL, O_NONBLOCK);
  42.305 +    socket_set_nonblock(fd);
  42.306  #endif
  42.307      return fd;
  42.308  }
    43.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    43.2 +++ b/tools/ioemu/hw/acpi-dsdt.dsl	Mon Aug 07 18:25:30 2006 +0100
    43.3 @@ -0,0 +1,559 @@
    43.4 +/*
    43.5 + * QEMU ACPI DSDT ASL definition
    43.6 + * 
    43.7 + * Copyright (c) 2006 Fabrice Bellard
    43.8 + * 
    43.9 + * This library is free software; you can redistribute it and/or
   43.10 + * modify it under the terms of the GNU Lesser General Public
   43.11 + * License version 2 as published by the Free Software Foundation.
   43.12 + *
   43.13 + * This library is distributed in the hope that it will be useful,
   43.14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   43.15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   43.16 + * Lesser General Public License for more details.
   43.17 + *
   43.18 + * You should have received a copy of the GNU Lesser General Public
   43.19 + * License along with this library; if not, write to the Free Software
   43.20 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   43.21 + */
   43.22 +DefinitionBlock (
   43.23 +    "acpi-dsdt.aml",    // Output Filename
   43.24 +    "DSDT",             // Signature
   43.25 +    0x01,               // DSDT Compliance Revision
   43.26 +    "QEMU",             // OEMID
   43.27 +    "QEMUDSDT",         // TABLE ID
   43.28 +    0x1                 // OEM Revision
   43.29 +    )
   43.30 +{
   43.31 +    Scope (\)
   43.32 +    {
   43.33 +        /* CMOS memory access */
   43.34 +        OperationRegion (CMS, SystemIO, 0x70, 0x02)
   43.35 +        Field (CMS, ByteAcc, NoLock, Preserve)
   43.36 +        {
   43.37 +            CMSI,   8, 
   43.38 +            CMSD,   8
   43.39 +        }
   43.40 +        Method (CMRD, 1, NotSerialized)
   43.41 +        {
   43.42 +            Store (Arg0, CMSI)
   43.43 +            Store (CMSD, Local0)
   43.44 +            Return (Local0)
   43.45 +        }
   43.46 +
   43.47 +        /* Debug Output */
   43.48 +        OperationRegion (DBG, SystemIO, 0xb044, 0x04)
   43.49 +        Field (DBG, DWordAcc, NoLock, Preserve)
   43.50 +        {
   43.51 +            DBGL,   32, 
   43.52 +        }
   43.53 +    }
   43.54 +
   43.55 +
   43.56 +    /* PCI Bus definition */
   43.57 +    Scope(\_SB) {
   43.58 +        Device(PCI0) {
   43.59 +            Name (_HID, EisaId ("PNP0A03"))
   43.60 +            Name (_ADR, 0x00)
   43.61 +            Name (_UID, 1)
   43.62 +            Name(_PRT, Package() {
   43.63 +                /* PCI IRQ routing table, example from ACPI 2.0a specification,
   43.64 +                   section 6.2.8.1 */
   43.65 +                /* Note: we provide the same info as the PCI routing
   43.66 +                   table of the Bochs BIOS */
   43.67 +                   
   43.68 +                // PCI Slot 0
   43.69 +                Package() {0x0000ffff, 0, LNKD, 0}, 
   43.70 +                Package() {0x0000ffff, 1, LNKA, 0}, 
   43.71 +                Package() {0x0000ffff, 2, LNKB, 0}, 
   43.72 +                Package() {0x0000ffff, 3, LNKC, 0}, 
   43.73 +
   43.74 +                // PCI Slot 1
   43.75 +                Package() {0x0001ffff, 0, LNKA, 0}, 
   43.76 +                Package() {0x0001ffff, 1, LNKB, 0}, 
   43.77 +                Package() {0x0001ffff, 2, LNKC, 0}, 
   43.78 +                Package() {0x0001ffff, 3, LNKD, 0}, 
   43.79 +                
   43.80 +                // PCI Slot 2
   43.81 +                Package() {0x0002ffff, 0, LNKB, 0}, 
   43.82 +                Package() {0x0002ffff, 1, LNKC, 0}, 
   43.83 +                Package() {0x0002ffff, 2, LNKD, 0}, 
   43.84 +                Package() {0x0002ffff, 3, LNKA, 0}, 
   43.85 +
   43.86 +                // PCI Slot 3
   43.87 +                Package() {0x0003ffff, 0, LNKC, 0}, 
   43.88 +                Package() {0x0003ffff, 1, LNKD, 0}, 
   43.89 +                Package() {0x0003ffff, 2, LNKA, 0}, 
   43.90 +                Package() {0x0003ffff, 3, LNKB, 0}, 
   43.91 +
   43.92 +                // PCI Slot 4
   43.93 +                Package() {0x0004ffff, 0, LNKD, 0}, 
   43.94 +                Package() {0x0004ffff, 1, LNKA, 0}, 
   43.95 +                Package() {0x0004ffff, 2, LNKB, 0}, 
   43.96 +                Package() {0x0004ffff, 3, LNKC, 0}, 
   43.97 +
   43.98 +                // PCI Slot 5
   43.99 +                Package() {0x0005ffff, 0, LNKA, 0}, 
  43.100 +                Package() {0x0005ffff, 1, LNKB, 0}, 
  43.101 +                Package() {0x0005ffff, 2, LNKC, 0}, 
  43.102 +                Package() {0x0005ffff, 3, LNKD, 0}, 
  43.103 +            })
  43.104 +
  43.105 +            Method (_CRS, 0, NotSerialized)
  43.106 +            {
  43.107 +            Name (MEMP, ResourceTemplate ()
  43.108 +            {
  43.109 +                WordBusNumber (ResourceProducer, MinFixed, MaxFixed, PosDecode,
  43.110 +                    0x0000,             // Address Space Granularity
  43.111 +                    0x0000,             // Address Range Minimum
  43.112 +                    0x00FF,             // Address Range Maximum
  43.113 +                    0x0000,             // Address Translation Offset
  43.114 +                    0x0100,             // Address Length
  43.115 +                    ,, )
  43.116 +                IO (Decode16,
  43.117 +                    0x0CF8,             // Address Range Minimum
  43.118 +                    0x0CF8,             // Address Range Maximum
  43.119 +                    0x01,               // Address Alignment
  43.120 +                    0x08,               // Address Length
  43.121 +                    )
  43.122 +                WordIO (ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange,
  43.123 +                    0x0000,             // Address Space Granularity
  43.124 +                    0x0000,             // Address Range Minimum
  43.125 +                    0x0CF7,             // Address Range Maximum
  43.126 +                    0x0000,             // Address Translation Offset
  43.127 +                    0x0CF8,             // Address Length
  43.128 +                    ,, , TypeStatic)
  43.129 +                WordIO (ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange,
  43.130 +                    0x0000,             // Address Space Granularity
  43.131 +                    0x0D00,             // Address Range Minimum
  43.132 +                    0xFFFF,             // Address Range Maximum
  43.133 +                    0x0000,             // Address Translation Offset
  43.134 +                    0xF300,             // Address Length
  43.135 +                    ,, , TypeStatic)
  43.136 +                DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, Cacheable, ReadWrite,
  43.137 +                    0x00000000,         // Address Space Granularity
  43.138 +                    0x000A0000,         // Address Range Minimum
  43.139 +                    0x000BFFFF,         // Address Range Maximum
  43.140 +                    0x00000000,         // Address Translation Offset
  43.141 +                    0x00020000,         // Address Length
  43.142 +                    ,, , AddressRangeMemory, TypeStatic)
  43.143 +                DWordMemory (ResourceProducer, PosDecode, MinNotFixed, MaxFixed, NonCacheable, ReadWrite,
  43.144 +                    0x00000000,         // Address Space Granularity
  43.145 +                    0x00000000,         // Address Range Minimum
  43.146 +                    0xFEBFFFFF,         // Address Range Maximum
  43.147 +                    0x00000000,         // Address Translation Offset
  43.148 +                    0x00000000,         // Address Length
  43.149 +                    ,, MEMF, AddressRangeMemory, TypeStatic)
  43.150 +            })
  43.151 +                CreateDWordField (MEMP, \_SB.PCI0._CRS.MEMF._MIN, PMIN)
  43.152 +                CreateDWordField (MEMP, \_SB.PCI0._CRS.MEMF._MAX, PMAX)
  43.153 +                CreateDWordField (MEMP, \_SB.PCI0._CRS.MEMF._LEN, PLEN)
  43.154 +                /* compute available RAM */
  43.155 +                Add(CMRD(0x34), ShiftLeft(CMRD(0x35), 8), Local0)
  43.156 +                ShiftLeft(Local0, 16, Local0)
  43.157 +                Add(Local0, 0x1000000, Local0)
  43.158 +                /* update field of last region */
  43.159 +                Store(Local0, PMIN)
  43.160 +                Subtract (PMAX, PMIN, PLEN)
  43.161 +                Increment (PLEN)
  43.162 +                Return (MEMP)
  43.163 +            }
  43.164 +        }
  43.165 +    }
  43.166 +
  43.167 +    Scope(\_SB.PCI0) {
  43.168 +
  43.169 +	/* PIIX3 ISA bridge */
  43.170 +        Device (ISA) {
  43.171 +            Name (_ADR, 0x00010000)
  43.172 +        
  43.173 +            /* PIIX PCI to ISA irq remapping */
  43.174 +            OperationRegion (P40C, PCI_Config, 0x60, 0x04)
  43.175 +
  43.176 +
  43.177 +            /* Keyboard seems to be important for WinXP install */
  43.178 +            Device (KBD)
  43.179 +            {
  43.180 +                Name (_HID, EisaId ("PNP0303"))
  43.181 +                Method (_STA, 0, NotSerialized)
  43.182 +                {
  43.183 +                    Return (0x0f)
  43.184 +                }
  43.185 +
  43.186 +                Method (_CRS, 0, NotSerialized)
  43.187 +                {
  43.188 +                     Name (TMP, ResourceTemplate ()
  43.189 +                     {
  43.190 +                    IO (Decode16,
  43.191 +                        0x0060,             // Address Range Minimum
  43.192 +                        0x0060,             // Address Range Maximum
  43.193 +                        0x01,               // Address Alignment
  43.194 +                        0x01,               // Address Length
  43.195 +                        )
  43.196 +                    IO (Decode16,
  43.197 +                        0x0064,             // Address Range Minimum
  43.198 +                        0x0064,             // Address Range Maximum
  43.199 +                        0x01,               // Address Alignment
  43.200 +                        0x01,               // Address Length
  43.201 +                        )
  43.202 +                    IRQNoFlags ()
  43.203 +                        {1}
  43.204 +                    })
  43.205 +                    Return (TMP)
  43.206 +                }
  43.207 +            }
  43.208 +
  43.209 +	    /* PS/2 mouse */
  43.210 +            Device (MOU) 
  43.211 +            {
  43.212 +                Name (_HID, EisaId ("PNP0F13"))
  43.213 +                Method (_STA, 0, NotSerialized)
  43.214 +                {
  43.215 +                    Return (0x0f)
  43.216 +                }
  43.217 +
  43.218 +                Method (_CRS, 0, NotSerialized)
  43.219 +                {
  43.220 +                    Name (TMP, ResourceTemplate ()
  43.221 +                    {
  43.222 +                         IRQNoFlags () {12}
  43.223 +                    })
  43.224 +                    Return (TMP)
  43.225 +                }
  43.226 +            }
  43.227 +
  43.228 +	    /* PS/2 floppy controller */
  43.229 +	    Device (FDC0)
  43.230 +	    {
  43.231 +	        Name (_HID, EisaId ("PNP0700"))
  43.232 +		Method (_STA, 0, NotSerialized)
  43.233 +		{
  43.234 +		    Return (0x0F)
  43.235 +		}
  43.236 +		Method (_CRS, 0, NotSerialized)
  43.237 +		{
  43.238 +		    Name (BUF0, ResourceTemplate ()
  43.239 +                    {
  43.240 +                        IO (Decode16, 0x03F2, 0x03F2, 0x00, 0x04)
  43.241 +                        IO (Decode16, 0x03F7, 0x03F7, 0x00, 0x01)
  43.242 +                        IRQNoFlags () {6}
  43.243 +                        DMA (Compatibility, NotBusMaster, Transfer8) {2}
  43.244 +                    })
  43.245 +		    Return (BUF0)
  43.246 +		}
  43.247 +	    }
  43.248 +
  43.249 +	    /* Parallel port */
  43.250 +	    Device (LPT)
  43.251 +	    {
  43.252 +	        Name (_HID, EisaId ("PNP0400"))
  43.253 +		Method (_STA, 0, NotSerialized)
  43.254 +		{
  43.255 +		    Store (\_SB.PCI0.PX13.DRSA, Local0)
  43.256 +		    And (Local0, 0x80000000, Local0)
  43.257 +		    If (LEqual (Local0, 0))
  43.258 +		    {
  43.259 +			Return (0x00)
  43.260 +		    }
  43.261 +		    Else
  43.262 +		    {
  43.263 +			Return (0x0F)
  43.264 +		    }
  43.265 +		}
  43.266 +		Method (_CRS, 0, NotSerialized)
  43.267 +		{
  43.268 +		    Name (BUF0, ResourceTemplate ()
  43.269 +                    {
  43.270 +			IO (Decode16, 0x0378, 0x0378, 0x08, 0x08)
  43.271 +			IRQNoFlags () {7}
  43.272 +		    })
  43.273 +		    Return (BUF0)
  43.274 +		}
  43.275 +	    }
  43.276 +
  43.277 +	    /* Serial Ports */
  43.278 +	    Device (COM1)
  43.279 +	    {
  43.280 +	        Name (_HID, EisaId ("PNP0501"))
  43.281 +		Name (_UID, 0x01)
  43.282 +		Method (_STA, 0, NotSerialized)
  43.283 +		{
  43.284 +		    Store (\_SB.PCI0.PX13.DRSC, Local0)
  43.285 +		    And (Local0, 0x08000000, Local0)
  43.286 +		    If (LEqual (Local0, 0))
  43.287 +		    {
  43.288 +			Return (0x00)
  43.289 +		    }
  43.290 +		    Else
  43.291 +		    {
  43.292 +			Return (0x0F)
  43.293 +		    }
  43.294 +		}
  43.295 +		Method (_CRS, 0, NotSerialized)
  43.296 +		{
  43.297 +		    Name (BUF0, ResourceTemplate ()
  43.298 +                    {
  43.299 +			IO (Decode16, 0x03F8, 0x03F8, 0x00, 0x08)
  43.300 +                	IRQNoFlags () {4}
  43.301 +		    })
  43.302 +		    Return (BUF0)
  43.303 +		}
  43.304 +	    }
  43.305 +
  43.306 +	    Device (COM2)
  43.307 +	    {
  43.308 +	        Name (_HID, EisaId ("PNP0501"))
  43.309 +		Name (_UID, 0x02)
  43.310 +		Method (_STA, 0, NotSerialized)
  43.311 +		{
  43.312 +		    Store (\_SB.PCI0.PX13.DRSC, Local0)
  43.313 +		    And (Local0, 0x80000000, Local0)
  43.314 +		    If (LEqual (Local0, 0))
  43.315 +		    {
  43.316 +			Return (0x00)
  43.317 +		    }
  43.318 +		    Else
  43.319 +		    {
  43.320 +			Return (0x0F)
  43.321 +		    }
  43.322 +		}
  43.323 +		Method (_CRS, 0, NotSerialized)
  43.324 +		{
  43.325 +		    Name (BUF0, ResourceTemplate ()
  43.326 +                    {
  43.327 +			IO (Decode16, 0x02F8, 0x02F8, 0x00, 0x08)
  43.328 +                	IRQNoFlags () {3}
  43.329 +		    })
  43.330 +		    Return (BUF0)
  43.331 +		}
  43.332 +	    }
  43.333 +        }
  43.334 +
  43.335 +	/* PIIX4 PM */
  43.336 +        Device (PX13) {
  43.337 +	    Name (_ADR, 0x00010003)
  43.338 +
  43.339 +	    OperationRegion (P13C, PCI_Config, 0x5c, 0x24)
  43.340 +	    Field (P13C, DWordAcc, NoLock, Preserve)
  43.341 +	    {
  43.342 +		DRSA, 32,
  43.343 +		DRSB, 32,
  43.344 +		DRSC, 32,
  43.345 +		DRSE, 32,
  43.346 +		DRSF, 32,
  43.347 +		DRSG, 32,
  43.348 +		DRSH, 32,
  43.349 +		DRSI, 32,
  43.350 +		DRSJ, 32
  43.351 +	    }
  43.352 +	}
  43.353 +    }
  43.354 +
  43.355 +    /* PCI IRQs */
  43.356 +    Scope(\_SB) {
  43.357 +         Field (\_SB.PCI0.ISA.P40C, ByteAcc, NoLock, Preserve)
  43.358 +         {
  43.359 +             PRQ0,   8, 
  43.360 +             PRQ1,   8, 
  43.361 +             PRQ2,   8, 
  43.362 +             PRQ3,   8
  43.363 +         }
  43.364 +
  43.365 +        Device(LNKA){
  43.366 +                Name(_HID, EISAID("PNP0C0F"))     // PCI interrupt link
  43.367 +                Name(_UID, 1)
  43.368 +                Name(_PRS, ResourceTemplate(){
  43.369 +                    IRQ (Level, ActiveLow, Shared)
  43.370 +                        {3,4,5,6,7,9,10,11,12}
  43.371 +                })
  43.372 +                Method (_STA, 0, NotSerialized)
  43.373 +                {
  43.374 +                    Store (0x0B, Local0)
  43.375 +                    If (And (0x80, PRQ0, Local1))
  43.376 +                    {
  43.377 +                         Store (0x09, Local0)
  43.378 +                    }
  43.379 +                    Return (Local0)
  43.380 +                }
  43.381 +                Method (_DIS, 0, NotSerialized)
  43.382 +                {
  43.383 +                    Or (PRQ0, 0x80, PRQ0)
  43.384 +                }
  43.385 +                Method (_CRS, 0, NotSerialized)
  43.386 +                {
  43.387 +                    Name (PRR0, ResourceTemplate ()
  43.388 +                    {
  43.389 +                        IRQ (Level, ActiveLow, Shared)
  43.390 +                            {1}
  43.391 +                    })
  43.392 +                    CreateWordField (PRR0, 0x01, TMP)
  43.393 +                    Store (PRQ0, Local0)
  43.394 +                    If (LLess (Local0, 0x80))
  43.395 +                    {
  43.396 +                        ShiftLeft (One, Local0, TMP)
  43.397 +                    }
  43.398 +                    Else
  43.399 +                    {
  43.400 +                        Store (Zero, TMP)
  43.401 +                    }
  43.402 +                    Return (PRR0)
  43.403 +                }
  43.404 +                Method (_SRS, 1, NotSerialized)
  43.405 +                {
  43.406 +                    CreateWordField (Arg0, 0x01, TMP)
  43.407 +                    FindSetRightBit (TMP, Local0)
  43.408 +                    Decrement (Local0)
  43.409 +                    Store (Local0, PRQ0)
  43.410 +                }
  43.411 +        }
  43.412 +        Device(LNKB){
  43.413 +                Name(_HID, EISAID("PNP0C0F"))     // PCI interrupt link
  43.414 +                Name(_UID, 2)
  43.415 +                Name(_PRS, ResourceTemplate(){
  43.416 +                    IRQ (Level, ActiveLow, Shared)
  43.417 +                        {3,4,5,6,7,9,10,11,12}
  43.418 +                })
  43.419 +                Method (_STA, 0, NotSerialized)
  43.420 +                {
  43.421 +                    Store (0x0B, Local0)
  43.422 +                    If (And (0x80, PRQ1, Local1))
  43.423 +                    {
  43.424 +                         Store (0x09, Local0)
  43.425 +                    }
  43.426 +                    Return (Local0)
  43.427 +                }
  43.428 +                Method (_DIS, 0, NotSerialized)
  43.429 +                {
  43.430 +                    Or (PRQ1, 0x80, PRQ1)
  43.431 +                }
  43.432 +                Method (_CRS, 0, NotSerialized)
  43.433 +                {
  43.434 +                    Name (PRR0, ResourceTemplate ()
  43.435 +                    {
  43.436 +                        IRQ (Level, ActiveLow, Shared)
  43.437 +                            {1}
  43.438 +                    })
  43.439 +                    CreateWordField (PRR0, 0x01, TMP)
  43.440 +                    Store (PRQ1, Local0)
  43.441 +                    If (LLess (Local0, 0x80))
  43.442 +                    {
  43.443 +                        ShiftLeft (One, Local0, TMP)
  43.444 +                    }
  43.445 +                    Else
  43.446 +                    {
  43.447 +                        Store (Zero, TMP)
  43.448 +                    }
  43.449 +                    Return (PRR0)
  43.450 +                }
  43.451 +                Method (_SRS, 1, NotSerialized)
  43.452 +                {
  43.453 +                    CreateWordField (Arg0, 0x01, TMP)
  43.454 +                    FindSetRightBit (TMP, Local0)
  43.455 +                    Decrement (Local0)
  43.456 +                    Store (Local0, PRQ1)
  43.457 +                }
  43.458 +        }
  43.459 +        Device(LNKC){
  43.460 +                Name(_HID, EISAID("PNP0C0F"))     // PCI interrupt link
  43.461 +                Name(_UID, 3)
  43.462 +                Name(_PRS, ResourceTemplate(){
  43.463 +                    IRQ (Level, ActiveLow, Shared)
  43.464 +                        {3,4,5,6,7,9,10,11,12}
  43.465 +                })
  43.466 +                Method (_STA, 0, NotSerialized)
  43.467 +                {
  43.468 +                    Store (0x0B, Local0)
  43.469 +                    If (And (0x80, PRQ2, Local1))
  43.470 +                    {
  43.471 +                         Store (0x09, Local0)
  43.472 +                    }
  43.473 +                    Return (Local0)
  43.474 +                }
  43.475 +                Method (_DIS, 0, NotSerialized)
  43.476 +                {
  43.477 +                    Or (PRQ2, 0x80, PRQ2)
  43.478 +                }
  43.479 +                Method (_CRS, 0, NotSerialized)
  43.480 +                {
  43.481 +                    Name (PRR0, ResourceTemplate ()
  43.482 +                    {
  43.483 +                        IRQ (Level, ActiveLow, Shared)
  43.484 +                            {1}
  43.485 +                    })
  43.486 +                    CreateWordField (PRR0, 0x01, TMP)
  43.487 +                    Store (PRQ2, Local0)
  43.488 +                    If (LLess (Local0, 0x80))
  43.489 +                    {
  43.490 +                        ShiftLeft (One, Local0, TMP)
  43.491 +                    }
  43.492 +                    Else
  43.493 +                    {
  43.494 +                        Store (Zero, TMP)
  43.495 +                    }
  43.496 +                    Return (PRR0)
  43.497 +                }
  43.498 +                Method (_SRS, 1, NotSerialized)
  43.499 +                {
  43.500 +                    CreateWordField (Arg0, 0x01, TMP)
  43.501 +                    FindSetRightBit (TMP, Local0)
  43.502 +                    Decrement (Local0)
  43.503 +                    Store (Local0, PRQ2)
  43.504 +                }
  43.505 +        }
  43.506 +        Device(LNKD){
  43.507 +                Name(_HID, EISAID("PNP0C0F"))     // PCI interrupt link
  43.508 +                Name(_UID, 4)
  43.509 +                Name(_PRS, ResourceTemplate(){
  43.510 +                    IRQ (Level, ActiveLow, Shared)
  43.511 +                        {3,4,5,6,7,9,10,11,12}
  43.512 +                })
  43.513 +                Method (_STA, 0, NotSerialized)
  43.514 +                {
  43.515 +                    Store (0x0B, Local0)
  43.516 +                    If (And (0x80, PRQ3, Local1))
  43.517 +                    {
  43.518 +                         Store (0x09, Local0)
  43.519 +                    }
  43.520 +                    Return (Local0)
  43.521 +                }
  43.522 +                Method (_DIS, 0, NotSerialized)
  43.523 +                {
  43.524 +                    Or (PRQ3, 0x80, PRQ3)
  43.525 +                }
  43.526 +                Method (_CRS, 0, NotSerialized)
  43.527 +                {
  43.528 +                    Name (PRR0, ResourceTemplate ()
  43.529 +                    {
  43.530 +                        IRQ (Level, ActiveLow, Shared)
  43.531 +                            {1}
  43.532 +                    })
  43.533 +                    CreateWordField (PRR0, 0x01, TMP)
  43.534 +                    Store (PRQ3, Local0)
  43.535 +                    If (LLess (Local0, 0x80))
  43.536 +                    {
  43.537 +                        ShiftLeft (One, Local0, TMP)
  43.538 +                    }
  43.539 +                    Else
  43.540 +                    {
  43.541 +                        Store (Zero, TMP)
  43.542 +                    }
  43.543 +                    Return (PRR0)
  43.544 +                }
  43.545 +                Method (_SRS, 1, NotSerialized)
  43.546 +                {
  43.547 +                    CreateWordField (Arg0, 0x01, TMP)
  43.548 +                    FindSetRightBit (TMP, Local0)
  43.549 +                    Decrement (Local0)
  43.550 +                    Store (Local0, PRQ3)
  43.551 +                }
  43.552 +        }
  43.553 +    }
  43.554 +
  43.555 +    /* S5 = power off state */
  43.556 +    Name (_S5, Package (4) {
  43.557 +        0x00, // PM1a_CNT.SLP_TYP 
  43.558 +        0x00, // PM2a_CNT.SLP_TYP 
  43.559 +        0x00, // reserved
  43.560 +        0x00, // reserved
  43.561 +    })
  43.562 +}
    44.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    44.2 +++ b/tools/ioemu/hw/acpi-dsdt.hex	Mon Aug 07 18:25:30 2006 +0100
    44.3 @@ -0,0 +1,278 @@
    44.4 +/*
    44.5 + * 
    44.6 + * Intel ACPI Component Architecture
    44.7 + * ASL Optimizing Compiler version 20060421 [Apr 29 2006]
    44.8 + * Copyright (C) 2000 - 2006 Intel Corporation
    44.9 + * Supports ACPI Specification Revision 3.0a
   44.10 + * 
   44.11 + * Compilation of "/usr/local/home/bellard/qemu-current/hw/acpi-dsdt.dsl" - Wed Jun 14 20:09:53 2006
   44.12 + * 
   44.13 + * C source code output
   44.14 + *
   44.15 + */
   44.16 +unsigned char AmlCode[] =
   44.17 +{
   44.18 +    0x44,0x53,0x44,0x54,0x32,0x08,0x00,0x00,  /* 00000000    "DSDT2..." */
   44.19 +    0x01,0x5B,0x51,0x45,0x4D,0x55,0x00,0x00,  /* 00000008    ".[QEMU.." */
   44.20 +    0x51,0x45,0x4D,0x55,0x44,0x53,0x44,0x54,  /* 00000010    "QEMUDSDT" */
   44.21 +    0x01,0x00,0x00,0x00,0x49,0x4E,0x54,0x4C,  /* 00000018    "....INTL" */
   44.22 +    0x21,0x04,0x06,0x20,0x10,0x4F,0x04,0x5C,  /* 00000020    "!.. .O.\" */
   44.23 +    0x00,0x5B,0x80,0x43,0x4D,0x53,0x5F,0x01,  /* 00000028    ".[.CMS_." */
   44.24 +    0x0A,0x70,0x0A,0x02,0x5B,0x81,0x10,0x43,  /* 00000030    ".p..[..C" */
   44.25 +    0x4D,0x53,0x5F,0x01,0x43,0x4D,0x53,0x49,  /* 00000038    "MS_.CMSI" */
   44.26 +    0x08,0x43,0x4D,0x53,0x44,0x08,0x14,0x14,  /* 00000040    ".CMSD..." */
   44.27 +    0x43,0x4D,0x52,0x44,0x01,0x70,0x68,0x43,  /* 00000048    "CMRD.phC" */
   44.28 +    0x4D,0x53,0x49,0x70,0x43,0x4D,0x53,0x44,  /* 00000050    "MSIpCMSD" */
   44.29 +    0x60,0xA4,0x60,0x5B,0x80,0x44,0x42,0x47,  /* 00000058    "`.`[.DBG" */
   44.30 +    0x5F,0x01,0x0B,0x44,0xB0,0x0A,0x04,0x5B,  /* 00000060    "_..D...[" */
   44.31 +    0x81,0x0B,0x44,0x42,0x47,0x5F,0x03,0x44,  /* 00000068    "..DBG_.D" */
   44.32 +    0x42,0x47,0x4C,0x20,0x10,0x4E,0x25,0x5F,  /* 00000070    "BGL .N%_" */
   44.33 +    0x53,0x42,0x5F,0x5B,0x82,0x46,0x25,0x50,  /* 00000078    "SB_[.F%P" */
   44.34 +    0x43,0x49,0x30,0x08,0x5F,0x48,0x49,0x44,  /* 00000080    "CI0._HID" */
   44.35 +    0x0C,0x41,0xD0,0x0A,0x03,0x08,0x5F,0x41,  /* 00000088    ".A...._A" */
   44.36 +    0x44,0x52,0x00,0x08,0x5F,0x55,0x49,0x44,  /* 00000090    "DR.._UID" */
   44.37 +    0x01,0x08,0x5F,0x50,0x52,0x54,0x12,0x47,  /* 00000098    ".._PRT.G" */
   44.38 +    0x15,0x18,0x12,0x0B,0x04,0x0B,0xFF,0xFF,  /* 000000A0    "........" */
   44.39 +    0x00,0x4C,0x4E,0x4B,0x44,0x00,0x12,0x0B,  /* 000000A8    ".LNKD..." */
   44.40 +    0x04,0x0B,0xFF,0xFF,0x01,0x4C,0x4E,0x4B,  /* 000000B0    ".....LNK" */
   44.41 +    0x41,0x00,0x12,0x0C,0x04,0x0B,0xFF,0xFF,  /* 000000B8    "A......." */
   44.42 +    0x0A,0x02,0x4C,0x4E,0x4B,0x42,0x00,0x12,  /* 000000C0    "..LNKB.." */
   44.43 +    0x0C,0x04,0x0B,0xFF,0xFF,0x0A,0x03,0x4C,  /* 000000C8    ".......L" */
   44.44 +    0x4E,0x4B,0x43,0x00,0x12,0x0D,0x04,0x0C,  /* 000000D0    "NKC....." */
   44.45 +    0xFF,0xFF,0x01,0x00,0x00,0x4C,0x4E,0x4B,  /* 000000D8    ".....LNK" */
   44.46 +    0x41,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,  /* 000000E0    "A......." */
   44.47 +    0x01,0x00,0x01,0x4C,0x4E,0x4B,0x42,0x00,  /* 000000E8    "...LNKB." */
   44.48 +    0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x01,0x00,  /* 000000F0    "........" */
   44.49 +    0x0A,0x02,0x4C,0x4E,0x4B,0x43,0x00,0x12,  /* 000000F8    "..LNKC.." */
   44.50 +    0x0E,0x04,0x0C,0xFF,0xFF,0x01,0x00,0x0A,  /* 00000100    "........" */
   44.51 +    0x03,0x4C,0x4E,0x4B,0x44,0x00,0x12,0x0D,  /* 00000108    ".LNKD..." */
   44.52 +    0x04,0x0C,0xFF,0xFF,0x02,0x00,0x00,0x4C,  /* 00000110    ".......L" */
   44.53 +    0x4E,0x4B,0x42,0x00,0x12,0x0D,0x04,0x0C,  /* 00000118    "NKB....." */
   44.54 +    0xFF,0xFF,0x02,0x00,0x01,0x4C,0x4E,0x4B,  /* 00000120    ".....LNK" */
   44.55 +    0x43,0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,  /* 00000128    "C......." */
   44.56 +    0x02,0x00,0x0A,0x02,0x4C,0x4E,0x4B,0x44,  /* 00000130    "....LNKD" */
   44.57 +    0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x02,  /* 00000138    "........" */
   44.58 +    0x00,0x0A,0x03,0x4C,0x4E,0x4B,0x41,0x00,  /* 00000140    "...LNKA." */
   44.59 +    0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x03,0x00,  /* 00000148    "........" */
   44.60 +    0x00,0x4C,0x4E,0x4B,0x43,0x00,0x12,0x0D,  /* 00000150    ".LNKC..." */
   44.61 +    0x04,0x0C,0xFF,0xFF,0x03,0x00,0x01,0x4C,  /* 00000158    ".......L" */
   44.62 +    0x4E,0x4B,0x44,0x00,0x12,0x0E,0x04,0x0C,  /* 00000160    "NKD....." */
   44.63 +    0xFF,0xFF,0x03,0x00,0x0A,0x02,0x4C,0x4E,  /* 00000168    "......LN" */
   44.64 +    0x4B,0x41,0x00,0x12,0x0E,0x04,0x0C,0xFF,  /* 00000170    "KA......" */
   44.65 +    0xFF,0x03,0x00,0x0A,0x03,0x4C,0x4E,0x4B,  /* 00000178    ".....LNK" */
   44.66 +    0x42,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,  /* 00000180    "B......." */
   44.67 +    0x04,0x00,0x00,0x4C,0x4E,0x4B,0x44,0x00,  /* 00000188    "...LNKD." */
   44.68 +    0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x04,0x00,  /* 00000190    "........" */
   44.69 +    0x01,0x4C,0x4E,0x4B,0x41,0x00,0x12,0x0E,  /* 00000198    ".LNKA..." */
   44.70 +    0x04,0x0C,0xFF,0xFF,0x04,0x00,0x0A,0x02,  /* 000001A0    "........" */
   44.71 +    0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0E,0x04,  /* 000001A8    "LNKB...." */
   44.72 +    0x0C,0xFF,0xFF,0x04,0x00,0x0A,0x03,0x4C,  /* 000001B0    ".......L" */
   44.73 +    0x4E,0x4B,0x43,0x00,0x12,0x0D,0x04,0x0C,  /* 000001B8    "NKC....." */
   44.74 +    0xFF,0xFF,0x05,0x00,0x00,0x4C,0x4E,0x4B,  /* 000001C0    ".....LNK" */
   44.75 +    0x41,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,  /* 000001C8    "A......." */
   44.76 +    0x05,0x00,0x01,0x4C,0x4E,0x4B,0x42,0x00,  /* 000001D0    "...LNKB." */
   44.77 +    0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x05,0x00,  /* 000001D8    "........" */
   44.78 +    0x0A,0x02,0x4C,0x4E,0x4B,0x43,0x00,0x12,  /* 000001E0    "..LNKC.." */
   44.79 +    0x0E,0x04,0x0C,0xFF,0xFF,0x05,0x00,0x0A,  /* 000001E8    "........" */
   44.80 +    0x03,0x4C,0x4E,0x4B,0x44,0x00,0x14,0x4C,  /* 000001F0    ".LNKD..L" */
   44.81 +    0x0D,0x5F,0x43,0x52,0x53,0x00,0x08,0x4D,  /* 000001F8    "._CRS..M" */
   44.82 +    0x45,0x4D,0x50,0x11,0x42,0x07,0x0A,0x6E,  /* 00000200    "EMP.B..n" */
   44.83 +    0x88,0x0D,0x00,0x02,0x0C,0x00,0x00,0x00,  /* 00000208    "........" */
   44.84 +    0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x01,  /* 00000210    "........" */
   44.85 +    0x47,0x01,0xF8,0x0C,0xF8,0x0C,0x01,0x08,  /* 00000218    "G......." */
   44.86 +    0x88,0x0D,0x00,0x01,0x0C,0x03,0x00,0x00,  /* 00000220    "........" */
   44.87 +    0x00,0x00,0xF7,0x0C,0x00,0x00,0xF8,0x0C,  /* 00000228    "........" */
   44.88 +    0x88,0x0D,0x00,0x01,0x0C,0x03,0x00,0x00,  /* 00000230    "........" */
   44.89 +    0x00,0x0D,0xFF,0xFF,0x00,0x00,0x00,0xF3,  /* 00000238    "........" */
   44.90 +    0x87,0x17,0x00,0x00,0x0C,0x03,0x00,0x00,  /* 00000240    "........" */
   44.91 +    0x00,0x00,0x00,0x00,0x0A,0x00,0xFF,0xFF,  /* 00000248    "........" */
   44.92 +    0x0B,0x00,0x00,0x00,0x00,0x00,0x00,0x00,  /* 00000250    "........" */
   44.93 +    0x02,0x00,0x87,0x17,0x00,0x00,0x08,0x01,  /* 00000258    "........" */
   44.94 +    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,  /* 00000260    "........" */
   44.95 +    0xFF,0xFF,0xBF,0xFE,0x00,0x00,0x00,0x00,  /* 00000268    "........" */
   44.96 +    0x00,0x00,0x00,0x00,0x79,0x00,0x8A,0x4D,  /* 00000270    "....y..M" */
   44.97 +    0x45,0x4D,0x50,0x0A,0x5C,0x50,0x4D,0x49,  /* 00000278    "EMP.\PMI" */
   44.98 +    0x4E,0x8A,0x4D,0x45,0x4D,0x50,0x0A,0x60,  /* 00000280    "N.MEMP.`" */
   44.99 +    0x50,0x4D,0x41,0x58,0x8A,0x4D,0x45,0x4D,  /* 00000288    "PMAX.MEM" */
  44.100 +    0x50,0x0A,0x68,0x50,0x4C,0x45,0x4E,0x72,  /* 00000290    "P.hPLENr" */
  44.101 +    0x43,0x4D,0x52,0x44,0x0A,0x34,0x79,0x43,  /* 00000298    "CMRD.4yC" */
  44.102 +    0x4D,0x52,0x44,0x0A,0x35,0x0A,0x08,0x00,  /* 000002A0    "MRD.5..." */
  44.103 +    0x60,0x79,0x60,0x0A,0x10,0x60,0x72,0x60,  /* 000002A8    "`y`..`r`" */
  44.104 +    0x0C,0x00,0x00,0x00,0x01,0x60,0x70,0x60,  /* 000002B0    ".....`p`" */
  44.105 +    0x50,0x4D,0x49,0x4E,0x74,0x50,0x4D,0x41,  /* 000002B8    "PMINtPMA" */
  44.106 +    0x58,0x50,0x4D,0x49,0x4E,0x50,0x4C,0x45,  /* 000002C0    "XPMINPLE" */
  44.107 +    0x4E,0x75,0x50,0x4C,0x45,0x4E,0xA4,0x4D,  /* 000002C8    "NuPLEN.M" */
  44.108 +    0x45,0x4D,0x50,0x10,0x42,0x26,0x2E,0x5F,  /* 000002D0    "EMP.B&._" */
  44.109 +    0x53,0x42,0x5F,0x50,0x43,0x49,0x30,0x5B,  /* 000002D8    "SB_PCI0[" */
  44.110 +    0x82,0x43,0x20,0x49,0x53,0x41,0x5F,0x08,  /* 000002E0    ".C ISA_." */
  44.111 +    0x5F,0x41,0x44,0x52,0x0C,0x00,0x00,0x01,  /* 000002E8    "_ADR...." */
  44.112 +    0x00,0x5B,0x80,0x50,0x34,0x30,0x43,0x02,  /* 000002F0    ".[.P40C." */
  44.113 +    0x0A,0x60,0x0A,0x04,0x5B,0x82,0x44,0x04,  /* 000002F8    ".`..[.D." */
  44.114 +    0x4B,0x42,0x44,0x5F,0x08,0x5F,0x48,0x49,  /* 00000300    "KBD_._HI" */
  44.115 +    0x44,0x0C,0x41,0xD0,0x03,0x03,0x14,0x09,  /* 00000308    "D.A....." */
  44.116 +    0x5F,0x53,0x54,0x41,0x00,0xA4,0x0A,0x0F,  /* 00000310    "_STA...." */
  44.117 +    0x14,0x29,0x5F,0x43,0x52,0x53,0x00,0x08,  /* 00000318    ".)_CRS.." */
  44.118 +    0x54,0x4D,0x50,0x5F,0x11,0x18,0x0A,0x15,  /* 00000320    "TMP_...." */
  44.119 +    0x47,0x01,0x60,0x00,0x60,0x00,0x01,0x01,  /* 00000328    "G.`.`..." */
  44.120 +    0x47,0x01,0x64,0x00,0x64,0x00,0x01,0x01,  /* 00000330    "G.d.d..." */
  44.121 +    0x22,0x02,0x00,0x79,0x00,0xA4,0x54,0x4D,  /* 00000338    ""..y..TM" */
  44.122 +    0x50,0x5F,0x5B,0x82,0x33,0x4D,0x4F,0x55,  /* 00000340    "P_[.3MOU" */
  44.123 +    0x5F,0x08,0x5F,0x48,0x49,0x44,0x0C,0x41,  /* 00000348    "_._HID.A" */
  44.124 +    0xD0,0x0F,0x13,0x14,0x09,0x5F,0x53,0x54,  /* 00000350    "....._ST" */
  44.125 +    0x41,0x00,0xA4,0x0A,0x0F,0x14,0x19,0x5F,  /* 00000358    "A......_" */
  44.126 +    0x43,0x52,0x53,0x00,0x08,0x54,0x4D,0x50,  /* 00000360    "CRS..TMP" */
  44.127 +    0x5F,0x11,0x08,0x0A,0x05,0x22,0x00,0x10,  /* 00000368    "_....".." */
  44.128 +    0x79,0x00,0xA4,0x54,0x4D,0x50,0x5F,0x5B,  /* 00000370    "y..TMP_[" */
  44.129 +    0x82,0x47,0x04,0x46,0x44,0x43,0x30,0x08,  /* 00000378    ".G.FDC0." */
  44.130 +    0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0,0x07,  /* 00000380    "_HID.A.." */
  44.131 +    0x00,0x14,0x09,0x5F,0x53,0x54,0x41,0x00,  /* 00000388    "..._STA." */
  44.132 +    0xA4,0x0A,0x0F,0x14,0x2C,0x5F,0x43,0x52,  /* 00000390    "....,_CR" */
  44.133 +    0x53,0x00,0x08,0x42,0x55,0x46,0x30,0x11,  /* 00000398    "S..BUF0." */
  44.134 +    0x1B,0x0A,0x18,0x47,0x01,0xF2,0x03,0xF2,  /* 000003A0    "...G...." */
  44.135 +    0x03,0x00,0x04,0x47,0x01,0xF7,0x03,0xF7,  /* 000003A8    "...G...." */
  44.136 +    0x03,0x00,0x01,0x22,0x40,0x00,0x2A,0x04,  /* 000003B0    "..."@.*." */
  44.137 +    0x00,0x79,0x00,0xA4,0x42,0x55,0x46,0x30,  /* 000003B8    ".y..BUF0" */
  44.138 +    0x5B,0x82,0x4B,0x05,0x4C,0x50,0x54,0x5F,  /* 000003C0    "[.K.LPT_" */
  44.139 +    0x08,0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0,  /* 000003C8    "._HID.A." */
  44.140 +    0x04,0x00,0x14,0x28,0x5F,0x53,0x54,0x41,  /* 000003D0    "...(_STA" */
  44.141 +    0x00,0x70,0x5E,0x5E,0x5E,0x2E,0x50,0x58,  /* 000003D8    ".p^^^.PX" */
  44.142 +    0x31,0x33,0x44,0x52,0x53,0x41,0x60,0x7B,  /* 000003E0    "13DRSA`{" */
  44.143 +    0x60,0x0C,0x00,0x00,0x00,0x80,0x60,0xA0,  /* 000003E8    "`.....`." */
  44.144 +    0x06,0x93,0x60,0x00,0xA4,0x00,0xA1,0x04,  /* 000003F0    "..`....." */
  44.145 +    0xA4,0x0A,0x0F,0x14,0x21,0x5F,0x43,0x52,  /* 000003F8    "....!_CR" */
  44.146 +    0x53,0x00,0x08,0x42,0x55,0x46,0x30,0x11,  /* 00000400    "S..BUF0." */
  44.147 +    0x10,0x0A,0x0D,0x47,0x01,0x78,0x03,0x78,  /* 00000408    "...G.x.x" */
  44.148 +    0x03,0x08,0x08,0x22,0x80,0x00,0x79,0x00,  /* 00000410    "..."..y." */
  44.149 +    0xA4,0x42,0x55,0x46,0x30,0x5B,0x82,0x41,  /* 00000418    ".BUF0[.A" */
  44.150 +    0x06,0x43,0x4F,0x4D,0x31,0x08,0x5F,0x48,  /* 00000420    ".COM1._H" */
  44.151 +    0x49,0x44,0x0C,0x41,0xD0,0x05,0x01,0x08,  /* 00000428    "ID.A...." */
  44.152 +    0x5F,0x55,0x49,0x44,0x01,0x14,0x28,0x5F,  /* 00000430    "_UID..(_" */
  44.153 +    0x53,0x54,0x41,0x00,0x70,0x5E,0x5E,0x5E,  /* 00000438    "STA.p^^^" */
  44.154 +    0x2E,0x50,0x58,0x31,0x33,0x44,0x52,0x53,  /* 00000440    ".PX13DRS" */
  44.155 +    0x43,0x60,0x7B,0x60,0x0C,0x00,0x00,0x00,  /* 00000448    "C`{`...." */
  44.156 +    0x08,0x60,0xA0,0x06,0x93,0x60,0x00,0xA4,  /* 00000450    ".`...`.." */
  44.157 +    0x00,0xA1,0x04,0xA4,0x0A,0x0F,0x14,0x21,  /* 00000458    ".......!" */
  44.158 +    0x5F,0x43,0x52,0x53,0x00,0x08,0x42,0x55,  /* 00000460    "_CRS..BU" */
  44.159 +    0x46,0x30,0x11,0x10,0x0A,0x0D,0x47,0x01,  /* 00000468    "F0....G." */
  44.160 +    0xF8,0x03,0xF8,0x03,0x00,0x08,0x22,0x10,  /* 00000470    "......"." */
  44.161 +    0x00,0x79,0x00,0xA4,0x42,0x55,0x46,0x30,  /* 00000478    ".y..BUF0" */
  44.162 +    0x5B,0x82,0x42,0x06,0x43,0x4F,0x4D,0x32,  /* 00000480    "[.B.COM2" */
  44.163 +    0x08,0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0,  /* 00000488    "._HID.A." */
  44.164 +    0x05,0x01,0x08,0x5F,0x55,0x49,0x44,0x0A,  /* 00000490    "..._UID." */
  44.165 +    0x02,0x14,0x28,0x5F,0x53,0x54,0x41,0x00,  /* 00000498    "..(_STA." */
  44.166 +    0x70,0x5E,0x5E,0x5E,0x2E,0x50,0x58,0x31,  /* 000004A0    "p^^^.PX1" */
  44.167 +    0x33,0x44,0x52,0x53,0x43,0x60,0x7B,0x60,  /* 000004A8    "3DRSC`{`" */
  44.168 +    0x0C,0x00,0x00,0x00,0x80,0x60,0xA0,0x06,  /* 000004B0    ".....`.." */
  44.169 +    0x93,0x60,0x00,0xA4,0x00,0xA1,0x04,0xA4,  /* 000004B8    ".`......" */
  44.170 +    0x0A,0x0F,0x14,0x21,0x5F,0x43,0x52,0x53,  /* 000004C0    "...!_CRS" */
  44.171 +    0x00,0x08,0x42,0x55,0x46,0x30,0x11,0x10,  /* 000004C8    "..BUF0.." */
  44.172 +    0x0A,0x0D,0x47,0x01,0xF8,0x02,0xF8,0x02,  /* 000004D0    "..G....." */
  44.173 +    0x00,0x08,0x22,0x08,0x00,0x79,0x00,0xA4,  /* 000004D8    ".."..y.." */
  44.174 +    0x42,0x55,0x46,0x30,0x5B,0x82,0x40,0x05,  /* 000004E0    "BUF0[.@." */
  44.175 +    0x50,0x58,0x31,0x33,0x08,0x5F,0x41,0x44,  /* 000004E8    "PX13._AD" */
  44.176 +    0x52,0x0C,0x03,0x00,0x01,0x00,0x5B,0x80,  /* 000004F0    "R.....[." */
  44.177 +    0x50,0x31,0x33,0x43,0x02,0x0A,0x5C,0x0A,  /* 000004F8    "P13C..\." */
  44.178 +    0x24,0x5B,0x81,0x33,0x50,0x31,0x33,0x43,  /* 00000500    "$[.3P13C" */
  44.179 +    0x03,0x44,0x52,0x53,0x41,0x20,0x44,0x52,  /* 00000508    ".DRSA DR" */
  44.180 +    0x53,0x42,0x20,0x44,0x52,0x53,0x43,0x20,  /* 00000510    "SB DRSC " */
  44.181 +    0x44,0x52,0x53,0x45,0x20,0x44,0x52,0x53,  /* 00000518    "DRSE DRS" */
  44.182 +    0x46,0x20,0x44,0x52,0x53,0x47,0x20,0x44,  /* 00000520    "F DRSG D" */
  44.183 +    0x52,0x53,0x48,0x20,0x44,0x52,0x53,0x49,  /* 00000528    "RSH DRSI" */
  44.184 +    0x20,0x44,0x52,0x53,0x4A,0x20,0x10,0x4F,  /* 00000530    " DRSJ .O" */
  44.185 +    0x2E,0x5F,0x53,0x42,0x5F,0x5B,0x81,0x24,  /* 00000538    "._SB_[.$" */
  44.186 +    0x2F,0x03,0x50,0x43,0x49,0x30,0x49,0x53,  /* 00000540    "/.PCI0IS" */
  44.187 +    0x41,0x5F,0x50,0x34,0x30,0x43,0x01,0x50,  /* 00000548    "A_P40C.P" */
  44.188 +    0x52,0x51,0x30,0x08,0x50,0x52,0x51,0x31,  /* 00000550    "RQ0.PRQ1" */
  44.189 +    0x08,0x50,0x52,0x51,0x32,0x08,0x50,0x52,  /* 00000558    ".PRQ2.PR" */
  44.190 +    0x51,0x33,0x08,0x5B,0x82,0x4E,0x0A,0x4C,  /* 00000560    "Q3.[.N.L" */
  44.191 +    0x4E,0x4B,0x41,0x08,0x5F,0x48,0x49,0x44,  /* 00000568    "NKA._HID" */
  44.192 +    0x0C,0x41,0xD0,0x0C,0x0F,0x08,0x5F,0x55,  /* 00000570    ".A...._U" */
  44.193 +    0x49,0x44,0x01,0x08,0x5F,0x50,0x52,0x53,  /* 00000578    "ID.._PRS" */
  44.194 +    0x11,0x09,0x0A,0x06,0x23,0xF8,0x1E,0x18,  /* 00000580    "....#..." */
  44.195 +    0x79,0x00,0x14,0x1A,0x5F,0x53,0x54,0x41,  /* 00000588    "y..._STA" */
  44.196 +    0x00,0x70,0x0A,0x0B,0x60,0xA0,0x0D,0x7B,  /* 00000590    ".p..`..{" */
  44.197 +    0x0A,0x80,0x50,0x52,0x51,0x30,0x61,0x70,  /* 00000598    "..PRQ0ap" */
  44.198 +    0x0A,0x09,0x60,0xA4,0x60,0x14,0x11,0x5F,  /* 000005A0    "..`.`.._" */
  44.199 +    0x44,0x49,0x53,0x00,0x7D,0x50,0x52,0x51,  /* 000005A8    "DIS.}PRQ" */
  44.200 +    0x30,0x0A,0x80,0x50,0x52,0x51,0x30,0x14,  /* 000005B0    "0..PRQ0." */
  44.201 +    0x3F,0x5F,0x43,0x52,0x53,0x00,0x08,0x50,  /* 000005B8    "?_CRS..P" */
  44.202 +    0x52,0x52,0x30,0x11,0x09,0x0A,0x06,0x23,  /* 000005C0    "RR0....#" */
  44.203 +    0x02,0x00,0x18,0x79,0x00,0x8B,0x50,0x52,  /* 000005C8    "...y..PR" */
  44.204 +    0x52,0x30,0x01,0x54,0x4D,0x50,0x5F,0x70,  /* 000005D0    "R0.TMP_p" */
  44.205 +    0x50,0x52,0x51,0x30,0x60,0xA0,0x0C,0x95,  /* 000005D8    "PRQ0`..." */
  44.206 +    0x60,0x0A,0x80,0x79,0x01,0x60,0x54,0x4D,  /* 000005E0    "`..y.`TM" */
  44.207 +    0x50,0x5F,0xA1,0x07,0x70,0x00,0x54,0x4D,  /* 000005E8    "P_..p.TM" */
  44.208 +    0x50,0x5F,0xA4,0x50,0x52,0x52,0x30,0x14,  /* 000005F0    "P_.PRR0." */
  44.209 +    0x1B,0x5F,0x53,0x52,0x53,0x01,0x8B,0x68,  /* 000005F8    "._SRS..h" */
  44.210 +    0x01,0x54,0x4D,0x50,0x5F,0x82,0x54,0x4D,  /* 00000600    ".TMP_.TM" */
  44.211 +    0x50,0x5F,0x60,0x76,0x60,0x70,0x60,0x50,  /* 00000608    "P_`v`p`P" */
  44.212 +    0x52,0x51,0x30,0x5B,0x82,0x4F,0x0A,0x4C,  /* 00000610    "RQ0[.O.L" */
  44.213 +    0x4E,0x4B,0x42,0x08,0x5F,0x48,0x49,0x44,  /* 00000618    "NKB._HID" */
  44.214 +    0x0C,0x41,0xD0,0x0C,0x0F,0x08,0x5F,0x55,  /* 00000620    ".A...._U" */
  44.215 +    0x49,0x44,0x0A,0x02,0x08,0x5F,0x50,0x52,  /* 00000628    "ID..._PR" */
  44.216 +    0x53,0x11,0x09,0x0A,0x06,0x23,0xF8,0x1E,  /* 00000630    "S....#.." */
  44.217 +    0x18,0x79,0x00,0x14,0x1A,0x5F,0x53,0x54,  /* 00000638    ".y..._ST" */
  44.218 +    0x41,0x00,0x70,0x0A,0x0B,0x60,0xA0,0x0D,  /* 00000640    "A.p..`.." */
  44.219 +    0x7B,0x0A,0x80,0x50,0x52,0x51,0x31,0x61,  /* 00000648    "{..PRQ1a" */
  44.220 +    0x70,0x0A,0x09,0x60,0xA4,0x60,0x14,0x11,  /* 00000650    "p..`.`.." */
  44.221 +    0x5F,0x44,0x49,0x53,0x00,0x7D,0x50,0x52,  /* 00000658    "_DIS.}PR" */
  44.222 +    0x51,0x31,0x0A,0x80,0x50,0x52,0x51,0x31,  /* 00000660    "Q1..PRQ1" */
  44.223 +    0x14,0x3F,0x5F,0x43,0x52,0x53,0x00,0x08,  /* 00000668    ".?_CRS.." */
  44.224 +    0x50,0x52,0x52,0x30,0x11,0x09,0x0A,0x06,  /* 00000670    "PRR0...." */
  44.225 +    0x23,0x02,0x00,0x18,0x79,0x00,0x8B,0x50,  /* 00000678    "#...y..P" */
  44.226 +    0x52,0x52,0x30,0x01,0x54,0x4D,0x50,0x5F,  /* 00000680    "RR0.TMP_" */
  44.227 +    0x70,0x50,0x52,0x51,0x31,0x60,0xA0,0x0C,  /* 00000688    "pPRQ1`.." */
  44.228 +    0x95,0x60,0x0A,0x80,0x79,0x01,0x60,0x54,  /* 00000690    ".`..y.`T" */
  44.229 +    0x4D,0x50,0x5F,0xA1,0x07,0x70,0x00,0x54,  /* 00000698    "MP_..p.T" */
  44.230 +    0x4D,0x50,0x5F,0xA4,0x50,0x52,0x52,0x30,  /* 000006A0    "MP_.PRR0" */
  44.231 +    0x14,0x1B,0x5F,0x53,0x52,0x53,0x01,0x8B,  /* 000006A8    ".._SRS.." */
  44.232 +    0x68,0x01,0x54,0x4D,0x50,0x5F,0x82,0x54,  /* 000006B0    "h.TMP_.T" */
  44.233 +    0x4D,0x50,0x5F,0x60,0x76,0x60,0x70,0x60,  /* 000006B8    "MP_`v`p`" */
  44.234 +    0x50,0x52,0x51,0x31,0x5B,0x82,0x4F,0x0A,  /* 000006C0    "PRQ1[.O." */
  44.235 +    0x4C,0x4E,0x4B,0x43,0x08,0x5F,0x48,0x49,  /* 000006C8    "LNKC._HI" */
  44.236 +    0x44,0x0C,0x41,0xD0,0x0C,0x0F,0x08,0x5F,  /* 000006D0    "D.A...._" */
  44.237 +    0x55,0x49,0x44,0x0A,0x03,0x08,0x5F,0x50,  /* 000006D8    "UID..._P" */
  44.238 +    0x52,0x53,0x11,0x09,0x0A,0x06,0x23,0xF8,  /* 000006E0    "RS....#." */
  44.239 +    0x1E,0x18,0x79,0x00,0x14,0x1A,0x5F,0x53,  /* 000006E8    "..y..._S" */
  44.240 +    0x54,0x41,0x00,0x70,0x0A,0x0B,0x60,0xA0,  /* 000006F0    "TA.p..`." */
  44.241 +    0x0D,0x7B,0x0A,0x80,0x50,0x52,0x51,0x32,  /* 000006F8    ".{..PRQ2" */
  44.242 +    0x61,0x70,0x0A,0x09,0x60,0xA4,0x60,0x14,  /* 00000700    "ap..`.`." */
  44.243 +    0x11,0x5F,0x44,0x49,0x53,0x00,0x7D,0x50,  /* 00000708    "._DIS.}P" */
  44.244 +    0x52,0x51,0x32,0x0A,0x80,0x50,0x52,0x51,  /* 00000710    "RQ2..PRQ" */
  44.245 +    0x32,0x14,0x3F,0x5F,0x43,0x52,0x53,0x00,  /* 00000718    "2.?_CRS." */
  44.246 +    0x08,0x50,0x52,0x52,0x30,0x11,0x09,0x0A,  /* 00000720    ".PRR0..." */
  44.247 +    0x06,0x23,0x02,0x00,0x18,0x79,0x00,0x8B,  /* 00000728    ".#...y.." */
  44.248 +    0x50,0x52,0x52,0x30,0x01,0x54,0x4D,0x50,  /* 00000730    "PRR0.TMP" */
  44.249 +    0x5F,0x70,0x50,0x52,0x51,0x32,0x60,0xA0,  /* 00000738    "_pPRQ2`." */
  44.250 +    0x0C,0x95,0x60,0x0A,0x80,0x79,0x01,0x60,  /* 00000740    "..`..y.`" */
  44.251 +    0x54,0x4D,0x50,0x5F,0xA1,0x07,0x70,0x00,  /* 00000748    "TMP_..p." */
  44.252 +    0x54,0x4D,0x50,0x5F,0xA4,0x50,0x52,0x52,  /* 00000750    "TMP_.PRR" */
  44.253 +    0x30,0x14,0x1B,0x5F,0x53,0x52,0x53,0x01,  /* 00000758    "0.._SRS." */
  44.254 +    0x8B,0x68,0x01,0x54,0x4D,0x50,0x5F,0x82,  /* 00000760    ".h.TMP_." */
  44.255 +    0x54,0x4D,0x50,0x5F,0x60,0x76,0x60,0x70,  /* 00000768    "TMP_`v`p" */
  44.256 +    0x60,0x50,0x52,0x51,0x32,0x5B,0x82,0x4F,  /* 00000770    "`PRQ2[.O" */
  44.257 +    0x0A,0x4C,0x4E,0x4B,0x44,0x08,0x5F,0x48,  /* 00000778    ".LNKD._H" */
  44.258 +    0x49,0x44,0x0C,0x41,0xD0,0x0C,0x0F,0x08,  /* 00000780    "ID.A...." */
  44.259 +    0x5F,0x55,0x49,0x44,0x0A,0x04,0x08,0x5F,  /* 00000788    "_UID..._" */
  44.260 +    0x50,0x52,0x53,0x11,0x09,0x0A,0x06,0x23,  /* 00000790    "PRS....#" */
  44.261 +    0xF8,0x1E,0x18,0x79,0x00,0x14,0x1A,0x5F,  /* 00000798    "...y..._" */
  44.262 +    0x53,0x54,0x41,0x00,0x70,0x0A,0x0B,0x60,  /* 000007A0    "STA.p..`" */
  44.263 +    0xA0,0x0D,0x7B,0x0A,0x80,0x50,0x52,0x51,  /* 000007A8    "..{..PRQ" */
  44.264 +    0x33,0x61,0x70,0x0A,0x09,0x60,0xA4,0x60,  /* 000007B0    "3ap..`.`" */
  44.265 +    0x14,0x11,0x5F,0x44,0x49,0x53,0x00,0x7D,  /* 000007B8    ".._DIS.}" */
  44.266 +    0x50,0x52,0x51,0x33,0x0A,0x80,0x50,0x52,  /* 000007C0    "PRQ3..PR" */
  44.267 +    0x51,0x33,0x14,0x3F,0x5F,0x43,0x52,0x53,  /* 000007C8    "Q3.?_CRS" */
  44.268 +    0x00,0x08,0x50,0x52,0x52,0x30,0x11,0x09,  /* 000007D0    "..PRR0.." */
  44.269 +    0x0A,0x06,0x23,0x02,0x00,0x18,0x79,0x00,  /* 000007D8    "..#...y." */
  44.270 +    0x8B,0x50,0x52,0x52,0x30,0x01,0x54,0x4D,  /* 000007E0    ".PRR0.TM" */
  44.271 +    0x50,0x5F,0x70,0x50,0x52,0x51,0x33,0x60,  /* 000007E8    "P_pPRQ3`" */
  44.272 +    0xA0,0x0C,0x95,0x60,0x0A,0x80,0x79,0x01,  /* 000007F0    "...`..y." */
  44.273 +    0x60,0x54,0x4D,0x50,0x5F,0xA1,0x07,0x70,  /* 000007F8    "`TMP_..p" */
  44.274 +    0x00,0x54,0x4D,0x50,0x5F,0xA4,0x50,0x52,  /* 00000800    ".TMP_.PR" */
  44.275 +    0x52,0x30,0x14,0x1B,0x5F,0x53,0x52,0x53,  /* 00000808    "R0.._SRS" */
  44.276 +    0x01,0x8B,0x68,0x01,0x54,0x4D,0x50,0x5F,  /* 00000810    "..h.TMP_" */
  44.277 +    0x82,0x54,0x4D,0x50,0x5F,0x60,0x76,0x60,  /* 00000818    ".TMP_`v`" */
  44.278 +    0x70,0x60,0x50,0x52,0x51,0x33,0x08,0x5F,  /* 00000820    "p`PRQ3._" */
  44.279 +    0x53,0x35,0x5F,0x12,0x06,0x04,0x00,0x00,  /* 00000828    "S5_....." */
  44.280 +    0x00,0x00,
  44.281 +};
    45.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    45.2 +++ b/tools/ioemu/hw/acpi.c	Mon Aug 07 18:25:30 2006 +0100
    45.3 @@ -0,0 +1,615 @@
    45.4 +/*
    45.5 + * ACPI implementation
    45.6 + * 
    45.7 + * Copyright (c) 2006 Fabrice Bellard
    45.8 + * 
    45.9 + * This library is free software; you can redistribute it and/or
   45.10 + * modify it under the terms of the GNU Lesser General Public
   45.11 + * License version 2 as published by the Free Software Foundation.
   45.12 + *
   45.13 + * This library is distributed in the hope that it will be useful,
   45.14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   45.15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   45.16 + * Lesser General Public License for more details.
   45.17 + *
   45.18 + * You should have received a copy of the GNU Lesser General Public
   45.19 + * License along with this library; if not, write to the Free Software
   45.20 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   45.21 + */
   45.22 +#include "vl.h"
   45.23 +
   45.24 +//#define DEBUG
   45.25 +
   45.26 +/* i82731AB (PIIX4) compatible power management function */
   45.27 +#define PM_FREQ 3579545
   45.28 +
   45.29 +/* XXX: make them variable */
   45.30 +#define PM_IO_BASE        0xb000
   45.31 +#define SMI_CMD_IO_ADDR   0xb040
   45.32 +#define ACPI_DBG_IO_ADDR  0xb044
   45.33 +
   45.34 +typedef struct PIIX4PMState {
   45.35 +    PCIDevice dev;
   45.36 +    uint16_t pmsts;
   45.37 +    uint16_t pmen;
   45.38 +    uint16_t pmcntrl;
   45.39 +    QEMUTimer *tmr_timer;
   45.40 +    int64_t tmr_overflow_time;
   45.41 +} PIIX4PMState;
   45.42 +
   45.43 +#define RTC_EN (1 << 10)
   45.44 +#define PWRBTN_EN (1 << 8)
   45.45 +#define GBL_EN (1 << 5)
   45.46 +#define TMROF_EN (1 << 0)
   45.47 +
   45.48 +#define SCI_EN (1 << 0)
   45.49 +
   45.50 +#define SUS_EN (1 << 13)
   45.51 +
   45.52 +/* Note: only used for ACPI bios init. Could be deleted when ACPI init
   45.53 +   is integrated in Bochs BIOS */
   45.54 +static PIIX4PMState *piix4_pm_state;
   45.55 +
   45.56 +static uint32_t get_pmtmr(PIIX4PMState *s)
   45.57 +{
   45.58 +    uint32_t d;
   45.59 +    d = muldiv64(qemu_get_clock(vm_clock), PM_FREQ, ticks_per_sec);
   45.60 +    return d & 0xffffff;
   45.61 +}
   45.62 +
   45.63 +static int get_pmsts(PIIX4PMState *s)
   45.64 +{
   45.65 +    int64_t d;
   45.66 +    int pmsts;
   45.67 +    pmsts = s->pmsts;
   45.68 +    d = muldiv64(qemu_get_clock(vm_clock), PM_FREQ, ticks_per_sec);
   45.69 +    if (d >= s->tmr_overflow_time)
   45.70 +        s->pmsts |= TMROF_EN;
   45.71 +    return pmsts;
   45.72 +}
   45.73 +
   45.74 +static void pm_update_sci(PIIX4PMState *s)
   45.75 +{
   45.76 +    int sci_level, pmsts;
   45.77 +    int64_t expire_time;
   45.78 +    
   45.79 +    pmsts = get_pmsts(s);
   45.80 +    sci_level = (((pmsts & s->pmen) & 
   45.81 +                  (RTC_EN | PWRBTN_EN | GBL_EN | TMROF_EN)) != 0);
   45.82 +    pci_set_irq(&s->dev, 0, sci_level);
   45.83 +    /* schedule a timer interruption if needed */
   45.84 +    if ((s->pmen & TMROF_EN) && !(pmsts & TMROF_EN)) {
   45.85 +        expire_time = muldiv64(s->tmr_overflow_time, ticks_per_sec, PM_FREQ);
   45.86 +        qemu_mod_timer(s->tmr_timer, expire_time);
   45.87 +    } else {
   45.88 +        qemu_del_timer(s->tmr_timer);
   45.89 +    }
   45.90 +}
   45.91 +
   45.92 +static void pm_tmr_timer(void *opaque)
   45.93 +{
   45.94 +    PIIX4PMState *s = opaque;
   45.95 +    pm_update_sci(s);
   45.96 +}
   45.97 +
   45.98 +static void pm_ioport_writew(void *opaque, uint32_t addr, uint32_t val)
   45.99 +{
  45.100 +    PIIX4PMState *s = opaque;
  45.101 +    addr &= 0x3f;
  45.102 +    switch(addr) {
  45.103 +    case 0x00:
  45.104 +        {
  45.105 +            int64_t d;
  45.106 +            int pmsts;
  45.107 +            pmsts = get_pmsts(s);
  45.108 +            if (pmsts & val & TMROF_EN) {
  45.109 +                /* if TMRSTS is reset, then compute the new overflow time */
  45.110 +                d = muldiv64(qemu_get_clock(vm_clock), PM_FREQ, ticks_per_sec);
  45.111 +                s->tmr_overflow_time = (d + 0x800000LL) & ~0x7fffffLL;
  45.112 +            }
  45.113 +            s->pmsts &= ~val;
  45.114 +            pm_update_sci(s);
  45.115 +        }
  45.116 +        break;
  45.117 +    case 0x02:
  45.118 +        s->pmen = val;
  45.119 +        pm_update_sci(s);
  45.120 +        break;
  45.121 +    case 0x04:
  45.122 +        {
  45.123 +            int sus_typ;
  45.124 +            s->pmcntrl = val & ~(SUS_EN);
  45.125 +            if (val & SUS_EN) {
  45.126 +                /* change suspend type */
  45.127 +                sus_typ = (val >> 10) & 3;
  45.128 +                switch(sus_typ) {
  45.129 +                case 0: /* soft power off */
  45.130 +                    qemu_system_shutdown_request();
  45.131 +                    break;
  45.132 +                default:
  45.133 +                    break;
  45.134 +                }
  45.135 +            }
  45.136 +        }
  45.137 +        break;
  45.138 +    default:
  45.139 +        break;
  45.140 +    }
  45.141 +#ifdef DEBUG
  45.142 +    printf("PM writew port=0x%04x val=0x%04x\n", addr, val);
  45.143 +#endif
  45.144 +}
  45.145 +
  45.146 +static uint32_t pm_ioport_readw(void *opaque, uint32_t addr)
  45.147 +{
  45.148 +    PIIX4PMState *s = opaque;
  45.149 +    uint32_t val;
  45.150 +
  45.151 +    addr &= 0x3f;
  45.152 +    switch(addr) {
  45.153 +    case 0x00:
  45.154 +        val = get_pmsts(s);
  45.155 +        break;
  45.156 +    case 0x02:
  45.157 +        val = s->pmen;
  45.158 +        break;
  45.159 +    case 0x04:
  45.160 +        val = s->pmcntrl;
  45.161 +        break;
  45.162 +    default:
  45.163 +        val = 0;
  45.164 +        break;
  45.165 +    }
  45.166 +#ifdef DEBUG
  45.167 +    printf("PM readw port=0x%04x val=0x%04x\n", addr, val);
  45.168 +#endif
  45.169 +    return val;
  45.170 +}
  45.171 +
  45.172 +static void pm_ioport_writel(void *opaque, uint32_t addr, uint32_t val)
  45.173 +{
  45.174 +    //    PIIX4PMState *s = opaque;
  45.175 +    addr &= 0x3f;
  45.176 +#ifdef DEBUG
  45.177 +    printf("PM writel port=0x%04x val=0x%08x\n", addr, val);
  45.178 +#endif
  45.179 +}
  45.180 +
  45.181 +static uint32_t pm_ioport_readl(void *opaque, uint32_t addr)
  45.182 +{
  45.183 +    PIIX4PMState *s = opaque;
  45.184 +    uint32_t val;
  45.185 +
  45.186 +    addr &= 0x3f;
  45.187 +    switch(addr) {
  45.188 +    case 0x08:
  45.189 +        val = get_pmtmr(s);
  45.190 +        break;
  45.191 +    default:
  45.192 +        val = 0;
  45.193 +        break;
  45.194 +    }
  45.195 +#ifdef DEBUG
  45.196 +    printf("PM readl port=0x%04x val=0x%08x\n", addr, val);
  45.197 +#endif
  45.198 +    return val;
  45.199 +}
  45.200 +
  45.201 +static void smi_cmd_writeb(void *opaque, uint32_t addr, uint32_t val)
  45.202 +{
  45.203 +    PIIX4PMState *s = opaque;
  45.204 +#ifdef DEBUG
  45.205 +    printf("SMI cmd val=0x%02x\n", val);
  45.206 +#endif
  45.207 +    switch(val) {
  45.208 +    case 0xf0: /* ACPI disable */
  45.209 +        s->pmcntrl &= ~SCI_EN;
  45.210 +        break;
  45.211 +    case 0xf1: /* ACPI enable */
  45.212 +        s->pmcntrl |= SCI_EN;
  45.213 +        break;
  45.214 +    }
  45.215 +}
  45.216 +
  45.217 +static void acpi_dbg_writel(void *opaque, uint32_t addr, uint32_t val)
  45.218 +{
  45.219 +#if defined(DEBUG)
  45.220 +    printf("ACPI: DBG: 0x%08x\n", val);
  45.221 +#endif
  45.222 +}
  45.223 +
  45.224 +/* XXX: we still add it to the PIIX3 and we count on the fact that
  45.225 +   OSes are smart enough to accept this strange configuration */
  45.226 +void piix4_pm_init(PCIBus *bus, int devfn)
  45.227 +{
  45.228 +    PIIX4PMState *s;
  45.229 +    uint8_t *pci_conf;
  45.230 +    uint32_t pm_io_base;
  45.231 +
  45.232 +    s = (PIIX4PMState *)pci_register_device(bus,
  45.233 +                                         "PM", sizeof(PIIX4PMState),
  45.234 +                                         devfn, NULL, NULL);
  45.235 +    pci_conf = s->dev.config;
  45.236 +    pci_conf[0x00] = 0x86;
  45.237 +    pci_conf[0x01] = 0x80;
  45.238 +    pci_conf[0x02] = 0x13;
  45.239 +    pci_conf[0x03] = 0x71;
  45.240 +    pci_conf[0x08] = 0x00; // revision number
  45.241 +    pci_conf[0x09] = 0x00;
  45.242 +    pci_conf[0x0a] = 0x80; // other bridge device
  45.243 +    pci_conf[0x0b] = 0x06; // bridge device
  45.244 +    pci_conf[0x0e] = 0x00; // header_type
  45.245 +    pci_conf[0x3d] = 0x01; // interrupt pin 1
  45.246 +    
  45.247 +    pm_io_base = PM_IO_BASE;
  45.248 +    pci_conf[0x40] = pm_io_base | 1;
  45.249 +    pci_conf[0x41] = pm_io_base >> 8;
  45.250 +    register_ioport_write(pm_io_base, 64, 2, pm_ioport_writew, s);
  45.251 +    register_ioport_read(pm_io_base, 64, 2, pm_ioport_readw, s);
  45.252 +    register_ioport_write(pm_io_base, 64, 4, pm_ioport_writel, s);
  45.253 +    register_ioport_read(pm_io_base, 64, 4, pm_ioport_readl, s);
  45.254 +    
  45.255 +    register_ioport_write(SMI_CMD_IO_ADDR, 1, 1, smi_cmd_writeb, s);
  45.256 +    register_ioport_write(ACPI_DBG_IO_ADDR, 4, 4, acpi_dbg_writel, s);
  45.257 +
  45.258 +    /* XXX: which specification is used ? The i82731AB has different
  45.259 +       mappings */
  45.260 +    pci_conf[0x5f] = (parallel_hds[0] != NULL ? 0x80 : 0) | 0x10;
  45.261 +    pci_conf[0x63] = 0x60;
  45.262 +    pci_conf[0x67] = (serial_hds[0] != NULL ? 0x08 : 0) |
  45.263 +	(serial_hds[1] != NULL ? 0x90 : 0);
  45.264 +
  45.265 +    s->tmr_timer = qemu_new_timer(vm_clock, pm_tmr_timer, s);
  45.266 +    piix4_pm_state = s;
  45.267 +}
  45.268 +
  45.269 +/* ACPI tables */
  45.270 +/* XXX: move them in the Bochs BIOS ? */
  45.271 +
  45.272 +/*************************************************/
  45.273 +
  45.274 +/* Table structure from Linux kernel (the ACPI tables are under the
  45.275 +   BSD license) */
  45.276 +
  45.277 +#define ACPI_TABLE_HEADER_DEF   /* ACPI common table header */ \
  45.278 +	uint8_t                            signature [4];          /* ACPI signature (4 ASCII characters) */\
  45.279 +	uint32_t                             length;                 /* Length of table, in bytes, including header */\
  45.280 +	uint8_t                              revision;               /* ACPI Specification minor version # */\
  45.281 +	uint8_t                              checksum;               /* To make sum of entire table == 0 */\
  45.282 +	uint8_t                            oem_id [6];             /* OEM identification */\
  45.283 +	uint8_t                            oem_table_id [8];       /* OEM table identification */\
  45.284 +	uint32_t                             oem_revision;           /* OEM revision number */\
  45.285 +	uint8_t                            asl_compiler_id [4];    /* ASL compiler vendor ID */\
  45.286 +	uint32_t                             asl_compiler_revision;  /* ASL compiler revision number */
  45.287 +
  45.288 +
  45.289 +struct acpi_table_header         /* ACPI common table header */
  45.290 +{
  45.291 +	ACPI_TABLE_HEADER_DEF
  45.292 +};
  45.293 +
  45.294 +struct rsdp_descriptor         /* Root System Descriptor Pointer */
  45.295 +{
  45.296 +	uint8_t                            signature [8];          /* ACPI signature, contains "RSD PTR " */
  45.297 +	uint8_t                              checksum;               /* To make sum of struct == 0 */
  45.298 +	uint8_t                            oem_id [6];             /* OEM identification */
  45.299 +	uint8_t                              revision;               /* Must be 0 for 1.0, 2 for 2.0 */
  45.300 +	uint32_t                             rsdt_physical_address;  /* 32-bit physical address of RSDT */
  45.301 +	uint32_t                             length;                 /* XSDT Length in bytes including hdr */
  45.302 +	uint64_t                             xsdt_physical_address;  /* 64-bit physical address of XSDT */
  45.303 +	uint8_t                              extended_checksum;      /* Checksum of entire table */
  45.304 +	uint8_t                            reserved [3];           /* Reserved field must be 0 */
  45.305 +};
  45.306 +
  45.307 +/*
  45.308 + * ACPI 1.0 Root System Description Table (RSDT)
  45.309 + */
  45.310 +struct rsdt_descriptor_rev1
  45.311 +{
  45.312 +	ACPI_TABLE_HEADER_DEF                           /* ACPI common table header */
  45.313 +	uint32_t                             table_offset_entry [2]; /* Array of pointers to other */
  45.314 +			 /* ACPI tables */
  45.315 +};
  45.316 +
  45.317 +/*
  45.318 + * ACPI 1.0 Firmware ACPI Control Structure (FACS)
  45.319 + */
  45.320 +struct facs_descriptor_rev1
  45.321 +{
  45.322 +	uint8_t                            signature[4];           /* ACPI Signature */
  45.323 +	uint32_t                             length;                 /* Length of structure, in bytes */
  45.324 +	uint32_t                             hardware_signature;     /* Hardware configuration signature */
  45.325 +	uint32_t                             firmware_waking_vector; /* ACPI OS waking vector */
  45.326 +	uint32_t                             global_lock;            /* Global Lock */
  45.327 +	uint32_t                             S4bios_f        : 1;    /* Indicates if S4BIOS support is present */
  45.328 +	uint32_t                             reserved1       : 31;   /* Must be 0 */
  45.329 +	uint8_t                              resverved3 [40];        /* Reserved - must be zero */
  45.330 +};
  45.331 +
  45.332 +
  45.333 +/*
  45.334 + * ACPI 1.0 Fixed ACPI Description Table (FADT)
  45.335 + */
  45.336 +struct fadt_descriptor_rev1
  45.337 +{
  45.338 +	ACPI_TABLE_HEADER_DEF                           /* ACPI common table header */
  45.339 +	uint32_t                             firmware_ctrl;          /* Physical address of FACS */
  45.340 +	uint32_t                             dsdt;                   /* Physical address of DSDT */
  45.341 +	uint8_t                              model;                  /* System Interrupt Model */
  45.342 +	uint8_t                              reserved1;              /* Reserved */
  45.343 +	uint16_t                             sci_int;                /* System vector of SCI interrupt */
  45.344 +	uint32_t                             smi_cmd;                /* Port address of SMI command port */
  45.345 +	uint8_t                              acpi_enable;            /* Value to write to smi_cmd to enable ACPI */
  45.346 +	uint8_t                              acpi_disable;           /* Value to write to smi_cmd to disable ACPI */
  45.347 +	uint8_t                              S4bios_req;             /* Value to write to SMI CMD to enter S4BIOS state */
  45.348 +	uint8_t                              reserved2;              /* Reserved - must be zero */
  45.349 +	uint32_t                             pm1a_evt_blk;           /* Port address of Power Mgt 1a acpi_event Reg Blk */
  45.350 +	uint32_t                             pm1b_evt_blk;           /* Port address of Power Mgt 1b acpi_event Reg Blk */
  45.351 +	uint32_t                             pm1a_cnt_blk;           /* Port address of Power Mgt 1a Control Reg Blk */
  45.352 +	uint32_t                             pm1b_cnt_blk;           /* Port address of Power Mgt 1b Control Reg Blk */
  45.353 +	uint32_t                             pm2_cnt_blk;            /* Port address of Power Mgt 2 Control Reg Blk */
  45.354 +	uint32_t                             pm_tmr_blk;             /* Port address of Power Mgt Timer Ctrl Reg Blk */
  45.355 +	uint32_t                             gpe0_blk;               /* Port addr of General Purpose acpi_event 0 Reg Blk */
  45.356 +	uint32_t                             gpe1_blk;               /* Port addr of General Purpose acpi_event 1 Reg Blk */
  45.357 +	uint8_t                              pm1_evt_len;            /* Byte length of ports at pm1_x_evt_blk */
  45.358 +	uint8_t                              pm1_cnt_len;            /* Byte length of ports at pm1_x_cnt_blk */
  45.359 +	uint8_t                              pm2_cnt_len;            /* Byte Length of ports at pm2_cnt_blk */
  45.360 +	uint8_t                              pm_tmr_len;              /* Byte Length of ports at pm_tm_blk */
  45.361 +	uint8_t                              gpe0_blk_len;           /* Byte Length of ports at gpe0_blk */
  45.362 +	uint8_t                              gpe1_blk_len;           /* Byte Length of ports at gpe1_blk */
  45.363 +	uint8_t                              gpe1_base;              /* Offset in gpe model where gpe1 events start */
  45.364 +	uint8_t                              reserved3;              /* Reserved */
  45.365 +	uint16_t                             plvl2_lat;              /* Worst case HW latency to enter/exit C2 state */
  45.366 +	uint16_t                             plvl3_lat;              /* Worst case HW latency to enter/exit C3 state */
  45.367 +	uint16_t                             flush_size;             /* Size of area read to flush caches */
  45.368 +	uint16_t                             flush_stride;           /* Stride used in flushing caches */
  45.369 +	uint8_t                              duty_offset;            /* Bit location of duty cycle field in p_cnt reg */
  45.370 +	uint8_t                              duty_width;             /* Bit width of duty cycle field in p_cnt reg */
  45.371 +	uint8_t                              day_alrm;               /* Index to day-of-month alarm in RTC CMOS RAM */
  45.372 +	uint8_t                              mon_alrm;               /* Index to month-of-year alarm in RTC CMOS RAM */
  45.373 +	uint8_t                              century;                /* Index to century in RTC CMOS RAM */
  45.374 +	uint8_t                              reserved4;              /* Reserved */
  45.375 +	uint8_t                              reserved4a;             /* Reserved */
  45.376 +	uint8_t                              reserved4b;             /* Reserved */
  45.377 +#if 0
  45.378 +	uint32_t                             wb_invd         : 1;    /* The wbinvd instruction works properly */
  45.379 +	uint32_t                             wb_invd_flush   : 1;    /* The wbinvd flushes but does not invalidate */
  45.380 +	uint32_t                             proc_c1         : 1;    /* All processors support C1 state */
  45.381 +	uint32_t                             plvl2_up        : 1;    /* C2 state works on MP system */
  45.382 +	uint32_t                             pwr_button      : 1;    /* Power button is handled as a generic feature */
  45.383 +	uint32_t                             sleep_button    : 1;    /* Sleep button is handled as a generic feature, or not present */
  45.384 +	uint32_t                             fixed_rTC       : 1;    /* RTC wakeup stat not in fixed register space */
  45.385 +	uint32_t                             rtcs4           : 1;    /* RTC wakeup stat not possible from S4 */
  45.386 +	uint32_t                             tmr_val_ext     : 1;    /* The tmr_val width is 32 bits (0 = 24 bits) */
  45.387 +	uint32_t                             reserved5       : 23;   /* Reserved - must be zero */
  45.388 +#else
  45.389 +        uint32_t flags;
  45.390 +#endif
  45.391 +};
  45.392 +
  45.393 +/*
  45.394 + * MADT values and structures
  45.395 + */
  45.396 +
  45.397 +/* Values for MADT PCATCompat */
  45.398 +
  45.399 +#define DUAL_PIC                0
  45.400 +#define MULTIPLE_APIC           1
  45.401 +
  45.402 +
  45.403 +/* Master MADT */
  45.404 +
  45.405 +struct multiple_apic_table
  45.406 +{
  45.407 +	ACPI_TABLE_HEADER_DEF                           /* ACPI common table header */
  45.408 +	uint32_t                             local_apic_address;     /* Physical address of local APIC */
  45.409 +#if 0
  45.410 +	uint32_t                             PCATcompat      : 1;    /* A one indicates system also has dual 8259s */
  45.411 +	uint32_t                             reserved1       : 31;
  45.412 +#else
  45.413 +        uint32_t                             flags;
  45.414 +#endif
  45.415 +};
  45.416 +
  45.417 +
  45.418 +/* Values for Type in APIC_HEADER_DEF */
  45.419 +
  45.420 +#define APIC_PROCESSOR          0
  45.421 +#define APIC_IO                 1
  45.422 +#define APIC_XRUPT_OVERRIDE     2
  45.423 +#define APIC_NMI                3
  45.424 +#define APIC_LOCAL_NMI          4
  45.425 +#define APIC_ADDRESS_OVERRIDE   5
  45.426 +#define APIC_IO_SAPIC           6
  45.427 +#define APIC_LOCAL_SAPIC        7
  45.428 +#define APIC_XRUPT_SOURCE       8
  45.429 +#define APIC_RESERVED           9           /* 9 and greater are reserved */
  45.430 +
  45.431 +/*
  45.432 + * MADT sub-structures (Follow MULTIPLE_APIC_DESCRIPTION_TABLE)
  45.433 + */
  45.434 +#define APIC_HEADER_DEF                     /* Common APIC sub-structure header */\
  45.435 +	uint8_t                              type; \
  45.436 +	uint8_t                              length;
  45.437 +
  45.438 +/* Sub-structures for MADT */
  45.439 +
  45.440 +struct madt_processor_apic
  45.441 +{
  45.442 +	APIC_HEADER_DEF
  45.443 +	uint8_t                              processor_id;           /* ACPI processor id */
  45.444 +	uint8_t                              local_apic_id;          /* Processor's local APIC id */
  45.445 +#if 0
  45.446 +	uint32_t                             processor_enabled: 1;   /* Processor is usable if set */
  45.447 +	uint32_t                             reserved2       : 31;   /* Reserved, must be zero */
  45.448 +#else
  45.449 +        uint32_t flags;
  45.450 +#endif
  45.451 +};
  45.452 +
  45.453 +struct madt_io_apic
  45.454 +{
  45.455 +	APIC_HEADER_DEF
  45.456 +	uint8_t                              io_apic_id;             /* I/O APIC ID */
  45.457 +	uint8_t                              reserved;               /* Reserved - must be zero */
  45.458 +	uint32_t                             address;                /* APIC physical address */
  45.459 +	uint32_t                             interrupt;              /* Global system interrupt where INTI
  45.460 +			  * lines start */
  45.461 +};
  45.462 +
  45.463 +#include "acpi-dsdt.hex"
  45.464 +
  45.465 +static int acpi_checksum(const uint8_t *data, int len)
  45.466 +{
  45.467 +    int sum, i;
  45.468 +    sum = 0;
  45.469 +    for(i = 0; i < len; i++)
  45.470 +        sum += data[i];
  45.471 +    return (-sum) & 0xff;
  45.472 +}
  45.473 +
  45.474 +static void acpi_build_table_header(struct acpi_table_header *h, 
  45.475 +                                    char *sig, int len)
  45.476 +{
  45.477 +    memcpy(h->signature, sig, 4);
  45.478 +    h->length = cpu_to_le32(len);
  45.479 +    h->revision = 0;
  45.480 +    memcpy(h->oem_id, "QEMU  ", 6);
  45.481 +    memcpy(h->oem_table_id, "QEMU", 4);
  45.482 +    memcpy(h->oem_table_id + 4, sig, 4);
  45.483 +    h->oem_revision = cpu_to_le32(1);
  45.484 +    memcpy(h->asl_compiler_id, "QEMU", 4);
  45.485 +    h->asl_compiler_revision = cpu_to_le32(1);
  45.486 +    h->checksum = acpi_checksum((void *)h, len);
  45.487 +}
  45.488 +
  45.489 +#define ACPI_TABLES_BASE 0x000e8000
  45.490 +
  45.491 +/* base_addr must be a multiple of 4KB */
  45.492 +void acpi_bios_init(void)
  45.493 +{
  45.494 +    struct rsdp_descriptor *rsdp;
  45.495 +    struct rsdt_descriptor_rev1 *rsdt;
  45.496 +    struct fadt_descriptor_rev1 *fadt;
  45.497 +    struct facs_descriptor_rev1 *facs;
  45.498 +    struct multiple_apic_table *madt;
  45.499 +    uint8_t *dsdt;
  45.500 +    uint32_t base_addr, rsdt_addr, fadt_addr, addr, facs_addr, dsdt_addr;
  45.501 +    uint32_t pm_io_base, acpi_tables_size, madt_addr, madt_size;
  45.502 +    int i;
  45.503 +
  45.504 +    /* compute PCI I/O addresses */
  45.505 +    pm_io_base = (piix4_pm_state->dev.config[0x40] | 
  45.506 +        (piix4_pm_state->dev.config[0x41] << 8)) & ~0x3f;
  45.507 +    
  45.508 +    base_addr = ACPI_TABLES_BASE;
  45.509 +
  45.510 +    /* reserve memory space for tables */
  45.511 +    addr = base_addr;
  45.512 +    rsdp = (void *)(phys_ram_base + addr);
  45.513 +    addr += sizeof(*rsdp);
  45.514 +
  45.515 +    rsdt_addr = addr;
  45.516 +    rsdt = (void *)(phys_ram_base + addr);
  45.517 +    addr += sizeof(*rsdt);
  45.518 +    
  45.519 +    fadt_addr = addr;
  45.520 +    fadt = (void *)(phys_ram_base + addr);
  45.521 +    addr += sizeof(*fadt);
  45.522 +
  45.523 +    /* XXX: FACS should be in RAM */
  45.524 +    addr = (addr + 63) & ~63; /* 64 byte alignment for FACS */
  45.525 +    facs_addr = addr;
  45.526 +    facs = (void *)(phys_ram_base + addr);
  45.527 +    addr += sizeof(*facs);
  45.528 +
  45.529 +    dsdt_addr = addr;
  45.530 +    dsdt = (void *)(phys_ram_base + addr);
  45.531 +    addr += sizeof(AmlCode);
  45.532 +
  45.533 +    addr = (addr + 7) & ~7;
  45.534 +    madt_addr = addr;
  45.535 +    madt_size = sizeof(*madt) + 
  45.536 +        sizeof(struct madt_processor_apic) * smp_cpus +
  45.537 +        sizeof(struct madt_io_apic);
  45.538 +    madt = (void *)(phys_ram_base + addr);
  45.539 +    addr += madt_size;
  45.540 +
  45.541 +    acpi_tables_size = addr - base_addr;
  45.542 +
  45.543 +    cpu_register_physical_memory(base_addr, acpi_tables_size, 
  45.544 +                                 base_addr | IO_MEM_ROM);
  45.545 +    
  45.546 +    /* RSDP */
  45.547 +    memset(rsdp, 0, sizeof(*rsdp));
  45.548 +    memcpy(rsdp->signature, "RSD PTR ", 8);
  45.549 +    memcpy(rsdp->oem_id, "QEMU  ", 6);
  45.550 +    rsdp->rsdt_physical_address = cpu_to_le32(rsdt_addr);
  45.551 +    rsdp->checksum = acpi_checksum((void *)rsdp, 20);
  45.552 +    
  45.553 +    /* RSDT */
  45.554 +    rsdt->table_offset_entry[0] = cpu_to_le32(fadt_addr);
  45.555 +    rsdt->table_offset_entry[1] = cpu_to_le32(madt_addr);
  45.556 +    acpi_build_table_header((struct acpi_table_header *)rsdt, 
  45.557 +                            "RSDT", sizeof(*rsdt));
  45.558 +    
  45.559 +    /* FADT */
  45.560 +    memset(fadt, 0, sizeof(*fadt));
  45.561 +    fadt->firmware_ctrl = cpu_to_le32(facs_addr);
  45.562 +    fadt->dsdt = cpu_to_le32(dsdt_addr);
  45.563 +    fadt->model = 1;
  45.564 +    fadt->reserved1 = 0;
  45.565 +    fadt->sci_int = cpu_to_le16(piix4_pm_state->dev.config[0x3c]);
  45.566 +    fadt->smi_cmd = cpu_to_le32(SMI_CMD_IO_ADDR);
  45.567 +    fadt->acpi_enable = 0xf1;
  45.568 +    fadt->acpi_disable = 0xf0;
  45.569 +    fadt->pm1a_evt_blk = cpu_to_le32(pm_io_base);
  45.570 +    fadt->pm1a_cnt_blk = cpu_to_le32(pm_io_base + 0x04);
  45.571 +    fadt->pm_tmr_blk = cpu_to_le32(pm_io_base + 0x08);
  45.572 +    fadt->pm1_evt_len = 4;
  45.573 +    fadt->pm1_cnt_len = 2;
  45.574 +    fadt->pm_tmr_len = 4;
  45.575 +    fadt->plvl2_lat = cpu_to_le16(50);
  45.576 +    fadt->plvl3_lat = cpu_to_le16(50);
  45.577 +    fadt->plvl3_lat = cpu_to_le16(50);
  45.578 +    /* WBINVD + PROC_C1 + PWR_BUTTON + SLP_BUTTON + FIX_RTC */
  45.579 +    fadt->flags = cpu_to_le32((1 << 0) | (1 << 2) | (1 << 4) | (1 << 5) | (1 << 6));
  45.580 +    acpi_build_table_header((struct acpi_table_header *)fadt, "FACP", 
  45.581 +                            sizeof(*fadt));
  45.582 +
  45.583 +    /* FACS */
  45.584 +    memset(facs, 0, sizeof(*facs));
  45.585 +    memcpy(facs->signature, "FACS", 4);
  45.586 +    facs->length = cpu_to_le32(sizeof(*facs));
  45.587 +
  45.588 +    /* DSDT */
  45.589 +    memcpy(dsdt, AmlCode, sizeof(AmlCode));
  45.590 +
  45.591 +    /* MADT */
  45.592 +    {
  45.593 +        struct madt_processor_apic *apic;
  45.594 +        struct madt_io_apic *io_apic;
  45.595 +
  45.596 +        memset(madt, 0, madt_size);
  45.597 +        madt->local_apic_address = cpu_to_le32(0xfee00000);
  45.598 +        madt->flags = cpu_to_le32(1);
  45.599 +        apic = (void *)(madt + 1);
  45.600 +        for(i=0;i<smp_cpus;i++) {
  45.601 +            apic->type = APIC_PROCESSOR;
  45.602 +            apic->length = sizeof(*apic);
  45.603 +            apic->processor_id = i;
  45.604 +            apic->local_apic_id = i;
  45.605 +            apic->flags = cpu_to_le32(1);
  45.606 +            apic++;
  45.607 +        }
  45.608 +        io_apic = (void *)apic;
  45.609 +        io_apic->type = APIC_IO;
  45.610 +        io_apic->length = sizeof(*io_apic);
  45.611 +        io_apic->io_apic_id = smp_cpus;
  45.612 +        io_apic->address = cpu_to_le32(0xfec00000);
  45.613 +        io_apic->interrupt = cpu_to_le32(0);
  45.614 +
  45.615 +        acpi_build_table_header((struct acpi_table_header *)madt, 
  45.616 +                                "APIC", madt_size);
  45.617 +    }
  45.618 +}
    46.1 --- a/tools/ioemu/hw/adlib.c	Mon Aug 07 18:11:59 2006 +0100
    46.2 +++ b/tools/ioemu/hw/adlib.c	Mon Aug 07 18:25:30 2006 +0100
    46.3 @@ -301,6 +301,7 @@ int Adlib_init (AudioState *audio)
    46.4      as.freq = conf.freq;
    46.5      as.nchannels = SHIFT;
    46.6      as.fmt = AUD_FMT_S16;
    46.7 +    as.endianness = AUDIO_HOST_ENDIANNESS;
    46.8  
    46.9      AUD_register_card (audio, "adlib", &s->card);
   46.10  
   46.11 @@ -310,8 +311,7 @@ int Adlib_init (AudioState *audio)
   46.12          "adlib",
   46.13          s,
   46.14          adlib_callback,
   46.15 -        &as,
   46.16 -        0                       /* XXX: little endian? */
   46.17 +        &as
   46.18          );
   46.19      if (!s->voice) {
   46.20          Adlib_fini (s);
    47.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    47.2 +++ b/tools/ioemu/hw/apb_pci.c	Mon Aug 07 18:25:30 2006 +0100
    47.3 @@ -0,0 +1,232 @@
    47.4 +/*
    47.5 + * QEMU Ultrasparc APB PCI host
    47.6 + *
    47.7 + * Copyright (c) 2006 Fabrice Bellard
    47.8 + * 
    47.9 + * Permission is hereby granted, free of charge, to any person obtaining a copy
   47.10 + * of this software and associated documentation files (the "Software"), to deal
   47.11 + * in the Software without restriction, including without limitation the rights
   47.12 + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
   47.13 + * copies of the Software, and to permit persons to whom the Software is
   47.14 + * furnished to do so, subject to the following conditions:
   47.15 + *
   47.16 + * The above copyright notice and this permission notice shall be included in
   47.17 + * all copies or substantial portions of the Software.
   47.18 + *
   47.19 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   47.20 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   47.21 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
   47.22 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   47.23 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
   47.24 + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
   47.25 + * THE SOFTWARE.
   47.26 + */
   47.27 +#include "vl.h"
   47.28 +typedef target_phys_addr_t pci_addr_t;
   47.29 +#include "pci_host.h"
   47.30 +
   47.31 +typedef PCIHostState APBState;
   47.32 +
   47.33 +static void pci_apb_config_writel (void *opaque, target_phys_addr_t addr,
   47.34 +                                         uint32_t val)
   47.35 +{
   47.36 +    APBState *s = opaque;
   47.37 +    int i;
   47.38 +
   47.39 +    for (i = 11; i < 32; i++) {
   47.40 +        if ((val & (1 << i)) != 0)
   47.41 +            break;
   47.42 +    }
   47.43 +    s->config_reg = (1 << 16) | (val & 0x7FC) | (i << 11);
   47.44 +}
   47.45 +
   47.46 +static uint32_t pci_apb_config_readl (void *opaque,
   47.47 +                                            target_phys_addr_t addr)
   47.48 +{
   47.49 +    APBState *s = opaque;
   47.50 +    uint32_t val;
   47.51 +    int devfn;
   47.52 +
   47.53 +    devfn = (s->config_reg >> 8) & 0xFF;
   47.54 +    val = (1 << (devfn >> 3)) | ((devfn & 0x07) << 8) | (s->config_reg & 0xFC);
   47.55 +    return val;
   47.56 +}
   47.57 +
   47.58 +static CPUWriteMemoryFunc *pci_apb_config_write[] = {
   47.59 +    &pci_apb_config_writel,
   47.60 +    &pci_apb_config_writel,
   47.61 +    &pci_apb_config_writel,
   47.62 +};
   47.63 +
   47.64 +static CPUReadMemoryFunc *pci_apb_config_read[] = {
   47.65 +    &pci_apb_config_readl,
   47.66 +    &pci_apb_config_readl,
   47.67 +    &pci_apb_config_readl,
   47.68 +};
   47.69 +
   47.70 +static void apb_config_writel (void *opaque, target_phys_addr_t addr,
   47.71 +			       uint32_t val)
   47.72 +{
   47.73 +    //PCIBus *s = opaque;
   47.74 +
   47.75 +    switch (addr & 0x3f) {
   47.76 +    case 0x00: // Control/Status
   47.77 +    case 0x10: // AFSR
   47.78 +    case 0x18: // AFAR
   47.79 +    case 0x20: // Diagnostic
   47.80 +    case 0x28: // Target address space
   47.81 +	// XXX
   47.82 +    default:
   47.83 +	break;
   47.84 +    }
   47.85 +}
   47.86 +
   47.87 +static uint32_t apb_config_readl (void *opaque,
   47.88 +				  target_phys_addr_t addr)
   47.89 +{
   47.90 +    //PCIBus *s = opaque;
   47.91 +    uint32_t val;
   47.92 +
   47.93 +    switch (addr & 0x3f) {
   47.94 +    case 0x00: // Control/Status
   47.95 +    case 0x10: // AFSR
   47.96 +    case 0x18: // AFAR
   47.97 +    case 0x20: // Diagnostic
   47.98 +    case 0x28: // Target address space
   47.99 +	// XXX
  47.100 +    default:
  47.101 +	val = 0;
  47.102 +	break;
  47.103 +    }
  47.104 +    return val;
  47.105 +}
  47.106 +
  47.107 +static CPUWriteMemoryFunc *apb_config_write[] = {
  47.108 +    &apb_config_writel,
  47.109 +    &apb_config_writel,
  47.110 +    &apb_config_writel,
  47.111 +};
  47.112 +
  47.113 +static CPUReadMemoryFunc *apb_config_read[] = {
  47.114 +    &apb_config_readl,
  47.115 +    &apb_config_readl,
  47.116 +    &apb_config_readl,
  47.117 +};
  47.118 +
  47.119 +static CPUWriteMemoryFunc *pci_apb_write[] = {
  47.120 +    &pci_host_data_writeb,
  47.121 +    &pci_host_data_writew,
  47.122 +    &pci_host_data_writel,
  47.123 +};
  47.124 +
  47.125 +static CPUReadMemoryFunc *pci_apb_read[] = {
  47.126 +    &pci_host_data_readb,
  47.127 +    &pci_host_data_readw,
  47.128 +    &pci_host_data_readl,
  47.129 +};
  47.130 +
  47.131 +static void pci_apb_iowriteb (void *opaque, target_phys_addr_t addr,
  47.132 +                                  uint32_t val)
  47.133 +{
  47.134 +    cpu_outb(NULL, addr & 0xffff, val);
  47.135 +}
  47.136 +
  47.137 +static void pci_apb_iowritew (void *opaque, target_phys_addr_t addr,
  47.138 +                                  uint32_t val)
  47.139 +{
  47.140 +    cpu_outw(NULL, addr & 0xffff, val);
  47.141 +}
  47.142 +
  47.143 +static void pci_apb_iowritel (void *opaque, target_phys_addr_t addr,
  47.144 +                                uint32_t val)
  47.145 +{
  47.146 +    cpu_outl(NULL, addr & 0xffff, val);
  47.147 +}
  47.148 +
  47.149 +static uint32_t pci_apb_ioreadb (void *opaque, target_phys_addr_t addr)
  47.150 +{
  47.151 +    uint32_t val;
  47.152 +
  47.153 +    val = cpu_inb(NULL, addr & 0xffff);
  47.154 +    return val;
  47.155 +}
  47.156 +
  47.157 +static uint32_t pci_apb_ioreadw (void *opaque, target_phys_addr_t addr)
  47.158 +{
  47.159 +    uint32_t val;
  47.160 +
  47.161 +    val = cpu_inw(NULL, addr & 0xffff);
  47.162 +    return val;
  47.163 +}
  47.164 +
  47.165 +static uint32_t pci_apb_ioreadl (void *opaque, target_phys_addr_t addr)
  47.166 +{
  47.167 +    uint32_t val;
  47.168 +
  47.169 +    val = cpu_inl(NULL, addr & 0xffff);
  47.170 +    return val;
  47.171 +}
  47.172 +
  47.173 +static CPUWriteMemoryFunc *pci_apb_iowrite[] = {
  47.174 +    &pci_apb_iowriteb,
  47.175 +    &pci_apb_iowritew,
  47.176 +    &pci_apb_iowritel,
  47.177 +};
  47.178 +
  47.179 +static CPUReadMemoryFunc *pci_apb_ioread[] = {
  47.180 +    &pci_apb_ioreadb,
  47.181 +    &pci_apb_ioreadw,
  47.182 +    &pci_apb_ioreadl,
  47.183 +};
  47.184 +
  47.185 +/* ??? This is probably wrong.  */
  47.186 +static void pci_apb_set_irq(PCIDevice *d, void *pic, int irq_num, int level)
  47.187 +{
  47.188 +    pic_set_irq_new(pic, d->config[PCI_INTERRUPT_LINE], level);
  47.189 +}
  47.190 +
  47.191 +PCIBus *pci_apb_init(target_ulong special_base, target_ulong mem_base,
  47.192 +                     void *pic)
  47.193 +{
  47.194 +    APBState *s;
  47.195 +    PCIDevice *d;
  47.196 +    int pci_mem_config, pci_mem_data, apb_config, pci_ioport;
  47.197 +
  47.198 +    s = qemu_mallocz(sizeof(APBState));
  47.199 +    /* Ultrasparc APB main bus */
  47.200 +    s->bus = pci_register_bus(pci_apb_set_irq, pic, 0);
  47.201 +
  47.202 +    pci_mem_config = cpu_register_io_memory(0, pci_apb_config_read,
  47.203 +                                            pci_apb_config_write, s);
  47.204 +    apb_config = cpu_register_io_memory(0, apb_config_read,
  47.205 +					apb_config_write, s);
  47.206 +    pci_mem_data = cpu_register_io_memory(0, pci_apb_read,
  47.207 +                                          pci_apb_write, s);
  47.208 +    pci_ioport = cpu_register_io_memory(0, pci_apb_ioread,
  47.209 +                                          pci_apb_iowrite, s);
  47.210 +
  47.211 +    cpu_register_physical_memory(special_base + 0x2000ULL, 0x40, apb_config);
  47.212 +    cpu_register_physical_memory(special_base + 0x1000000ULL, 0x10, pci_mem_config);
  47.213 +    cpu_register_physical_memory(special_base + 0x2000000ULL, 0x10000, pci_ioport);
  47.214 +    cpu_register_physical_memory(mem_base, 0x10000000, pci_mem_data); // XXX size should be 4G-prom
  47.215 +
  47.216 +    d = pci_register_device(s->bus, "Advanced PCI Bus", sizeof(PCIDevice), 
  47.217 +                            -1, NULL, NULL);
  47.218 +    d->config[0x00] = 0x8e; // vendor_id : Sun
  47.219 +    d->config[0x01] = 0x10;
  47.220 +    d->config[0x02] = 0x00; // device_id
  47.221 +    d->config[0x03] = 0xa0;
  47.222 +    d->config[0x04] = 0x06; // command = bus master, pci mem
  47.223 +    d->config[0x05] = 0x00;
  47.224 +    d->config[0x06] = 0xa0; // status = fast back-to-back, 66MHz, no error
  47.225 +    d->config[0x07] = 0x03; // status = medium devsel
  47.226 +    d->config[0x08] = 0x00; // revision
  47.227 +    d->config[0x09] = 0x00; // programming i/f
  47.228 +    d->config[0x0A] = 0x00; // class_sub = pci host
  47.229 +    d->config[0x0B] = 0x06; // class_base = PCI_bridge
  47.230 +    d->config[0x0D] = 0x10; // latency_timer
  47.231 +    d->config[0x0E] = 0x00; // header_type
  47.232 +    return s->bus;
  47.233 +}
  47.234 +
  47.235 +
    48.1 --- a/tools/ioemu/hw/apic.c	Mon Aug 07 18:11:59 2006 +0100
    48.2 +++ b/tools/ioemu/hw/apic.c	Mon Aug 07 18:25:30 2006 +0100
    48.3 @@ -239,7 +239,7 @@ void cpu_set_apic_base(CPUState *env, ui
    48.4  {
    48.5      APICState *s = env->apic_state;
    48.6  #ifdef DEBUG_APIC
    48.7 -    printf("cpu_set_apic_base: %016llx\n", val);
    48.8 +    printf("cpu_set_apic_base: %016" PRIx64 "\n", val);
    48.9  #endif
   48.10      s->apicbase = (val & 0xfffff000) | 
   48.11          (s->apicbase & (MSR_IA32_APICBASE_BSP | MSR_IA32_APICBASE_ENABLE));
   48.12 @@ -255,7 +255,7 @@ uint64_t cpu_get_apic_base(CPUState *env
   48.13  {
   48.14      APICState *s = env->apic_state;
   48.15  #ifdef DEBUG_APIC
   48.16 -    printf("cpu_get_apic_base: %016llx\n", (uint64_t)s->apicbase);
   48.17 +    printf("cpu_get_apic_base: %016" PRIx64 "\n", (uint64_t)s->apicbase);
   48.18  #endif
   48.19      return s->apicbase;
   48.20  }
    49.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    49.2 +++ b/tools/ioemu/hw/cdrom.c	Mon Aug 07 18:25:30 2006 +0100
    49.3 @@ -0,0 +1,156 @@
    49.4 +/*
    49.5 + * QEMU ATAPI CD-ROM Emulator
    49.6 + * 
    49.7 + * Copyright (c) 2006 Fabrice Bellard
    49.8 + * 
    49.9 + * Permission is hereby granted, free of charge, to any person obtaining a copy
   49.10 + * of this software and associated documentation files (the "Software"), to deal
   49.11 + * in the Software without restriction, including without limitation the rights
   49.12 + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
   49.13 + * copies of the Software, and to permit persons to whom the Software is
   49.14 + * furnished to do so, subject to the following conditions:
   49.15 + *
   49.16 + * The above copyright notice and this permission notice shall be included in
   49.17 + * all copies or substantial portions of the Software.
   49.18 + *
   49.19 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   49.20 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   49.21 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
   49.22 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   49.23 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
   49.24 + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
   49.25 + * THE SOFTWARE.
   49.26 + */
   49.27 +
   49.28 +/* ??? Most of the ATAPI emulation is still in ide.c.  It should be moved
   49.29 +   here.  */
   49.30 +
   49.31 +#include <vl.h>
   49.32 +
   49.33 +static void lba_to_msf(uint8_t *buf, int lba)
   49.34 +{
   49.35 +    lba += 150;
   49.36 +    buf[0] = (lba / 75) / 60;
   49.37 +    buf[1] = (lba / 75) % 60;
   49.38 +    buf[2] = lba % 75;
   49.39 +}
   49.40 +
   49.41 +/* same toc as bochs. Return -1 if error or the toc length */
   49.42 +/* XXX: check this */
   49.43 +int cdrom_read_toc(int nb_sectors, uint8_t *buf, int msf, int start_track)
   49.44 +{
   49.45 +    uint8_t *q;
   49.46 +    int len;
   49.47 +    
   49.48 +    if (start_track > 1 && start_track != 0xaa)
   49.49 +        return -1;
   49.50 +    q = buf + 2;
   49.51 +    *q++ = 1; /* first session */
   49.52 +    *q++ = 1; /* last session */
   49.53 +    if (start_track <= 1) {
   49.54 +        *q++ = 0; /* reserved */
   49.55 +        *q++ = 0x14; /* ADR, control */
   49.56 +        *q++ = 1;    /* track number */
   49.57 +        *q++ = 0; /* reserved */
   49.58 +        if (msf) {
   49.59 +            *q++ = 0; /* reserved */
   49.60 +            lba_to_msf(q, 0);
   49.61 +            q += 3;
   49.62 +        } else {
   49.63 +            /* sector 0 */
   49.64 +            cpu_to_be32wu((uint32_t *)q, 0);
   49.65 +            q += 4;
   49.66 +        }
   49.67 +    }
   49.68 +    /* lead out track */
   49.69 +    *q++ = 0; /* reserved */
   49.70 +    *q++ = 0x16; /* ADR, control */
   49.71 +    *q++ = 0xaa; /* track number */
   49.72 +    *q++ = 0; /* reserved */
   49.73 +    if (msf) {
   49.74 +        *q++ = 0; /* reserved */
   49.75 +        lba_to_msf(q, nb_sectors);
   49.76 +        q += 3;
   49.77 +    } else {
   49.78 +        cpu_to_be32wu((uint32_t *)q, nb_sectors);
   49.79 +        q += 4;
   49.80 +    }
   49.81 +    len = q - buf;
   49.82 +    cpu_to_be16wu((uint16_t *)buf, len - 2);
   49.83 +    return len;
   49.84 +}
   49.85 +
   49.86 +/* mostly same info as PearPc */
   49.87 +int cdrom_read_toc_raw(int nb_sectors, uint8_t *buf, int msf, int session_num)
   49.88 +{
   49.89 +    uint8_t *q;
   49.90 +    int len;
   49.91 +    
   49.92 +    q = buf + 2;
   49.93 +    *q++ = 1; /* first session */
   49.94 +    *q++ = 1; /* last session */
   49.95 +
   49.96 +    *q++ = 1; /* session number */
   49.97 +    *q++ = 0x14; /* data track */
   49.98 +    *q++ = 0; /* track number */
   49.99 +    *q++ = 0xa0; /* lead-in */
  49.100 +    *q++ = 0; /* min */
  49.101 +    *q++ = 0; /* sec */
  49.102 +    *q++ = 0; /* frame */
  49.103 +    *q++ = 0;
  49.104 +    *q++ = 1; /* first track */
  49.105 +    *q++ = 0x00; /* disk type */
  49.106 +    *q++ = 0x00;
  49.107 +    
  49.108 +    *q++ = 1; /* session number */
  49.109 +    *q++ = 0x14; /* data track */
  49.110 +    *q++ = 0; /* track number */
  49.111 +    *q++ = 0xa1;
  49.112 +    *q++ = 0; /* min */
  49.113 +    *q++ = 0; /* sec */
  49.114 +    *q++ = 0; /* frame */
  49.115 +    *q++ = 0;
  49.116 +    *q++ = 1; /* last track */
  49.117 +    *q++ = 0x00;
  49.118 +    *q++ = 0x00;
  49.119 +    
  49.120 +    *q++ = 1; /* session number */
  49.121 +    *q++ = 0x14; /* data track */
  49.122 +    *q++ = 0; /* track number */
  49.123 +    *q++ = 0xa2; /* lead-out */
  49.124 +    *q++ = 0; /* min */
  49.125 +    *q++ = 0; /* sec */
  49.126 +    *q++ = 0; /* frame */
  49.127 +    if (msf) {
  49.128 +        *q++ = 0; /* reserved */
  49.129 +        lba_to_msf(q, nb_sectors);
  49.130 +        q += 3;
  49.131 +    } else {
  49.132 +        cpu_to_be32wu((uint32_t *)q, nb_sectors);
  49.133 +        q += 4;
  49.134 +    }
  49.135 +
  49.136 +    *q++ = 1; /* session number */
  49.137 +    *q++ = 0x14; /* ADR, control */
  49.138 +    *q++ = 0;    /* track number */
  49.139 +    *q++ = 1;    /* point */
  49.140 +    *q++ = 0; /* min */
  49.141 +    *q++ = 0; /* sec */
  49.142 +    *q++ = 0; /* frame */
  49.143 +    if (msf) {
  49.144 +        *q++ = 0; 
  49.145 +        lba_to_msf(q, 0);
  49.146 +        q += 3;
  49.147 +    } else {
  49.148 +        *q++ = 0; 
  49.149 +        *q++ = 0; 
  49.150 +        *q++ = 0; 
  49.151 +        *q++ = 0; 
  49.152 +    }
  49.153 +
  49.154 +    len = q - buf;
  49.155 +    cpu_to_be16wu((uint16_t *)buf, len - 2);
  49.156 +    return len;
  49.157 +}
  49.158 +
  49.159 +
    50.1 --- a/tools/ioemu/hw/cuda.c	Mon Aug 07 18:11:59 2006 +0100
    50.2 +++ b/tools/ioemu/hw/cuda.c	Mon Aug 07 18:25:30 2006 +0100
    50.3 @@ -209,7 +209,7 @@ static int64_t get_next_irq_time(CUDATim
    50.4      }
    50.5  #if 0
    50.6  #ifdef DEBUG_CUDA
    50.7 -    printf("latch=%d counter=%lld delta_next=%lld\n", 
    50.8 +    printf("latch=%d counter=%" PRId64 " delta_next=%" PRId64 "\n", 
    50.9             s->latch, d, next_time - d);
   50.10  #endif
   50.11  #endif
    51.1 --- a/tools/ioemu/hw/es1370.c	Mon Aug 07 18:11:59 2006 +0100
    51.2 +++ b/tools/ioemu/hw/es1370.c	Mon Aug 07 18:25:30 2006 +0100
    51.3 @@ -423,6 +423,7 @@ static void es1370_update_voices (ES1370
    51.4                  as.freq = new_freq;
    51.5                  as.nchannels = 1 << (new_fmt & 1);
    51.6                  as.fmt = (new_fmt & 2) ? AUD_FMT_S16 : AUD_FMT_U8;
    51.7 +                as.endianness = 0;
    51.8  
    51.9                  if (i == ADC_CHANNEL) {
   51.10                      s->adc_voice =
   51.11 @@ -432,8 +433,7 @@ static void es1370_update_voices (ES1370
   51.12                              "es1370.adc",
   51.13                              s,
   51.14                              es1370_adc_callback,
   51.15 -                            &as,
   51.16 -                            0   /* little endian */
   51.17 +                            &as
   51.18                              );
   51.19                  }
   51.20                  else {
   51.21 @@ -444,8 +444,7 @@ static void es1370_update_voices (ES1370
   51.22                              i ? "es1370.dac2" : "es1370.dac1",
   51.23                              s,
   51.24                              i ? es1370_dac2_callback : es1370_dac1_callback,
   51.25 -                            &as,
   51.26 -                            0   /* litle endian */
   51.27 +                            &as
   51.28                              );
   51.29                  }
   51.30              }
   51.31 @@ -479,8 +478,9 @@ static inline uint32_t es1370_fixup (ES1
   51.32  IO_WRITE_PROTO (es1370_writeb)
   51.33  {
   51.34      ES1370State *s = opaque;
   51.35 +    uint32_t shift, mask;
   51.36 +
   51.37      addr = es1370_fixup (s, addr);
   51.38 -    uint32_t shift, mask;
   51.39  
   51.40      switch (addr) {
   51.41      case ES1370_REG_CONTROL:
    52.1 --- a/tools/ioemu/hw/esp.c	Mon Aug 07 18:11:59 2006 +0100
    52.2 +++ b/tools/ioemu/hw/esp.c	Mon Aug 07 18:25:30 2006 +0100
    52.3 @@ -38,17 +38,14 @@ do { printf("ESP: set_irq(%d): %d\n", (i
    52.4  #define ESPDMA_REGS 4
    52.5  #define ESPDMA_MAXADDR (ESPDMA_REGS * 4 - 1)
    52.6  #define ESP_MAXREG 0x3f
    52.7 -#define TI_BUFSZ 1024*1024 // XXX
    52.8 +#define TI_BUFSZ 32
    52.9  #define DMA_VER 0xa0000000
   52.10  #define DMA_INTR 1
   52.11  #define DMA_INTREN 0x10
   52.12 +#define DMA_WRITE_MEM 0x100
   52.13  #define DMA_LOADED 0x04000000
   52.14  typedef struct ESPState ESPState;
   52.15  
   52.16 -typedef int ESPDMAFunc(ESPState *s, 
   52.17 -                       target_phys_addr_t phys_addr, 
   52.18 -                       int transfer_size1);
   52.19 -
   52.20  struct ESPState {
   52.21      BlockDriverState **bd;
   52.22      uint8_t rregs[ESP_MAXREG];
   52.23 @@ -57,12 +54,14 @@ struct ESPState {
   52.24      uint32_t espdmaregs[ESPDMA_REGS];
   52.25      uint32_t ti_size;
   52.26      uint32_t ti_rptr, ti_wptr;
   52.27 -    int ti_dir;
   52.28      uint8_t ti_buf[TI_BUFSZ];
   52.29 +    int sense;
   52.30      int dma;
   52.31 -    ESPDMAFunc *dma_cb;
   52.32 -    int64_t offset, len;
   52.33 -    int target;
   52.34 +    SCSIDevice *scsi_dev[MAX_DISKS];
   52.35 +    SCSIDevice *current_dev;
   52.36 +    uint8_t cmdbuf[TI_BUFSZ];
   52.37 +    int cmdlen;
   52.38 +    int do_cmd;
   52.39  };
   52.40  
   52.41  #define STAT_DO 0x00
   52.42 @@ -83,394 +82,200 @@ struct ESPState {
   52.43  #define SEQ_0 0x0
   52.44  #define SEQ_CD 0x4
   52.45  
   52.46 -/* XXX: stolen from ide.c, move to common ATAPI/SCSI library */
   52.47 -static void lba_to_msf(uint8_t *buf, int lba)
   52.48 -{
   52.49 -    lba += 150;
   52.50 -    buf[0] = (lba / 75) / 60;
   52.51 -    buf[1] = (lba / 75) % 60;
   52.52 -    buf[2] = lba % 75;
   52.53 -}
   52.54 -
   52.55 -static inline void cpu_to_ube16(uint8_t *buf, int val)
   52.56 -{
   52.57 -    buf[0] = val >> 8;
   52.58 -    buf[1] = val;
   52.59 -}
   52.60 -
   52.61 -static inline void cpu_to_ube32(uint8_t *buf, unsigned int val)
   52.62 -{
   52.63 -    buf[0] = val >> 24;
   52.64 -    buf[1] = val >> 16;
   52.65 -    buf[2] = val >> 8;
   52.66 -    buf[3] = val;
   52.67 -}
   52.68 -
   52.69 -/* same toc as bochs. Return -1 if error or the toc length */
   52.70 -/* XXX: check this */
   52.71 -static int cdrom_read_toc(int nb_sectors, uint8_t *buf, int msf, int start_track)
   52.72 -{
   52.73 -    uint8_t *q;
   52.74 -    int len;
   52.75 -    
   52.76 -    if (start_track > 1 && start_track != 0xaa)
   52.77 -        return -1;
   52.78 -    q = buf + 2;
   52.79 -    *q++ = 1; /* first session */
   52.80 -    *q++ = 1; /* last session */
   52.81 -    if (start_track <= 1) {
   52.82 -        *q++ = 0; /* reserved */
   52.83 -        *q++ = 0x14; /* ADR, control */
   52.84 -        *q++ = 1;    /* track number */
   52.85 -        *q++ = 0; /* reserved */
   52.86 -        if (msf) {
   52.87 -            *q++ = 0; /* reserved */
   52.88 -            lba_to_msf(q, 0);
   52.89 -            q += 3;
   52.90 -        } else {
   52.91 -            /* sector 0 */
   52.92 -            cpu_to_ube32(q, 0);
   52.93 -            q += 4;
   52.94 -        }
   52.95 -    }
   52.96 -    /* lead out track */
   52.97 -    *q++ = 0; /* reserved */
   52.98 -    *q++ = 0x16; /* ADR, control */
   52.99 -    *q++ = 0xaa; /* track number */
  52.100 -    *q++ = 0; /* reserved */
  52.101 -    if (msf) {
  52.102 -        *q++ = 0; /* reserved */
  52.103 -        lba_to_msf(q, nb_sectors);
  52.104 -        q += 3;
  52.105 -    } else {
  52.106 -        cpu_to_ube32(q, nb_sectors);
  52.107 -        q += 4;
  52.108 -    }
  52.109 -    len = q - buf;
  52.110 -    cpu_to_ube16(buf, len - 2);
  52.111 -    return len;
  52.112 -}
  52.113 -
  52.114 -/* mostly same info as PearPc */
  52.115 -static int cdrom_read_toc_raw(int nb_sectors, uint8_t *buf, int msf, 
  52.116 -                              int session_num)
  52.117 +static int get_cmd(ESPState *s, uint8_t *buf)
  52.118  {
  52.119 -    uint8_t *q;
  52.120 -    int len;
  52.121 -    
  52.122 -    q = buf + 2;
  52.123 -    *q++ = 1; /* first session */
  52.124 -    *q++ = 1; /* last session */
  52.125 -
  52.126 -    *q++ = 1; /* session number */
  52.127 -    *q++ = 0x14; /* data track */
  52.128 -    *q++ = 0; /* track number */
  52.129 -    *q++ = 0xa0; /* lead-in */
  52.130 -    *q++ = 0; /* min */
  52.131 -    *q++ = 0; /* sec */
  52.132 -    *q++ = 0; /* frame */
  52.133 -    *q++ = 0;
  52.134 -    *q++ = 1; /* first track */
  52.135 -    *q++ = 0x00; /* disk type */
  52.136 -    *q++ = 0x00;
  52.137 -    
  52.138 -    *q++ = 1; /* session number */
  52.139 -    *q++ = 0x14; /* data track */
  52.140 -    *q++ = 0; /* track number */
  52.141 -    *q++ = 0xa1;
  52.142 -    *q++ = 0; /* min */
  52.143 -    *q++ = 0; /* sec */
  52.144 -    *q++ = 0; /* frame */
  52.145 -    *q++ = 0;
  52.146 -    *q++ = 1; /* last track */
  52.147 -    *q++ = 0x00;
  52.148 -    *q++ = 0x00;
  52.149 -    
  52.150 -    *q++ = 1; /* session number */
  52.151 -    *q++ = 0x14; /* data track */
  52.152 -    *q++ = 0; /* track number */
  52.153 -    *q++ = 0xa2; /* lead-out */
  52.154 -    *q++ = 0; /* min */
  52.155 -    *q++ = 0; /* sec */
  52.156 -    *q++ = 0; /* frame */
  52.157 -    if (msf) {
  52.158 -        *q++ = 0; /* reserved */
  52.159 -        lba_to_msf(q, nb_sectors);
  52.160 -        q += 3;
  52.161 -    } else {
  52.162 -        cpu_to_ube32(q, nb_sectors);
  52.163 -        q += 4;
  52.164 -    }
  52.165 -
  52.166 -    *q++ = 1; /* session number */
  52.167 -    *q++ = 0x14; /* ADR, control */
  52.168 -    *q++ = 0;    /* track number */
  52.169 -    *q++ = 1;    /* point */
  52.170 -    *q++ = 0; /* min */
  52.171 -    *q++ = 0; /* sec */
  52.172 -    *q++ = 0; /* frame */
  52.173 -    if (msf) {
  52.174 -        *q++ = 0; 
  52.175 -        lba_to_msf(q, 0);
  52.176 -        q += 3;
  52.177 -    } else {
  52.178 -        *q++ = 0; 
  52.179 -        *q++ = 0; 
  52.180 -        *q++ = 0; 
  52.181 -        *q++ = 0; 
  52.182 -    }
  52.183 -
  52.184 -    len = q - buf;
  52.185 -    cpu_to_ube16(buf, len - 2);
  52.186 -    return len;
  52.187 -}
  52.188 -
  52.189 -static int esp_write_dma_cb(ESPState *s, 
  52.190 -                            target_phys_addr_t phys_addr, 
  52.191 -                            int transfer_size1)
  52.192 -{
  52.193 -    DPRINTF("Write callback (offset %lld len %lld size %d trans_size %d)\n",
  52.194 -            s->offset, s->len, s->ti_size, transfer_size1);
  52.195 -    bdrv_write(s->bd[s->target], s->offset, s->ti_buf, s->len);
  52.196 -    s->offset = 0;
  52.197 -    s->len = 0;
  52.198 -    s->target = 0;
  52.199 -    return 0;
  52.200 -}
  52.201 -
  52.202 -static void handle_satn(ESPState *s)
  52.203 -{
  52.204 -    uint8_t buf[32];
  52.205      uint32_t dmaptr, dmalen;
  52.206 -    unsigned int i;
  52.207 -    int64_t nb_sectors;
  52.208      int target;
  52.209  
  52.210      dmalen = s->wregs[0] | (s->wregs[1] << 8);
  52.211      target = s->wregs[4] & 7;
  52.212 -    DPRINTF("Select with ATN len %d target %d\n", dmalen, target);
  52.213 +    DPRINTF("get_cmd: len %d target %d\n", dmalen, target);
  52.214      if (s->dma) {
  52.215  	dmaptr = iommu_translate(s->espdmaregs[1]);
  52.216 -	DPRINTF("DMA Direction: %c, addr 0x%8.8x\n", s->espdmaregs[0] & 0x100? 'w': 'r', dmaptr);
  52.217 +	DPRINTF("DMA Direction: %c, addr 0x%8.8x\n",
  52.218 +                s->espdmaregs[0] & DMA_WRITE_MEM ? 'w': 'r', dmaptr);
  52.219  	cpu_physical_memory_read(dmaptr, buf, dmalen);
  52.220      } else {
  52.221  	buf[0] = 0;
  52.222  	memcpy(&buf[1], s->ti_buf, dmalen);
  52.223  	dmalen++;
  52.224      }
  52.225 -    for (i = 0; i < dmalen; i++) {
  52.226 -	DPRINTF("Command %2.2x\n", buf[i]);
  52.227 -    }
  52.228 -    s->ti_dir = 0;
  52.229 +
  52.230      s->ti_size = 0;
  52.231      s->ti_rptr = 0;
  52.232      s->ti_wptr = 0;
  52.233  
  52.234 -    if (target >= 4 || !s->bd[target]) { // No such drive
  52.235 +    if (target >= 4 || !s->scsi_dev[target]) {
  52.236 +        // No such drive
  52.237  	s->rregs[4] = STAT_IN;
  52.238  	s->rregs[5] = INTR_DC;
  52.239  	s->rregs[6] = SEQ_0;
  52.240  	s->espdmaregs[0] |= DMA_INTR;
  52.241  	pic_set_irq(s->irq, 1);
  52.242 -	return;
  52.243 +	return 0;
  52.244      }
  52.245 -    switch (buf[1]) {
  52.246 -    case 0x0:
  52.247 -	DPRINTF("Test Unit Ready (len %d)\n", buf[5]);
  52.248 -	break;
  52.249 -    case 0x12:
  52.250 -	DPRINTF("Inquiry (len %d)\n", buf[5]);
  52.251 -	memset(s->ti_buf, 0, 36);
  52.252 -	if (bdrv_get_type_hint(s->bd[target]) == BDRV_TYPE_CDROM) {
  52.253 -	    s->ti_buf[0] = 5;
  52.254 -	    memcpy(&s->ti_buf[16], "QEMU CDROM     ", 16);
  52.255 -	} else {
  52.256 -	    s->ti_buf[0] = 0;
  52.257 -	    memcpy(&s->ti_buf[16], "QEMU HARDDISK  ", 16);
  52.258 -	}
  52.259 -	memcpy(&s->ti_buf[8], "QEMU   ", 8);
  52.260 -	s->ti_buf[2] = 1;
  52.261 -	s->ti_buf[3] = 2;
  52.262 -	s->ti_buf[4] = 32;
  52.263 -	s->ti_dir = 1;
  52.264 -	s->ti_size = 36;
  52.265 -	break;
  52.266 -    case 0x1a:
  52.267 -	DPRINTF("Mode Sense(6) (page %d, len %d)\n", buf[3], buf[5]);
  52.268 -	break;
  52.269 -    case 0x25:
  52.270 -	DPRINTF("Read Capacity (len %d)\n", buf[5]);
  52.271 -	memset(s->ti_buf, 0, 8);
  52.272 -	bdrv_get_geometry(s->bd[target], &nb_sectors);
  52.273 -	s->ti_buf[0] = (nb_sectors >> 24) & 0xff;
  52.274 -	s->ti_buf[1] = (nb_sectors >> 16) & 0xff;
  52.275 -	s->ti_buf[2] = (nb_sectors >> 8) & 0xff;
  52.276 -	s->ti_buf[3] = nb_sectors & 0xff;
  52.277 -	s->ti_buf[4] = 0;
  52.278 -	s->ti_buf[5] = 0;
  52.279 -	if (bdrv_get_type_hint(s->bd[target]) == BDRV_TYPE_CDROM)
  52.280 -	    s->ti_buf[6] = 8; // sector size 2048
  52.281 -	else
  52.282 -	    s->ti_buf[6] = 2; // sector size 512
  52.283 -	s->ti_buf[7] = 0;
  52.284 -	s->ti_dir = 1;
  52.285 -	s->ti_size = 8;
  52.286 -	break;
  52.287 -    case 0x28:
  52.288 -	{
  52.289 -	    int64_t offset, len;
  52.290 +    s->current_dev = s->scsi_dev[target];
  52.291 +    return dmalen;
  52.292 +}
  52.293  
  52.294 -	    if (bdrv_get_type_hint(s->bd[target]) == BDRV_TYPE_CDROM) {
  52.295 -		offset = ((buf[3] << 24) | (buf[4] << 16) | (buf[5] << 8) | buf[6]) * 4;
  52.296 -		len = ((buf[8] << 8) | buf[9]) * 4;
  52.297 -		s->ti_size = len * 2048;
  52.298 -	    } else {
  52.299 -		offset = (buf[3] << 24) | (buf[4] << 16) | (buf[5] << 8) | buf[6];
  52.300 -		len = (buf[8] << 8) | buf[9];
  52.301 -		s->ti_size = len * 512;
  52.302 -	    }
  52.303 -	    DPRINTF("Read (10) (offset %lld len %lld)\n", offset, len);
  52.304 -            if (s->ti_size > TI_BUFSZ) {
  52.305 -                DPRINTF("size too large %d\n", s->ti_size);
  52.306 -            }
  52.307 -	    bdrv_read(s->bd[target], offset, s->ti_buf, len);
  52.308 -	    // XXX error handling
  52.309 -	    s->ti_dir = 1;
  52.310 -	    break;
  52.311 -	}
  52.312 -    case 0x2a:
  52.313 -	{
  52.314 -	    int64_t offset, len;
  52.315 +static void do_cmd(ESPState *s, uint8_t *buf)
  52.316 +{
  52.317 +    int32_t datalen;
  52.318 +    int lun;
  52.319  
  52.320 -	    if (bdrv_get_type_hint(s->bd[target]) == BDRV_TYPE_CDROM) {
  52.321 -		offset = ((buf[3] << 24) | (buf[4] << 16) | (buf[5] << 8) | buf[6]) * 4;
  52.322 -		len = ((buf[8] << 8) | buf[9]) * 4;
  52.323 -		s->ti_size = len * 2048;
  52.324 -	    } else {
  52.325 -		offset = (buf[3] << 24) | (buf[4] << 16) | (buf[5] << 8) | buf[6];
  52.326 -		len = (buf[8] << 8) | buf[9];
  52.327 -		s->ti_size = len * 512;
  52.328 -	    }
  52.329 -	    DPRINTF("Write (10) (offset %lld len %lld)\n", offset, len);
  52.330 -            if (s->ti_size > TI_BUFSZ) {
  52.331 -                DPRINTF("size too large %d\n", s->ti_size);
  52.332 -            }
  52.333 -            s->dma_cb = esp_write_dma_cb;
  52.334 -            s->offset = offset;
  52.335 -            s->len = len;
  52.336 -            s->target = target;
  52.337 -	    // XXX error handling
  52.338 -	    s->ti_dir = 0;
  52.339 -	    break;
  52.340 -	}
  52.341 -    case 0x43:
  52.342 -        {
  52.343 -            int start_track, format, msf, len;
  52.344 -
  52.345 -            msf = buf[2] & 2;
  52.346 -            format = buf[3] & 0xf;
  52.347 -            start_track = buf[7];
  52.348 -            bdrv_get_geometry(s->bd[target], &nb_sectors);
  52.349 -            DPRINTF("Read TOC (track %d format %d msf %d)\n", start_track, format, msf >> 1);
  52.350 -            switch(format) {
  52.351 -            case 0:
  52.352 -                len = cdrom_read_toc(nb_sectors, buf, msf, start_track);
  52.353 -                if (len < 0)
  52.354 -                    goto error_cmd;
  52.355 -                s->ti_size = len;
  52.356 -                break;
  52.357 -            case 1:
  52.358 -                /* multi session : only a single session defined */
  52.359 -                memset(buf, 0, 12);
  52.360 -                buf[1] = 0x0a;
  52.361 -                buf[2] = 0x01;
  52.362 -                buf[3] = 0x01;
  52.363 -                s->ti_size = 12;
  52.364 -                break;
  52.365 -            case 2:
  52.366 -                len = cdrom_read_toc_raw(nb_sectors, buf, msf, start_track);
  52.367 -                if (len < 0)
  52.368 -                    goto error_cmd;
  52.369 -                s->ti_size = len;
  52.370 -                break;
  52.371 -            default:
  52.372 -            error_cmd:
  52.373 -                DPRINTF("Read TOC error\n");
  52.374 -                // XXX error handling
  52.375 -                break;
  52.376 -            }
  52.377 -	    s->ti_dir = 1;
  52.378 -            break;
  52.379 +    DPRINTF("do_cmd: busid 0x%x\n", buf[0]);
  52.380 +    lun = buf[0] & 7;
  52.381 +    datalen = scsi_send_command(s->current_dev, 0, &buf[1], lun);
  52.382 +    if (datalen == 0) {
  52.383 +        s->ti_size = 0;
  52.384 +    } else {
  52.385 +        s->rregs[4] = STAT_IN | STAT_TC;
  52.386 +        if (datalen > 0) {
  52.387 +            s->rregs[4] |= STAT_DI;
  52.388 +            s->ti_size = datalen;
  52.389 +        } else {
  52.390 +            s->rregs[4] |= STAT_DO;
  52.391 +            s->ti_size = -datalen;
  52.392          }
  52.393 -    default:
  52.394 -	DPRINTF("Unknown SCSI command (%2.2x)\n", buf[1]);
  52.395 -	break;
  52.396      }
  52.397 -    s->rregs[4] = STAT_IN | STAT_TC | STAT_DI;
  52.398      s->rregs[5] = INTR_BS | INTR_FC;
  52.399      s->rregs[6] = SEQ_CD;
  52.400      s->espdmaregs[0] |= DMA_INTR;
  52.401      pic_set_irq(s->irq, 1);
  52.402  }
  52.403  
  52.404 -static void dma_write(ESPState *s, const uint8_t *buf, uint32_t len)
  52.405 +static void handle_satn(ESPState *s)
  52.406  {
  52.407 -    uint32_t dmaptr, dmalen;
  52.408 +    uint8_t buf[32];
  52.409 +    int len;
  52.410  
  52.411 -    dmalen = s->wregs[0] | (s->wregs[1] << 8);
  52.412 -    DPRINTF("Transfer status len %d\n", dmalen);
  52.413 +    len = get_cmd(s, buf);
  52.414 +    if (len)
  52.415 +        do_cmd(s, buf);
  52.416 +}
  52.417 +
  52.418 +static void handle_satn_stop(ESPState *s)
  52.419 +{
  52.420 +    s->cmdlen = get_cmd(s, s->cmdbuf);
  52.421 +    if (s->cmdlen) {
  52.422 +        DPRINTF("Set ATN & Stop: cmdlen %d\n", s->cmdlen);
  52.423 +        s->do_cmd = 1;
  52.424 +        s->espdmaregs[1] += s->cmdlen;
  52.425 +        s->rregs[4] = STAT_IN | STAT_TC | STAT_CD;
  52.426 +        s->rregs[5] = INTR_BS | INTR_FC;
  52.427 +        s->rregs[6] = SEQ_CD;
  52.428 +        s->espdmaregs[0] |= DMA_INTR;
  52.429 +        pic_set_irq(s->irq, 1);
  52.430 +    }
  52.431 +}
  52.432 +
  52.433 +static void write_response(ESPState *s)
  52.434 +{
  52.435 +    uint32_t dmaptr;
  52.436 +
  52.437 +    DPRINTF("Transfer status (sense=%d)\n", s->sense);
  52.438 +    s->ti_buf[0] = s->sense;
  52.439 +    s->ti_buf[1] = 0;
  52.440      if (s->dma) {
  52.441  	dmaptr = iommu_translate(s->espdmaregs[1]);
  52.442 -	DPRINTF("DMA Direction: %c\n", s->espdmaregs[0] & 0x100? 'w': 'r');
  52.443 -	cpu_physical_memory_write(dmaptr, buf, len);
  52.444 +	DPRINTF("DMA Direction: %c\n",
  52.445 +                s->espdmaregs[0] & DMA_WRITE_MEM ? 'w': 'r');
  52.446 +	cpu_physical_memory_write(dmaptr, s->ti_buf, 2);
  52.447  	s->rregs[4] = STAT_IN | STAT_TC | STAT_ST;
  52.448  	s->rregs[5] = INTR_BS | INTR_FC;
  52.449  	s->rregs[6] = SEQ_CD;
  52.450      } else {
  52.451 -	memcpy(s->ti_buf, buf, len);
  52.452 -	s->ti_size = dmalen;
  52.453 +	s->ti_size = 2;
  52.454  	s->ti_rptr = 0;
  52.455  	s->ti_wptr = 0;
  52.456 -	s->rregs[7] = dmalen;
  52.457 +	s->rregs[7] = 2;
  52.458      }
  52.459      s->espdmaregs[0] |= DMA_INTR;
  52.460      pic_set_irq(s->irq, 1);
  52.461  
  52.462  }
  52.463  
  52.464 -static const uint8_t okbuf[] = {0, 0};
  52.465 +static void esp_command_complete(void *opaque, uint32_t tag, int sense)
  52.466 +{
  52.467 +    ESPState *s = (ESPState *)opaque;
  52.468 +
  52.469 +    DPRINTF("SCSI Command complete\n");
  52.470 +    if (s->ti_size != 0)
  52.471 +        DPRINTF("SCSI command completed unexpectedly\n");
  52.472 +    s->ti_size = 0;
  52.473 +    if (sense)
  52.474 +        DPRINTF("Command failed\n");
  52.475 +    s->sense = sense;
  52.476 +    s->rregs[4] = STAT_IN | STAT_TC | STAT_ST;
  52.477 +}
  52.478  
  52.479  static void handle_ti(ESPState *s)
  52.480  {
  52.481 -    uint32_t dmaptr, dmalen;
  52.482 +    uint32_t dmaptr, dmalen, minlen, len, from, to;
  52.483      unsigned int i;
  52.484 +    int to_device;
  52.485 +    uint8_t buf[TARGET_PAGE_SIZE];
  52.486  
  52.487      dmalen = s->wregs[0] | (s->wregs[1] << 8);
  52.488 -    DPRINTF("Transfer Information len %d\n", dmalen);
  52.489 +    if (dmalen==0) {
  52.490 +      dmalen=0x10000;
  52.491 +    }
  52.492 +
  52.493 +    if (s->do_cmd)
  52.494 +        minlen = (dmalen < 32) ? dmalen : 32;
  52.495 +    else
  52.496 +        minlen = (dmalen < s->ti_size) ? dmalen : s->ti_size;
  52.497 +    DPRINTF("Transfer Information len %d\n", minlen);
  52.498      if (s->dma) {
  52.499  	dmaptr = iommu_translate(s->espdmaregs[1]);
  52.500 -	DPRINTF("DMA Direction: %c, addr 0x%8.8x\n", s->espdmaregs[0] & 0x100? 'w': 'r', dmaptr);
  52.501 -	for (i = 0; i < s->ti_size; i++) {
  52.502 +        /* Check if the transfer writes to to reads from the device.  */
  52.503 +        to_device = (s->espdmaregs[0] & DMA_WRITE_MEM) == 0;
  52.504 +	DPRINTF("DMA Direction: %c, addr 0x%8.8x %08x\n",
  52.505 +                to_device ? 'r': 'w', dmaptr, s->ti_size);
  52.506 +	from = s->espdmaregs[1];
  52.507 +	to = from + minlen;
  52.508 +	for (i = 0; i < minlen; i += len, from += len) {
  52.509  	    dmaptr = iommu_translate(s->espdmaregs[1] + i);
  52.510 -	    if (s->ti_dir)
  52.511 -		cpu_physical_memory_write(dmaptr, &s->ti_buf[i], 1);
  52.512 -	    else
  52.513 -		cpu_physical_memory_read(dmaptr, &s->ti_buf[i], 1);
  52.514 -	}
  52.515 -        if (s->dma_cb) {
  52.516 -            s->dma_cb(s, s->espdmaregs[1], dmalen);
  52.517 -            s->dma_cb = NULL;
  52.518 +	    if ((from & TARGET_PAGE_MASK) != (to & TARGET_PAGE_MASK)) {
  52.519 +               len = TARGET_PAGE_SIZE - (from & ~TARGET_PAGE_MASK);
  52.520 +            } else {
  52.521 +	       len = to - from;
  52.522 +            }
  52.523 +            DPRINTF("DMA address p %08x v %08x len %08x, from %08x, to %08x\n", dmaptr, s->espdmaregs[1] + i, len, from, to);
  52.524 +            s->ti_size -= len;
  52.525 +            if (s->do_cmd) {
  52.526 +                DPRINTF("command len %d + %d\n", s->cmdlen, len);
  52.527 +                cpu_physical_memory_read(dmaptr, &s->cmdbuf[s->cmdlen], len);
  52.528 +                s->ti_size = 0;
  52.529 +                s->cmdlen = 0;
  52.530 +                s->do_cmd = 0;
  52.531 +                do_cmd(s, s->cmdbuf);
  52.532 +                return;
  52.533 +            } else {
  52.534 +                if (to_device) {
  52.535 +                    cpu_physical_memory_read(dmaptr, buf, len);
  52.536 +                    scsi_write_data(s->current_dev, buf, len);
  52.537 +                } else {
  52.538 +                    scsi_read_data(s->current_dev, buf, len);
  52.539 +                    cpu_physical_memory_write(dmaptr, buf, len);
  52.540 +                }
  52.541 +            }
  52.542          }
  52.543 -	s->rregs[4] = STAT_IN | STAT_TC | STAT_ST;
  52.544 -	s->rregs[5] = INTR_BS;
  52.545 +        if (s->ti_size) {
  52.546 +	    s->rregs[4] = STAT_IN | STAT_TC | (to_device ? STAT_DO : STAT_DI);
  52.547 +        }
  52.548 +        s->rregs[5] = INTR_BS;
  52.549  	s->rregs[6] = 0;
  52.550 +	s->rregs[7] = 0;
  52.551  	s->espdmaregs[0] |= DMA_INTR;
  52.552 -    } else {
  52.553 -	s->ti_size = dmalen;
  52.554 -	s->ti_rptr = 0;
  52.555 -	s->ti_wptr = 0;
  52.556 -	s->rregs[7] = dmalen;
  52.557 -    }	
  52.558 +    } else if (s->do_cmd) {
  52.559 +        DPRINTF("command len %d\n", s->cmdlen);
  52.560 +        s->ti_size = 0;
  52.561 +        s->cmdlen = 0;
  52.562 +        s->do_cmd = 0;
  52.563 +        do_cmd(s, s->cmdbuf);
  52.564 +        return;
  52.565 +    }
  52.566      pic_set_irq(s->irq, 1);
  52.567  }
  52.568  
  52.569 @@ -484,9 +289,8 @@ static void esp_reset(void *opaque)
  52.570      s->ti_size = 0;
  52.571      s->ti_rptr = 0;
  52.572      s->ti_wptr = 0;
  52.573 -    s->ti_dir = 0;
  52.574      s->dma = 0;
  52.575 -    s->dma_cb = NULL;
  52.576 +    s->do_cmd = 0;
  52.577  }
  52.578  
  52.579  static uint32_t esp_mem_readb(void *opaque, target_phys_addr_t addr)
  52.580 @@ -501,7 +305,12 @@ static uint32_t esp_mem_readb(void *opaq
  52.581  	// FIFO
  52.582  	if (s->ti_size > 0) {
  52.583  	    s->ti_size--;
  52.584 -	    s->rregs[saddr] = s->ti_buf[s->ti_rptr++];
  52.585 +            if ((s->rregs[4] & 6) == 0) {
  52.586 +                /* Data in/out.  */
  52.587 +                scsi_read_data(s->current_dev, &s->rregs[2], 0);
  52.588 +            } else {
  52.589 +                s->rregs[2] = s->ti_buf[s->ti_rptr++];
  52.590 +            }
  52.591  	    pic_set_irq(s->irq, 1);
  52.592  	}
  52.593  	if (s->ti_size == 0) {
  52.594 @@ -536,8 +345,17 @@ static void esp_mem_writeb(void *opaque,
  52.595          break;
  52.596      case 2:
  52.597  	// FIFO
  52.598 -	s->ti_size++;
  52.599 -	s->ti_buf[s->ti_wptr++] = val & 0xff;
  52.600 +        if (s->do_cmd) {
  52.601 +            s->cmdbuf[s->cmdlen++] = val & 0xff;
  52.602 +        } else if ((s->rregs[4] & 6) == 0) {
  52.603 +            uint8_t buf;
  52.604 +            buf = val & 0xff;
  52.605 +            s->ti_size--;
  52.606 +            scsi_write_data(s->current_dev, &buf, 0);
  52.607 +        } else {
  52.608 +            s->ti_size++;
  52.609 +            s->ti_buf[s->ti_wptr++] = val & 0xff;
  52.610 +        }
  52.611  	break;
  52.612      case 3:
  52.613          s->rregs[saddr] = val;
  52.614 @@ -574,11 +392,11 @@ static void esp_mem_writeb(void *opaque,
  52.615  	    break;
  52.616  	case 0x11:
  52.617  	    DPRINTF("Initiator Command Complete Sequence (%2.2x)\n", val);
  52.618 -	    dma_write(s, okbuf, 2);
  52.619 +	    write_response(s);
  52.620  	    break;
  52.621  	case 0x12:
  52.622  	    DPRINTF("Message Accepted (%2.2x)\n", val);
  52.623 -	    dma_write(s, okbuf, 2);
  52.624 +	    write_response(s);
  52.625  	    s->rregs[5] = INTR_DC;
  52.626  	    s->rregs[6] = 0;
  52.627  	    break;
  52.628 @@ -586,11 +404,12 @@ static void esp_mem_writeb(void *opaque,
  52.629  	    DPRINTF("Set ATN (%2.2x)\n", val);
  52.630  	    break;
  52.631  	case 0x42:
  52.632 +	    DPRINTF("Set ATN (%2.2x)\n", val);
  52.633  	    handle_satn(s);
  52.634  	    break;
  52.635  	case 0x43:
  52.636  	    DPRINTF("Set ATN & stop (%2.2x)\n", val);
  52.637 -	    handle_satn(s);
  52.638 +	    handle_satn_stop(s);
  52.639  	    break;
  52.640  	default:
  52.641  	    DPRINTF("Unhandled ESP command (%2.2x)\n", val);
  52.642 @@ -660,7 +479,7 @@ static void espdma_mem_writel(void *opaq
  52.643          val |= DMA_VER;
  52.644  	break;
  52.645      case 1:
  52.646 -        s->espdmaregs[0] = DMA_LOADED;
  52.647 +        s->espdmaregs[0] |= DMA_LOADED;
  52.648          break;
  52.649      default:
  52.650  	break;
  52.651 @@ -693,7 +512,6 @@ static void esp_save(QEMUFile *f, void *
  52.652      qemu_put_be32s(f, &s->ti_size);
  52.653      qemu_put_be32s(f, &s->ti_rptr);
  52.654      qemu_put_be32s(f, &s->ti_wptr);
  52.655 -    qemu_put_be32s(f, &s->ti_dir);
  52.656      qemu_put_buffer(f, s->ti_buf, TI_BUFSZ);
  52.657      qemu_put_be32s(f, &s->dma);
  52.658  }
  52.659 @@ -714,7 +532,6 @@ static int esp_load(QEMUFile *f, void *o
  52.660      qemu_get_be32s(f, &s->ti_size);
  52.661      qemu_get_be32s(f, &s->ti_rptr);
  52.662      qemu_get_be32s(f, &s->ti_wptr);
  52.663 -    qemu_get_be32s(f, &s->ti_dir);
  52.664      qemu_get_buffer(f, s->ti_buf, TI_BUFSZ);
  52.665      qemu_get_be32s(f, &s->dma);
  52.666  
  52.667 @@ -725,6 +542,7 @@ void esp_init(BlockDriverState **bd, int
  52.668  {
  52.669      ESPState *s;
  52.670      int esp_io_memory, espdma_io_memory;
  52.671 +    int i;
  52.672  
  52.673      s = qemu_mallocz(sizeof(ESPState));
  52.674      if (!s)
  52.675 @@ -743,5 +561,11 @@ void esp_init(BlockDriverState **bd, int
  52.676  
  52.677      register_savevm("esp", espaddr, 1, esp_save, esp_load, s);
  52.678      qemu_register_reset(esp_reset, s);
  52.679 +    for (i = 0; i < MAX_DISKS; i++) {
  52.680 +        if (bs_table[i]) {
  52.681 +            s->scsi_dev[i] =
  52.682 +                scsi_disk_init(bs_table[i], esp_command_complete, s);
  52.683 +        }
  52.684 +    }
  52.685  }
  52.686  
    53.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    53.2 +++ b/tools/ioemu/hw/grackle_pci.c	Mon Aug 07 18:25:30 2006 +0100
    53.3 @@ -0,0 +1,156 @@
    53.4 +/*
    53.5 + * QEMU Grackle (heathrow PPC) PCI host
    53.6 + *
    53.7 + * Copyright (c) 2006 Fabrice Bellard
    53.8 + * 
    53.9 + * Permission is hereby granted, free of charge, to any person obtaining a copy
   53.10 + * of this software and associated documentation files (the "Software"), to deal
   53.11 + * in the Software without restriction, including without limitation the rights
   53.12 + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
   53.13 + * copies of the Software, and to permit persons to whom the Software is
   53.14 + * furnished to do so, subject to the following conditions:
   53.15 + *
   53.16 + * The above copyright notice and this permission notice shall be included in
   53.17 + * all copies or substantial portions of the Software.
   53.18 + *
   53.19 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   53.20 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   53.21 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
   53.22 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   53.23 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
   53.24 + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
   53.25 + * THE SOFTWARE.
   53.26 + */
   53.27 +
   53.28 +#include "vl.h"
   53.29 +typedef target_phys_addr_t pci_addr_t;
   53.30 +#include "pci_host.h"
   53.31 +
   53.32 +typedef PCIHostState GrackleState;
   53.33 +
   53.34 +static void pci_grackle_config_writel (void *opaque, target_phys_addr_t addr,
   53.35 +                                       uint32_t val)
   53.36 +{
   53.37 +    GrackleState *s = opaque;
   53.38 +#ifdef TARGET_WORDS_BIGENDIAN
   53.39 +    val = bswap32(val);
   53.40 +#endif
   53.41 +    s->config_reg = val;
   53.42 +}
   53.43 +
   53.44 +static uint32_t pci_grackle_config_readl (void *opaque, target_phys_addr_t addr)
   53.45 +{
   53.46 +    GrackleState *s = opaque;
   53.47 +    uint32_t val;
   53.48 +
   53.49 +    val = s->config_reg;
   53.50 +#ifdef TARGET_WORDS_BIGENDIAN
   53.51 +    val = bswap32(val);
   53.52 +#endif
   53.53 +    return val;
   53.54 +}
   53.55 +
   53.56 +static CPUWriteMemoryFunc *pci_grackle_config_write[] = {
   53.57 +    &pci_grackle_config_writel,
   53.58 +    &pci_grackle_config_writel,
   53.59 +    &pci_grackle_config_writel,
   53.60 +};
   53.61 +
   53.62 +static CPUReadMemoryFunc *pci_grackle_config_read[] = {
   53.63 +    &pci_grackle_config_readl,
   53.64 +    &pci_grackle_config_readl,
   53.65 +    &pci_grackle_config_readl,
   53.66 +};
   53.67 +
   53.68 +static CPUWriteMemoryFunc *pci_grackle_write[] = {
   53.69 +    &pci_host_data_writeb,
   53.70 +    &pci_host_data_writew,
   53.71 +    &pci_host_data_writel,
   53.72 +};
   53.73 +
   53.74 +static CPUReadMemoryFunc *pci_grackle_read[] = {
   53.75 +    &pci_host_data_readb,
   53.76 +    &pci_host_data_readw,
   53.77 +    &pci_host_data_readl,
   53.78 +};
   53.79 +
   53.80 +/* XXX: we do not simulate the hardware - we rely on the BIOS to
   53.81 +   set correctly for irq line field */
   53.82 +static void pci_grackle_set_irq(PCIDevice *d, void *pic, int irq_num, int level)
   53.83 +{
   53.84 +    heathrow_pic_set_irq(pic, d->config[PCI_INTERRUPT_LINE], level);
   53.85 +}
   53.86 +
   53.87 +PCIBus *pci_grackle_init(uint32_t base, void *pic)
   53.88 +{
   53.89 +    GrackleState *s;
   53.90 +    PCIDevice *d;
   53.91 +    int pci_mem_config, pci_mem_data;
   53.92 +
   53.93 +    s = qemu_mallocz(sizeof(GrackleState));
   53.94 +    s->bus = pci_register_bus(pci_grackle_set_irq, pic, 0);
   53.95 +
   53.96 +    pci_mem_config = cpu_register_io_memory(0, pci_grackle_config_read, 
   53.97 +                                            pci_grackle_config_write, s);
   53.98 +    pci_mem_data = cpu_register_io_memory(0, pci_grackle_read,
   53.99 +                                          pci_grackle_write, s);
  53.100 +    cpu_register_physical_memory(base, 0x1000, pci_mem_config);
  53.101 +    cpu_register_physical_memory(base + 0x00200000, 0x1000, pci_mem_data);
  53.102 +    d = pci_register_device(s->bus, "Grackle host bridge", sizeof(PCIDevice), 
  53.103 +                            0, NULL, NULL);
  53.104 +    d->config[0x00] = 0x57; // vendor_id
  53.105 +    d->config[0x01] = 0x10;
  53.106 +    d->config[0x02] = 0x02; // device_id
  53.107 +    d->config[0x03] = 0x00;
  53.108 +    d->config[0x08] = 0x00; // revision
  53.109 +    d->config[0x09] = 0x01;
  53.110 +    d->config[0x0a] = 0x00; // class_sub = host
  53.111 +    d->config[0x0b] = 0x06; // class_base = PCI_bridge
  53.112 +    d->config[0x0e] = 0x00; // header_type
  53.113 +
  53.114 +    d->config[0x18] = 0x00;  // primary_bus
  53.115 +    d->config[0x19] = 0x01;  // secondary_bus
  53.116 +    d->config[0x1a] = 0x00;  // subordinate_bus
  53.117 +    d->config[0x1c] = 0x00;
  53.118 +    d->config[0x1d] = 0x00;
  53.119 +    
  53.120 +    d->config[0x20] = 0x00; // memory_base
  53.121 +    d->config[0x21] = 0x00;
  53.122 +    d->config[0x22] = 0x01; // memory_limit
  53.123 +    d->config[0x23] = 0x00;
  53.124 +    
  53.125 +    d->config[0x24] = 0x00; // prefetchable_memory_base
  53.126 +    d->config[0x25] = 0x00;
  53.127 +    d->config[0x26] = 0x00; // prefetchable_memory_limit
  53.128 +    d->config[0x27] = 0x00;
  53.129 +
  53.130 +#if 0
  53.131 +    /* PCI2PCI bridge same values as PearPC - check this */
  53.132 +    d->config[0x00] = 0x11; // vendor_id
  53.133 +    d->config[0x01] = 0x10;
  53.134 +    d->config[0x02] = 0x26; // device_id
  53.135 +    d->config[0x03] = 0x00;
  53.136 +    d->config[0x08] = 0x02; // revision
  53.137 +    d->config[0x0a] = 0x04; // class_sub = pci2pci
  53.138 +    d->config[0x0b] = 0x06; // class_base = PCI_bridge
  53.139 +    d->config[0x0e] = 0x01; // header_type
  53.140 +
  53.141 +    d->config[0x18] = 0x0;  // primary_bus
  53.142 +    d->config[0x19] = 0x1;  // secondary_bus
  53.143 +    d->config[0x1a] = 0x1;  // subordinate_bus
  53.144 +    d->config[0x1c] = 0x10; // io_base
  53.145 +    d->config[0x1d] = 0x20; // io_limit
  53.146 +    
  53.147 +    d->config[0x20] = 0x80; // memory_base
  53.148 +    d->config[0x21] = 0x80;
  53.149 +    d->config[0x22] = 0x90; // memory_limit
  53.150 +    d->config[0x23] = 0x80;
  53.151 +    
  53.152 +    d->config[0x24] = 0x00; // prefetchable_memory_base
  53.153 +    d->config[0x25] = 0x84;
  53.154 +    d->config[0x26] = 0x00; // prefetchable_memory_limit
  53.155 +    d->config[0x27] = 0x85;
  53.156 +#endif
  53.157 +    return s->bus;
  53.158 +}
  53.159 +
    54.1 --- a/tools/ioemu/hw/i8259.c	Mon Aug 07 18:11:59 2006 +0100
    54.2 +++ b/tools/ioemu/hw/i8259.c	Mon Aug 07 18:25:30 2006 +0100
    54.3 @@ -531,7 +531,7 @@ void irq_info(void)
    54.4      for (i = 0; i < 16; i++) {
    54.5          count = irq_count[i];
    54.6          if (count > 0)
    54.7 -            term_printf("%2d: %lld\n", i, count);
    54.8 +            term_printf("%2d: %" PRId64 "\n", i, count);
    54.9      }
   54.10  #endif
   54.11  }
    55.1 --- a/tools/ioemu/hw/ide.c	Mon Aug 07 18:11:59 2006 +0100
    55.2 +++ b/tools/ioemu/hw/ide.c	Mon Aug 07 18:25:30 2006 +0100
    55.3 @@ -1133,127 +1133,6 @@ static void ide_atapi_cmd_read(IDEState 
    55.4      }
    55.5  }
    55.6  
    55.7 -/* same toc as bochs. Return -1 if error or the toc length */
    55.8 -/* XXX: check this */
    55.9 -static int cdrom_read_toc(IDEState *s, uint8_t *buf, int msf, int start_track)
   55.10 -{
   55.11 -    uint8_t *q;
   55.12 -    int nb_sectors, len;
   55.13 -    
   55.14 -    if (start_track > 1 && start_track != 0xaa)
   55.15 -        return -1;
   55.16 -    q = buf + 2;
   55.17 -    *q++ = 1; /* first session */
   55.18 -    *q++ = 1; /* last session */
   55.19 -    if (start_track <= 1) {
   55.20 -        *q++ = 0; /* reserved */
   55.21 -        *q++ = 0x14; /* ADR, control */
   55.22 -        *q++ = 1;    /* track number */
   55.23 -        *q++ = 0; /* reserved */
   55.24 -        if (msf) {
   55.25 -            *q++ = 0; /* reserved */
   55.26 -            lba_to_msf(q, 0);
   55.27 -            q += 3;
   55.28 -        } else {
   55.29 -            /* sector 0 */
   55.30 -            cpu_to_ube32(q, 0);
   55.31 -            q += 4;
   55.32 -        }
   55.33 -    }
   55.34 -    /* lead out track */
   55.35 -    *q++ = 0; /* reserved */
   55.36 -    *q++ = 0x16; /* ADR, control */
   55.37 -    *q++ = 0xaa; /* track number */
   55.38 -    *q++ = 0; /* reserved */
   55.39 -    nb_sectors = s->nb_sectors >> 2;
   55.40 -    if (msf) {
   55.41 -        *q++ = 0; /* reserved */
   55.42 -        lba_to_msf(q, nb_sectors);
   55.43 -        q += 3;
   55.44 -    } else {
   55.45 -        cpu_to_ube32(q, nb_sectors);
   55.46 -        q += 4;
   55.47 -    }
   55.48 -    len = q - buf;
   55.49 -    cpu_to_ube16(buf, len - 2);
   55.50 -    return len;
   55.51 -}
   55.52 -
   55.53 -/* mostly same info as PearPc */
   55.54 -static int cdrom_read_toc_raw(IDEState *s, uint8_t *buf, int msf, 
   55.55 -                              int session_num)
   55.56 -{
   55.57 -    uint8_t *q;
   55.58 -    int nb_sectors, len;
   55.59 -    
   55.60 -    q = buf + 2;
   55.61 -    *q++ = 1; /* first session */
   55.62 -    *q++ = 1; /* last session */
   55.63 -
   55.64 -    *q++ = 1; /* session number */
   55.65 -    *q++ = 0x14; /* data track */
   55.66 -    *q++ = 0; /* track number */
   55.67 -    *q++ = 0xa0; /* lead-in */
   55.68 -    *q++ = 0; /* min */
   55.69 -    *q++ = 0; /* sec */
   55.70 -    *q++ = 0; /* frame */
   55.71 -    *q++ = 0;
   55.72 -    *q++ = 1; /* first track */
   55.73 -    *q++ = 0x00; /* disk type */
   55.74 -    *q++ = 0x00;
   55.75 -    
   55.76 -    *q++ = 1; /* session number */
   55.77 -    *q++ = 0x14; /* data track */
   55.78 -    *q++ = 0; /* track number */
   55.79 -    *q++ = 0xa1;
   55.80 -    *q++ = 0; /* min */
   55.81 -    *q++ = 0; /* sec */
   55.82 -    *q++ = 0; /* frame */
   55.83 -    *q++ = 0;
   55.84 -    *q++ = 1; /* last track */
   55.85 -    *q++ = 0x00;
   55.86 -    *q++ = 0x00;
   55.87 -    
   55.88 -    *q++ = 1; /* session number */
   55.89 -    *q++ = 0x14; /* data track */
   55.90 -    *q++ = 0; /* track number */
   55.91 -    *q++ = 0xa2; /* lead-out */
   55.92 -    *q++ = 0; /* min */
   55.93 -    *q++ = 0; /* sec */
   55.94 -    *q++ = 0; /* frame */
   55.95 -    nb_sectors = s->nb_sectors >> 2;
   55.96 -    if (msf) {
   55.97 -        *q++ = 0; /* reserved */
   55.98 -        lba_to_msf(q, nb_sectors);
   55.99 -        q += 3;
  55.100 -    } else {
  55.101 -        cpu_to_ube32(q, nb_sectors);
  55.102 -        q += 4;
  55.103 -    }
  55.104 -
  55.105 -    *q++ = 1; /* session number */
  55.106 -    *q++ = 0x14; /* ADR, control */
  55.107 -    *q++ = 0;    /* track number */
  55.108 -    *q++ = 1;    /* point */
  55.109 -    *q++ = 0; /* min */
  55.110 -    *q++ = 0; /* sec */
  55.111 -    *q++ = 0; /* frame */
  55.112 -    if (msf) {
  55.113 -        *q++ = 0; 
  55.114 -        lba_to_msf(q, 0);
  55.115 -        q += 3;
  55.116 -    } else {
  55.117 -        *q++ = 0; 
  55.118 -        *q++ = 0; 
  55.119 -        *q++ = 0; 
  55.120 -        *q++ = 0; 
  55.121 -    }
  55.122 -
  55.123 -    len = q - buf;
  55.124 -    cpu_to_ube16(buf, len - 2);
  55.125 -    return len;
  55.126 -}
  55.127 -
  55.128  static void ide_atapi_cmd(IDEState *s)
  55.129  {
  55.130      const uint8_t *packet;
  55.131 @@ -1501,7 +1380,7 @@ static void ide_atapi_cmd(IDEState *s)
  55.132              start_track = packet[6];
  55.133              switch(format) {
  55.134              case 0:
  55.135 -                len = cdrom_read_toc(s, buf, msf, start_track);
  55.136 +                len = cdrom_read_toc(s->nb_sectors >> 2, buf, msf, start_track);
  55.137                  if (len < 0)
  55.138                      goto error_cmd;
  55.139                  ide_atapi_cmd_reply(s, len, max_len);
  55.140 @@ -1515,7 +1394,7 @@ static void ide_atapi_cmd(IDEState *s)
  55.141                  ide_atapi_cmd_reply(s, 12, max_len);
  55.142                  break;
  55.143              case 2:
  55.144 -                len = cdrom_read_toc_raw(s, buf, msf, start_track);
  55.145 +                len = cdrom_read_toc_raw(s->nb_sectors >> 2, buf, msf, start_track);
  55.146                  if (len < 0)
  55.147                      goto error_cmd;
  55.148                  ide_atapi_cmd_reply(s, len, max_len);
  55.149 @@ -1829,6 +1708,11 @@ static void ide_ioport_write(void *opaqu
  55.150              break;
  55.151          case WIN_FLUSH_CACHE:
  55.152          case WIN_FLUSH_CACHE_EXT:
  55.153 +            if (s->bs)
  55.154 +                bdrv_flush(s->bs);
  55.155 +	    s->status = READY_STAT;
  55.156 +            ide_set_irq(s);
  55.157 +            break;
  55.158  	case WIN_STANDBYNOW1:
  55.159          case WIN_IDLEIMMEDIATE:
  55.160  	    s->status = READY_STAT;
  55.161 @@ -2563,7 +2447,7 @@ void pci_cmd646_ide_init(PCIBus *bus, Bl
  55.162  
  55.163  /* hd_table must contain 4 block drivers */
  55.164  /* NOTE: for the PIIX3, the IRQs and IOports are hardcoded */
  55.165 -void pci_piix3_ide_init(PCIBus *bus, BlockDriverState **hd_table)
  55.166 +void pci_piix3_ide_init(PCIBus *bus, BlockDriverState **hd_table, int devfn)
  55.167  {
  55.168      PCIIDEState *d;
  55.169      uint8_t *pci_conf;
  55.170 @@ -2571,7 +2455,7 @@ void pci_piix3_ide_init(PCIBus *bus, Blo
  55.171      /* register a function 1 of PIIX3 */
  55.172      d = (PCIIDEState *)pci_register_device(bus, "PIIX3 IDE", 
  55.173                                             sizeof(PCIIDEState),
  55.174 -                                           ((PCIDevice *)piix3_state)->devfn + 1, 
  55.175 +                                           devfn,
  55.176                                             NULL, NULL);
  55.177      d->type = IDE_TYPE_PIIX3;
  55.178  
    56.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    56.2 +++ b/tools/ioemu/hw/lsi53c895a.c	Mon Aug 07 18:25:30 2006 +0100
    56.3 @@ -0,0 +1,1571 @@
    56.4 +/* 
    56.5 + * QEMU LSI53C895A SCSI Host Bus Adapter emulation
    56.6 + *
    56.7 + * Copyright (c) 2006 CodeSourcery.
    56.8 + * Written by Paul Brook
    56.9 + *
   56.10 + * This code is licenced under the LGPL.
   56.11 + */
   56.12 +
   56.13 +/* ??? Need to check if the {read,write}[wl] routines work properly on
   56.14 +   big-endian targets.  */
   56.15 +
   56.16 +#include "vl.h"
   56.17 +
   56.18 +//#define DEBUG_LSI
   56.19 +//#define DEBUG_LSI_REG
   56.20 +
   56.21 +#ifdef DEBUG_LSI
   56.22 +#define DPRINTF(fmt, args...) \
   56.23 +do { printf("lsi_scsi: " fmt , ##args); } while (0)
   56.24 +#define BADF(fmt, args...) \
   56.25 +do { fprintf(stderr, "lsi_scsi: " fmt , ##args); exit(1);} while (0)
   56.26 +#else
   56.27 +#define DPRINTF(fmt, args...) do {} while(0)
   56.28 +#define BADF(fmt, args...) \
   56.29 +do { fprintf(stderr, "lsi_scsi: " fmt , ##args); } while (0)
   56.30 +#endif
   56.31 +
   56.32 +#define LSI_SCNTL0_TRG    0x01
   56.33 +#define LSI_SCNTL0_AAP    0x02
   56.34 +#define LSI_SCNTL0_EPC    0x08
   56.35 +#define LSI_SCNTL0_WATN   0x10
   56.36 +#define LSI_SCNTL0_START  0x20
   56.37 +
   56.38 +#define LSI_SCNTL1_SST    0x01
   56.39 +#define LSI_SCNTL1_IARB   0x02
   56.40 +#define LSI_SCNTL1_AESP   0x04
   56.41 +#define LSI_SCNTL1_RST    0x08
   56.42 +#define LSI_SCNTL1_CON    0x10
   56.43 +#define LSI_SCNTL1_DHP    0x20
   56.44 +#define LSI_SCNTL1_ADB    0x40
   56.45 +#define LSI_SCNTL1_EXC    0x80
   56.46 +
   56.47 +#define LSI_SCNTL2_WSR    0x01
   56.48 +#define LSI_SCNTL2_VUE0   0x02
   56.49 +#define LSI_SCNTL2_VUE1   0x04
   56.50 +#define LSI_SCNTL2_WSS    0x08
   56.51 +#define LSI_SCNTL2_SLPHBEN 0x10
   56.52 +#define LSI_SCNTL2_SLPMD  0x20
   56.53 +#define LSI_SCNTL2_CHM    0x40
   56.54 +#define LSI_SCNTL2_SDU    0x80
   56.55 +
   56.56 +#define LSI_ISTAT0_DIP    0x01
   56.57 +#define LSI_ISTAT0_SIP    0x02
   56.58 +#define LSI_ISTAT0_INTF   0x04
   56.59 +#define LSI_ISTAT0_CON    0x08
   56.60 +#define LSI_ISTAT0_SEM    0x10
   56.61 +#define LSI_ISTAT0_SIGP   0x20
   56.62 +#define LSI_ISTAT0_SRST   0x40
   56.63 +#define LSI_ISTAT0_ABRT   0x80
   56.64 +
   56.65 +#define LSI_ISTAT1_SI     0x01
   56.66 +#define LSI_ISTAT1_SRUN   0x02
   56.67 +#define LSI_ISTAT1_FLSH   0x04
   56.68 +
   56.69 +#define LSI_SSTAT0_SDP0   0x01
   56.70 +#define LSI_SSTAT0_RST    0x02
   56.71 +#define LSI_SSTAT0_WOA    0x04
   56.72 +#define LSI_SSTAT0_LOA    0x08
   56.73 +#define LSI_SSTAT0_AIP    0x10
   56.74 +#define LSI_SSTAT0_OLF    0x20
   56.75 +#define LSI_SSTAT0_ORF    0x40
   56.76 +#define LSI_SSTAT0_ILF    0x80
   56.77 +
   56.78 +#define LSI_SIST0_PAR     0x01
   56.79 +#define LSI_SIST0_RST     0x02
   56.80 +#define LSI_SIST0_UDC     0x04
   56.81 +#define LSI_SIST0_SGE     0x08
   56.82 +#define LSI_SIST0_RSL     0x10
   56.83 +#define LSI_SIST0_SEL     0x20
   56.84 +#define LSI_SIST0_CMP     0x40
   56.85 +#define LSI_SIST0_MA      0x80
   56.86 +
   56.87 +#define LSI_SIST1_HTH     0x01
   56.88 +#define LSI_SIST1_GEN     0x02
   56.89 +#define LSI_SIST1_STO     0x04
   56.90 +#define LSI_SIST1_SBMC    0x10
   56.91 +
   56.92 +#define LSI_SOCL_IO       0x01
   56.93 +#define LSI_SOCL_CD       0x02
   56.94 +#define LSI_SOCL_MSG      0x04
   56.95 +#define LSI_SOCL_ATN      0x08
   56.96 +#define LSI_SOCL_SEL      0x10
   56.97 +#define LSI_SOCL_BSY      0x20
   56.98 +#define LSI_SOCL_ACK      0x40
   56.99 +#define LSI_SOCL_REQ      0x80
  56.100 +
  56.101 +#define LSI_DSTAT_IID     0x01
  56.102 +#define LSI_DSTAT_SIR     0x04
  56.103 +#define LSI_DSTAT_SSI     0x08
  56.104 +#define LSI_DSTAT_ABRT    0x10
  56.105 +#define LSI_DSTAT_BF      0x20
  56.106 +#define LSI_DSTAT_MDPE    0x40
  56.107 +#define LSI_DSTAT_DFE     0x80
  56.108 +
  56.109 +#define LSI_DCNTL_COM     0x01
  56.110 +#define LSI_DCNTL_IRQD    0x02
  56.111 +#define LSI_DCNTL_STD     0x04
  56.112 +#define LSI_DCNTL_IRQM    0x08
  56.113 +#define LSI_DCNTL_SSM     0x10
  56.114 +#define LSI_DCNTL_PFEN    0x20
  56.115 +#define LSI_DCNTL_PFF     0x40
  56.116 +#define LSI_DCNTL_CLSE    0x80
  56.117 +
  56.118 +#define LSI_DMODE_MAN     0x01
  56.119 +#define LSI_DMODE_BOF     0x02
  56.120 +#define LSI_DMODE_ERMP    0x04
  56.121 +#define LSI_DMODE_ERL     0x08
  56.122 +#define LSI_DMODE_DIOM    0x10
  56.123 +#define LSI_DMODE_SIOM    0x20
  56.124 +
  56.125 +#define LSI_CTEST2_DACK   0x01
  56.126 +#define LSI_CTEST2_DREQ   0x02
  56.127 +#define LSI_CTEST2_TEOP   0x04
  56.128 +#define LSI_CTEST2_PCICIE 0x08
  56.129 +#define LSI_CTEST2_CM     0x10
  56.130 +#define LSI_CTEST2_CIO    0x20
  56.131 +#define LSI_CTEST2_SIGP   0x40
  56.132 +#define LSI_CTEST2_DDIR   0x80
  56.133 +
  56.134 +#define LSI_CTEST5_BL2    0x04
  56.135 +#define LSI_CTEST5_DDIR   0x08
  56.136 +#define LSI_CTEST5_MASR   0x10
  56.137 +#define LSI_CTEST5_DFSN   0x20
  56.138 +#define LSI_CTEST5_BBCK   0x40
  56.139 +#define LSI_CTEST5_ADCK   0x80
  56.140 +
  56.141 +#define LSI_CCNTL0_DILS   0x01
  56.142 +#define LSI_CCNTL0_DISFC  0x10
  56.143 +#define LSI_CCNTL0_ENNDJ  0x20
  56.144 +#define LSI_CCNTL0_PMJCTL 0x40
  56.145 +#define LSI_CCNTL0_ENPMJ  0x80
  56.146 +
  56.147 +#define PHASE_DO          0
  56.148 +#define PHASE_DI          1
  56.149 +#define PHASE_CMD         2
  56.150 +#define PHASE_ST          3
  56.151 +#define PHASE_MO          6
  56.152 +#define PHASE_MI          7
  56.153 +#define PHASE_MASK        7
  56.154 +
  56.155 +/* The HBA is ID 7, so for simplicitly limit to 7 devices.  */
  56.156 +#define LSI_MAX_DEVS      7
  56.157 +
  56.158 +typedef struct {
  56.159 +    PCIDevice pci_dev;
  56.160 +    int mmio_io_addr;
  56.161 +    int ram_io_addr;
  56.162 +    uint32_t script_ram_base;
  56.163 +    uint32_t data_len;
  56.164 +
  56.165 +    int carry; /* ??? Should this be an a visible register somewhere?  */
  56.166 +    int sense;
  56.167 +    uint8_t msg;
  56.168 +    /* Nonzero if a Wait Reselect instruction has been issued.  */
  56.169 +    int waiting;
  56.170 +    SCSIDevice *scsi_dev[LSI_MAX_DEVS];
  56.171 +    SCSIDevice *current_dev;
  56.172 +    int current_lun;
  56.173 +
  56.174 +    uint32_t dsa;
  56.175 +    uint32_t temp;
  56.176 +    uint32_t dnad;
  56.177 +    uint32_t dbc;
  56.178 +    uint8_t istat0;
  56.179 +    uint8_t istat1;
  56.180 +    uint8_t dcmd;
  56.181 +    uint8_t dstat;
  56.182 +    uint8_t dien;
  56.183 +    uint8_t sist0;
  56.184 +    uint8_t sist1;
  56.185 +    uint8_t sien0;
  56.186 +    uint8_t sien1;
  56.187 +    uint8_t mbox0;
  56.188 +    uint8_t mbox1;
  56.189 +    uint8_t dfifo;
  56.190 +    uint8_t ctest3;
  56.191 +    uint8_t ctest4;
  56.192 +    uint8_t ctest5;
  56.193 +    uint8_t ccntl0;
  56.194 +    uint8_t ccntl1;
  56.195 +    uint32_t dsp;
  56.196 +    uint32_t dsps;
  56.197 +    uint8_t dmode;
  56.198 +    uint8_t dcntl;
  56.199 +    uint8_t scntl0;
  56.200 +    uint8_t scntl1;
  56.201 +    uint8_t scntl2;
  56.202 +    uint8_t scntl3;
  56.203 +    uint8_t sstat0;
  56.204 +    uint8_t sstat1;
  56.205 +    uint8_t scid;
  56.206 +    uint8_t sxfer;
  56.207 +    uint8_t socl;
  56.208 +    uint8_t sdid;
  56.209 +    uint8_t sfbr;
  56.210 +    uint8_t stest1;
  56.211 +    uint8_t stest2;
  56.212 +    uint8_t stest3;
  56.213 +    uint8_t stime0;
  56.214 +    uint8_t respid0;
  56.215 +    uint8_t respid1;
  56.216 +    uint32_t mmrs;
  56.217 +    uint32_t mmws;
  56.218 +    uint32_t sfs;
  56.219 +    uint32_t drs;
  56.220 +    uint32_t sbms;
  56.221 +    uint32_t dmbs;
  56.222 +    uint32_t dnad64;
  56.223 +    uint32_t pmjad1;
  56.224 +    uint32_t pmjad2;
  56.225 +    uint32_t rbc;
  56.226 +    uint32_t ua;
  56.227 +    uint32_t ia;
  56.228 +    uint32_t sbc;
  56.229 +    uint32_t csbc;
  56.230 +    uint32_t scratch[13]; /* SCRATCHA-SCRATCHR */
  56.231 +
  56.232 +    /* Script ram is stored as 32-bit words in host byteorder.  */
  56.233 +    uint32_t script_ram[2048];
  56.234 +} LSIState;
  56.235 +
  56.236 +static void lsi_soft_reset(LSIState *s)
  56.237 +{
  56.238 +    DPRINTF("Reset\n");
  56.239 +    s->carry = 0;
  56.240 +
  56.241 +    s->waiting = 0;
  56.242 +    s->dsa = 0;
  56.243 +    s->dnad = 0;
  56.244 +    s->dbc = 0;
  56.245 +    s->temp = 0;
  56.246 +    memset(s->scratch, 0, sizeof(s->scratch));
  56.247 +    s->istat0 = 0;
  56.248 +    s->istat1 = 0;
  56.249 +    s->dcmd = 0;
  56.250 +    s->dstat = 0;
  56.251 +    s->dien = 0;
  56.252 +    s->sist0 = 0;
  56.253 +    s->sist1 = 0;
  56.254 +    s->sien0 = 0;
  56.255 +    s->sien1 = 0;
  56.256 +    s->mbox0 = 0;
  56.257 +    s->mbox1 = 0;
  56.258 +    s->dfifo = 0;
  56.259 +    s->ctest3 = 0;
  56.260 +    s->ctest4 = 0;
  56.261 +    s->ctest5 = 0;
  56.262 +    s->ccntl0 = 0;
  56.263 +    s->ccntl1 = 0;
  56.264 +    s->dsp = 0;
  56.265 +    s->dsps = 0;
  56.266 +    s->dmode = 0;
  56.267 +    s->dcntl = 0;
  56.268 +    s->scntl0 = 0xc0;
  56.269 +    s->scntl1 = 0;
  56.270 +    s->scntl2 = 0;
  56.271 +    s->scntl3 = 0;
  56.272 +    s->sstat0 = 0;
  56.273 +    s->sstat1 = 0;
  56.274 +    s->scid = 7;
  56.275 +    s->sxfer = 0;
  56.276 +    s->socl = 0;
  56.277 +    s->stest1 = 0;
  56.278 +    s->stest2 = 0;
  56.279 +    s->stest3 = 0;
  56.280 +    s->stime0 = 0;
  56.281 +    s->respid0 = 0x80;
  56.282 +    s->respid1 = 0;
  56.283 +    s->mmrs = 0;
  56.284 +    s->mmws = 0;
  56.285 +    s->sfs = 0;
  56.286 +    s->drs = 0;
  56.287 +    s->sbms = 0;
  56.288 +    s->dmbs = 0;
  56.289 +    s->dnad64 = 0;
  56.290 +    s->pmjad1 = 0;
  56.291 +    s->pmjad2 = 0;
  56.292 +    s->rbc = 0;
  56.293 +    s->ua = 0;
  56.294 +    s->ia = 0;
  56.295 +    s->sbc = 0;
  56.296 +    s->csbc = 0;
  56.297 +}
  56.298 +
  56.299 +static uint8_t lsi_reg_readb(LSIState *s, int offset);
  56.300 +static void lsi_reg_writeb(LSIState *s, int offset, uint8_t val);
  56.301 +
  56.302 +static inline uint32_t read_dword(LSIState *s, uint32_t addr)
  56.303 +{
  56.304 +    uint32_t buf;
  56.305 +
  56.306 +    /* Optimize reading from SCRIPTS RAM.  */
  56.307 +    if ((addr & 0xffffe000) == s->script_ram_base) {
  56.308 +        return s->script_ram[(addr & 0x1fff) >> 2];
  56.309 +    }
  56.310 +    cpu_physical_memory_read(addr, (uint8_t *)&buf, 4);
  56.311 +    return cpu_to_le32(buf);
  56.312 +}
  56.313 +
  56.314 +static void lsi_stop_script(LSIState *s)
  56.315 +{
  56.316 +    s->istat1 &= ~LSI_ISTAT1_SRUN;
  56.317 +}
  56.318 +
  56.319 +static void lsi_update_irq(LSIState *s)
  56.320 +{
  56.321 +    int level;
  56.322 +    static int last_level;
  56.323 +
  56.324 +    /* It's unclear whether the DIP/SIP bits should be cleared when the
  56.325 +       Interrupt Status Registers are cleared or when istat0 is read.
  56.326 +       We currently do the formwer, which seems to work.  */
  56.327 +    level = 0;
  56.328 +    if (s->dstat) {
  56.329 +        if (s->dstat & s->dien)
  56.330 +            level = 1;
  56.331 +        s->istat0 |= LSI_ISTAT0_DIP;
  56.332 +    } else {
  56.333 +        s->istat0 &= ~LSI_ISTAT0_DIP;
  56.334 +    }
  56.335 +
  56.336 +    if (s->sist0 || s->sist1) {
  56.337 +        if ((s->sist0 & s->sien0) || (s->sist1 & s->sien1))
  56.338 +            level = 1;
  56.339 +        s->istat0 |= LSI_ISTAT0_SIP;
  56.340 +    } else {
  56.341 +        s->istat0 &= ~LSI_ISTAT0_SIP;
  56.342 +    }
  56.343 +    if (s->istat0 & LSI_ISTAT0_INTF)
  56.344 +        level = 1;
  56.345 +
  56.346 +    if (level != last_level) {
  56.347 +        DPRINTF("Update IRQ level %d dstat %02x sist %02x%02x\n",
  56.348 +                level, s->dstat, s->sist1, s->sist0);
  56.349 +        last_level = level;
  56.350 +    }
  56.351 +    pci_set_irq(&s->pci_dev, 0, level);
  56.352 +}
  56.353 +
  56.354 +/* Stop SCRIPTS execution and raise a SCSI interrupt.  */
  56.355 +static void lsi_script_scsi_interrupt(LSIState *s, int stat0, int stat1)
  56.356 +{
  56.357 +    uint32_t mask0;
  56.358 +    uint32_t mask1;
  56.359 +
  56.360 +    DPRINTF("SCSI Interrupt 0x%02x%02x prev 0x%02x%02x\n",
  56.361 +            stat1, stat0, s->sist1, s->sist0);
  56.362 +    s->sist0 |= stat0;
  56.363 +    s->sist1 |= stat1;
  56.364 +    /* Stop processor on fatal or unmasked interrupt.  As a special hack
  56.365 +       we don't stop processing when raising STO.  Instead continue
  56.366 +       execution and stop at the next insn that accesses the SCSI bus.  */
  56.367 +    mask0 = s->sien0 | ~(LSI_SIST0_CMP | LSI_SIST0_SEL | LSI_SIST0_RSL);
  56.368 +    mask1 = s->sien1 | ~(LSI_SIST1_GEN | LSI_SIST1_HTH);
  56.369 +    mask1 &= ~LSI_SIST1_STO;
  56.370 +    if (s->sist0 & mask0 || s->sist1 & mask1) {
  56.371 +        lsi_stop_script(s);
  56.372 +    }
  56.373 +    lsi_update_irq(s);
  56.374 +}
  56.375 +
  56.376 +/* Stop SCRIPTS execution and raise a DMA interrupt.  */
  56.377 +static void lsi_script_dma_interrupt(LSIState *s, int stat)
  56.378 +{
  56.379 +    DPRINTF("DMA Interrupt 0x%x prev 0x%x\n", stat, s->dstat);
  56.380 +    s->dstat |= stat;
  56.381 +    lsi_update_irq(s);
  56.382 +    lsi_stop_script(s);
  56.383 +}
  56.384 +
  56.385 +static inline void lsi_set_phase(LSIState *s, int phase)
  56.386 +{
  56.387 +    s->sstat1 = (s->sstat1 & ~PHASE_MASK) | phase;
  56.388 +}
  56.389 +
  56.390 +static void lsi_bad_phase(LSIState *s, int out, int new_phase)
  56.391 +{
  56.392 +    /* Trigger a phase mismatch.  */
  56.393 +    if (s->ccntl0 & LSI_CCNTL0_ENPMJ) {
  56.394 +        if ((s->ccntl0 & LSI_CCNTL0_PMJCTL) || out) {
  56.395 +            s->dsp = s->pmjad1;
  56.396 +        } else {
  56.397 +            s->dsp = s->pmjad2;
  56.398 +        }
  56.399 +        DPRINTF("Data phase mismatch jump to %08x\n", s->dsp);
  56.400 +    } else {
  56.401 +        DPRINTF("Phase mismatch interrupt\n");
  56.402 +        lsi_script_scsi_interrupt(s, LSI_SIST0_MA, 0);
  56.403 +        lsi_stop_script(s);
  56.404 +    }
  56.405 +    lsi_set_phase(s, new_phase);
  56.406 +}
  56.407 +
  56.408 +static void lsi_do_dma(LSIState *s, int out)
  56.409 +{
  56.410 +    uint8_t buf[TARGET_PAGE_SIZE];
  56.411 +    uint32_t addr;
  56.412 +    uint32_t count;
  56.413 +    int n;
  56.414 +
  56.415 +    count = s->dbc;
  56.416 +    addr = s->dnad;
  56.417 +    DPRINTF("DMA %s addr=0x%08x len=%d avail=%d\n", out ? "out" : "in",
  56.418 +            addr, count, s->data_len);
  56.419 +    /* ??? Too long transfers are truncated. Don't know if this is the
  56.420 +       correct behavior.  */
  56.421 +    if (count > s->data_len) {
  56.422 +        /* If the DMA length is greater then the device data length then
  56.423 +           a phase mismatch will occur.  */
  56.424 +        count = s->data_len;
  56.425 +        s->dbc = count;
  56.426 +        lsi_bad_phase(s, out, PHASE_ST);
  56.427 +    }
  56.428 +
  56.429 +    s->csbc += count;
  56.430 +
  56.431 +    /* ??? Set SFBR to first data byte.  */
  56.432 +    while (count) {
  56.433 +        n = (count > TARGET_PAGE_SIZE) ? TARGET_PAGE_SIZE : count;
  56.434 +        if (out) {
  56.435 +            cpu_physical_memory_read(addr, buf, n);
  56.436 +            scsi_write_data(s->current_dev, buf, n);
  56.437 +        } else {
  56.438 +            scsi_read_data(s->current_dev, buf, n);
  56.439 +            cpu_physical_memory_write(addr, buf, n);
  56.440 +        }
  56.441 +        addr += n;
  56.442 +        count -= n;
  56.443 +    }
  56.444 +}
  56.445 +
  56.446 +
  56.447 +static void lsi_do_command(LSIState *s)
  56.448 +{
  56.449 +    uint8_t buf[16];
  56.450 +    int n;
  56.451 +
  56.452 +    DPRINTF("Send command len=%d\n", s->dbc);
  56.453 +    if (s->dbc > 16)
  56.454 +        s->dbc = 16;
  56.455 +    cpu_physical_memory_read(s->dnad, buf, s->dbc);
  56.456 +    s->sfbr = buf[0];
  56.457 +    n = scsi_send_command(s->current_dev, 0, buf, s->current_lun);
  56.458 +    if (n > 0) {
  56.459 +        s->data_len = n;
  56.460 +        lsi_set_phase(s, PHASE_DI);
  56.461 +    } else if (n < 0) {
  56.462 +        s->data_len = -n;
  56.463 +        lsi_set_phase(s, PHASE_DO);
  56.464 +    }
  56.465 +}
  56.466 +
  56.467 +static void lsi_command_complete(void *opaque, uint32_t tag, int sense)
  56.468 +{
  56.469 +    LSIState *s = (LSIState *)opaque;
  56.470 +
  56.471 +    DPRINTF("Command complete sense=%d\n", sense);
  56.472 +    s->sense = sense;
  56.473 +    lsi_set_phase(s, PHASE_ST);
  56.474 +}
  56.475 +
  56.476 +static void lsi_do_status(LSIState *s)
  56.477 +{
  56.478 +    DPRINTF("Get status len=%d sense=%d\n", s->dbc, s->sense);
  56.479 +    if (s->dbc != 1)
  56.480 +        BADF("Bad Status move\n");
  56.481 +    s->dbc = 1;
  56.482 +    s->msg = s->sense;
  56.483 +    cpu_physical_memory_write(s->dnad, &s->msg, 1);
  56.484 +    s->sfbr = s->msg;
  56.485 +    lsi_set_phase(s, PHASE_MI);
  56.486 +    s->msg = 0; /* COMMAND COMPLETE */
  56.487 +}
  56.488 +
  56.489 +static void lsi_disconnect(LSIState *s)
  56.490 +{
  56.491 +    s->scntl1 &= ~LSI_SCNTL1_CON;
  56.492 +    s->sstat1 &= ~PHASE_MASK;
  56.493 +}
  56.494 +
  56.495 +static void lsi_do_msgin(LSIState *s)
  56.496 +{
  56.497 +    DPRINTF("Message in len=%d\n", s->dbc);
  56.498 +    s->dbc = 1;
  56.499 +    s->sfbr = s->msg;
  56.500 +    cpu_physical_memory_write(s->dnad, &s->msg, 1);
  56.501 +    if (s->msg == 0) {
  56.502 +        lsi_disconnect(s);
  56.503 +    } else {
  56.504 +        /* ??? Check if ATN (not yet implemented) is asserted and maybe
  56.505 +           switch to PHASE_MO.  */
  56.506 +        lsi_set_phase(s, PHASE_CMD);
  56.507 +    }
  56.508 +}
  56.509 +
  56.510 +static void lsi_do_msgout(LSIState *s)
  56.511 +{
  56.512 +    uint8_t msg;
  56.513 +
  56.514 +    DPRINTF("MSG out len=%d\n", s->dbc);
  56.515 +    if (s->dbc != 1) {
  56.516 +        /* Multibyte messages not implemented.  */
  56.517 +        s->msg = 7; /* MESSAGE REJECT */
  56.518 +        //s->dbc = 1;
  56.519 +        //lsi_bad_phase(s, 1, PHASE_MI);
  56.520 +        lsi_set_phase(s, PHASE_MI);
  56.521 +        return;
  56.522 +    }
  56.523 +    cpu_physical_memory_read(s->dnad, &msg, 1);
  56.524 +    s->sfbr = msg;
  56.525 +    s->dnad++;
  56.526 +
  56.527 +    switch (msg) {
  56.528 +    case 0x00:
  56.529 +        DPRINTF("Got Disconnect\n");
  56.530 +        lsi_disconnect(s);
  56.531 +        return;
  56.532 +    case 0x08:
  56.533 +        DPRINTF("Got No Operation\n");
  56.534 +        lsi_set_phase(s, PHASE_CMD);
  56.535 +        return;
  56.536 +    }
  56.537 +    if ((msg & 0x80) == 0) {
  56.538 +        DPRINTF("Unimplemented message 0x%d\n", msg);
  56.539 +        s->msg = 7; /* MESSAGE REJECT */
  56.540 +        lsi_bad_phase(s, 1, PHASE_MI);
  56.541 +        return;
  56.542 +    }
  56.543 +    s->current_lun = msg & 7;
  56.544 +    DPRINTF("Select LUN %d\n", s->current_lun);
  56.545 +    lsi_set_phase(s, PHASE_CMD);
  56.546 +}
  56.547 +
  56.548 +/* Sign extend a 24-bit value.  */
  56.549 +static inline int32_t sxt24(int32_t n)
  56.550 +{
  56.551 +    return (n << 8) >> 8;
  56.552 +}
  56.553 +
  56.554 +static void lsi_memcpy(LSIState *s, uint32_t dest, uint32_t src, int count)
  56.555 +{
  56.556 +    int n;
  56.557 +    uint8_t buf[TARGET_PAGE_SIZE];
  56.558 +
  56.559 +    DPRINTF("memcpy dest 0x%08x src 0x%08x count %d\n", dest, src, count);
  56.560 +    while (count) {
  56.561 +        n = (count > TARGET_PAGE_SIZE) ? TARGET_PAGE_SIZE : count;
  56.562 +        cpu_physical_memory_read(src, buf, n);
  56.563 +        cpu_physical_memory_write(dest, buf, n);
  56.564 +        src += n;
  56.565 +        dest += n;
  56.566 +        count -= n;
  56.567 +    }
  56.568 +}
  56.569 +
  56.570 +static void lsi_execute_script(LSIState *s)
  56.571 +{
  56.572 +    uint32_t insn;
  56.573 +    uint32_t addr;
  56.574 +    int opcode;
  56.575 +
  56.576 +    s->istat1 |= LSI_ISTAT1_SRUN;
  56.577 +again:
  56.578 +    insn = read_dword(s, s->dsp);
  56.579 +    addr = read_dword(s, s->dsp + 4);
  56.580 +    DPRINTF("SCRIPTS dsp=%08x opcode %08x arg %08x\n", s->dsp, insn, addr);
  56.581 +    s->dsps = addr;
  56.582 +    s->dcmd = insn >> 24;
  56.583 +    s->dsp += 8;
  56.584 +    switch (insn >> 30) {
  56.585 +    case 0: /* Block move.  */
  56.586 +        if (s->sist1 & LSI_SIST1_STO) {
  56.587 +            DPRINTF("Delayed select timeout\n");
  56.588 +            lsi_stop_script(s);
  56.589 +            break;
  56.590 +        }
  56.591 +        s->dbc = insn & 0xffffff;
  56.592 +        s->rbc = s->dbc;
  56.593 +        if (insn & (1 << 29)) {
  56.594 +            /* Indirect addressing.  */
  56.595 +            addr = read_dword(s, addr);
  56.596 +        } else if (insn & (1 << 28)) {
  56.597 +            uint32_t buf[2];
  56.598 +            int32_t offset;
  56.599 +            /* Table indirect addressing.  */
  56.600 +            offset = sxt24(addr);
  56.601 +            cpu_physical_memory_read(s->dsa + offset, (uint8_t *)buf, 8);
  56.602 +            s->dbc = cpu_to_le32(buf[0]);
  56.603 +            addr = cpu_to_le32(buf[1]);
  56.604 +        }
  56.605 +        if ((s->sstat1 & PHASE_MASK) != ((insn >> 24) & 7)) {
  56.606 +            DPRINTF("Wrong phase got %d expected %d\n",
  56.607 +                    s->sstat1 & PHASE_MASK, (insn >> 24) & 7);
  56.608 +            lsi_script_scsi_interrupt(s, LSI_SIST0_MA, 0);
  56.609 +            break;
  56.610 +        }
  56.611 +        s->dnad = addr;
  56.612 +        switch (s->sstat1 & 0x7) {
  56.613 +        case PHASE_DO:
  56.614 +            lsi_do_dma(s, 1);
  56.615 +            break;
  56.616 +        case PHASE_DI:
  56.617 +            lsi_do_dma(s, 0);
  56.618 +            break;
  56.619 +        case PHASE_CMD:
  56.620 +            lsi_do_command(s);
  56.621 +            break;
  56.622 +        case PHASE_ST:
  56.623 +            lsi_do_status(s);
  56.624 +            break;
  56.625 +        case PHASE_MO:
  56.626 +            lsi_do_msgout(s);
  56.627 +            break;
  56.628 +        case PHASE_MI:
  56.629 +            lsi_do_msgin(s);
  56.630 +            break;
  56.631 +        default:
  56.632 +            BADF("Unimplemented phase %d\n", s->sstat1 & PHASE_MASK);
  56.633 +            exit(1);
  56.634 +        }
  56.635 +        s->dfifo = s->dbc & 0xff;
  56.636 +        s->ctest5 = (s->ctest5 & 0xfc) | ((s->dbc >> 8) & 3);
  56.637 +        s->sbc = s->dbc;
  56.638 +        s->rbc -= s->dbc;
  56.639 +        s->ua = addr + s->dbc;
  56.640 +        /* ??? Set ESA.  */
  56.641 +        s->ia = s->dsp - 8;
  56.642 +        break;
  56.643 +
  56.644 +    case 1: /* IO or Read/Write instruction.  */
  56.645 +        opcode = (insn >> 27) & 7;
  56.646 +        if (opcode < 5) {
  56.647 +            uint32_t id;
  56.648 +
  56.649 +            if (insn & (1 << 25)) {
  56.650 +                id = read_dword(s, s->dsa + sxt24(insn));
  56.651 +            } else {
  56.652 +                id = addr;
  56.653 +            }
  56.654 +            id = (id >> 16) & 0xf;
  56.655 +            if (insn & (1 << 26)) {
  56.656 +                addr = s->dsp + sxt24(addr);
  56.657 +            }
  56.658 +            s->dnad = addr;
  56.659 +            switch (opcode) {
  56.660 +            case 0: /* Select */
  56.661 +                s->sstat0 |= LSI_SSTAT0_WOA;
  56.662 +                s->scntl1 &= ~LSI_SCNTL1_IARB;
  56.663 +                s->sdid = id;
  56.664 +                if (id >= LSI_MAX_DEVS || !s->scsi_dev[id]) {
  56.665 +                    DPRINTF("Selected absent target %d\n", id);
  56.666 +                    lsi_script_scsi_interrupt(s, 0, LSI_SIST1_STO);
  56.667 +                    lsi_disconnect(s);
  56.668 +                    break;
  56.669 +                }
  56.670 +                DPRINTF("Selected target %d%s\n",
  56.671 +                        id, insn & (1 << 3) ? " ATN" : "");
  56.672 +                /* ??? Linux drivers compain when this is set.  Maybe
  56.673 +                   it only applies in low-level mode (unimplemented).
  56.674 +                lsi_script_scsi_interrupt(s, LSI_SIST0_CMP, 0); */
  56.675 +                s->current_dev = s->scsi_dev[id];
  56.676 +                s->scntl1 |= LSI_SCNTL1_CON;
  56.677 +                if (insn & (1 << 3)) {
  56.678 +                    s->socl |= LSI_SOCL_ATN;
  56.679 +                }
  56.680 +                lsi_set_phase(s, PHASE_MO);
  56.681 +                break;
  56.682 +            case 1: /* Disconnect */
  56.683 +                DPRINTF("Wait Disconect\n");
  56.684 +                s->scntl1 &= ~LSI_SCNTL1_CON;
  56.685 +                break;
  56.686 +            case 2: /* Wait Reselect */
  56.687 +                DPRINTF("Wait Reselect\n");
  56.688 +                s->waiting = 1;
  56.689 +                break;
  56.690 +            case 3: /* Set */
  56.691 +                DPRINTF("Set%s%s%s%s\n",
  56.692 +                        insn & (1 << 3) ? " ATN" : "",
  56.693 +                        insn & (1 << 6) ? " ACK" : "",
  56.694 +                        insn & (1 << 9) ? " TM" : "",
  56.695 +                        insn & (1 << 10) ? " CC" : "");
  56.696 +                if (insn & (1 << 3)) {
  56.697 +                    s->socl |= LSI_SOCL_ATN;
  56.698 +                    lsi_set_phase(s, PHASE_MO);
  56.699 +                }
  56.700 +                if (insn & (1 << 9)) {
  56.701 +                    BADF("Target mode not implemented\n");
  56.702 +                    exit(1);
  56.703 +                }
  56.704 +                if (insn & (1 << 10))
  56.705 +                    s->carry = 1;
  56.706 +                break;
  56.707 +            case 4: /* Clear */
  56.708 +                DPRINTF("Clear%s%s%s%s\n",
  56.709 +                        insn & (1 << 3) ? " ATN" : "",
  56.710 +                        insn & (1 << 6) ? " ACK" : "",
  56.711 +                        insn & (1 << 9) ? " TM" : "",
  56.712 +                        insn & (1 << 10) ? " CC" : "");
  56.713 +                if (insn & (1 << 3)) {
  56.714 +                    s->socl &= ~LSI_SOCL_ATN;
  56.715 +                }
  56.716 +                if (insn & (1 << 10))
  56.717 +                    s->carry = 0;
  56.718 +                break;
  56.719 +            }
  56.720 +        } else {
  56.721 +            uint8_t op0;
  56.722 +            uint8_t op1;
  56.723 +            uint8_t data8;
  56.724 +            int reg;
  56.725 +            int operator;
  56.726 +#ifdef DEBUG_LSI
  56.727 +            static const char *opcode_names[3] =
  56.728 +                {"Write", "Read", "Read-Modify-Write"};
  56.729 +            static const char *operator_names[8] =
  56.730 +                {"MOV", "SHL", "OR", "XOR", "AND", "SHR", "ADD", "ADC"};
  56.731 +#endif
  56.732 +
  56.733 +            reg = ((insn >> 16) & 0x7f) | (insn & 0x80);
  56.734 +            data8 = (insn >> 8) & 0xff;
  56.735 +            opcode = (insn >> 27) & 7;
  56.736 +            operator = (insn >> 24) & 7;
  56.737 +            DPRINTF("%s reg 0x%x %s data8 %d%s\n",
  56.738 +                    opcode_names[opcode - 5], reg,
  56.739 +                    operator_names[operator], data8,
  56.740 +                    (insn & (1 << 23)) ? " SFBR" : "");
  56.741 +            op0 = op1 = 0;
  56.742 +            switch (opcode) {
  56.743 +            case 5: /* From SFBR */
  56.744 +                op0 = s->sfbr;
  56.745 +                op1 = data8;
  56.746 +                break;
  56.747 +            case 6: /* To SFBR */
  56.748 +                if (operator)
  56.749 +                    op0 = lsi_reg_readb(s, reg);
  56.750 +                op1 = data8;
  56.751 +                break;
  56.752 +            case 7: /* Read-modify-write */
  56.753 +                if (operator)
  56.754 +                    op0 = lsi_reg_readb(s, reg);
  56.755 +                if (insn & (1 << 23)) {
  56.756 +                    op1 = s->sfbr;
  56.757 +                } else {
  56.758 +                    op1 = data8;
  56.759 +                }
  56.760 +                break;
  56.761 +            }
  56.762 +
  56.763 +            switch (operator) {
  56.764 +            case 0: /* move */
  56.765 +                op0 = op1;
  56.766 +                break;
  56.767 +            case 1: /* Shift left */
  56.768 +                op1 = op0 >> 7;
  56.769 +                op0 = (op0 << 1) | s->carry;
  56.770 +                s->carry = op1;
  56.771 +                break;
  56.772 +            case 2: /* OR */
  56.773 +                op0 |= op1;
  56.774 +                break;
  56.775 +            case 3: /* XOR */
  56.776 +                op0 |= op1;
  56.777 +                break;
  56.778 +            case 4: /* AND */
  56.779 +                op0 &= op1;
  56.780 +                break;
  56.781 +            case 5: /* SHR */
  56.782 +                op1 = op0 & 1;
  56.783 +                op0 = (op0 >> 1) | (s->carry << 7);
  56.784 +                break;
  56.785 +            case 6: /* ADD */
  56.786 +                op0 += op1;
  56.787 +                s->carry = op0 < op1;
  56.788 +                break;
  56.789 +            case 7: /* ADC */
  56.790 +                op0 += op1 + s->carry;
  56.791 +                if (s->carry)
  56.792 +                    s->carry = op0 <= op1;
  56.793 +                else
  56.794 +                    s->carry = op0 < op1;
  56.795 +                break;
  56.796 +            }
  56.797 +
  56.798 +            switch (opcode) {
  56.799 +            case 5: /* From SFBR */
  56.800 +            case 7: /* Read-modify-write */
  56.801 +                lsi_reg_writeb(s, reg, op0);
  56.802 +                break;
  56.803 +            case 6: /* To SFBR */
  56.804 +                s->sfbr = op0;
  56.805 +                break;
  56.806 +            }
  56.807 +        }
  56.808 +        break;
  56.809 +
  56.810 +    case 2: /* Transfer Control.  */
  56.811 +        {
  56.812 +            int cond;
  56.813 +            int jmp;
  56.814 +
  56.815 +            if ((insn & 0x002e0000) == 0) {
  56.816 +                DPRINTF("NOP\n");
  56.817 +                break;
  56.818 +            }
  56.819 +            if (s->sist1 & LSI_SIST1_STO) {
  56.820 +                DPRINTF("Delayed select timeout\n");
  56.821 +                lsi_stop_script(s);
  56.822 +                break;
  56.823 +            }
  56.824 +            cond = jmp = (insn & (1 << 19)) != 0;
  56.825 +            if (cond == jmp && (insn & (1 << 21))) {
  56.826 +                DPRINTF("Compare carry %d\n", s->carry == jmp);
  56.827 +                cond = s->carry != 0;
  56.828 +            }
  56.829 +            if (cond == jmp && (insn & (1 << 17))) {
  56.830 +                DPRINTF("Compare phase %d %c= %d\n",
  56.831 +                        (s->sstat1 & PHASE_MASK),
  56.832 +                        jmp ? '=' : '!',
  56.833 +                        ((insn >> 24) & 7));
  56.834 +                cond = (s->sstat1 & PHASE_MASK) == ((insn >> 24) & 7);
  56.835 +            }
  56.836 +            if (cond == jmp && (insn & (1 << 18))) {
  56.837 +                uint8_t mask;
  56.838 +
  56.839 +                mask = (~insn >> 8) & 0xff;
  56.840 +                DPRINTF("Compare data 0x%x & 0x%x %c= 0x%x\n",
  56.841 +                        s->sfbr, mask, jmp ? '=' : '!', insn & mask);
  56.842 +                cond = (s->sfbr & mask) == (insn & mask);
  56.843 +            }
  56.844 +            if (cond == jmp) {
  56.845 +                if (insn & (1 << 23)) {
  56.846 +                    /* Relative address.  */
  56.847 +                    addr = s->dsp + sxt24(addr);
  56.848 +                }
  56.849 +                switch ((insn >> 27) & 7) {
  56.850 +                case 0: /* Jump */
  56.851 +                    DPRINTF("Jump to 0x%08x\n", addr);
  56.852 +                    s->dsp = addr;
  56.853 +                    break;
  56.854 +                case 1: /* Call */
  56.855 +                    DPRINTF("Call 0x%08x\n", addr);
  56.856 +                    s->temp = s->dsp;
  56.857 +                    s->dsp = addr;
  56.858 +                    break;
  56.859 +                case 2: /* Return */
  56.860 +                    DPRINTF("Return to 0x%08x\n", s->temp);
  56.861 +                    s->dsp = s->temp;
  56.862 +                    break;
  56.863 +                case 3: /* Interrupt */
  56.864 +                    DPRINTF("Interrupt 0x%08x\n", s->dsps);
  56.865 +                    if ((insn & (1 << 20)) != 0) {
  56.866 +                        s->istat0 |= LSI_ISTAT0_INTF;
  56.867 +                        lsi_update_irq(s);
  56.868 +                    } else {
  56.869 +                        lsi_script_dma_interrupt(s, LSI_DSTAT_SIR);
  56.870 +                    }
  56.871 +                    break;
  56.872 +                default:
  56.873 +                    DPRINTF("Illegal transfer control\n");
  56.874 +                    lsi_script_dma_interrupt(s, LSI_DSTAT_IID);
  56.875 +                    break;
  56.876 +                }
  56.877 +            } else {
  56.878 +                DPRINTF("Control condition failed\n");
  56.879 +            }
  56.880 +        }
  56.881 +        break;
  56.882 +
  56.883 +    case 3:
  56.884 +        if ((insn & (1 << 29)) == 0) {
  56.885 +            /* Memory move.  */
  56.886 +            uint32_t dest;
  56.887 +            /* ??? The docs imply the destination address is loaded into
  56.888 +               the TEMP register.  However the Linux drivers rely on
  56.889 +               the value being presrved.  */
  56.890 +            dest = read_dword(s, s->dsp);
  56.891 +            s->dsp += 4;
  56.892 +            lsi_memcpy(s, dest, addr, insn & 0xffffff);
  56.893 +        } else {
  56.894 +            uint8_t data[7];
  56.895 +            int reg;
  56.896 +            int n;
  56.897 +            int i;
  56.898 +
  56.899 +            if (insn & (1 << 28)) {
  56.900 +                addr = s->dsa + sxt24(addr);
  56.901 +            }
  56.902 +            n = (insn & 7);
  56.903 +            reg = (insn >> 16) & 0xff;
  56.904 +            if (insn & (1 << 24)) {
  56.905 +                DPRINTF("Load reg 0x%x size %d addr 0x%08x\n", reg, n, addr);
  56.906 +                cpu_physical_memory_read(addr, data, n);
  56.907 +                for (i = 0; i < n; i++) {
  56.908 +                    lsi_reg_writeb(s, reg + i, data[i]);
  56.909 +                }
  56.910 +            } else {
  56.911 +                DPRINTF("Store reg 0x%x size %d addr 0x%08x\n", reg, n, addr);
  56.912 +                for (i = 0; i < n; i++) {
  56.913 +                    data[i] = lsi_reg_readb(s, reg + i);
  56.914 +                }
  56.915 +                cpu_physical_memory_write(addr, data, n);
  56.916 +            }
  56.917 +        }
  56.918 +    }
  56.919 +    /* ??? Need to avoid infinite loops.  */
  56.920 +    if (s->istat1 & LSI_ISTAT1_SRUN && !s->waiting) {
  56.921 +        if (s->dcntl & LSI_DCNTL_SSM) {
  56.922 +            lsi_script_dma_interrupt(s, LSI_DSTAT_SSI);
  56.923 +        } else {
  56.924 +            goto again;
  56.925 +        }
  56.926 +    }
  56.927 +    DPRINTF("SCRIPTS execution stopped\n");
  56.928 +}
  56.929 +
  56.930 +static uint8_t lsi_reg_readb(LSIState *s, int offset)
  56.931 +{
  56.932 +    uint8_t tmp;
  56.933 +#define CASE_GET_REG32(name, addr) \
  56.934 +    case addr: return s->name & 0xff; \
  56.935 +    case addr + 1: return (s->name >> 8) & 0xff; \
  56.936 +    case addr + 2: return (s->name >> 16) & 0xff; \
  56.937 +    case addr + 3: return (s->name >> 24) & 0xff;
  56.938 +
  56.939 +#ifdef DEBUG_LSI_REG
  56.940 +    DPRINTF("Read reg %x\n", offset);
  56.941 +#endif
  56.942 +    switch (offset) {
  56.943 +    case 0x00: /* SCNTL0 */
  56.944 +        return s->scntl0;
  56.945 +    case 0x01: /* SCNTL1 */
  56.946 +        return s->scntl1;
  56.947 +    case 0x02: /* SCNTL2 */
  56.948 +        return s->scntl2;
  56.949 +    case 0x03: /* SCNTL3 */
  56.950 +        return s->scntl3;
  56.951 +    case 0x04: /* SCID */
  56.952 +        return s->scid;
  56.953 +    case 0x05: /* SXFER */
  56.954 +        return s->sxfer;
  56.955 +    case 0x06: /* SDID */
  56.956 +        return s->sdid;
  56.957 +    case 0x07: /* GPREG0 */
  56.958 +        return 0x7f;
  56.959 +    case 0xb: /* SBCL */
  56.960 +        /* ??? This is not correct. However it's (hopefully) only
  56.961 +           used for diagnostics, so should be ok.  */
  56.962 +        return 0;
  56.963 +    case 0xc: /* DSTAT */
  56.964 +        tmp = s->dstat | 0x80;
  56.965 +        if ((s->istat0 & LSI_ISTAT0_INTF) == 0)
  56.966 +            s->dstat = 0;
  56.967 +        lsi_update_irq(s);
  56.968 +        return tmp;
  56.969 +    case 0x0d: /* SSTAT0 */
  56.970 +        return s->sstat0;
  56.971 +    case 0x0e: /* SSTAT1 */
  56.972 +        return s->sstat1;
  56.973 +    case 0x0f: /* SSTAT2 */
  56.974 +        return s->scntl1 & LSI_SCNTL1_CON ? 0 : 2;
  56.975 +    CASE_GET_REG32(dsa, 0x10)
  56.976 +    case 0x14: /* ISTAT0 */
  56.977 +        return s->istat0;
  56.978 +    case 0x16: /* MBOX0 */
  56.979 +        return s->mbox0;
  56.980 +    case 0x17: /* MBOX1 */
  56.981 +        return s->mbox1;
  56.982 +    case 0x18: /* CTEST0 */
  56.983 +        return 0xff;
  56.984 +    case 0x19: /* CTEST1 */
  56.985 +        return 0;
  56.986 +    case 0x1a: /* CTEST2 */
  56.987 +        tmp = LSI_CTEST2_DACK | LSI_CTEST2_CM;
  56.988 +        if (s->istat0 & LSI_ISTAT0_SIGP) {
  56.989 +            s->istat0 &= ~LSI_ISTAT0_SIGP;
  56.990 +            tmp |= LSI_CTEST2_SIGP;
  56.991 +        }
  56.992 +        return tmp;
  56.993 +    case 0x1b: /* CTEST3 */
  56.994 +        return s->ctest3;
  56.995 +    CASE_GET_REG32(temp, 0x1c)
  56.996 +    case 0x20: /* DFIFO */
  56.997 +        return 0;
  56.998 +    case 0x21: /* CTEST4 */
  56.999 +        return s->ctest4;
 56.1000 +    case 0x22: /* CTEST5 */
 56.1001 +        return s->ctest5;
 56.1002 +    case 0x24: /* DBC[0:7] */
 56.1003 +        return s->dbc & 0xff;
 56.1004 +    case 0x25: /* DBC[8:15] */
 56.1005 +        return (s->dbc >> 8) & 0xff;
 56.1006 +    case 0x26: /* DBC[16->23] */
 56.1007 +        return (s->dbc >> 16) & 0xff;
 56.1008 +    case 0x27: /* DCMD */
 56.1009 +        return s->dcmd;
 56.1010 +    CASE_GET_REG32(dsp, 0x2c)
 56.1011 +    CASE_GET_REG32(dsps, 0x30)
 56.1012 +    CASE_GET_REG32(scratch[0], 0x34)
 56.1013 +    case 0x38: /* DMODE */
 56.1014 +        return s->dmode;
 56.1015 +    case 0x39: /* DIEN */
 56.1016 +        return s->dien;
 56.1017 +    case 0x3b: /* DCNTL */
 56.1018 +        return s->dcntl;
 56.1019 +    case 0x40: /* SIEN0 */
 56.1020 +        return s->sien0;
 56.1021 +    case 0x41: /* SIEN1 */
 56.1022 +        return s->sien1;
 56.1023 +    case 0x42: /* SIST0 */
 56.1024 +        tmp = s->sist0;
 56.1025 +        s->sist0 = 0;
 56.1026 +        lsi_update_irq(s);
 56.1027 +        return tmp;
 56.1028 +    case 0x43: /* SIST1 */
 56.1029 +        tmp = s->sist1;
 56.1030 +        s->sist1 = 0;
 56.1031 +        lsi_update_irq(s);
 56.1032 +        return tmp;
 56.1033 +    case 0x47: /* GPCNTL0 */
 56.1034 +        return 0x0f;
 56.1035 +    case 0x48: /* STIME0 */
 56.1036 +        return s->stime0;
 56.1037 +    case 0x4a: /* RESPID0 */
 56.1038 +        return s->respid0;
 56.1039 +    case 0x4b: /* RESPID1 */
 56.1040 +        return s->respid1;
 56.1041 +    case 0x4d: /* STEST1 */
 56.1042 +        return s->stest1;
 56.1043 +    case 0x4e: /* STEST2 */
 56.1044 +        return s->stest2;
 56.1045 +    case 0x4f: /* STEST3 */
 56.1046 +        return s->stest3;
 56.1047 +    case 0x52: /* STEST4 */
 56.1048 +        return 0xe0;
 56.1049 +    case 0x56: /* CCNTL0 */
 56.1050 +        return s->ccntl0;
 56.1051 +    case 0x57: /* CCNTL1 */
 56.1052 +        return s->ccntl1;
 56.1053 +    case 0x58: case 0x59: /* SBDL */
 56.1054 +        return 0;
 56.1055 +    CASE_GET_REG32(mmrs, 0xa0)
 56.1056 +    CASE_GET_REG32(mmws, 0xa4)
 56.1057 +    CASE_GET_REG32(sfs, 0xa8)
 56.1058 +    CASE_GET_REG32(drs, 0xac)
 56.1059 +    CASE_GET_REG32(sbms, 0xb0)
 56.1060 +    CASE_GET_REG32(dmbs, 0xb4)
 56.1061 +    CASE_GET_REG32(dnad64, 0xb8)
 56.1062 +    CASE_GET_REG32(pmjad1, 0xc0)
 56.1063 +    CASE_GET_REG32(pmjad2, 0xc4)
 56.1064 +    CASE_GET_REG32(rbc, 0xc8)
 56.1065 +    CASE_GET_REG32(ua, 0xcc)
 56.1066 +    CASE_GET_REG32(ia, 0xd4)
 56.1067 +    CASE_GET_REG32(sbc, 0xd8)
 56.1068 +    CASE_GET_REG32(csbc, 0xdc)
 56.1069 +    }
 56.1070 +    if (offset >= 0x5c && offset < 0xa0) {
 56.1071 +        int n;
 56.1072 +        int shift;
 56.1073 +        n = (offset - 0x58) >> 2;
 56.1074 +        shift = (offset & 3) * 8;
 56.1075 +        return (s->scratch[n] >> shift) & 0xff;
 56.1076 +    }
 56.1077 +    BADF("readb 0x%x\n", offset);
 56.1078 +    exit(1);
 56.1079 +#undef CASE_GET_REG32
 56.1080 +}
 56.1081 +
 56.1082 +static void lsi_reg_writeb(LSIState *s, int offset, uint8_t val)
 56.1083 +{
 56.1084 +#define CASE_SET_REG32(name, addr) \
 56.1085 +    case addr    : s->name &= 0xffffff00; s->name |= val;       break; \
 56.1086 +    case addr + 1: s->name &= 0xffff00ff; s->name |= val << 8;  break; \
 56.1087 +    case addr + 2: s->name &= 0xff00ffff; s->name |= val << 16; break; \
 56.1088 +    case addr + 3: s->name &= 0x00ffffff; s->name |= val << 24; break;
 56.1089 +
 56.1090 +#ifdef DEBUG_LSI_REG
 56.1091 +    DPRINTF("Write reg %x = %02x\n", offset, val);
 56.1092 +#endif
 56.1093 +    switch (offset) {
 56.1094 +    case 0x00: /* SCNTL0 */
 56.1095 +        s->scntl0 = val;
 56.1096 +        if (val & LSI_SCNTL0_START) {
 56.1097 +            BADF("Start sequence not implemented\n");
 56.1098 +        }
 56.1099 +        break;
 56.1100 +    case 0x01: /* SCNTL1 */
 56.1101 +        s->scntl1 = val & ~LSI_SCNTL1_SST;
 56.1102 +        if (val & LSI_SCNTL1_IARB) {
 56.1103 +            BADF("Immediate Arbritration not implemented\n");
 56.1104 +        }
 56.1105 +        if (val & LSI_SCNTL1_RST) {
 56.1106 +            s->sstat0 |= LSI_SSTAT0_RST;
 56.1107 +            lsi_script_scsi_interrupt(s, LSI_SIST0_RST, 0);
 56.1108 +        } else {
 56.1109 +            s->sstat0 &= ~LSI_SSTAT0_RST;
 56.1110 +        }
 56.1111 +        break;
 56.1112 +    case 0x02: /* SCNTL2 */
 56.1113 +        val &= ~(LSI_SCNTL2_WSR | LSI_SCNTL2_WSS);
 56.1114 +        s->scntl3 = val;
 56.1115 +        break;
 56.1116 +    case 0x03: /* SCNTL3 */
 56.1117 +        s->scntl3 = val;
 56.1118 +        break;
 56.1119 +    case 0x04: /* SCID */
 56.1120 +        s->scid = val;
 56.1121 +        break;
 56.1122 +    case 0x05: /* SXFER */
 56.1123 +        s->sxfer = val;
 56.1124 +        break;
 56.1125 +    case 0x07: /* GPREG0 */
 56.1126 +        break;
 56.1127 +    case 0x0c: case 0x0d: case 0x0e: case 0x0f:
 56.1128 +        /* Linux writes to these readonly registers on startup.  */
 56.1129 +        return;
 56.1130 +    CASE_SET_REG32(dsa, 0x10)
 56.1131 +    case 0x14: /* ISTAT0 */
 56.1132 +        s->istat0 = (s->istat0 & 0x0f) | (val & 0xf0);
 56.1133 +        if (val & LSI_ISTAT0_ABRT) {
 56.1134 +            lsi_script_dma_interrupt(s, LSI_DSTAT_ABRT);
 56.1135 +        }
 56.1136 +        if (val & LSI_ISTAT0_INTF) {
 56.1137 +            s->istat0 &= ~LSI_ISTAT0_INTF;
 56.1138 +            lsi_update_irq(s);
 56.1139 +        }
 56.1140 +        if (s->waiting && val & LSI_ISTAT0_SIGP) {
 56.1141 +            DPRINTF("Woken by SIGP\n");
 56.1142 +            s->waiting = 0;
 56.1143 +            s->dsp = s->dnad;
 56.1144 +            lsi_execute_script(s);
 56.1145 +        }
 56.1146 +        if (val & LSI_ISTAT0_SRST) {
 56.1147 +            lsi_soft_reset(s);
 56.1148 +        }
 56.1149 +    case 0x16: /* MBOX0 */
 56.1150 +        s->mbox0 = val;
 56.1151 +    case 0x17: /* MBOX1 */
 56.1152 +        s->mbox1 = val;
 56.1153 +    case 0x1b: /* CTEST3 */
 56.1154 +        s->ctest3 = val & 0x0f;
 56.1155 +        break;
 56.1156 +    CASE_SET_REG32(temp, 0x1c)
 56.1157 +    case 0x21: /* CTEST4 */
 56.1158 +        if (val & 7) {
 56.1159 +           BADF("Unimplemented CTEST4-FBL 0x%x\n", val);
 56.1160 +        }
 56.1161 +        s->ctest4 = val;
 56.1162 +        break;
 56.1163 +    case 0x22: /* CTEST5 */
 56.1164 +        if (val & (LSI_CTEST5_ADCK | LSI_CTEST5_BBCK)) {
 56.1165 +            BADF("CTEST5 DMA increment not implemented\n");
 56.1166 +        }
 56.1167 +        s->ctest5 = val;
 56.1168 +        break;
 56.1169 +    case 0x2c: /* DSPS[0:7] */
 56.1170 +        s->dsp &= 0xffffff00;
 56.1171 +        s->dsp |= val;
 56.1172 +        break;
 56.1173 +    case 0x2d: /* DSPS[8:15] */
 56.1174 +        s->dsp &= 0xffff00ff;
 56.1175 +        s->dsp |= val << 8;
 56.1176 +        break;
 56.1177 +    case 0x2e: /* DSPS[16:23] */
 56.1178 +        s->dsp &= 0xff00ffff;
 56.1179 +        s->dsp |= val << 16;
 56.1180 +        break;
 56.1181 +    case 0x2f: /* DSPS[14:31] */
 56.1182 +        s->dsp &= 0x00ffffff;
 56.1183 +        s->dsp |= val << 24;
 56.1184 +        if ((s->dmode & LSI_DMODE_MAN) == 0
 56.1185 +            && (s->istat1 & LSI_ISTAT1_SRUN) == 0)
 56.1186 +            lsi_execute_script(s);
 56.1187 +        break;
 56.1188 +    CASE_SET_REG32(dsps, 0x30)
 56.1189 +    CASE_SET_REG32(scratch[0], 0x34)
 56.1190 +    case 0x38: /* DMODE */
 56.1191 +        if (val & (LSI_DMODE_SIOM | LSI_DMODE_DIOM)) {
 56.1192 +            BADF("IO mappings not implemented\n");
 56.1193 +        }
 56.1194 +        s->dmode = val;
 56.1195 +        break;
 56.1196 +    case 0x39: /* DIEN */
 56.1197 +        s->dien = val;
 56.1198 +        lsi_update_irq(s);
 56.1199 +        break;
 56.1200 +    case 0x3b: /* DCNTL */
 56.1201 +        s->dcntl = val & ~(LSI_DCNTL_PFF | LSI_DCNTL_STD);
 56.1202 +        if ((val & LSI_DCNTL_STD) && (s->istat1 & LSI_ISTAT1_SRUN) == 0)
 56.1203 +            lsi_execute_script(s);
 56.1204 +        break;
 56.1205 +    case 0x40: /* SIEN0 */
 56.1206 +        s->sien0 = val;
 56.1207 +        lsi_update_irq(s);
 56.1208 +        break;
 56.1209 +    case 0x41: /* SIEN1 */
 56.1210 +        s->sien1 = val;
 56.1211 +        lsi_update_irq(s);
 56.1212 +        break;
 56.1213 +    case 0x47: /* GPCNTL0 */
 56.1214 +        break;
 56.1215 +    case 0x48: /* STIME0 */
 56.1216 +        s->stime0 = val;
 56.1217 +        break;
 56.1218 +    case 0x49: /* STIME1 */
 56.1219 +        if (val & 0xf) {
 56.1220 +            DPRINTF("General purpose timer not implemented\n");
 56.1221 +            /* ??? Raising the interrupt immediately seems to be sufficient
 56.1222 +               to keep the FreeBSD driver happy.  */
 56.1223 +            lsi_script_scsi_interrupt(s, 0, LSI_SIST1_GEN);
 56.1224 +        }
 56.1225 +        break;
 56.1226 +    case 0x4a: /* RESPID0 */
 56.1227 +        s->respid0 = val;
 56.1228 +        break;
 56.1229 +    case 0x4b: /* RESPID1 */
 56.1230 +        s->respid1 = val;
 56.1231 +        break;
 56.1232 +    case 0x4d: /* STEST1 */
 56.1233 +        s->stest1 = val;
 56.1234 +        break;
 56.1235 +    case 0x4e: /* STEST2 */
 56.1236 +        if (val & 1) {
 56.1237 +            BADF("Low level mode not implemented\n");
 56.1238 +        }
 56.1239 +        s->stest2 = val;
 56.1240 +        break;
 56.1241 +    case 0x4f: /* STEST3 */
 56.1242 +        if (val & 0x41) {
 56.1243 +            BADF("SCSI FIFO test mode not implemented\n");
 56.1244 +        }
 56.1245 +        s->stest3 = val;
 56.1246 +        break;
 56.1247 +    case 0x56: /* CCNTL0 */
 56.1248 +        s->ccntl0 = val;
 56.1249 +        break;
 56.1250 +    case 0x57: /* CCNTL1 */
 56.1251 +        s->ccntl1 = val;
 56.1252 +        break;
 56.1253 +    CASE_SET_REG32(mmrs, 0xa0)
 56.1254 +    CASE_SET_REG32(mmws, 0xa4)
 56.1255 +    CASE_SET_REG32(sfs, 0xa8)
 56.1256 +    CASE_SET_REG32(drs, 0xac)
 56.1257 +    CASE_SET_REG32(sbms, 0xb0)
 56.1258 +    CASE_SET_REG32(dmbs, 0xb4)
 56.1259 +    CASE_SET_REG32(dnad64, 0xb8)
 56.1260 +    CASE_SET_REG32(pmjad1, 0xc0)
 56.1261 +    CASE_SET_REG32(pmjad2, 0xc4)
 56.1262 +    CASE_SET_REG32(rbc, 0xc8)
 56.1263 +    CASE_SET_REG32(ua, 0xcc)
 56.1264 +    CASE_SET_REG32(ia, 0xd4)
 56.1265 +    CASE_SET_REG32(sbc, 0xd8)
 56.1266 +    CASE_SET_REG32(csbc, 0xdc)
 56.1267 +    default:
 56.1268 +        if (offset >= 0x5c && offset < 0xa0) {
 56.1269 +            int n;
 56.1270 +            int shift;
 56.1271 +            n = (offset - 0x58) >> 2;
 56.1272 +            shift = (offset & 3) * 8;
 56.1273 +            s->scratch[n] &= ~(0xff << shift);
 56.1274 +            s->scratch[n] |= (val & 0xff) << shift;
 56.1275 +        } else {
 56.1276 +            BADF("Unhandled writeb 0x%x = 0x%x\n", offset, val);
 56.1277 +        }
 56.1278 +    }
 56.1279 +#undef CASE_SET_REG32
 56.1280 +}
 56.1281 +
 56.1282 +static void lsi_mmio_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
 56.1283 +{
 56.1284 +    LSIState *s = (LSIState *)opaque;
 56.1285 +
 56.1286 +    lsi_reg_writeb(s, addr & 0xff, val);
 56.1287 +}
 56.1288 +
 56.1289 +static void lsi_mmio_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
 56.1290 +{
 56.1291 +    LSIState *s = (LSIState *)opaque;
 56.1292 +
 56.1293 +    addr &= 0xff;
 56.1294 +    lsi_reg_writeb(s, addr, val & 0xff);
 56.1295 +    lsi_reg_writeb(s, addr + 1, (val >> 8) & 0xff);
 56.1296 +}
 56.1297 +
 56.1298 +static void lsi_mmio_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
 56.1299 +{
 56.1300 +    LSIState *s = (LSIState *)opaque;
 56.1301 +
 56.1302 +    addr &= 0xff;
 56.1303 +    lsi_reg_writeb(s, addr, val & 0xff);
 56.1304 +    lsi_reg_writeb(s, addr + 1, (val >> 8) & 0xff);
 56.1305 +    lsi_reg_writeb(s, addr + 2, (val >> 16) & 0xff);
 56.1306 +    lsi_reg_writeb(s, addr + 3, (val >> 24) & 0xff);
 56.1307 +}
 56.1308 +
 56.1309 +static uint32_t lsi_mmio_readb(void *opaque, target_phys_addr_t addr)
 56.1310 +{
 56.1311 +    LSIState *s = (LSIState *)opaque;
 56.1312 +
 56.1313 +    return lsi_reg_readb(s, addr & 0xff);
 56.1314 +}
 56.1315 +
 56.1316 +static uint32_t lsi_mmio_readw(void *opaque, target_phys_addr_t addr)
 56.1317 +{
 56.1318 +    LSIState *s = (LSIState *)opaque;
 56.1319 +    uint32_t val;
 56.1320 +
 56.1321 +    addr &= 0xff;
 56.1322 +    val = lsi_reg_readb(s, addr);
 56.1323 +    val |= lsi_reg_readb(s, addr + 1) << 8;
 56.1324 +    return val;
 56.1325 +}
 56.1326 +
 56.1327 +static uint32_t lsi_mmio_readl(void *opaque, target_phys_addr_t addr)
 56.1328 +{
 56.1329 +    LSIState *s = (LSIState *)opaque;
 56.1330 +    uint32_t val;
 56.1331 +    addr &= 0xff;
 56.1332 +    val = lsi_reg_readb(s, addr);
 56.1333 +    val |= lsi_reg_readb(s, addr + 1) << 8;
 56.1334 +    val |= lsi_reg_readb(s, addr + 2) << 16;
 56.1335 +    val |= lsi_reg_readb(s, addr + 3) << 24;
 56.1336 +    return val;
 56.1337 +}
 56.1338 +
 56.1339 +static CPUReadMemoryFunc *lsi_mmio_readfn[3] = {
 56.1340 +    lsi_mmio_readb,
 56.1341 +    lsi_mmio_readw,
 56.1342 +    lsi_mmio_readl,
 56.1343 +};
 56.1344 +
 56.1345 +static CPUWriteMemoryFunc *lsi_mmio_writefn[3] = {
 56.1346 +    lsi_mmio_writeb,
 56.1347 +    lsi_mmio_writew,
 56.1348 +    lsi_mmio_writel,
 56.1349 +};
 56.1350 +
 56.1351 +static void lsi_ram_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
 56.1352 +{
 56.1353 +    LSIState *s = (LSIState *)opaque;
 56.1354 +    uint32_t newval;
 56.1355 +    int shift;
 56.1356 +
 56.1357 +    addr &= 0x1fff;
 56.1358 +    newval = s->script_ram[addr >> 2];
 56.1359 +    shift = (addr & 3) * 8;
 56.1360 +    newval &= ~(0xff << shift);
 56.1361 +    newval |= val << shift;
 56.1362 +    s->script_ram[addr >> 2] = newval;
 56.1363 +}
 56.1364 +
 56.1365 +static void lsi_ram_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
 56.1366 +{
 56.1367 +    LSIState *s = (LSIState *)opaque;
 56.1368 +    uint32_t newval;
 56.1369 +
 56.1370 +    addr &= 0x1fff;
 56.1371 +    newval = s->script_ram[addr >> 2];
 56.1372 +    if (addr & 2) {
 56.1373 +        newval = (newval & 0xffff) | (val << 16);
 56.1374 +    } else {
 56.1375 +        newval = (newval & 0xffff0000) | val;
 56.1376 +    }
 56.1377 +    s->script_ram[addr >> 2] = newval;
 56.1378 +}
 56.1379 +
 56.1380 +
 56.1381 +static void lsi_ram_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
 56.1382 +{
 56.1383 +    LSIState *s = (LSIState *)opaque;
 56.1384 +
 56.1385 +    addr &= 0x1fff;
 56.1386 +    s->script_ram[addr >> 2] = val;
 56.1387 +}
 56.1388 +
 56.1389 +static uint32_t lsi_ram_readb(void *opaque, target_phys_addr_t addr)
 56.1390 +{
 56.1391 +    LSIState *s = (LSIState *)opaque;
 56.1392 +    uint32_t val;
 56.1393 +
 56.1394 +    addr &= 0x1fff;
 56.1395 +    val = s->script_ram[addr >> 2];
 56.1396 +    val >>= (addr & 3) * 8;
 56.1397 +    return val & 0xff;
 56.1398 +}
 56.1399 +
 56.1400 +static uint32_t lsi_ram_readw(void *opaque, target_phys_addr_t addr)
 56.1401 +{
 56.1402 +    LSIState *s = (LSIState *)opaque;
 56.1403 +    uint32_t val;
 56.1404 +
 56.1405 +    addr &= 0x1fff;
 56.1406 +    val = s->script_ram[addr >> 2];
 56.1407 +    if (addr & 2)
 56.1408 +        val >>= 16;
 56.1409 +    return le16_to_cpu(val);
 56.1410 +}
 56.1411 +
 56.1412 +static uint32_t lsi_ram_readl(void *opaque, target_phys_addr_t addr)
 56.1413 +{
 56.1414 +    LSIState *s = (LSIState *)opaque;
 56.1415 +
 56.1416 +    addr &= 0x1fff;
 56.1417 +    return le32_to_cpu(s->script_ram[addr >> 2]);
 56.1418 +}
 56.1419 +
 56.1420 +static CPUReadMemoryFunc *lsi_ram_readfn[3] = {
 56.1421 +    lsi_ram_readb,
 56.1422 +    lsi_ram_readw,
 56.1423 +    lsi_ram_readl,
 56.1424 +};
 56.1425 +
 56.1426 +static CPUWriteMemoryFunc *lsi_ram_writefn[3] = {
 56.1427 +    lsi_ram_writeb,
 56.1428 +    lsi_ram_writew,
 56.1429 +    lsi_ram_writel,
 56.1430 +};
 56.1431 +
 56.1432 +static uint32_t lsi_io_readb(void *opaque, uint32_t addr)
 56.1433 +{
 56.1434 +    LSIState *s = (LSIState *)opaque;
 56.1435 +    return lsi_reg_readb(s, addr & 0xff);
 56.1436 +}
 56.1437 +
 56.1438 +static uint32_t lsi_io_readw(void *opaque, uint32_t addr)
 56.1439 +{
 56.1440 +    LSIState *s = (LSIState *)opaque;
 56.1441 +    uint32_t val;
 56.1442 +    addr &= 0xff;
 56.1443 +    val = lsi_reg_readb(s, addr);
 56.1444 +    val |= lsi_reg_readb(s, addr + 1) << 8;
 56.1445 +    return val;
 56.1446 +}
 56.1447 +
 56.1448 +static uint32_t lsi_io_readl(void *opaque, uint32_t addr)
 56.1449 +{
 56.1450 +    LSIState *s = (LSIState *)opaque;
 56.1451 +    uint32_t val;
 56.1452 +    addr &= 0xff;
 56.1453 +    val = lsi_reg_readb(s, addr);
 56.1454 +    val |= lsi_reg_readb(s, addr + 1) << 8;
 56.1455 +    val |= lsi_reg_readb(s, addr + 2) << 16;
 56.1456 +    val |= lsi_reg_readb(s, addr + 3) << 24;
 56.1457 +    return val;
 56.1458 +}
 56.1459 +
 56.1460 +static void lsi_io_writeb(void *opaque, uint32_t addr, uint32_t val)
 56.1461 +{
 56.1462 +    LSIState *s = (LSIState *)opaque;
 56.1463 +    lsi_reg_writeb(s, addr & 0xff, val);
 56.1464 +}
 56.1465 +
 56.1466 +static void lsi_io_writew(void *opaque, uint32_t addr, uint32_t val)
 56.1467 +{
 56.1468 +    LSIState *s = (LSIState *)opaque;
 56.1469 +    addr &= 0xff;
 56.1470 +    lsi_reg_writeb(s, addr, val & 0xff);
 56.1471 +    lsi_reg_writeb(s, addr + 1, (val >> 8) & 0xff);
 56.1472 +}
 56.1473 +
 56.1474 +static void lsi_io_writel(void *opaque, uint32_t addr, uint32_t val)
 56.1475 +{
 56.1476 +    LSIState *s = (LSIState *)opaque;
 56.1477 +    addr &= 0xff;
 56.1478 +    lsi_reg_writeb(s, addr, val & 0xff);
 56.1479 +    lsi_reg_writeb(s, addr + 1, (val >> 8) & 0xff);
 56.1480 +    lsi_reg_writeb(s, addr + 2, (val >> 16) & 0xff);
 56.1481 +    lsi_reg_writeb(s, addr + 2, (val >> 24) & 0xff);
 56.1482 +}
 56.1483 +
 56.1484 +static void lsi_io_mapfunc(PCIDevice *pci_dev, int region_num, 
 56.1485 +                           uint32_t addr, uint32_t size, int type)
 56.1486 +{
 56.1487 +    LSIState *s = (LSIState *)pci_dev;
 56.1488 +
 56.1489 +    DPRINTF("Mapping IO at %08x\n", addr);
 56.1490 +
 56.1491 +    register_ioport_write(addr, 256, 1, lsi_io_writeb, s);
 56.1492 +    register_ioport_read(addr, 256, 1, lsi_io_readb, s);
 56.1493 +    register_ioport_write(addr, 256, 2, lsi_io_writew, s);
 56.1494 +    register_ioport_read(addr, 256, 2, lsi_io_readw, s);
 56.1495 +    register_ioport_write(addr, 256, 4, lsi_io_writel, s);
 56.1496 +    register_ioport_read(addr, 256, 4, lsi_io_readl, s);
 56.1497 +}
 56.1498 +
 56.1499 +static void lsi_ram_mapfunc(PCIDevice *pci_dev, int region_num, 
 56.1500 +                            uint32_t addr, uint32_t size, int type)
 56.1501 +{
 56.1502 +    LSIState *s = (LSIState *)pci_dev;
 56.1503 +
 56.1504 +    DPRINTF("Mapping ram at %08x\n", addr);
 56.1505 +    s->script_ram_base = addr;
 56.1506 +    cpu_register_physical_memory(addr + 0, 0x2000, s->ram_io_addr);
 56.1507 +}
 56.1508 +
 56.1509 +static void lsi_mmio_mapfunc(PCIDevice *pci_dev, int region_num, 
 56.1510 +                             uint32_t addr, uint32_t size, int type)
 56.1511 +{
 56.1512 +    LSIState *s = (LSIState *)pci_dev;
 56.1513 +
 56.1514 +    DPRINTF("Mapping registers at %08x\n", addr);
 56.1515 +    cpu_register_physical_memory(addr + 0, 0x400, s->mmio_io_addr);
 56.1516 +}
 56.1517 +
 56.1518 +void lsi_scsi_attach(void *opaque, BlockDriverState *bd, int id)
 56.1519 +{
 56.1520 +    LSIState *s = (LSIState *)opaque;
 56.1521 +
 56.1522 +    if (id < 0) {
 56.1523 +        for (id = 0; id < LSI_MAX_DEVS; id++) {
 56.1524 +            if (s->scsi_dev[id] == NULL)
 56.1525 +                break;
 56.1526 +        }
 56.1527 +    }
 56.1528 +    if (id >= LSI_MAX_DEVS) {
 56.1529 +        BADF("Bad Device ID %d\n", id);
 56.1530 +        return;
 56.1531 +    }
 56.1532 +    if (s->scsi_dev[id]) {
 56.1533 +        DPRINTF("Destroying device %d\n", id);
 56.1534 +        scsi_disk_destroy(s->scsi_dev[id]);
 56.1535 +    }
 56.1536 +    DPRINTF("Attaching block device %d\n", id);
 56.1537 +    s->scsi_dev[id] = scsi_disk_init(bd, lsi_command_complete, s);
 56.1538 +}
 56.1539 +
 56.1540 +void *lsi_scsi_init(PCIBus *bus, int devfn)
 56.1541 +{
 56.1542 +    LSIState *s;
 56.1543 +
 56.1544 +    s = (LSIState *)pci_register_device(bus, "LSI53C895A SCSI HBA",
 56.1545 +                                        sizeof(*s), devfn, NULL, NULL);
 56.1546 +    if (s == NULL) {
 56.1547 +        fprintf(stderr, "lsi-scsi: Failed to register PCI device\n");
 56.1548 +        return NULL;
 56.1549 +    }
 56.1550 +
 56.1551 +    s->pci_dev.config[0x00] = 0x00;
 56.1552 +    s->pci_dev.config[0x01] = 0x10;
 56.1553 +    s->pci_dev.config[0x02] = 0x12;
 56.1554 +    s->pci_dev.config[0x03] = 0x00;
 56.1555 +    s->pci_dev.config[0x0b] = 0x01;
 56.1556 +    s->pci_dev.config[0x3d] = 0x01; /* interrupt pin 1 */
 56.1557 +
 56.1558 +    s->mmio_io_addr = cpu_register_io_memory(0, lsi_mmio_readfn,
 56.1559 +                                             lsi_mmio_writefn, s);
 56.1560 +    s->ram_io_addr = cpu_register_io_memory(0, lsi_ram_readfn,
 56.1561 +                                            lsi_ram_writefn, s);
 56.1562 +
 56.1563 +    pci_register_io_region((struct PCIDevice *)s, 0, 256,
 56.1564 +                           PCI_ADDRESS_SPACE_IO, lsi_io_mapfunc);
 56.1565 +    pci_register_io_region((struct PCIDevice *)s, 1, 0x400,
 56.1566 +                           PCI_ADDRESS_SPACE_MEM, lsi_mmio_mapfunc);
 56.1567 +    pci_register_io_region((struct PCIDevice *)s, 2, 0x2000,
 56.1568 +                           PCI_ADDRESS_SPACE_MEM, lsi_ram_mapfunc);
 56.1569 +
 56.1570 +    lsi_soft_reset(s);
 56.1571 +
 56.1572 +    return s;
 56.1573 +}
 56.1574 +
    57.1 --- a/tools/ioemu/hw/m48t59.c	Mon Aug 07 18:11:59 2006 +0100
    57.2 +++ b/tools/ioemu/hw/m48t59.c	Mon Aug 07 18:25:30 2006 +0100
    57.3 @@ -332,7 +332,10 @@ void m48t59_write (m48t59_t *NVRAM, uint
    57.4  	tmp = fromBCD(val);
    57.5  	if (tmp >= 0 && tmp <= 99) {
    57.6  	    get_time(NVRAM, &tm);
    57.7 -	    tm.tm_year = fromBCD(val);
    57.8 +            if (NVRAM->type == 8)
    57.9 +                tm.tm_year = fromBCD(val) + 68; // Base year is 1968
   57.10 +            else
   57.11 +                tm.tm_year = fromBCD(val);
   57.12  	    set_time(NVRAM, &tm);
   57.13  	}
   57.14          break;
   57.15 @@ -421,7 +424,10 @@ uint32_t m48t59_read (m48t59_t *NVRAM, u
   57.16      case 0x1FFF:
   57.17          /* year */
   57.18          get_time(NVRAM, &tm);
   57.19 -        retval = toBCD(tm.tm_year);
   57.20 +        if (NVRAM->type == 8) 
   57.21 +            retval = toBCD(tm.tm_year - 68); // Base year is 1968
   57.22 +        else
   57.23 +            retval = toBCD(tm.tm_year);
   57.24          break;
   57.25      default:
   57.26          /* Check lock registers state */
    58.1 --- a/tools/ioemu/hw/mips_r4k.c	Mon Aug 07 18:11:59 2006 +0100
    58.2 +++ b/tools/ioemu/hw/mips_r4k.c	Mon Aug 07 18:25:30 2006 +0100
    58.3 @@ -60,7 +60,7 @@ static void cpu_mips_update_count (CPUSt
    58.4  	next++;
    58.5  #if 0
    58.6      if (logfile) {
    58.7 -        fprintf(logfile, "%s: 0x%08llx %08x %08x => 0x%08llx\n",
    58.8 +        fprintf(logfile, "%s: 0x%08" PRIx64 " %08x %08x => 0x%08" PRIx64 "\n",
    58.9                  __func__, now, count, compare, next - now);
   58.10      }
   58.11  #endif
   58.12 @@ -214,14 +214,10 @@ void mips_r4k_init (int ram_size, int vg
   58.13         run. */
   58.14      bios_offset = ram_size + vga_ram_size;
   58.15      snprintf(buf, sizeof(buf), "%s/%s", bios_dir, BIOS_FILENAME);
   58.16 -    printf("%s: load BIOS '%s' size %d\n", __func__, buf, BIOS_SIZE);
   58.17      ret = load_image(buf, phys_ram_base + bios_offset);
   58.18      if (ret == BIOS_SIZE) {
   58.19  	cpu_register_physical_memory((uint32_t)(0x1fc00000),
   58.20  				     BIOS_SIZE, bios_offset | IO_MEM_ROM);
   58.21 -	env->PC = 0xBFC00000;
   58.22 -	if (!kernel_filename)
   58.23 -	    return;
   58.24      } else {
   58.25  	/* not fatal */
   58.26          fprintf(stderr, "qemu: Warning, could not load MIPS bios '%s'\n",
    59.1 --- a/tools/ioemu/hw/ne2000.c	Mon Aug 07 18:11:59 2006 +0100
    59.2 +++ b/tools/ioemu/hw/ne2000.c	Mon Aug 07 18:25:30 2006 +0100
    59.3 @@ -206,7 +206,7 @@ static int ne2000_buffer_full(NE2000Stat
    59.4  
    59.5      index = s->curpag << 8;
    59.6      boundary = s->boundary << 8;
    59.7 -    if (index < boundary)
    59.8 +    if (index <= boundary)
    59.9          avail = boundary - index;
   59.10      else
   59.11          avail = (s->stop - s->start) - (index - boundary);
    60.1 --- a/tools/ioemu/hw/pc.c	Mon Aug 07 18:11:59 2006 +0100
    60.2 +++ b/tools/ioemu/hw/pc.c	Mon Aug 07 18:25:30 2006 +0100
    60.3 @@ -44,7 +44,6 @@ static PITState *pit;
    60.4  #ifndef CONFIG_DM
    60.5  static IOAPICState *ioapic;
    60.6  #endif /* !CONFIG_DM */
    60.7 -static USBPort *usb_root_ports[2];
    60.8  
    60.9  static void ioport80_write(void *opaque, uint32_t addr, uint32_t data)
   60.10  {
   60.11 @@ -63,10 +62,19 @@ static void ioportF0_write(void *opaque,
   60.12  }
   60.13  
   60.14  /* TSC handling */
   60.15 -
   60.16  uint64_t cpu_get_tsc(CPUX86State *env)
   60.17  {
   60.18 -    return qemu_get_clock(vm_clock);
   60.19 +    /* Note: when using kqemu, it is more logical to return the host TSC
   60.20 +       because kqemu does not trap the RDTSC instruction for
   60.21 +       performance reasons */
   60.22 +#if USE_KQEMU
   60.23 +    if (env->kqemu_enabled) {
   60.24 +        return cpu_get_real_ticks();
   60.25 +    } else 
   60.26 +#endif
   60.27 +    {
   60.28 +        return cpu_get_ticks();
   60.29 +    }
   60.30  }
   60.31  
   60.32  #ifndef CONFIG_DM
   60.33 @@ -201,6 +209,8 @@ static void cmos_init(uint64_t ram_size,
   60.34      case 'a':
   60.35      case 'b':
   60.36          rtc_set_memory(s, 0x3d, 0x01); /* floppy boot */
   60.37 +        if (!fd_bootchk)
   60.38 +            rtc_set_memory(s, 0x38, 0x01); /* disable signature check */
   60.39          break;
   60.40      default:
   60.41      case 'c':
   60.42 @@ -272,10 +282,6 @@ static void cmos_init(uint64_t ram_size,
   60.43          }
   60.44      }
   60.45      rtc_set_memory(s, 0x39, val);
   60.46 -
   60.47 -    /* Disable check of 0x55AA signature on the last two bytes of
   60.48 -       first sector of disk. XXX: make it the default ? */
   60.49 -    //    rtc_set_memory(s, 0x38, 1);
   60.50  }
   60.51  
   60.52  void ioport_set_a20(int enable)
   60.53 @@ -567,7 +573,7 @@ static int parallel_io[MAX_PARALLEL_PORT
   60.54  static int parallel_irq[MAX_PARALLEL_PORTS] = { 7, 7, 7 };
   60.55  
   60.56  /* PIIX4 acpi pci configuration space, func 3 */
   60.57 -extern void pci_piix4_acpi_init(PCIBus *bus);
   60.58 +extern void pci_piix4_acpi_init(PCIBus *bus, int devfn);
   60.59  
   60.60  #ifdef HAS_AUDIO
   60.61  static void audio_init (PCIBus *pci_bus)
   60.62 @@ -630,6 +636,7 @@ static void pc_init1(uint64_t ram_size, 
   60.63      int bios_size, isa_bios_size;
   60.64  #endif /* !NOBIOS */
   60.65      PCIBus *pci_bus;
   60.66 +    int piix3_devfn = -1;
   60.67      CPUState *env;
   60.68      NICInfo *nd;
   60.69  
   60.70 @@ -774,7 +781,7 @@ static void pc_init1(uint64_t ram_size, 
   60.71  
   60.72      if (pci_enabled) {
   60.73          pci_bus = i440fx_init();
   60.74 -        piix3_init(pci_bus);
   60.75 +        piix3_devfn = piix3_init(pci_bus);
   60.76      } else {
   60.77          pci_bus = NULL;
   60.78      }
   60.79 @@ -852,7 +859,7 @@ static void pc_init1(uint64_t ram_size, 
   60.80      }
   60.81  
   60.82      if (pci_enabled) {
   60.83 -        pci_piix3_ide_init(pci_bus, bs_table);
   60.84 +        pci_piix3_ide_init(pci_bus, bs_table, piix3_devfn + 1);
   60.85      } else {
   60.86          for(i = 0; i < 2; i++) {
   60.87              isa_ide_init(ide_iobase[i], ide_iobase2[i], ide_irq[i],
   60.88 @@ -872,17 +879,39 @@ static void pc_init1(uint64_t ram_size, 
   60.89  
   60.90      /* using PIIX4 acpi model */
   60.91      if (pci_enabled && acpi_enabled)
   60.92 -        pci_piix4_acpi_init(pci_bus);
   60.93 +        pci_piix4_acpi_init(pci_bus, piix3_devfn + 3);
   60.94  
   60.95      if (pci_enabled && usb_enabled) {
   60.96 -        usb_uhci_init(pci_bus, usb_root_ports);
   60.97 -        usb_attach(usb_root_ports[0], vm_usb_hub);
   60.98 +        usb_uhci_init(pci_bus, piix3_devfn + 2);
   60.99      }
  60.100  
  60.101 +    if (pci_enabled && acpi_enabled && 0) {
  60.102 +        piix4_pm_init(pci_bus, piix3_devfn + 3);
  60.103 +    }
  60.104 +
  60.105 +#if 0
  60.106 +    /* ??? Need to figure out some way for the user to
  60.107 +       specify SCSI devices.  */
  60.108 +    if (pci_enabled) {
  60.109 +        void *scsi;
  60.110 +        BlockDriverState *bdrv;
  60.111 +
  60.112 +        scsi = lsi_scsi_init(pci_bus, -1);
  60.113 +        bdrv = bdrv_new("scsidisk");
  60.114 +        bdrv_open(bdrv, "scsi_disk.img", 0);
  60.115 +        lsi_scsi_attach(scsi, bdrv, -1);
  60.116 +        bdrv = bdrv_new("scsicd");
  60.117 +        bdrv_open(bdrv, "scsi_cd.iso", 0);
  60.118 +        bdrv_set_type_hint(bdrv, BDRV_TYPE_CDROM);
  60.119 +        lsi_scsi_attach(scsi, bdrv, -1);
  60.120 +    }
  60.121 +#endif
  60.122      /* must be done after all PCI devices are instanciated */
  60.123      /* XXX: should be done in the Bochs BIOS */
  60.124      if (pci_enabled) {
  60.125          pci_bios_init();
  60.126 +        if (acpi_enabled)
  60.127 +            acpi_bios_init();
  60.128      }
  60.129  }
  60.130  
    61.1 --- a/tools/ioemu/hw/pci.c	Mon Aug 07 18:11:59 2006 +0100
    61.2 +++ b/tools/ioemu/hw/pci.c	Mon Aug 07 18:25:30 2006 +0100
    61.3 @@ -25,25 +25,10 @@
    61.4  
    61.5  //#define DEBUG_PCI
    61.6  
    61.7 -#define PCI_VENDOR_ID		0x00	/* 16 bits */
    61.8 -#define PCI_DEVICE_ID		0x02	/* 16 bits */
    61.9 -#define PCI_COMMAND		0x04	/* 16 bits */
   61.10 -#define  PCI_COMMAND_IO		0x1	/* Enable response in I/O space */
   61.11 -#define  PCI_COMMAND_MEMORY	0x2	/* Enable response in Memory space */
   61.12 -#define PCI_CLASS_DEVICE        0x0a    /* Device class */
   61.13 -#define PCI_INTERRUPT_LINE	0x3c	/* 8 bits */
   61.14 -#define PCI_INTERRUPT_PIN	0x3d	/* 8 bits */
   61.15 -#define PCI_MIN_GNT		0x3e	/* 8 bits */
   61.16 -#define PCI_MAX_LAT		0x3f	/* 8 bits */
   61.17 -
   61.18 -/* just used for simpler irq handling. */
   61.19 -#define PCI_DEVICES_MAX 64
   61.20 -#define PCI_IRQ_WORDS   ((PCI_DEVICES_MAX + 31) / 32)
   61.21 -
   61.22  struct PCIBus {
   61.23      int bus_num;
   61.24      int devfn_min;
   61.25 -    void (*set_irq)(PCIDevice *pci_dev, int irq_num, int level);
   61.26 +    pci_set_irq_fn set_irq;
   61.27      uint32_t config_reg; /* XXX: suppress */
   61.28      /* low level pic */
   61.29      SetIRQFunc *low_set_irq;
   61.30 @@ -53,17 +38,24 @@ struct PCIBus {
   61.31  
   61.32  target_phys_addr_t pci_mem_base;
   61.33  static int pci_irq_index;
   61.34 -static uint32_t pci_irq_levels[4][PCI_IRQ_WORDS];
   61.35  static PCIBus *first_bus;
   61.36  
   61.37 -static PCIBus *pci_register_bus(void)
   61.38 +PCIBus *pci_register_bus(pci_set_irq_fn set_irq, void *pic, int devfn_min)
   61.39  {
   61.40      PCIBus *bus;
   61.41      bus = qemu_mallocz(sizeof(PCIBus));
   61.42 +    bus->set_irq = set_irq;
   61.43 +    bus->irq_opaque = pic;
   61.44 +    bus->devfn_min = devfn_min;
   61.45      first_bus = bus;
   61.46      return bus;
   61.47  }
   61.48  
   61.49 +int pci_bus_num(PCIBus *s)
   61.50 +{
   61.51 +    return s->bus_num;
   61.52 +}
   61.53 +
   61.54  void generic_pci_save(QEMUFile* f, void *opaque)
   61.55  {
   61.56      PCIDevice* s=(PCIDevice*)opaque;
   61.57 @@ -141,16 +133,9 @@ void pci_register_io_region(PCIDevice *p
   61.58      *(uint32_t *)(pci_dev->config + addr) = cpu_to_le32(type);
   61.59  }
   61.60  
   61.61 -static void pci_addr_writel(void* opaque, uint32_t addr, uint32_t val)
   61.62 +target_phys_addr_t pci_to_cpu_addr(target_phys_addr_t addr)
   61.63  {
   61.64 -    PCIBus *s = opaque;
   61.65 -    s->config_reg = val;
   61.66 -}
   61.67 -
   61.68 -static uint32_t pci_addr_readl(void* opaque, uint32_t addr)
   61.69 -{
   61.70 -    PCIBus *s = opaque;
   61.71 -    return s->config_reg;
   61.72 +    return addr + pci_mem_base;
   61.73  }
   61.74  
   61.75  static void pci_update_mappings(PCIDevice *d)
   61.76 @@ -218,7 +203,7 @@ static void pci_update_mappings(PCIDevic
   61.77                              isa_unassign_ioport(r->addr, r->size);
   61.78                          }
   61.79                      } else {
   61.80 -                        cpu_register_physical_memory(r->addr + pci_mem_base, 
   61.81 +                        cpu_register_physical_memory(pci_to_cpu_addr(r->addr),
   61.82                                                       r->size, 
   61.83                                                       IO_MEM_UNASSIGNED);
   61.84                      }
   61.85 @@ -346,8 +331,7 @@ void pci_default_write_config(PCIDevice 
   61.86      }
   61.87  }
   61.88  
   61.89 -static void pci_data_write(void *opaque, uint32_t addr, 
   61.90 -                           uint32_t val, int len)
   61.91 +void pci_data_write(void *opaque, uint32_t addr, uint32_t val, int len)
   61.92  {
   61.93      PCIBus *s = opaque;
   61.94      PCIDevice *pci_dev;
   61.95 @@ -355,18 +339,15 @@ static void pci_data_write(void *opaque,
   61.96      
   61.97  #if defined(DEBUG_PCI) && 0
   61.98      printf("pci_data_write: addr=%08x val=%08x len=%d\n",
   61.99 -           s->config_reg, val, len);
  61.100 +           addr, val, len);
  61.101  #endif
  61.102 -    if (!(s->config_reg & (1 << 31))) {
  61.103 -        return;
  61.104 -    }
  61.105 -    bus_num = (s->config_reg >> 16) & 0xff;
  61.106 +    bus_num = (addr >> 16) & 0xff;
  61.107      if (bus_num != 0)
  61.108          return;
  61.109 -    pci_dev = s->devices[(s->config_reg >> 8) & 0xff];
  61.110 +    pci_dev = s->devices[(addr >> 8) & 0xff];
  61.111      if (!pci_dev)
  61.112          return;
  61.113 -    config_addr = (s->config_reg & 0xfc) | (addr & 3);
  61.114 +    config_addr = addr & 0xff;
  61.115  #if defined(DEBUG_PCI)
  61.116      printf("pci_config_write: %s: addr=%02x val=%08x len=%d\n",
  61.117             pci_dev->name, config_addr, val, len);
  61.118 @@ -374,20 +355,17 @@ static void pci_data_write(void *opaque,
  61.119      pci_dev->config_write(pci_dev, config_addr, val, len);
  61.120  }
  61.121  
  61.122 -static uint32_t pci_data_read(void *opaque, uint32_t addr, 
  61.123 -                              int len)
  61.124 +uint32_t pci_data_read(void *opaque, uint32_t addr, int len)
  61.125  {
  61.126      PCIBus *s = opaque;
  61.127      PCIDevice *pci_dev;
  61.128      int config_addr, bus_num;
  61.129      uint32_t val;
  61.130  
  61.131 -    if (!(s->config_reg & (1 << 31)))
  61.132 -        goto fail;
  61.133 -    bus_num = (s->config_reg >> 16) & 0xff;
  61.134 +    bus_num = (addr >> 16) & 0xff;
  61.135      if (bus_num != 0)
  61.136          goto fail;
  61.137 -    pci_dev = s->devices[(s->config_reg >> 8) & 0xff];
  61.138 +    pci_dev = s->devices[(addr >> 8) & 0xff];
  61.139      if (!pci_dev) {
  61.140      fail:
  61.141          switch(len) {
  61.142 @@ -404,7 +382,7 @@ static uint32_t pci_data_read(void *opaq
  61.143          }
  61.144          goto the_end;
  61.145      }
  61.146 -    config_addr = (s->config_reg & 0xfc) | (addr & 3);
  61.147 +    config_addr = addr & 0xff;
  61.148      val = pci_dev->config_read(pci_dev, config_addr, len);
  61.149  #if defined(DEBUG_PCI)
  61.150      printf("pci_config_read: %s: addr=%02x val=%08x len=%d\n",
  61.151 @@ -413,1133 +391,11 @@ static uint32_t pci_data_read(void *opaq
  61.152   the_end:
  61.153  #if defined(DEBUG_PCI) && 0
  61.154      printf("pci_data_read: addr=%08x val=%08x len=%d\n",
  61.155 -           s->config_reg, val, len);
  61.156 -#endif
  61.157 -    return val;
  61.158 -}
  61.159 -
  61.160 -static void pci_data_writeb(void* opaque, uint32_t addr, uint32_t val)
  61.161 -{
  61.162 -    pci_data_write(opaque, addr, val, 1);
  61.163 -}
  61.164 -
  61.165 -static void pci_data_writew(void* opaque, uint32_t addr, uint32_t val)
  61.166 -{
  61.167 -    pci_data_write(opaque, addr, val, 2);
  61.168 -}
  61.169 -
  61.170 -static void pci_data_writel(void* opaque, uint32_t addr, uint32_t val)
  61.171 -{
  61.172 -    pci_data_write(opaque, addr, val, 4);
  61.173 -}
  61.174 -
  61.175 -static uint32_t pci_data_readb(void* opaque, uint32_t addr)
  61.176 -{
  61.177 -    return pci_data_read(opaque, addr, 1);
  61.178 -}
  61.179 -
  61.180 -static uint32_t pci_data_readw(void* opaque, uint32_t addr)
  61.181 -{
  61.182 -    return pci_data_read(opaque, addr, 2);
  61.183 -}
  61.184 -
  61.185 -static uint32_t pci_data_readl(void* opaque, uint32_t addr)
  61.186 -{
  61.187 -    return pci_data_read(opaque, addr, 4);
  61.188 -}
  61.189 -
  61.190 -/* i440FX PCI bridge */
  61.191 -
  61.192 -static void piix3_set_irq(PCIDevice *pci_dev, int irq_num, int level);
  61.193 -
  61.194 -PCIBus *i440fx_init(void)
  61.195 -{
  61.196 -    PCIBus *s;
  61.197 -    PCIDevice *d;
  61.198 -
  61.199 -    s = pci_register_bus();
  61.200 -    s->set_irq = piix3_set_irq;
  61.201 -
  61.202 -    register_ioport_write(0xcf8, 4, 4, pci_addr_writel, s);
  61.203 -    register_ioport_read(0xcf8, 4, 4, pci_addr_readl, s);
  61.204 -
  61.205 -    register_ioport_write(0xcfc, 4, 1, pci_data_writeb, s);
  61.206 -    register_ioport_write(0xcfc, 4, 2, pci_data_writew, s);
  61.207 -    register_ioport_write(0xcfc, 4, 4, pci_data_writel, s);
  61.208 -    register_ioport_read(0xcfc, 4, 1, pci_data_readb, s);
  61.209 -    register_ioport_read(0xcfc, 4, 2, pci_data_readw, s);
  61.210 -    register_ioport_read(0xcfc, 4, 4, pci_data_readl, s);
  61.211 -
  61.212 -    d = pci_register_device(s, "i440FX", sizeof(PCIDevice), 0, 
  61.213 -                            NULL, NULL);
  61.214 -
  61.215 -    d->config[0x00] = 0x86; // vendor_id
  61.216 -    d->config[0x01] = 0x80;
  61.217 -    d->config[0x02] = 0x37; // device_id
  61.218 -    d->config[0x03] = 0x12;
  61.219 -    d->config[0x08] = 0x02; // revision
  61.220 -    d->config[0x0a] = 0x00; // class_sub = host2pci
  61.221 -    d->config[0x0b] = 0x06; // class_base = PCI_bridge
  61.222 -    d->config[0x0e] = 0x00; // header_type
  61.223 -    return s;
  61.224 -}
  61.225 -
  61.226 -/* PIIX3 PCI to ISA bridge */
  61.227 -
  61.228 -typedef struct PIIX3State {
  61.229 -    PCIDevice dev;
  61.230 -} PIIX3State;
  61.231 -
  61.232 -PIIX3State *piix3_state;
  61.233 -
  61.234 -/* return the global irq number corresponding to a given device irq
  61.235 -   pin. We could also use the bus number to have a more precise
  61.236 -   mapping. */
  61.237 -static inline int pci_slot_get_pirq(PCIDevice *pci_dev, int irq_num)
  61.238 -{
  61.239 -    int slot_addend;
  61.240 -    slot_addend = (pci_dev->devfn >> 3) - 1;
  61.241 -    return (irq_num + slot_addend) & 3;
  61.242 -}
  61.243 -
  61.244 -static inline int get_pci_irq_level(int irq_num)
  61.245 -{
  61.246 -    int pic_level;
  61.247 -#if (PCI_IRQ_WORDS == 2)
  61.248 -    pic_level = ((pci_irq_levels[irq_num][0] | 
  61.249 -                  pci_irq_levels[irq_num][1]) != 0);
  61.250 -#else
  61.251 -    {
  61.252 -        int i;
  61.253 -        pic_level = 0;
  61.254 -        for(i = 0; i < PCI_IRQ_WORDS; i++) {
  61.255 -            if (pci_irq_levels[irq_num][i]) {
  61.256 -                pic_level = 1;
  61.257 -                break;
  61.258 -            }
  61.259 -        }
  61.260 -    }
  61.261 -#endif
  61.262 -    return pic_level;
  61.263 -}
  61.264 -
  61.265 -static void piix3_set_irq(PCIDevice *pci_dev, int irq_num, int level)
  61.266 -{
  61.267 -    int irq_index, shift, pic_irq, pic_level;
  61.268 -    uint32_t *p;
  61.269 -
  61.270 -    irq_num = pci_slot_get_pirq(pci_dev, irq_num);
  61.271 -    irq_index = pci_dev->irq_index;
  61.272 -    p = &pci_irq_levels[irq_num][irq_index >> 5];
  61.273 -    shift = (irq_index & 0x1f);
  61.274 -    *p = (*p & ~(1 << shift)) | (level << shift);
  61.275 -
  61.276 -    /* now we change the pic irq level according to the piix irq mappings */
  61.277 -    /* XXX: optimize */
  61.278 -    pic_irq = piix3_state->dev.config[0x60 + irq_num];
  61.279 -    if (pic_irq < 16) {
  61.280 -        /* the pic level is the logical OR of all the PCI irqs mapped
  61.281 -           to it */
  61.282 -        pic_level = 0;
  61.283 -        if (pic_irq == piix3_state->dev.config[0x60])
  61.284 -            pic_level |= get_pci_irq_level(0);
  61.285 -        if (pic_irq == piix3_state->dev.config[0x61])
  61.286 -            pic_level |= get_pci_irq_level(1);
  61.287 -        if (pic_irq == piix3_state->dev.config[0x62])
  61.288 -            pic_level |= get_pci_irq_level(2);
  61.289 -        if (pic_irq == piix3_state->dev.config[0x63])
  61.290 -            pic_level |= get_pci_irq_level(3);
  61.291 -        pic_set_irq(pic_irq, pic_level);
  61.292 -    }
  61.293 -}
  61.294 -
  61.295 -static void piix3_reset(PIIX3State *d)
  61.296 -{
  61.297 -    uint8_t *pci_conf = d->dev.config;
  61.298 -
  61.299 -    pci_conf[0x04] = 0x07; // master, memory and I/O
  61.300 -    pci_conf[0x05] = 0x00;
  61.301 -    pci_conf[0x06] = 0x00;
  61.302 -    pci_conf[0x07] = 0x02; // PCI_status_devsel_medium
  61.303 -    pci_conf[0x4c] = 0x4d;
  61.304 -    pci_conf[0x4e] = 0x03;
  61.305 -    pci_conf[0x4f] = 0x00;
  61.306 -    pci_conf[0x60] = 0x80;
  61.307 -    pci_conf[0x69] = 0x02;
  61.308 -    pci_conf[0x70] = 0x80;
  61.309 -    pci_conf[0x76] = 0x0c;
  61.310 -    pci_conf[0x77] = 0x0c;
  61.311 -    pci_conf[0x78] = 0x02;
  61.312 -    pci_conf[0x79] = 0x00;
  61.313 -    pci_conf[0x80] = 0x00;
  61.314 -    pci_conf[0x82] = 0x00;
  61.315 -    pci_conf[0xa0] = 0x08;
  61.316 -    pci_conf[0xa0] = 0x08;
  61.317 -    pci_conf[0xa2] = 0x00;
  61.318 -    pci_conf[0xa3] = 0x00;
  61.319 -    pci_conf[0xa4] = 0x00;
  61.320 -    pci_conf[0xa5] = 0x00;
  61.321 -    pci_conf[0xa6] = 0x00;
  61.322 -    pci_conf[0xa7] = 0x00;
  61.323 -    pci_conf[0xa8] = 0x0f;
  61.324 -    pci_conf[0xaa] = 0x00;
  61.325 -    pci_conf[0xab] = 0x00;
  61.326 -    pci_conf[0xac] = 0x00;
  61.327 -    pci_conf[0xae] = 0x00;
  61.328 -}
  61.329 -
  61.330 -void piix3_init(PCIBus *bus)
  61.331 -{
  61.332 -    PIIX3State *d;
  61.333 -    uint8_t *pci_conf;
  61.334 -
  61.335 -    d = (PIIX3State *)pci_register_device(bus, "PIIX3", sizeof(PIIX3State),
  61.336 -                                          -1, NULL, NULL);
  61.337 -    register_savevm("PIIX3", 0, 1, generic_pci_save, generic_pci_load, d);
  61.338 -
  61.339 -    piix3_state = d;
  61.340 -    pci_conf = d->dev.config;
  61.341 -
  61.342 -    pci_conf[0x00] = 0x86; // Intel
  61.343 -    pci_conf[0x01] = 0x80;
  61.344 -    pci_conf[0x02] = 0x00; // 82371SB PIIX3 PCI-to-ISA bridge (Step A1)
  61.345 -    pci_conf[0x03] = 0x70;
  61.346 -    pci_conf[0x0a] = 0x01; // class_sub = PCI_ISA
  61.347 -    pci_conf[0x0b] = 0x06; // class_base = PCI_bridge
  61.348 -    pci_conf[0x0e] = 0x80; // header_type = PCI_multifunction, generic
  61.349 -
  61.350 -    piix3_reset(d);
  61.351 -}
  61.352 -
  61.353 -/* PREP pci init */
  61.354 -
  61.355 -static inline void set_config(PCIBus *s, target_phys_addr_t addr)
  61.356 -{
  61.357 -    int devfn, i;
  61.358 -
  61.359 -    for(i = 0; i < 11; i++) {
  61.360 -        if ((addr & (1 << (11 + i))) != 0)
  61.361 -            break;
  61.362 -    }
  61.363 -    devfn = ((addr >> 8) & 7) | (i << 3);
  61.364 -    s->config_reg = 0x80000000 | (addr & 0xfc) | (devfn << 8);
  61.365 -}
  61.366 -
  61.367 -static void PPC_PCIIO_writeb (void *opaque, target_phys_addr_t addr, uint32_t val)
  61.368 -{
  61.369 -    PCIBus *s = opaque;
  61.370 -    set_config(s, addr);
  61.371 -    pci_data_write(s, addr, val, 1);
  61.372 -}
  61.373 -
  61.374 -static void PPC_PCIIO_writew (void *opaque, target_phys_addr_t addr, uint32_t val)
  61.375 -{
  61.376 -    PCIBus *s = opaque;
  61.377 -    set_config(s, addr);
  61.378 -#ifdef TARGET_WORDS_BIGENDIAN
  61.379 -    val = bswap16(val);
  61.380 -#endif
  61.381 -    pci_data_write(s, addr, val, 2);
  61.382 -}
  61.383 -
  61.384 -static void PPC_PCIIO_writel (void *opaque, target_phys_addr_t addr, uint32_t val)
  61.385 -{
  61.386 -    PCIBus *s = opaque;
  61.387 -    set_config(s, addr);
  61.388 -#ifdef TARGET_WORDS_BIGENDIAN
  61.389 -    val = bswap32(val);
  61.390 -#endif
  61.391 -    pci_data_write(s, addr, val, 4);
  61.392 -}
  61.393 -
  61.394 -static uint32_t PPC_PCIIO_readb (void *opaque, target_phys_addr_t addr)
  61.395 -{
  61.396 -    PCIBus *s = opaque;
  61.397 -    uint32_t val;
  61.398 -    set_config(s, addr);
  61.399 -    val = pci_data_read(s, addr, 1);
  61.400 -    return val;
  61.401 -}
  61.402 -
  61.403 -static uint32_t PPC_PCIIO_readw (void *opaque, target_phys_addr_t addr)
  61.404 -{
  61.405 -    PCIBus *s = opaque;
  61.406 -    uint32_t val;
  61.407 -    set_config(s, addr);
  61.408 -    val = pci_data_read(s, addr, 2);
  61.409 -#ifdef TARGET_WORDS_BIGENDIAN
  61.410 -    val = bswap16(val);
  61.411 -#endif
  61.412 -    return val;
  61.413 -}
  61.414 -
  61.415 -static uint32_t PPC_PCIIO_readl (void *opaque, target_phys_addr_t addr)
  61.416 -{
  61.417 -    PCIBus *s = opaque;
  61.418 -    uint32_t val;
  61.419 -    set_config(s, addr);
  61.420 -    val = pci_data_read(s, addr, 4);
  61.421 -#ifdef TARGET_WORDS_BIGENDIAN
  61.422 -    val = bswap32(val);
  61.423 -#endif
  61.424 -    return val;
  61.425 -}
  61.426 -
  61.427 -static CPUWriteMemoryFunc *PPC_PCIIO_write[] = {
  61.428 -    &PPC_PCIIO_writeb,
  61.429 -    &PPC_PCIIO_writew,
  61.430 -    &PPC_PCIIO_writel,
  61.431 -};
  61.432 -
  61.433 -static CPUReadMemoryFunc *PPC_PCIIO_read[] = {
  61.434 -    &PPC_PCIIO_readb,
  61.435 -    &PPC_PCIIO_readw,
  61.436 -    &PPC_PCIIO_readl,
  61.437 -};
  61.438 -
  61.439 -static void prep_set_irq(PCIDevice *d, int irq_num, int level)
  61.440 -{
  61.441 -    /* XXX: we do not simulate the hardware - we rely on the BIOS to
  61.442 -       set correctly for irq line field */
  61.443 -    pic_set_irq(d->config[PCI_INTERRUPT_LINE], level);
  61.444 -}
  61.445 -
  61.446 -PCIBus *pci_prep_init(void)
  61.447 -{
  61.448 -    PCIBus *s;
  61.449 -    PCIDevice *d;
  61.450 -    int PPC_io_memory;
  61.451 -
  61.452 -    s = pci_register_bus();
  61.453 -    s->set_irq = prep_set_irq;
  61.454 -
  61.455 -    register_ioport_write(0xcf8, 4, 4, pci_addr_writel, s);
  61.456 -    register_ioport_read(0xcf8, 4, 4, pci_addr_readl, s);
  61.457 -
  61.458 -    register_ioport_write(0xcfc, 4, 1, pci_data_writeb, s);
  61.459 -    register_ioport_write(0xcfc, 4, 2, pci_data_writew, s);
  61.460 -    register_ioport_write(0xcfc, 4, 4, pci_data_writel, s);
  61.461 -    register_ioport_read(0xcfc, 4, 1, pci_data_readb, s);
  61.462 -    register_ioport_read(0xcfc, 4, 2, pci_data_readw, s);
  61.463 -    register_ioport_read(0xcfc, 4, 4, pci_data_readl, s);
  61.464 -
  61.465 -    PPC_io_memory = cpu_register_io_memory(0, PPC_PCIIO_read, 
  61.466 -                                           PPC_PCIIO_write, s);
  61.467 -    cpu_register_physical_memory(0x80800000, 0x00400000, PPC_io_memory);
  61.468 -
  61.469 -    /* PCI host bridge */ 
  61.470 -    d = pci_register_device(s, "PREP Host Bridge - Motorola Raven", 
  61.471 -                            sizeof(PCIDevice), 0, NULL, NULL);
  61.472 -    d->config[0x00] = 0x57; // vendor_id : Motorola
  61.473 -    d->config[0x01] = 0x10;
  61.474 -    d->config[0x02] = 0x01; // device_id : Raven
  61.475 -    d->config[0x03] = 0x48;
  61.476 -    d->config[0x08] = 0x00; // revision
  61.477 -    d->config[0x0A] = 0x00; // class_sub = pci host
  61.478 -    d->config[0x0B] = 0x06; // class_base = PCI_bridge
  61.479 -    d->config[0x0C] = 0x08; // cache_line_size
  61.480 -    d->config[0x0D] = 0x10; // latency_timer
  61.481 -    d->config[0x0E] = 0x00; // header_type
  61.482 -    d->config[0x34] = 0x00; // capabilities_pointer
  61.483 -
  61.484 -    return s;
  61.485 -}
  61.486 -
  61.487 -
  61.488 -/* Grackle PCI host */
  61.489 -static void pci_grackle_config_writel (void *opaque, target_phys_addr_t addr,
  61.490 -                                       uint32_t val)
  61.491 -{
  61.492 -    PCIBus *s = opaque;
  61.493 -#ifdef TARGET_WORDS_BIGENDIAN
  61.494 -    val = bswap32(val);
  61.495 -#endif
  61.496 -    s->config_reg = val;
  61.497 -}
  61.498 -
  61.499 -static uint32_t pci_grackle_config_readl (void *opaque, target_phys_addr_t addr)
  61.500 -{
  61.501 -    PCIBus *s = opaque;
  61.502 -    uint32_t val;
  61.503 -
  61.504 -    val = s->config_reg;
  61.505 -#ifdef TARGET_WORDS_BIGENDIAN
  61.506 -    val = bswap32(val);
  61.507 -#endif
  61.508 -    return val;
  61.509 -}
  61.510 -
  61.511 -static CPUWriteMemoryFunc *pci_grackle_config_write[] = {
  61.512 -    &pci_grackle_config_writel,
  61.513 -    &pci_grackle_config_writel,
  61.514 -    &pci_grackle_config_writel,
  61.515 -};
  61.516 -
  61.517 -static CPUReadMemoryFunc *pci_grackle_config_read[] = {
  61.518 -    &pci_grackle_config_readl,
  61.519 -    &pci_grackle_config_readl,
  61.520 -    &pci_grackle_config_readl,
  61.521 -};
  61.522 -
  61.523 -static void pci_grackle_writeb (void *opaque, target_phys_addr_t addr,
  61.524 -                                uint32_t val)
  61.525 -{
  61.526 -    PCIBus *s = opaque;
  61.527 -    pci_data_write(s, addr, val, 1);
  61.528 -}
  61.529 -
  61.530 -static void pci_grackle_writew (void *opaque, target_phys_addr_t addr,
  61.531 -                                uint32_t val)
  61.532 -{
  61.533 -    PCIBus *s = opaque;
  61.534 -#ifdef TARGET_WORDS_BIGENDIAN
  61.535 -    val = bswap16(val);
  61.536 -#endif
  61.537 -    pci_data_write(s, addr, val, 2);
  61.538 -}
  61.539 -
  61.540 -static void pci_grackle_writel (void *opaque, target_phys_addr_t addr,
  61.541 -                                uint32_t val)
  61.542 -{
  61.543 -    PCIBus *s = opaque;
  61.544 -#ifdef TARGET_WORDS_BIGENDIAN
  61.545 -    val = bswap32(val);
  61.546 -#endif
  61.547 -    pci_data_write(s, addr, val, 4);
  61.548 -}
  61.549 -
  61.550 -static uint32_t pci_grackle_readb (void *opaque, target_phys_addr_t addr)
  61.551 -{
  61.552 -    PCIBus *s = opaque;
  61.553 -    uint32_t val;
  61.554 -    val = pci_data_read(s, addr, 1);
  61.555 -    return val;
  61.556 -}
  61.557 -
  61.558 -static uint32_t pci_grackle_readw (void *opaque, target_phys_addr_t addr)
  61.559 -{
  61.560 -    PCIBus *s = opaque;
  61.561 -    uint32_t val;
  61.562 -    val = pci_data_read(s, addr, 2);
  61.563 -#ifdef TARGET_WORDS_BIGENDIAN
  61.564 -    val = bswap16(val);
  61.565 -#endif
  61.566 -    return val;
  61.567 -}
  61.568 -
  61.569 -static uint32_t pci_grackle_readl (void *opaque, target_phys_addr_t addr)
  61.570 -{
  61.571 -    PCIBus *s = opaque;
  61.572 -    uint32_t val;
  61.573 -
  61.574 -    val = pci_data_read(s, addr, 4);
  61.575 -#ifdef TARGET_WORDS_BIGENDIAN
  61.576 -    val = bswap32(val);
  61.577 +           addr, val, len);
  61.578  #endif
  61.579      return val;
  61.580  }
  61.581  
  61.582 -static CPUWriteMemoryFunc *pci_grackle_write[] = {
  61.583 -    &pci_grackle_writeb,
  61.584 -    &pci_grackle_writew,
  61.585 -    &pci_grackle_writel,
  61.586 -};
  61.587 -
  61.588 -static CPUReadMemoryFunc *pci_grackle_read[] = {
  61.589 -    &pci_grackle_readb,
  61.590 -    &pci_grackle_readw,
  61.591 -    &pci_grackle_readl,
  61.592 -};
  61.593 -
  61.594 -void pci_set_pic(PCIBus *bus, SetIRQFunc *set_irq, void *irq_opaque)
  61.595 -{
  61.596 -    bus->low_set_irq = set_irq;
  61.597 -    bus->irq_opaque = irq_opaque;
  61.598 -}
  61.599 -
  61.600 -/* XXX: we do not simulate the hardware - we rely on the BIOS to
  61.601 -   set correctly for irq line field */
  61.602 -static void pci_set_irq_simple(PCIDevice *d, int irq_num, int level)
  61.603 -{
  61.604 -    PCIBus *s = d->bus;
  61.605 -    s->low_set_irq(s->irq_opaque, d->config[PCI_INTERRUPT_LINE], level);
  61.606 -}
  61.607 -
  61.608 -PCIBus *pci_grackle_init(uint32_t base)
  61.609 -{
  61.610 -    PCIBus *s;
  61.611 -    PCIDevice *d;
  61.612 -    int pci_mem_config, pci_mem_data;
  61.613 -
  61.614 -    s = pci_register_bus();
  61.615 -    s->set_irq = pci_set_irq_simple;
  61.616 -
  61.617 -    pci_mem_config = cpu_register_io_memory(0, pci_grackle_config_read, 
  61.618 -                                            pci_grackle_config_write, s);
  61.619 -    pci_mem_data = cpu_register_io_memory(0, pci_grackle_read,
  61.620 -                                          pci_grackle_write, s);
  61.621 -    cpu_register_physical_memory(base, 0x1000, pci_mem_config);
  61.622 -    cpu_register_physical_memory(base + 0x00200000, 0x1000, pci_mem_data);
  61.623 -    d = pci_register_device(s, "Grackle host bridge", sizeof(PCIDevice), 
  61.624 -                            0, NULL, NULL);
  61.625 -    d->config[0x00] = 0x57; // vendor_id
  61.626 -    d->config[0x01] = 0x10;
  61.627 -    d->config[0x02] = 0x02; // device_id
  61.628 -    d->config[0x03] = 0x00;
  61.629 -    d->config[0x08] = 0x00; // revision
  61.630 -    d->config[0x09] = 0x01;
  61.631 -    d->config[0x0a] = 0x00; // class_sub = host
  61.632 -    d->config[0x0b] = 0x06; // class_base = PCI_bridge
  61.633 -    d->config[0x0e] = 0x00; // header_type
  61.634 -
  61.635 -    d->config[0x18] = 0x00;  // primary_bus
  61.636 -    d->config[0x19] = 0x01;  // secondary_bus
  61.637 -    d->config[0x1a] = 0x00;  // subordinate_bus
  61.638 -    d->config[0x1c] = 0x00;
  61.639 -    d->config[0x1d] = 0x00;
  61.640 -    
  61.641 -    d->config[0x20] = 0x00; // memory_base
  61.642 -    d->config[0x21] = 0x00;
  61.643 -    d->config[0x22] = 0x01; // memory_limit
  61.644 -    d->config[0x23] = 0x00;
  61.645 -    
  61.646 -    d->config[0x24] = 0x00; // prefetchable_memory_base
  61.647 -    d->config[0x25] = 0x00;
  61.648 -    d->config[0x26] = 0x00; // prefetchable_memory_limit
  61.649 -    d->config[0x27] = 0x00;
  61.650 -
  61.651 -#if 0
  61.652 -    /* PCI2PCI bridge same values as PearPC - check this */
  61.653 -    d->config[0x00] = 0x11; // vendor_id
  61.654 -    d->config[0x01] = 0x10;
  61.655 -    d->config[0x02] = 0x26; // device_id
  61.656 -    d->config[0x03] = 0x00;
  61.657 -    d->config[0x08] = 0x02; // revision
  61.658 -    d->config[0x0a] = 0x04; // class_sub = pci2pci
  61.659 -    d->config[0x0b] = 0x06; // class_base = PCI_bridge
  61.660 -    d->config[0x0e] = 0x01; // header_type
  61.661 -
  61.662 -    d->config[0x18] = 0x0;  // primary_bus
  61.663 -    d->config[0x19] = 0x1;  // secondary_bus
  61.664 -    d->config[0x1a] = 0x1;  // subordinate_bus
  61.665 -    d->config[0x1c] = 0x10; // io_base
  61.666 -    d->config[0x1d] = 0x20; // io_limit
  61.667 -    
  61.668 -    d->config[0x20] = 0x80; // memory_base
  61.669 -    d->config[0x21] = 0x80;
  61.670 -    d->config[0x22] = 0x90; // memory_limit
  61.671 -    d->config[0x23] = 0x80;
  61.672 -    
  61.673 -    d->config[0x24] = 0x00; // prefetchable_memory_base
  61.674 -    d->config[0x25] = 0x84;
  61.675 -    d->config[0x26] = 0x00; // prefetchable_memory_limit
  61.676 -    d->config[0x27] = 0x85;
  61.677 -#endif
  61.678 -    return s;
  61.679 -}
  61.680 -
  61.681 -/* Uninorth PCI host (for all Mac99 and newer machines */
  61.682 -static void pci_unin_main_config_writel (void *opaque, target_phys_addr_t addr,
  61.683 -                                         uint32_t val)
  61.684 -{
  61.685 -    PCIBus *s = opaque;
  61.686 -    int i;
  61.687 -
  61.688 -#ifdef TARGET_WORDS_BIGENDIAN
  61.689 -    val = bswap32(val);
  61.690 -#endif
  61.691 -
  61.692 -    for (i = 11; i < 32; i++) {
  61.693 -        if ((val & (1 << i)) != 0)
  61.694 -            break;
  61.695 -    }
  61.696 -#if 0
  61.697 -    s->config_reg = 0x80000000 | (1 << 16) | (val & 0x7FC) | (i << 11);
  61.698 -#else
  61.699 -    s->config_reg = 0x80000000 | (0 << 16) | (val & 0x7FC) | (i << 11);
  61.700 -#endif
  61.701 -}
  61.702 -
  61.703 -static uint32_t pci_unin_main_config_readl (void *opaque,
  61.704 -                                            target_phys_addr_t addr)
  61.705 -{
  61.706 -    PCIBus *s = opaque;
  61.707 -    uint32_t val;
  61.708 -    int devfn;
  61.709 -
  61.710 -    devfn = (s->config_reg >> 8) & 0xFF;
  61.711 -    val = (1 << (devfn >> 3)) | ((devfn & 0x07) << 8) | (s->config_reg & 0xFC);
  61.712 -#ifdef TARGET_WORDS_BIGENDIAN
  61.713 -    val = bswap32(val);
  61.714 -#endif
  61.715 -
  61.716 -    return val;
  61.717 -}
  61.718 -
  61.719 -static CPUWriteMemoryFunc *pci_unin_main_config_write[] = {
  61.720 -    &pci_unin_main_config_writel,
  61.721 -    &pci_unin_main_config_writel,
  61.722 -    &pci_unin_main_config_writel,
  61.723 -};
  61.724 -
  61.725 -static CPUReadMemoryFunc *pci_unin_main_config_read[] = {
  61.726 -    &pci_unin_main_config_readl,
  61.727 -    &pci_unin_main_config_readl,
  61.728 -    &pci_unin_main_config_readl,
  61.729 -};
  61.730 -
  61.731 -static void pci_unin_main_writeb (void *opaque, target_phys_addr_t addr,
  61.732 -                                  uint32_t val)
  61.733 -{
  61.734 -    PCIBus *s = opaque;
  61.735 -    pci_data_write(s, addr & 7, val, 1);
  61.736 -}
  61.737 -
  61.738 -static void pci_unin_main_writew (void *opaque, target_phys_addr_t addr,
  61.739 -                                  uint32_t val)
  61.740 -{
  61.741 -    PCIBus *s = opaque;
  61.742 -#ifdef TARGET_WORDS_BIGENDIAN
  61.743 -    val = bswap16(val);
  61.744 -#endif
  61.745 -    pci_data_write(s, addr & 7, val, 2);
  61.746 -}
  61.747 -
  61.748 -static void pci_unin_main_writel (void *opaque, target_phys_addr_t addr,
  61.749 -                                uint32_t val)
  61.750 -{
  61.751 -    PCIBus *s = opaque;
  61.752 -#ifdef TARGET_WORDS_BIGENDIAN
  61.753 -    val = bswap32(val);
  61.754 -#endif
  61.755 -    pci_data_write(s, addr & 7, val, 4);
  61.756 -}
  61.757 -
  61.758 -static uint32_t pci_unin_main_readb (void *opaque, target_phys_addr_t addr)
  61.759 -{
  61.760 -    PCIBus *s = opaque;
  61.761 -    uint32_t val;
  61.762 -
  61.763 -    val = pci_data_read(s, addr & 7, 1);
  61.764 -
  61.765 -    return val;
  61.766 -}
  61.767 -
  61.768 -static uint32_t pci_unin_main_readw (void *opaque, target_phys_addr_t addr)
  61.769 -{
  61.770 -    PCIBus *s = opaque;
  61.771 -    uint32_t val;
  61.772 -
  61.773 -    val = pci_data_read(s, addr & 7, 2);
  61.774 -#ifdef TARGET_WORDS_BIGENDIAN
  61.775 -    val = bswap16(val);
  61.776 -#endif
  61.777 -
  61.778 -    return val;
  61.779 -}
  61.780 -
  61.781 -static uint32_t pci_unin_main_readl (void *opaque, target_phys_addr_t addr)
  61.782 -{
  61.783 -    PCIBus *s = opaque;
  61.784 -    uint32_t val;
  61.785 -
  61.786 -    val = pci_data_read(s, addr, 4);
  61.787 -#ifdef TARGET_WORDS_BIGENDIAN
  61.788 -    val = bswap32(val);
  61.789 -#endif
  61.790 -
  61.791 -    return val;
  61.792 -}
  61.793 -
  61.794 -static CPUWriteMemoryFunc *pci_unin_main_write[] = {
  61.795 -    &pci_unin_main_writeb,
  61.796 -    &pci_unin_main_writew,
  61.797 -    &pci_unin_main_writel,
  61.798 -};
  61.799 -
  61.800 -static CPUReadMemoryFunc *pci_unin_main_read[] = {
  61.801 -    &pci_unin_main_readb,
  61.802 -    &pci_unin_main_readw,
  61.803 -    &pci_unin_main_readl,
  61.804 -};
  61.805 -
  61.806 -#if 0
  61.807 -
  61.808 -static void pci_unin_config_writel (void *opaque, target_phys_addr_t addr,
  61.809 -                                    uint32_t val)
  61.810 -{
  61.811 -    PCIBus *s = opaque;
  61.812 -
  61.813 -#ifdef TARGET_WORDS_BIGENDIAN
  61.814 -    val = bswap32(val);
  61.815 -#endif
  61.816 -    s->config_reg = 0x80000000 | (val & ~0x00000001);
  61.817 -}
  61.818 -
  61.819 -static uint32_t pci_unin_config_readl (void *opaque,
  61.820 -                                       target_phys_addr_t addr)
  61.821 -{
  61.822 -    PCIBus *s = opaque;
  61.823 -    uint32_t val;
  61.824 -
  61.825 -    val = (s->config_reg | 0x00000001) & ~0x80000000;
  61.826 -#ifdef TARGET_WORDS_BIGENDIAN
  61.827 -    val = bswap32(val);
  61.828 -#endif
  61.829 -
  61.830 -    return val;
  61.831 -}
  61.832 -
  61.833 -static CPUWriteMemoryFunc *pci_unin_config_write[] = {
  61.834 -    &pci_unin_config_writel,
  61.835 -    &pci_unin_config_writel,
  61.836 -    &pci_unin_config_writel,
  61.837 -};
  61.838 -
  61.839 -static CPUReadMemoryFunc *pci_unin_config_read[] = {
  61.840 -    &pci_unin_config_readl,
  61.841 -    &pci_unin_config_readl,
  61.842 -    &pci_unin_config_readl,
  61.843 -};
  61.844 -
  61.845 -static void pci_unin_writeb (void *opaque, target_phys_addr_t addr,
  61.846 -                             uint32_t val)
  61.847 -{
  61.848 -    PCIBus *s = opaque;
  61.849 -    pci_data_write(s, addr & 3, val, 1);
  61.850 -}
  61.851 -
  61.852 -static void pci_unin_writew (void *opaque, target_phys_addr_t addr,
  61.853 -                             uint32_t val)
  61.854 -{
  61.855 -    PCIBus *s = opaque;
  61.856 -#ifdef TARGET_WORDS_BIGENDIAN
  61.857 -    val = bswap16(val);
  61.858 -#endif
  61.859 -    pci_data_write(s, addr & 3, val, 2);
  61.860 -}
  61.861 -
  61.862 -static void pci_unin_writel (void *opaque, target_phys_addr_t addr,
  61.863 -                             uint32_t val)
  61.864 -{
  61.865 -    PCIBus *s = opaque;
  61.866 -#ifdef TARGET_WORDS_BIGENDIAN
  61.867 -    val = bswap32(val);
  61.868 -#endif
  61.869 -    pci_data_write(s, addr & 3, val, 4);
  61.870 -}
  61.871 -
  61.872 -static uint32_t pci_unin_readb (void *opaque, target_phys_addr_t addr)
  61.873 -{
  61.874 -    PCIBus *s = opaque;
  61.875 -    uint32_t val;
  61.876 -
  61.877 -    val = pci_data_read(s, addr & 3, 1);
  61.878 -
  61.879 -    return val;
  61.880 -}
  61.881 -
  61.882 -static uint32_t pci_unin_readw (void *opaque, target_phys_addr_t addr)
  61.883 -{
  61.884 -    PCIBus *s = opaque;
  61.885 -    uint32_t val;
  61.886 -
  61.887 -    val = pci_data_read(s, addr & 3, 2);
  61.888 -#ifdef TARGET_WORDS_BIGENDIAN
  61.889 -    val = bswap16(val);
  61.890 -#endif
  61.891 -
  61.892 -    return val;
  61.893 -}
  61.894 -
  61.895 -static uint32_t pci_unin_readl (void *opaque, target_phys_addr_t addr)
  61.896 -{
  61.897 -    PCIBus *s = opaque;
  61.898 -    uint32_t val;
  61.899 -
  61.900 -    val = pci_data_read(s, addr & 3, 4);
  61.901 -#ifdef TARGET_WORDS_BIGENDIAN
  61.902 -    val = bswap32(val);
  61.903 -#endif
  61.904 -
  61.905 -    return val;
  61.906 -}
  61.907 -
  61.908 -static CPUWriteMemoryFunc *pci_unin_write[] = {
  61.909 -    &pci_unin_writeb,
  61.910 -    &pci_unin_writew,
  61.911 -    &pci_unin_writel,
  61.912 -};
  61.913 -
  61.914 -static CPUReadMemoryFunc *pci_unin_read[] = {
  61.915 -    &pci_unin_readb,
  61.916 -    &pci_unin_readw,
  61.917 -    &pci_unin_readl,
  61.918 -};
  61.919 -#endif
  61.920 -
  61.921 -PCIBus *pci_pmac_init(void)
  61.922 -{
  61.923 -    PCIBus *s;
  61.924 -    PCIDevice *d;
  61.925 -    int pci_mem_config, pci_mem_data;
  61.926 -
  61.927 -    /* Use values found on a real PowerMac */
  61.928 -    /* Uninorth main bus */
  61.929 -    s = pci_register_bus();
  61.930 -    s->set_irq = pci_set_irq_simple;
  61.931 -
  61.932 -    pci_mem_config = cpu_register_io_memory(0, pci_unin_main_config_read, 
  61.933 -                                            pci_unin_main_config_write, s);
  61.934 -    pci_mem_data = cpu_register_io_memory(0, pci_unin_main_read,
  61.935 -                                          pci_unin_main_write, s);
  61.936 -    cpu_register_physical_memory(0xf2800000, 0x1000, pci_mem_config);
  61.937 -    cpu_register_physical_memory(0xf2c00000, 0x1000, pci_mem_data);
  61.938 -    s->devfn_min = 11 << 3;
  61.939 -    d = pci_register_device(s, "Uni-north main", sizeof(PCIDevice), 
  61.940 -                            11 << 3, NULL, NULL);
  61.941 -    d->config[0x00] = 0x6b; // vendor_id : Apple
  61.942 -    d->config[0x01] = 0x10;
  61.943 -    d->config[0x02] = 0x1F; // device_id
  61.944 -    d->config[0x03] = 0x00;
  61.945 -    d->config[0x08] = 0x00; // revision
  61.946 -    d->config[0x0A] = 0x00; // class_sub = pci host
  61.947 -    d->config[0x0B] = 0x06; // class_base = PCI_bridge
  61.948 -    d->config[0x0C] = 0x08; // cache_line_size
  61.949 -    d->config[0x0D] = 0x10; // latency_timer
  61.950 -    d->config[0x0E] = 0x00; // header_type
  61.951 -    d->config[0x34] = 0x00; // capabilities_pointer
  61.952 -
  61.953 -#if 0 // XXX: not activated as PPC BIOS doesn't handle mutiple buses properly
  61.954 -    /* pci-to-pci bridge */
  61.955 -    d = pci_register_device("Uni-north bridge", sizeof(PCIDevice), 0, 13 << 3,
  61.956 -                            NULL, NULL);
  61.957 -    d->config[0x00] = 0x11; // vendor_id : TI
  61.958 -    d->config[0x01] = 0x10;
  61.959 -    d->config[0x02] = 0x26; // device_id
  61.960 -    d->config[0x03] = 0x00;
  61.961 -    d->config[0x08] = 0x05; // revision
  61.962 -    d->config[0x0A] = 0x04; // class_sub = pci2pci
  61.963 -    d->config[0x0B] = 0x06; // class_base = PCI_bridge
  61.964 -    d->config[0x0C] = 0x08; // cache_line_size
  61.965 -    d->config[0x0D] = 0x20; // latency_timer
  61.966 -    d->config[0x0E] = 0x01; // header_type
  61.967 -
  61.968 -    d->config[0x18] = 0x01; // primary_bus
  61.969 -    d->config[0x19] = 0x02; // secondary_bus
  61.970 -    d->config[0x1A] = 0x02; // subordinate_bus
  61.971 -    d->config[0x1B] = 0x20; // secondary_latency_timer
  61.972 -    d->config[0x1C] = 0x11; // io_base
  61.973 -    d->config[0x1D] = 0x01; // io_limit
  61.974 -    d->config[0x20] = 0x00; // memory_base
  61.975 -    d->config[0x21] = 0x80;
  61.976 -    d->config[0x22] = 0x00; // memory_limit
  61.977 -    d->config[0x23] = 0x80;
  61.978 -    d->config[0x24] = 0x01; // prefetchable_memory_base
  61.979 -    d->config[0x25] = 0x80;
  61.980 -    d->config[0x26] = 0xF1; // prefectchable_memory_limit
  61.981 -    d->config[0x27] = 0x7F;
  61.982 -    // d->config[0x34] = 0xdc // capabilities_pointer
  61.983 -#endif
  61.984 -#if 0 // XXX: not needed for now
  61.985 -    /* Uninorth AGP bus */
  61.986 -    s = &pci_bridge[1];
  61.987 -    pci_mem_config = cpu_register_io_memory(0, pci_unin_config_read, 
  61.988 -                                            pci_unin_config_write, s);
  61.989 -    pci_mem_data = cpu_register_io_memory(0, pci_unin_read,
  61.990 -                                          pci_unin_write, s);
  61.991 -    cpu_register_physical_memory(0xf0800000, 0x1000, pci_mem_config);
  61.992 -    cpu_register_physical_memory(0xf0c00000, 0x1000, pci_mem_data);
  61.993 -
  61.994 -    d = pci_register_device("Uni-north AGP", sizeof(PCIDevice), 0, 11 << 3,
  61.995 -                            NULL, NULL);
  61.996 -    d->config[0x00] = 0x6b; // vendor_id : Apple
  61.997 -    d->config[0x01] = 0x10;
  61.998 -    d->config[0x02] = 0x20; // device_id
  61.999 -    d->config[0x03] = 0x00;
 61.1000 -    d->config[0x08] = 0x00; // revision
 61.1001 -    d->config[0x0A] = 0x00; // class_sub = pci host
 61.1002 -    d->config[0x0B] = 0x06; // class_base = PCI_bridge
 61.1003 -    d->config[0x0C] = 0x08; // cache_line_size
 61.1004 -    d->config[0x0D] = 0x10; // latency_timer
 61.1005 -    d->config[0x0E] = 0x00; // header_type
 61.1006 -    //    d->config[0x34] = 0x80; // capabilities_pointer
 61.1007 -#endif
 61.1008 -
 61.1009 -#if 0 // XXX: not needed for now
 61.1010 -    /* Uninorth internal bus */
 61.1011 -    s = &pci_bridge[2];
 61.1012 -    pci_mem_config = cpu_register_io_memory(0, pci_unin_config_read, 
 61.1013 -                                            pci_unin_config_write, s);
 61.1014 -    pci_mem_data = cpu_register_io_memory(0, pci_unin_read,
 61.1015 -                                          pci_unin_write, s);
 61.1016 -    cpu_register_physical_memory(0xf4800000, 0x1000, pci_mem_config);
 61.1017 -    cpu_register_physical_memory(0xf4c00000, 0x1000, pci_mem_data);
 61.1018 -
 61.1019 -    d = pci_register_device("Uni-north internal", sizeof(PCIDevice),
 61.1020 -                            3, 11 << 3, NULL, NULL);
 61.1021 -    d->config[0x00] = 0x6b; // vendor_id : Apple
 61.1022 -    d->config[0x01] = 0x10;
 61.1023 -    d->config[0x02] = 0x1E; // device_id
 61.1024 -    d->config[0x03] = 0x00;
 61.1025 -    d->config[0x08] = 0x00; // revision
 61.1026 -    d->config[0x0A] = 0x00; // class_sub = pci host
 61.1027 -    d->config[0x0B] = 0x06; // class_base = PCI_bridge
 61.1028 -    d->config[0x0C] = 0x08; // cache_line_size
 61.1029 -    d->config[0x0D] = 0x10; // latency_timer
 61.1030 -    d->config[0x0E] = 0x00; // header_type
 61.1031 -    d->config[0x34] = 0x00; // capabilities_pointer
 61.1032 -#endif
 61.1033 -    return s;
 61.1034 -}
 61.1035 -
 61.1036 -/* Ultrasparc APB PCI host */
 61.1037 -static void pci_apb_config_writel (void *opaque, target_phys_addr_t addr,
 61.1038 -                                         uint32_t val)
 61.1039 -{
 61.1040 -    PCIBus *s = opaque;
 61.1041 -    int i;
 61.1042 -
 61.1043 -    for (i = 11; i < 32; i++) {
 61.1044 -        if ((val & (1 << i)) != 0)
 61.1045 -            break;
 61.1046 -    }
 61.1047 -    s->config_reg = 0x80000000 | (1 << 16) | (val & 0x7FC) | (i << 11);
 61.1048 -}
 61.1049 -
 61.1050 -static uint32_t pci_apb_config_readl (void *opaque,
 61.1051 -                                            target_phys_addr_t addr)
 61.1052 -{
 61.1053 -    PCIBus *s = opaque;
 61.1054 -    uint32_t val;
 61.1055 -    int devfn;
 61.1056 -
 61.1057 -    devfn = (s->config_reg >> 8) & 0xFF;
 61.1058 -    val = (1 << (devfn >> 3)) | ((devfn & 0x07) << 8) | (s->config_reg & 0xFC);
 61.1059 -    return val;
 61.1060 -}
 61.1061 -
 61.1062 -static CPUWriteMemoryFunc *pci_apb_config_write[] = {
 61.1063 -    &pci_apb_config_writel,
 61.1064 -    &pci_apb_config_writel,
 61.1065 -    &pci_apb_config_writel,
 61.1066 -};
 61.1067 -
 61.1068 -static CPUReadMemoryFunc *pci_apb_config_read[] = {
 61.1069 -    &pci_apb_config_readl,
 61.1070 -    &pci_apb_config_readl,
 61.1071 -    &pci_apb_config_readl,
 61.1072 -};
 61.1073 -
 61.1074 -static void apb_config_writel (void *opaque, target_phys_addr_t addr,
 61.1075 -			       uint32_t val)
 61.1076 -{
 61.1077 -    //PCIBus *s = opaque;
 61.1078 -
 61.1079 -    switch (addr & 0x3f) {
 61.1080 -    case 0x00: // Control/Status
 61.1081 -    case 0x10: // AFSR
 61.1082 -    case 0x18: // AFAR
 61.1083 -    case 0x20: // Diagnostic
 61.1084 -    case 0x28: // Target address space
 61.1085 -	// XXX
 61.1086 -    default:
 61.1087 -	break;
 61.1088 -    }
 61.1089 -}
 61.1090 -
 61.1091 -static uint32_t apb_config_readl (void *opaque,
 61.1092 -				  target_phys_addr_t addr)
 61.1093 -{
 61.1094 -    //PCIBus *s = opaque;
 61.1095 -    uint32_t val;
 61.1096 -
 61.1097 -    switch (addr & 0x3f) {
 61.1098 -    case 0x00: // Control/Status
 61.1099 -    case 0x10: // AFSR
 61.1100 -    case 0x18: // AFAR
 61.1101 -    case 0x20: // Diagnostic
 61.1102 -    case 0x28: // Target address space
 61.1103 -	// XXX
 61.1104 -    default:
 61.1105 -	val = 0;
 61.1106 -	break;
 61.1107 -    }
 61.1108 -    return val;
 61.1109 -}
 61.1110 -
 61.1111 -static CPUWriteMemoryFunc *apb_config_write[] = {
 61.1112 -    &apb_config_writel,
 61.1113 -    &apb_config_writel,
 61.1114 -    &apb_config_writel,
 61.1115 -};
 61.1116 -
 61.1117 -static CPUReadMemoryFunc *apb_config_read[] = {
 61.1118 -    &apb_config_readl,
 61.1119 -    &apb_config_readl,
 61.1120 -    &apb_config_readl,
 61.1121 -};
 61.1122 -
 61.1123 -static void pci_apb_writeb (void *opaque, target_phys_addr_t addr,
 61.1124 -                                  uint32_t val)
 61.1125 -{
 61.1126 -    PCIBus *s = opaque;
 61.1127 -
 61.1128 -    pci_data_write(s, addr & 7, val, 1);
 61.1129 -}
 61.1130 -
 61.1131 -static void pci_apb_writew (void *opaque, target_phys_addr_t addr,
 61.1132 -                                  uint32_t val)
 61.1133 -{
 61.1134 -    PCIBus *s = opaque;
 61.1135 -
 61.1136 -    pci_data_write(s, addr & 7, val, 2);
 61.1137 -}
 61.1138 -
 61.1139 -static void pci_apb_writel (void *opaque, target_phys_addr_t addr,
 61.1140 -                                uint32_t val)
 61.1141 -{
 61.1142 -    PCIBus *s = opaque;
 61.1143 -
 61.1144 -    pci_data_write(s, addr & 7, val, 4);
 61.1145 -}
 61.1146 -
 61.1147 -static uint32_t pci_apb_readb (void *opaque, target_phys_addr_t addr)
 61.1148 -{
 61.1149 -    PCIBus *s = opaque;
 61.1150 -    uint32_t val;
 61.1151 -
 61.1152 -    val = pci_data_read(s, addr & 7, 1);
 61.1153 -    return val;
 61.1154 -}
 61.1155 -
 61.1156 -static uint32_t pci_apb_readw (void *opaque, target_phys_addr_t addr)
 61.1157 -{
 61.1158 -    PCIBus *s = opaque;
 61.1159 -    uint32_t val;
 61.1160 -
 61.1161 -    val = pci_data_read(s, addr & 7, 2);
 61.1162 -    return val;
 61.1163 -}
 61.1164 -
 61.1165 -static uint32_t pci_apb_readl (void *opaque, target_phys_addr_t addr)
 61.1166 -{
 61.1167 -    PCIBus *s = opaque;
 61.1168 -    uint32_t val;
 61.1169 -
 61.1170 -    val = pci_data_read(s, addr, 4);
 61.1171 -    return val;
 61.1172 -}
 61.1173 -
 61.1174 -static CPUWriteMemoryFunc *pci_apb_write[] = {
 61.1175 -    &pci_apb_writeb,
 61.1176 -    &pci_apb_writew,
 61.1177 -    &pci_apb_writel,
 61.1178 -};
 61.1179 -
 61.1180 -static CPUReadMemoryFunc *pci_apb_read[] = {
 61.1181 -    &pci_apb_readb,
 61.1182 -    &pci_apb_readw,
 61.1183 -    &pci_apb_readl,
 61.1184 -};
 61.1185 -
 61.1186 -static void pci_apb_iowriteb (void *opaque, target_phys_addr_t addr,
 61.1187 -                                  uint32_t val)
 61.1188 -{
 61.1189 -    cpu_outb(NULL, addr & 0xffff, val);
 61.1190 -}
 61.1191 -
 61.1192 -static void pci_apb_iowritew (void *opaque, target_phys_addr_t addr,
 61.1193 -                                  uint32_t val)
 61.1194 -{
 61.1195 -    cpu_outw(NULL, addr & 0xffff, val);
 61.1196 -}
 61.1197 -
 61.1198 -static void pci_apb_iowritel (void *opaque, target_phys_addr_t addr,
 61.1199 -                                uint32_t val)
 61.1200 -{
 61.1201 -    cpu_outl(NULL, addr & 0xffff, val);
 61.1202 -}
 61.1203 -
 61.1204 -static uint32_t pci_apb_ioreadb (void *opaque, target_phys_addr_t addr)
 61.1205 -{
 61.1206 -    uint32_t val;
 61.1207 -
 61.1208 -    val = cpu_inb(NULL, addr & 0xffff);
 61.1209 -    return val;
 61.1210 -}
 61.1211 -
 61.1212 -static uint32_t pci_apb_ioreadw (void *opaque, target_phys_addr_t addr)
 61.1213 -{
 61.1214 -    uint32_t val;
 61.1215 -
 61.1216 -    val = cpu_inw(NULL, addr & 0xffff);
 61.1217 -    return val;
 61.1218 -}
 61.1219 -
 61.1220 -static uint32_t pci_apb_ioreadl (void *opaque, target_phys_addr_t addr)
 61.1221 -{
 61.1222 -    uint32_t val;
 61.1223 -
 61.1224 -    val = cpu_inl(NULL, addr & 0xffff);
 61.1225 -    return val;
 61.1226 -}
 61.1227 -
 61.1228 -static CPUWriteMemoryFunc *pci_apb_iowrite[] = {
 61.1229 -    &pci_apb_iowriteb,
 61.1230 -    &pci_apb_iowritew,
 61.1231 -    &pci_apb_iowritel,
 61.1232 -};
 61.1233 -
 61.1234 -static CPUReadMemoryFunc *pci_apb_ioread[] = {
 61.1235 -    &pci_apb_ioreadb,
 61.1236 -    &pci_apb_ioreadw,
 61.1237 -    &pci_apb_ioreadl,
 61.1238 -};
 61.1239 -
 61.1240 -PCIBus *pci_apb_init(target_ulong special_base, target_ulong mem_base)
 61.1241 -{
 61.1242 -    PCIBus *s;
 61.1243 -    PCIDevice *d;
 61.1244 -    int pci_mem_config, pci_mem_data, apb_config, pci_ioport;
 61.1245 -
 61.1246 -    /* Ultrasparc APB main bus */
 61.1247 -    s = pci_register_bus();
 61.1248 -    s->set_irq = pci_set_irq_simple;
 61.1249 -
 61.1250 -    pci_mem_config = cpu_register_io_memory(0, pci_apb_config_read,
 61.1251 -                                            pci_apb_config_write, s);
 61.1252 -    apb_config = cpu_register_io_memory(0, apb_config_read,
 61.1253 -					apb_config_write, s);
 61.1254 -    pci_mem_data = cpu_register_io_memory(0, pci_apb_read,
 61.1255 -                                          pci_apb_write, s);
 61.1256 -    pci_ioport = cpu_register_io_memory(0, pci_apb_ioread,
 61.1257 -                                          pci_apb_iowrite, s);
 61.1258 -
 61.1259 -    cpu_register_physical_memory(special_base + 0x2000ULL, 0x40, apb_config);
 61.1260 -    cpu_register_physical_memory(special_base + 0x1000000ULL, 0x10, pci_mem_config);
 61.1261 -    cpu_register_physical_memory(special_base + 0x2000000ULL, 0x10000, pci_ioport);
 61.1262 -    cpu_register_physical_memory(mem_base, 0x10000000, pci_mem_data); // XXX size should be 4G-prom
 61.1263 -
 61.1264 -    d = pci_register_device(s, "Advanced PCI Bus", sizeof(PCIDevice), 
 61.1265 -                            -1, NULL, NULL);
 61.1266 -    d->config[0x00] = 0x8e; // vendor_id : Sun
 61.1267 -    d->config[0x01] = 0x10;
 61.1268 -    d->config[0x02] = 0x00; // device_id
 61.1269 -    d->config[0x03] = 0xa0;
 61.1270 -    d->config[0x04] = 0x06; // command = bus master, pci mem
 61.1271 -    d->config[0x05] = 0x00;
 61.1272 -    d->config[0x06] = 0xa0; // status = fast back-to-back, 66MHz, no error
 61.1273 -    d->config[0x07] = 0x03; // status = medium devsel
 61.1274 -    d->config[0x08] = 0x00; // revision
 61.1275 -    d->config[0x09] = 0x00; // programming i/f
 61.1276 -    d->config[0x0A] = 0x00; // class_sub = pci host
 61.1277 -    d->config[0x0B] = 0x06; // class_base = PCI_bridge
 61.1278 -    d->config[0x0D] = 0x10; // latency_timer
 61.1279 -    d->config[0x0E] = 0x00; // header_type
 61.1280 -    return s;
 61.1281 -}
 61.1282 -
 61.1283  /***********************************************************/
 61.1284  /* generic PCI irq support */
 61.1285  
 61.1286 @@ -1547,34 +403,46 @@ PCIBus *pci_apb_init(target_ulong specia
 61.1287  void pci_set_irq(PCIDevice *pci_dev, int irq_num, int level)
 61.1288  {
 61.1289      PCIBus *bus = pci_dev->bus;
 61.1290 -    bus->set_irq(pci_dev, irq_num, level);
 61.1291 +    bus->set_irq(pci_dev, bus->irq_opaque, irq_num, level);
 61.1292  }
 61.1293  
 61.1294  /***********************************************************/
 61.1295  /* monitor info on PCI */
 61.1296  
 61.1297 +typedef struct {
 61.1298 +    uint16_t class;
 61.1299 +    const char *desc;
 61.1300 +} pci_class_desc;
 61.1301 +
 61.1302 +static pci_class_desc pci_class_descriptions[] = 
 61.1303 +{
 61.1304 +    { 0x0101, "IDE controller"},
 61.1305 +    { 0x0200, "Ethernet controller"},
 61.1306 +    { 0x0300, "VGA controller"},
 61.1307 +    { 0x0600, "Host bridge"},
 61.1308 +    { 0x0601, "ISA bridge"},
 61.1309 +    { 0x0604, "PCI bridge"},
 61.1310 +    { 0x0c03, "USB controller"},
 61.1311 +    { 0, NULL}
 61.1312 +};
 61.1313 +
 61.1314  static void pci_info_device(PCIDevice *d)
 61.1315  {
 61.1316      int i, class;
 61.1317      PCIIORegion *r;
 61.1318 +    pci_class_desc *desc;
 61.1319  
 61.1320      term_printf("  Bus %2d, device %3d, function %d:\n",
 61.1321             d->bus->bus_num, d->devfn >> 3, d->devfn & 7);
 61.1322      class = le16_to_cpu(*((uint16_t *)(d->config + PCI_CLASS_DEVICE)));
 61.1323      term_printf("    ");
 61.1324 -    switch(class) {
 61.1325 -    case 0x0101:
 61.1326 -        term_printf("IDE controller");
 61.1327 -        break;
 61.1328 -    case 0x0200:
 61.1329 -        term_printf("Ethernet controller");
 61.1330 -        break;
 61.1331 -    case 0x0300:
 61.1332 -        term_printf("VGA controller");
 61.1333 -        break;
 61.1334 -    default:
 61.1335 +    desc = pci_class_descriptions;
 61.1336 +    while (desc->desc && class != desc->class)
 61.1337 +        desc++;
 61.1338 +    if (desc->desc) {
 61.1339 +        term_printf("%s", desc->desc);
 61.1340 +    } else {
 61.1341          term_printf("Class %04x", class);
 61.1342 -        break;
 61.1343      }
 61.1344      term_printf(": PCI device %04x:%04x\n",
 61.1345             le16_to_cpu(*((uint16_t *)(d->config + PCI_VENDOR_ID))),
 61.1346 @@ -1598,7 +466,7 @@ static void pci_info_device(PCIDevice *d
 61.1347      }
 61.1348  }
 61.1349  
 61.1350 -void pci_info(void)
 61.1351 +void pci_for_each_device(void (*fn)(PCIDevice *d))
 61.1352  {
 61.1353      PCIBus *bus = first_bus;
 61.1354      PCIDevice *d;
 61.1355 @@ -1608,253 +476,14 @@ void pci_info(void)
 61.1356          for(devfn = 0; devfn < 256; devfn++) {
 61.1357              d = bus->devices[devfn];
 61.1358              if (d)
 61.1359 -                pci_info_device(d);
 61.1360 +                fn(d);
 61.1361          }
 61.1362      }
 61.1363  }
 61.1364  
 61.1365 -/***********************************************************/
 61.1366 -/* XXX: the following should be moved to the PC BIOS */
 61.1367 -
 61.1368 -static __attribute__((unused)) uint32_t isa_inb(uint32_t addr)
 61.1369 -{
 61.1370 -    return cpu_inb(NULL, addr);
 61.1371 -}
 61.1372 -
 61.1373 -static void isa_outb(uint32_t val, uint32_t addr)
 61.1374 -{
 61.1375 -    cpu_outb(NULL, addr, val);
 61.1376 -}
 61.1377 -
 61.1378 -static __attribute__((unused)) uint32_t isa_inw(uint32_t addr)
 61.1379 -{
 61.1380 -    return cpu_inw(NULL, addr);
 61.1381 -}
 61.1382 -
 61.1383 -static __attribute__((unused)) void isa_outw(uint32_t val, uint32_t addr)
 61.1384 -{
 61.1385 -    cpu_outw(NULL, addr, val);
 61.1386 -}
 61.1387 -
 61.1388 -static __attribute__((unused)) uint32_t isa_inl(uint32_t addr)
 61.1389 -{
 61.1390 -    return cpu_inl(NULL, addr);
 61.1391 -}
 61.1392 -
 61.1393 -static __attribute__((unused)) void isa_outl(uint32_t val, uint32_t addr)
 61.1394 -{
 61.1395 -    cpu_outl(NULL, addr, val);
 61.1396 -}
 61.1397 -
 61.1398 -static void pci_config_writel(PCIDevice *d, uint32_t addr, uint32_t val)
 61.1399 -{
 61.1400 -    PCIBus *s = d->bus;
 61.1401 -    s->config_reg = 0x80000000 | (s->bus_num << 16) | 
 61.1402 -        (d->devfn << 8) | addr;
 61.1403 -    pci_data_write(s, 0, val, 4);
 61.1404 -}
 61.1405 -
 61.1406 -static void pci_config_writew(PCIDevice *d, uint32_t addr, uint32_t val)
 61.1407 -{
 61.1408 -    PCIBus *s = d->bus;
 61.1409 -    s->config_reg = 0x80000000 | (s->bus_num << 16) | 
 61.1410 -        (d->devfn << 8) | (addr & ~3);
 61.1411 -    pci_data_write(s, addr & 3, val, 2);
 61.1412 -}
 61.1413 -
 61.1414 -static void pci_config_writeb(PCIDevice *d, uint32_t addr, uint32_t val)
 61.1415 -{
 61.1416 -    PCIBus *s = d->bus;
 61.1417 -    s->config_reg = 0x80000000 | (s->bus_num << 16) | 
 61.1418 -        (d->devfn << 8) | (addr & ~3);
 61.1419 -    pci_data_write(s, addr & 3, val, 1);
 61.1420 -}
 61.1421 -
 61.1422 -static __attribute__((unused)) uint32_t pci_config_readl(PCIDevice *d, uint32_t addr)
 61.1423 -{
 61.1424 -    PCIBus *s = d->bus;
 61.1425 -    s->config_reg = 0x80000000 | (s->bus_num << 16) | 
 61.1426 -        (d->devfn << 8) | addr;
 61.1427 -    return pci_data_read(s, 0, 4);
 61.1428 -}
 61.1429 -
 61.1430 -static uint32_t pci_config_readw(PCIDevice *d, uint32_t addr)
 61.1431 -{
 61.1432 -    PCIBus *s = d->bus;
 61.1433 -    s->config_reg = 0x80000000 | (s->bus_num << 16) | 
 61.1434 -        (d->devfn << 8) | (addr & ~3);
 61.1435 -    return pci_data_read(s, addr & 3, 2);
 61.1436 -}
 61.1437 -
 61.1438 -static uint32_t pci_config_readb(PCIDevice *d, uint32_t addr)
 61.1439 -{
 61.1440 -    PCIBus *s = d->bus;
 61.1441 -    s->config_reg = 0x80000000 | (s->bus_num << 16) | 
 61.1442 -        (d->devfn << 8) | (addr & ~3);
 61.1443 -    return pci_data_read(s, addr & 3, 1);
 61.1444 -}
 61.1445 -
 61.1446 -static uint32_t pci_bios_io_addr;
 61.1447 -static uint32_t pci_bios_mem_addr;
 61.1448 -/* host irqs corresponding to PCI irqs A-D */
 61.1449 -static uint8_t pci_irqs[4] = { 10, 11, 10, 11 };
 61.1450 -
 61.1451 -static void pci_set_io_region_addr(PCIDevice *d, int region_num, uint32_t addr)
 61.1452 -{
 61.1453 -    PCIIORegion *r;
 61.1454 -    uint16_t cmd;
 61.1455 -    uint32_t ofs;
 61.1456 -
 61.1457 -    if ( region_num == PCI_ROM_SLOT ) {
 61.1458 -        ofs = 0x30;
 61.1459 -    }else{
 61.1460 -        ofs = 0x10 + region_num * 4;
 61.1461 -    }
 61.1462 -
 61.1463 -    pci_config_writel(d, ofs, addr);
 61.1464 -    r = &d->io_regions[region_num];
 61.1465 -
 61.1466 -    /* enable memory mappings */
 61.1467 -    cmd = pci_config_readw(d, PCI_COMMAND);
 61.1468 -    if ( region_num == PCI_ROM_SLOT )
 61.1469 -        cmd |= 2;
 61.1470 -    else if (r->type & PCI_ADDRESS_SPACE_IO)
 61.1471 -        cmd |= 1;
 61.1472 -    else
 61.1473 -        cmd |= 2;
 61.1474 -    pci_config_writew(d, PCI_COMMAND, cmd);
 61.1475 -}
 61.1476 -
 61.1477 -static void pci_bios_init_device(PCIDevice *d)
 61.1478 +void pci_info(void)
 61.1479  {
 61.1480 -    int class;
 61.1481 -    PCIIORegion *r;
 61.1482 -    uint32_t *paddr;
 61.1483 -    int i, pin, pic_irq, vendor_id, device_id;
 61.1484 -
 61.1485 -    class = pci_config_readw(d, PCI_CLASS_DEVICE);
 61.1486 -    vendor_id = pci_config_readw(d, PCI_VENDOR_ID);
 61.1487 -    device_id = pci_config_readw(d, PCI_DEVICE_ID);
 61.1488 -    switch(class) {
 61.1489 -    case 0x0101:
 61.1490 -        if (vendor_id == 0x8086 && device_id == 0x7010) {
 61.1491 -            /* PIIX3 IDE */
 61.1492 -            pci_config_writew(d, 0x40, 0x8000); // enable IDE0
 61.1493 -            pci_config_writew(d, 0x42, 0x8000); // enable IDE1
 61.1494 -            goto default_map;
 61.1495 -        } else {
 61.1496 -            /* IDE: we map it as in ISA mode */
 61.1497 -            pci_set_io_region_addr(d, 0, 0x1f0);
 61.1498 -            pci_set_io_region_addr(d, 1, 0x3f4);
 61.1499 -            pci_set_io_region_addr(d, 2, 0x170);
 61.1500 -            pci_set_io_region_addr(d, 3, 0x374);
 61.1501 -        }
 61.1502 -        break;
 61.1503 -       case 0x0680:
 61.1504 -       if (vendor_id == 0x8086 && device_id == 0x7113) {
 61.1505 -          // PIIX4 ACPI PM 
 61.1506 -        pci_config_writew(d, 0x20, 0x0000); // NO smb bus IO enable in PIIX4
 61.1507 -        pci_config_writew(d, 0x22, 0x0000); 
 61.1508 -        goto default_map;
 61.1509 - 	}
 61.1510 -         break;
 61.1511 -
 61.1512 -    case 0x0300:
 61.1513 -        if (vendor_id != 0x1234)
 61.1514 -            goto default_map;
 61.1515 -        /* VGA: map frame buffer to default Bochs VBE address */
 61.1516 -        pci_set_io_region_addr(d, 0, 0xE0000000);
 61.1517 -        break;
 61.1518 -
 61.1519 -    case 0x0800:
 61.1520 -        /* PIC */
 61.1521 -        vendor_id = pci_config_readw(d, PCI_VENDOR_ID);
 61.1522 -        device_id = pci_config_readw(d, PCI_DEVICE_ID);
 61.1523 -        if (vendor_id == 0x1014) {
 61.1524 -            /* IBM */
 61.1525 -            if (device_id == 0x0046 || device_id == 0xFFFF) {
 61.1526 -                /* MPIC & MPIC2 */
 61.1527 -                pci_set_io_region_addr(d, 0, 0x80800000 + 0x00040000);
 61.1528 -            }
 61.1529 -        }
 61.1530 -        break;
 61.1531 -    case 0xff00:
 61.1532 -        if (vendor_id == 0x0106b &&
 61.1533 -            (device_id == 0x0017 || device_id == 0x0022)) {
 61.1534 -            /* macio bridge */
 61.1535 -            pci_set_io_region_addr(d, 0, 0x80800000);
 61.1536 -        }
 61.1537 -        break;
 61.1538 -    default:
 61.1539 -    default_map:
 61.1540 -        /* default memory mappings */
 61.1541 -        for(i = 0; i < PCI_NUM_REGIONS; i++) {
 61.1542 -            r = &d->io_regions[i];
 61.1543 -            if (r->size) {
 61.1544 -                if (r->type & PCI_ADDRESS_SPACE_IO)
 61.1545 -                    paddr = &pci_bios_io_addr;
 61.1546 -                else
 61.1547 -                    paddr = &pci_bios_mem_addr;
 61.1548 -                *paddr = (*paddr + r->size - 1) & ~(r->size - 1);
 61.1549 -                pci_set_io_region_addr(d, i, *paddr);
 61.1550 -                *paddr += r->size;
 61.1551 -            }
 61.1552 -        }
 61.1553 -        break;
 61.1554 -    }
 61.1555 -
 61.1556 -    /* map the interrupt */
 61.1557 -    pin = pci_config_readb(d, PCI_INTERRUPT_PIN);
 61.1558 -    if (pin != 0) {
 61.1559 -        pin = pci_slot_get_pirq(d, pin - 1);
 61.1560 -        pic_irq = pci_irqs[pin];
 61.1561 -        pci_config_writeb(d, PCI_INTERRUPT_LINE, pic_irq);
 61.1562 -    }
 61.1563 -    if (class== 0x0680&& vendor_id == 0x8086 && device_id == 0x7113) {
 61.1564 -         // PIIX4 ACPI PM
 61.1565 -       pci_config_writew(d, 0x20, 0x0000); // NO smb bus IO enable in PIIX4
 61.1566 -       pci_config_writew(d, 0x22, 0x0000);
 61.1567 -       pci_config_writew(d, 0x3c, 0x0009); // Hardcodeed IRQ9
 61.1568 -       pci_config_writew(d, 0x3d, 0x0001);
 61.1569 -    }
 61.1570 -}
 61.1571 -
 61.1572 -/*
 61.1573 - * This function initializes the PCI devices as a normal PCI BIOS
 61.1574 - * would do. It is provided just in case the BIOS has no support for
 61.1575 - * PCI.
 61.1576 - */
 61.1577 -void pci_bios_init(void)
 61.1578 -{
 61.1579 -    PCIBus *bus;
 61.1580 -    PCIDevice *d;
 61.1581 -    int devfn, i, irq;
 61.1582 -    uint8_t elcr[2];
 61.1583 -
 61.1584 -    pci_bios_io_addr = 0xc000;
 61.1585 -    pci_bios_mem_addr = 0xf0000000;
 61.1586 -
 61.1587 -    /* activate IRQ mappings */
 61.1588 -    elcr[0] = 0x00;
 61.1589 -    elcr[1] = 0x00;
 61.1590 -    for(i = 0; i < 4; i++) {
 61.1591 -        irq = pci_irqs[i];
 61.1592 -        /* set to trigger level */
 61.1593 -        elcr[irq >> 3] |= (1 << (irq & 7));
 61.1594 -        /* activate irq remapping in PIIX */
 61.1595 -        pci_config_writeb((PCIDevice *)piix3_state, 0x60 + i, irq);
 61.1596 -    }
 61.1597 -    isa_outb(elcr[0], 0x4d0);
 61.1598 -    isa_outb(elcr[1], 0x4d1);
 61.1599 -
 61.1600 -    bus = first_bus;
 61.1601 -    if (bus) {
 61.1602 -        for(devfn = 0; devfn < 256; devfn++) {
 61.1603 -            d = bus->devices[devfn];
 61.1604 -            if (d)
 61.1605 -                pci_bios_init_device(d);
 61.1606 -        }
 61.1607 -    }
 61.1608 +    pci_for_each_device(pci_info_device);
 61.1609  }
 61.1610  
 61.1611  /* Initialize a PCI NIC.  */
 61.1612 @@ -1864,6 +493,8 @@ void pci_nic_init(PCIBus *bus, NICInfo *
 61.1613          pci_ne2000_init(bus, nd);
 61.1614      } else if (strcmp(nd->model, "rtl8139") == 0) {
 61.1615          pci_rtl8139_init(bus, nd);
 61.1616 +    } else if (strcmp(nd->model, "pcnet") == 0) {
 61.1617 +        pci_pcnet_init(bus, nd);
 61.1618      } else {
 61.1619          fprintf(stderr, "qemu: Unsupported NIC: %s\n", nd->model);
 61.1620          exit (1);
    62.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    62.2 +++ b/tools/ioemu/hw/pci_host.h	Mon Aug 07 18:25:30 2006 +0100
    62.3 @@ -0,0 +1,93 @@
    62.4 +/*
    62.5 + * QEMU Common PCI Host bridge configuration data space access routines.
    62.6 + *
    62.7 + * Copyright (c) 2006 Fabrice Bellard
    62.8 + * 
    62.9 + * Permission is hereby granted, free of charge, to any person obtaining a copy
   62.10 + * of this software and associated documentation files (the "Software"), to deal
   62.11 + * in the Software without restriction, including without limitation the rights
   62.12 + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
   62.13 + * copies of the Software, and to permit persons to whom the Software is
   62.14 + * furnished to do so, subject to the following conditions:
   62.15 + *
   62.16 + * The above copyright notice and this permission notice shall be included in
   62.17 + * all copies or substantial portions of the Software.
   62.18 + *
   62.19 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   62.20 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   62.21 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
   62.22 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   62.23 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
   62.24 + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
   62.25 + * THE SOFTWARE.
   62.26 + */
   62.27 +
   62.28 +/* Worker routines for a PCI host controller that uses an {address,data}
   62.29 +   register pair to access PCI configuration space.  */
   62.30 +
   62.31 +typedef struct {
   62.32 +    uint32_t config_reg;
   62.33 +    PCIBus *bus;
   62.34 +} PCIHostState;
   62.35 +
   62.36 +static void pci_host_data_writeb(void* opaque, pci_addr_t addr, uint32_t val)
   62.37 +{
   62.38 +    PCIHostState *s = opaque;
   62.39 +    if (s->config_reg & (1u << 31))
   62.40 +        pci_data_write(s->bus, s->config_reg | (addr & 3), val, 1);
   62.41 +}
   62.42 +
   62.43 +static void pci_host_data_writew(void* opaque, pci_addr_t addr, uint32_t val)
   62.44 +{
   62.45 +    PCIHostState *s = opaque;
   62.46 +#ifdef TARGET_WORDS_BIGENDIAN
   62.47 +    val = bswap16(val);
   62.48 +#endif
   62.49 +    if (s->config_reg & (1u << 31))
   62.50 +        pci_data_write(s->bus, s->config_reg | (addr & 3), val, 2);
   62.51 +}
   62.52 +
   62.53 +static void pci_host_data_writel(void* opaque, pci_addr_t addr, uint32_t val)
   62.54 +{
   62.55 +    PCIHostState *s = opaque;
   62.56 +#ifdef TARGET_WORDS_BIGENDIAN
   62.57 +    val = bswap32(val);
   62.58 +#endif
   62.59 +    if (s->config_reg & (1u << 31))
   62.60 +        pci_data_write(s->bus, s->config_reg, val, 4);
   62.61 +}
   62.62 +
   62.63 +static uint32_t pci_host_data_readb(void* opaque, pci_addr_t addr)
   62.64 +{
   62.65 +    PCIHostState *s = opaque;
   62.66 +    if (!(s->config_reg & (1 << 31)))