ia64/xen-unstable
changeset 10985:08a11694b109
[qemu] Update ioemu to qemu 0.8.2.
Signed-off-by: Christian Limpach <Christian.Limpach@xensource.com>
Signed-off-by: Christian Limpach <Christian.Limpach@xensource.com>
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 +static void do_cmd(ESPState *s, uint8_t *buf) 52.295 +{ 52.296 + int32_t datalen; 52.297 + int lun; 52.298 52.299 - if (bdrv_get_type_hint(s->bd[target]) == BDRV_TYPE_CDROM) { 52.300 - offset = ((buf[3] << 24) | (buf[4] << 16) | (buf[5] << 8) | buf[6]) * 4; 52.301 - len = ((buf[8] << 8) | buf[9]) * 4; 52.302 - s->ti_size = len * 2048; 52.303 - } else { 52.304 - offset = (buf[3] << 24) | (buf[4] << 16) | (buf[5] << 8) | buf[6]; 52.305 - len = (buf[8] << 8) | buf[9]; 52.306 - s->ti_size = len * 512; 52.307 - } 52.308 - DPRINTF("Read (10) (offset %lld len %lld)\n", offset, len); 52.309 - if (s->ti_size > TI_BUFSZ) { 52.310 - DPRINTF("size too large %d\n", s->ti_size); 52.311 - } 52.312 - bdrv_read(s->bd[target], offset, s->ti_buf, len); 52.313 - // XXX error handling 52.314 - s->ti_dir = 1; 52.315 - break; 52.316 - } 52.317 - case 0x2a: 52.318 - { 52.319 - int64_t offset, len; 52.320 - 52.321 - if (bdrv_get_type_hint(s->bd[target]) == BDRV_TYPE_CDROM) { 52.322 - offset = ((buf[3] << 24) | (buf[4] << 16) | (buf[5] << 8) | buf[6]) * 4; 52.323 - len = ((buf[8] << 8) | buf[9]) * 4; 52.324 - s->ti_size = len * 2048; 52.325 - } else { 52.326 - offset = (buf[3] << 24) | (buf[4] << 16) | (buf[5] << 8) | buf[6]; 52.327 - len = (buf[8] << 8) | buf[9]; 52.328 - s->ti_size = len * 512; 52.329 - } 52.330 - DPRINTF("Write (10) (offset %lld len %lld)\n", offset, len); 52.331 - if (s->ti_size > TI_BUFSZ) { 52.332 - DPRINTF("size too large %d\n", s->ti_size); 52.333 - } 52.334 - s->dma_cb = esp_write_dma_cb; 52.335 - s->offset = offset; 52.336 - s->len = len; 52.337 - s->target = target; 52.338 - // XXX error handling 52.339 - s->ti_dir = 0; 52.340 - break; 52.341 - } 52.342 - case 0x43: 52.343 - { 52.344 - int start_track, format, msf, len; 52.345 - 52.346 - msf = buf[2] & 2; 52.347 - format = buf[3] & 0xf; 52.348 - start_track = buf[7]; 52.349 - bdrv_get_geometry(s->bd[target], &nb_sectors); 52.350 - DPRINTF("Read TOC (track %d format %d msf %d)\n", start_track, format, msf >> 1); 52.351 - switch(format) { 52.352 - case 0: 52.353 - len = cdrom_read_toc(nb_sectors, buf, msf, start_track); 52.354 - if (len < 0) 52.355 - goto error_cmd; 52.356 - s->ti_size = len; 52.357 - break; 52.358 - case 1: 52.359 - /* multi session : only a single session defined */ 52.360 - memset(buf, 0, 12); 52.361 - buf[1] = 0x0a; 52.362 - buf[2] = 0x01; 52.363 - buf[3] = 0x01; 52.364 - s->ti_size = 12; 52.365 - break; 52.366 - case 2: 52.367 - len = cdrom_read_toc_raw(nb_sectors, buf, msf, start_track); 52.368 - if (len < 0) 52.369 - goto error_cmd; 52.370 - s->ti_size = len; 52.371 - break; 52.372 - default: 52.373 - error_cmd: 52.374 - DPRINTF("Read TOC error\n"); 52.375 - // XXX error handling 52.376 - break; 52.377 - } 52.378 - s->ti_dir = 1; 52.379 - break; 52.380 + DPRINTF("do_cmd: busid 0x%x\n", buf[0]); 52.381 + lun = buf[0] & 7; 52.382 + datalen = scsi_send_command(s->current_dev, 0, &buf[1], lun); 52.383 + if (datalen == 0) { 52.384 + s->ti_size = 0; 52.385 + } else { 52.386 + s->rregs[4] = STAT_IN | STAT_TC; 52.387 + if (datalen > 0) { 52.388 + s->rregs[4] |= STAT_DI; 52.389 + s->ti_size = datalen; 52.390 + } else { 52.391 + s->rregs[4] |= STAT_DO; 52.392 + s->ti_size = -datalen; 52.393 } 52.394 - default: 52.395 - DPRINTF("Unknown SCSI command (%2.2x)\n", buf[1]); 52.396 - break; 52.397 } 52.398 - s->rregs[4] = STAT_IN | STAT_TC | STAT_DI; 52.399 s->rregs[5] = INTR_BS | INTR_FC; 52.400 s->rregs[6] = SEQ_CD; 52.401 s->espdmaregs[0] |= DMA_INTR; 52.402 pic_set_irq(s->irq, 1); 52.403 } 52.404 52.405 -static void dma_write(ESPState *s, const uint8_t *buf, uint32_t len) 52.406 +static void handle_satn(ESPState *s) 52.407 +{ 52.408 + uint8_t buf[32]; 52.409 + int len; 52.410 + 52.411 + len = get_cmd(s, buf); 52.412 + if (len) 52.413 + do_cmd(s, buf); 52.414 +} 52.415 + 52.416 +static void handle_satn_stop(ESPState *s) 52.417 { 52.418 - uint32_t dmaptr, dmalen; 52.419 + s->cmdlen = get_cmd(s, s->cmdbuf); 52.420 + if (s->cmdlen) { 52.421 + DPRINTF("Set ATN & Stop: cmdlen %d\n", s->cmdlen); 52.422 + s->do_cmd = 1; 52.423 + s->espdmaregs[1] += s->cmdlen; 52.424 + s->rregs[4] = STAT_IN | STAT_TC | STAT_CD; 52.425 + s->rregs[5] = INTR_BS | INTR_FC; 52.426 + s->rregs[6] = SEQ_CD; 52.427 + s->espdmaregs[0] |= DMA_INTR; 52.428 + pic_set_irq(s->irq, 1); 52.429 + } 52.430 +} 52.431 52.432 - dmalen = s->wregs[0] | (s->wregs[1] << 8); 52.433 - DPRINTF("Transfer status len %d\n", dmalen); 52.434 +static void write_response(ESPState *s) 52.435 +{ 52.436 + uint32_t dmaptr; 52.437 + 52.438 + DPRINTF("Transfer status (sense=%d)\n", s->sense); 52.439 + s->ti_buf[0] = s->sense; 52.440 + s->ti_buf[1] = 0; 52.441 if (s->dma) { 52.442 dmaptr = iommu_translate(s->espdmaregs[1]); 52.443 - DPRINTF("DMA Direction: %c\n", s->espdmaregs[0] & 0x100? 'w': 'r'); 52.444 - cpu_physical_memory_write(dmaptr, buf, len); 52.445 + DPRINTF("DMA Direction: %c\n", 52.446 + s->espdmaregs[0] & DMA_WRITE_MEM ? 'w': 'r'); 52.447 + cpu_physical_memory_write(dmaptr, s->ti_buf, 2); 52.448 s->rregs[4] = STAT_IN | STAT_TC | STAT_ST; 52.449 s->rregs[5] = INTR_BS | INTR_FC; 52.450 s->rregs[6] = SEQ_CD; 52.451 } else { 52.452 - memcpy(s->ti_buf, buf, len); 52.453 - s->ti_size = dmalen; 52.454 + s->ti_size = 2; 52.455 s->ti_rptr = 0; 52.456 s->ti_wptr = 0; 52.457 - s->rregs[7] = dmalen; 52.458 + s->rregs[7] = 2; 52.459 } 52.460 s->espdmaregs[0] |= DMA_INTR; 52.461 pic_set_irq(s->irq, 1); 52.462 52.463 } 52.464 52.465 -static const uint8_t okbuf[] = {0, 0}; 52.466 +static void esp_command_complete(void *opaque, uint32_t tag, int sense) 52.467 +{ 52.468 + ESPState *s = (ESPState *)opaque; 52.469 + 52.470 + DPRINTF("SCSI Command complete\n"); 52.471 + if (s->ti_size != 0) 52.472 + DPRINTF("SCSI command completed unexpectedly\n"); 52.473 + s->ti_size = 0; 52.474 + if (sense) 52.475 + DPRINTF("Command failed\n"); 52.476 + s->sense = sense; 52.477 + s->rregs[4] = STAT_IN | STAT_TC | STAT_ST; 52.478 +} 52.479 52.480 static void handle_ti(ESPState *s) 52.481 { 52.482 - uint32_t dmaptr, dmalen; 52.483 + uint32_t dmaptr, dmalen, minlen, len, from, to; 52.484 unsigned int i; 52.485 + int to_device; 52.486 + uint8_t buf[TARGET_PAGE_SIZE]; 52.487 52.488 dmalen = s->wregs[0] | (s->wregs[1] << 8); 52.489 - DPRINTF("Transfer Information len %d\n", dmalen); 52.490 + if (dmalen==0) { 52.491 + dmalen=0x10000; 52.492 + } 52.493 + 52.494 + if (s->do_cmd) 52.495 + minlen = (dmalen < 32) ? dmalen : 32; 52.496 + else 52.497 + minlen = (dmalen < s->ti_size) ? dmalen : s->ti_size; 52.498 + DPRINTF("Transfer Information len %d\n", minlen); 52.499 if (s->dma) { 52.500 dmaptr = iommu_translate(s->espdmaregs[1]); 52.501 - DPRINTF("DMA Direction: %c, addr 0x%8.8x\n", s->espdmaregs[0] & 0x100? 'w': 'r', dmaptr); 52.502 - for (i = 0; i < s->ti_size; i++) { 52.503 + /* Check if the transfer writes to to reads from the device. */ 52.504 + to_device = (s->espdmaregs[0] & DMA_WRITE_MEM) == 0; 52.505 + DPRINTF("DMA Direction: %c, addr 0x%8.8x %08x\n", 52.506 + to_device ? 'r': 'w', dmaptr, s->ti_size); 52.507 + from = s->espdmaregs[1]; 52.508 + to = from + minlen; 52.509 + for (i = 0; i < minlen; i += len, from += len) { 52.510 dmaptr = iommu_translate(s->espdmaregs[1] + i); 52.511 - if (s->ti_dir) 52.512 - cpu_physical_memory_write(dmaptr, &s->ti_buf[i], 1); 52.513 - else 52.514 - cpu_physical_memory_read(dmaptr, &s->ti_buf[i], 1); 52.515 - } 52.516 - if (s->dma_cb) { 52.517 - s->dma_cb(s, s->espdmaregs[1], dmalen); 52.518 - s->dma_cb = NULL; 52.519 + if ((from & TARGET_PAGE_MASK) != (to & TARGET_PAGE_MASK)) { 52.520 + len = TARGET_PAGE_SIZE - (from & ~TARGET_PAGE_MASK); 52.521 + } else { 52.522 + len = to - from; 52.523 + } 52.524 + DPRINTF("DMA address p %08x v %08x len %08x, from %08x, to %08x\n", dmaptr, s->espdmaregs[1] + i, len, from, to); 52.525 + s->ti_size -= len; 52.526 + if (s->do_cmd) { 52.527 + DPRINTF("command len %d + %d\n", s->cmdlen, len); 52.528 + cpu_physical_memory_read(dmaptr, &s->cmdbuf[s->cmdlen], len); 52.529 + s->ti_size = 0; 52.530 + s->cmdlen = 0; 52.531 + s->do_cmd = 0; 52.532 + do_cmd(s, s->cmdbuf); 52.533 + return; 52.534 + } else { 52.535 + if (to_device) { 52.536 + cpu_physical_memory_read(dmaptr, buf, len); 52.537 + scsi_write_data(s->current_dev, buf, len); 52.538 + } else { 52.539 + scsi_read_data(s->current_dev, buf, len); 52.540 + cpu_physical_memory_write(dmaptr, buf, len); 52.541 + } 52.542 + } 52.543 } 52.544 - s->rregs[4] = STAT_IN | STAT_TC | STAT_ST; 52.545 - s->rregs[5] = INTR_BS; 52.546 + if (s->ti_size) { 52.547 + s->rregs[4] = STAT_IN | STAT_TC | (to_device ? STAT_DO : STAT_DI); 52.548 + } 52.549 + s->rregs[5] = INTR_BS; 52.550 s->rregs[6] = 0; 52.551 + s->rregs[7] = 0; 52.552 s->espdmaregs[0] |= DMA_INTR; 52.553 - } else { 52.554 - s->ti_size = dmalen; 52.555 - s->ti_rptr = 0; 52.556 - s->ti_wptr = 0; 52.557 - s->rregs[7] = dmalen; 52.558 - } 52.559 + } else if (s->do_cmd) { 52.560 + DPRINTF("command len %d\n", s->cmdlen); 52.561 + s->ti_size = 0; 52.562 + s->cmdlen = 0; 52.563 + s->do_cmd = 0; 52.564 + do_cmd(s, s->cmdbuf); 52.565 + return; 52.566 + } 52.567 pic_set_irq(s->irq, 1); 52.568 } 52.569 52.570 @@ -484,9 +289,8 @@ static void esp_reset(void *opaque) 52.571 s->ti_size = 0; 52.572 s->ti_rptr = 0; 52.573 s->ti_wptr = 0; 52.574 - s->ti_dir = 0; 52.575 s->dma = 0; 52.576 - s->dma_cb = NULL; 52.577 + s->do_cmd = 0; 52.578 } 52.579 52.580 static uint32_t esp_mem_readb(void *opaque, target_phys_addr_t addr) 52.581 @@ -501,7 +305,12 @@ static uint32_t esp_mem_readb(void *opaq 52.582 // FIFO 52.583 if (s->ti_size > 0) { 52.584 s->ti_size--; 52.585 - s->rregs[saddr] = s->ti_buf[s->ti_rptr++]; 52.586 + if ((s->rregs[4] & 6) == 0) { 52.587 + /* Data in/out. */ 52.588 + scsi_read_data(s->current_dev, &s->rregs[2], 0); 52.589 + } else { 52.590 + s->rregs[2] = s->ti_buf[s->ti_rptr++]; 52.591 + } 52.592 pic_set_irq(s->irq, 1); 52.593 } 52.594 if (s->ti_size == 0) { 52.595 @@ -536,8 +345,17 @@ static void esp_mem_writeb(void *opaque, 52.596 break; 52.597 case 2: 52.598 // FIFO 52.599 - s->ti_size++; 52.600 - s->ti_buf[s->ti_wptr++] = val & 0xff; 52.601 + if (s->do_cmd) { 52.602 + s->cmdbuf[s->cmdlen++] = val & 0xff; 52.603 + } else if ((s->rregs[4] & 6) == 0) { 52.604 + uint8_t buf; 52.605 + buf = val & 0xff; 52.606 + s->ti_size--; 52.607 + scsi_write_data(s->current_dev, &buf, 0); 52.608 + } else { 52.609 + s->ti_size++; 52.610 + s->ti_buf[s->ti_wptr++] = val & 0xff; 52.611 + } 52.612 break; 52.613 case 3: 52.614 s->rregs[saddr] = val; 52.615 @@ -574,11 +392,11 @@ static void esp_mem_writeb(void *opaque, 52.616 break; 52.617 case 0x11: 52.618 DPRINTF("Initiator Command Complete Sequence (%2.2x)\n", val); 52.619 - dma_write(s, okbuf, 2); 52.620 + write_response(s); 52.621 break; 52.622 case 0x12: 52.623 DPRINTF("Message Accepted (%2.2x)\n", val); 52.624 - dma_write(s, okbuf, 2); 52.625 + write_response(s); 52.626 s->rregs[5] = INTR_DC; 52.627 s->rregs[6] = 0; 52.628 break; 52.629 @@ -586,11 +404,12 @@ static void esp_mem_writeb(void *opaque, 52.630 DPRINTF("Set ATN (%2.2x)\n", val); 52.631 break; 52.632 case 0x42: 52.633 + DPRINTF("Set ATN (%2.2x)\n", val); 52.634 handle_satn(s); 52.635 break; 52.636 case 0x43: 52.637 DPRINTF("Set ATN & stop (%2.2x)\n", val); 52.638 - handle_satn(s); 52.639 + handle_satn_stop(s); 52.640 break; 52.641 default: 52.642 DPRINTF("Unhandled ESP command (%2.2x)\n", val); 52.643 @@ -660,7 +479,7 @@ static void espdma_mem_writel(void *opaq 52.644 val |= DMA_VER; 52.645 break; 52.646 case 1: 52.647 - s->espdmaregs[0] = DMA_LOADED; 52.648 + s->espdmaregs[0] |= DMA_LOADED; 52.649 break; 52.650 default: 52.651 break; 52.652 @@ -693,7 +512,6 @@ static void esp_save(QEMUFile *f, void * 52.653 qemu_put_be32s(f, &s->ti_size); 52.654 qemu_put_be32s(f, &s->ti_rptr); 52.655 qemu_put_be32s(f, &s->ti_wptr); 52.656 - qemu_put_be32s(f, &s->ti_dir); 52.657 qemu_put_buffer(f, s->ti_buf, TI_BUFSZ); 52.658 qemu_put_be32s(f, &s->dma); 52.659 } 52.660 @@ -714,7 +532,6 @@ static int esp_load(QEMUFile *f, void *o 52.661 qemu_get_be32s(f, &s->ti_size); 52.662 qemu_get_be32s(f, &s->ti_rptr); 52.663 qemu_get_be32s(f, &s->ti_wptr); 52.664 - qemu_get_be32s(f, &s->ti_dir); 52.665 qemu_get_buffer(f, s->ti_buf, TI_BUFSZ); 52.666 qemu_get_be32s(f, &s->dma); 52.667 52.668 @@ -725,6 +542,7 @@ void esp_init(BlockDriverState **bd, int 52.669 { 52.670 ESPState *s; 52.671 int esp_io_memory, espdma_io_memory; 52.672 + int i; 52.673 52.674 s = qemu_mallocz(sizeof(ESPState)); 52.675 if (!s) 52.676 @@ -743,5 +561,11 @@ void esp_init(BlockDriverState **bd, int 52.677 52.678 register_savevm("esp", espaddr, 1, esp_save, esp_load, s); 52.679 qemu_register_reset(esp_reset, s); 52.680 + for (i = 0; i < MAX_DISKS; i++) { 52.681 + if (bs_table[i]) { 52.682 + s->scsi_dev[i] = 52.683 + scsi_disk_init(bs_table[i], esp_command_complete, s); 52.684 + } 52.685 + } 52.686 } 52.687
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