update qemu to 0.8.2, from brad@
See http://fabrice.bellard.free.fr/qemu/changelog.html for details.
This commit is contained in:
parent
4c8fe3687b
commit
bb1d809e7d
@ -1,10 +1,11 @@
|
||||
# $OpenBSD: Makefile,v 1.15 2006/06/08 14:33:38 todd Exp $
|
||||
# $OpenBSD: Makefile,v 1.16 2006/12/22 17:31:45 todd Exp $
|
||||
|
||||
# no success building on other archs yet
|
||||
ONLY_FOR_ARCHS= amd64 arm i386 powerpc
|
||||
|
||||
COMMENT= "multi system emulator"
|
||||
DISTNAME= qemu-0.8.1
|
||||
|
||||
DISTNAME= qemu-0.8.2
|
||||
CATEGORIES= emulators
|
||||
|
||||
HOMEPAGE= http://fabrice.bellard.free.fr/qemu/
|
||||
|
@ -1,4 +1,4 @@
|
||||
MD5 (qemu-0.8.1.tar.gz) = 67d924324a5ab79d017bd97a1e767285
|
||||
RMD160 (qemu-0.8.1.tar.gz) = 04d163d4792bbea39fc0b1e52af124cdb7e907dc
|
||||
SHA1 (qemu-0.8.1.tar.gz) = 72c943c24bed6aa066dcc3012b198c20f04aef30
|
||||
SIZE (qemu-0.8.1.tar.gz) = 1623264
|
||||
MD5 (qemu-0.8.2.tar.gz) = 5b3a89eb2f256a8a6f3bb07f7b3f1b07
|
||||
RMD160 (qemu-0.8.2.tar.gz) = 715c24997330352aa675cd7279731cec251f833a
|
||||
SHA1 (qemu-0.8.2.tar.gz) = d775239a545e7d0c5b677660a2122df590afde6d
|
||||
SIZE (qemu-0.8.2.tar.gz) = 1810909
|
||||
|
@ -1,16 +1,7 @@
|
||||
$OpenBSD: patch-Makefile,v 1.4 2006/06/08 14:33:38 todd Exp $
|
||||
--- Makefile.orig Wed May 3 15:32:58 2006
|
||||
+++ Makefile Thu May 11 20:45:07 2006
|
||||
@@ -19,7 +19,7 @@ endif
|
||||
|
||||
all: dyngen$(EXESUF) $(TOOLS) $(DOCS)
|
||||
for d in $(TARGET_DIRS); do \
|
||||
- $(MAKE) -C $$d $@ || exit 1 ; \
|
||||
+ $(MAKE) -C $$d $@ || exit $$? ; \
|
||||
done
|
||||
|
||||
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
|
||||
@@ -34,13 +34,13 @@ clean:
|
||||
$OpenBSD: patch-Makefile,v 1.5 2006/12/22 17:31:45 todd Exp $
|
||||
--- Makefile.orig Sat Jul 22 13:23:34 2006
|
||||
+++ Makefile Sun Nov 12 17:10:10 2006
|
||||
@@ -44,7 +44,7 @@ clean:
|
||||
rm -f *.o *.a $(TOOLS) dyngen$(EXESUF) TAGS *.pod *~ */*~
|
||||
$(MAKE) -C tests clean
|
||||
for d in $(TARGET_DIRS); do \
|
||||
@ -19,60 +10,7 @@ $OpenBSD: patch-Makefile,v 1.4 2006/06/08 14:33:38 todd Exp $
|
||||
done
|
||||
|
||||
distclean: clean
|
||||
rm -f config-host.mak config-host.h $(DOCS)
|
||||
for d in $(TARGET_DIRS); do \
|
||||
- rm -rf $$d || exit 1 ; \
|
||||
+ rm -rf $$d || exit $$? ; \
|
||||
done
|
||||
|
||||
KEYMAPS=da en-gb et fr fr-ch is lt modifiers no pt-br sv \
|
||||
@@ -48,29 +48,34 @@ ar de en-us fi fr-be hr
|
||||
common de-ch es fo fr-ca hu ja mk nl-be pt sl tr
|
||||
|
||||
install-doc: $(DOCS)
|
||||
- mkdir -p "$(DESTDIR)$(docdir)"
|
||||
- $(INSTALL) -m 644 qemu-doc.html qemu-tech.html "$(DESTDIR)$(docdir)"
|
||||
+ mkdir -p "$(docdir)"
|
||||
+ $(INSTALL) -m 644 qemu-doc.html qemu-tech.html "$(docdir)"
|
||||
ifndef CONFIG_WIN32
|
||||
- mkdir -p "$(DESTDIR)$(mandir)/man1"
|
||||
- $(INSTALL) qemu.1 qemu-img.1 "$(DESTDIR)$(mandir)/man1"
|
||||
+ mkdir -p "$(mandir)/man1"
|
||||
+ $(INSTALL) qemu.1 qemu-img.1 "$(mandir)/man1"
|
||||
endif
|
||||
|
||||
+bindir=${PREFIX}/bin
|
||||
+docdir=${PREFIX}/share/doc/qemu
|
||||
+datadir=${PREFIX}/share/qemu
|
||||
+mandir=${PREFIX}/man
|
||||
+
|
||||
install: all $(if $(BUILD_DOCS),install-doc)
|
||||
- mkdir -p "$(DESTDIR)$(bindir)"
|
||||
- $(INSTALL) -m 755 -s $(TOOLS) "$(DESTDIR)$(bindir)"
|
||||
- mkdir -p "$(DESTDIR)$(datadir)"
|
||||
+ mkdir -p "$(bindir)"
|
||||
+ $(INSTALL) -m 755 -s $(TOOLS) "$(bindir)"
|
||||
+ mkdir -p "$(datadir)"
|
||||
for x in bios.bin vgabios.bin vgabios-cirrus.bin ppc_rom.bin \
|
||||
video.x proll.elf linux_boot.bin; do \
|
||||
- $(INSTALL) -m 644 $(SRC_PATH)/pc-bios/$$x "$(DESTDIR)$(datadir)"; \
|
||||
+ $(INSTALL) -m 644 $(SRC_PATH)/pc-bios/$$x "$(datadir)"; \
|
||||
done
|
||||
ifndef CONFIG_WIN32
|
||||
- mkdir -p "$(DESTDIR)$(datadir)/keymaps"
|
||||
+ mkdir -p "$(datadir)/keymaps"
|
||||
for x in $(KEYMAPS); do \
|
||||
- $(INSTALL) -m 644 $(SRC_PATH)/keymaps/$$x "$(DESTDIR)$(datadir)/keymaps"; \
|
||||
+ $(INSTALL) -m 644 $(SRC_PATH)/keymaps/$$x "$(datadir)/keymaps"; \
|
||||
done
|
||||
endif
|
||||
for d in $(TARGET_DIRS); do \
|
||||
- $(MAKE) -C $$d $@ || exit 1 ; \
|
||||
+ $(MAKE) -C $$d $@ || exit $$? ; \
|
||||
done
|
||||
|
||||
# various test targets
|
||||
@@ -87,7 +92,7 @@ cscope:
|
||||
@@ -98,7 +98,7 @@ cscope:
|
||||
|
||||
# documentation
|
||||
%.html: %.texi
|
||||
|
@ -1,6 +1,6 @@
|
||||
$OpenBSD: patch-Makefile_target,v 1.9 2006/06/08 14:33:38 todd Exp $
|
||||
--- Makefile.target.orig Wed May 3 15:32:58 2006
|
||||
+++ Makefile.target Thu May 11 20:49:55 2006
|
||||
$OpenBSD: patch-Makefile_target,v 1.10 2006/12/22 17:31:45 todd Exp $
|
||||
--- Makefile.target.orig Sat Jul 22 13:23:34 2006
|
||||
+++ Makefile.target Mon Dec 18 17:16:21 2006
|
||||
@@ -17,8 +17,9 @@ ifdef CONFIG_USER_ONLY
|
||||
VPATH+=:$(SRC_PATH)/linux-user
|
||||
DEFINES+=-I$(SRC_PATH)/linux-user -I$(SRC_PATH)/linux-user/$(TARGET_ARCH)
|
||||
@ -12,7 +12,7 @@ $OpenBSD: patch-Makefile_target,v 1.9 2006/06/08 14:33:38 todd Exp $
|
||||
LDFLAGS=-g
|
||||
LIBS=
|
||||
HELPER_CFLAGS=$(CFLAGS)
|
||||
@@ -132,7 +133,7 @@ LDFLAGS+=-Wl,-G0 -Wl,-T,$(SRC_PATH)/ia64
|
||||
@@ -144,7 +145,7 @@ LDFLAGS+=-Wl,-G0 -Wl,-T,$(SRC_PATH)/ia64
|
||||
endif
|
||||
|
||||
ifeq ($(ARCH),arm)
|
||||
@ -21,7 +21,7 @@ $OpenBSD: patch-Makefile_target,v 1.9 2006/06/08 14:33:38 todd Exp $
|
||||
LDFLAGS+=-Wl,-T,$(SRC_PATH)/arm.ld
|
||||
endif
|
||||
|
||||
@@ -141,6 +142,12 @@ OP_CFLAGS=$(CFLAGS) -fomit-frame-pointer
|
||||
@@ -153,6 +154,12 @@ OP_CFLAGS=$(CFLAGS) -fomit-frame-pointer
|
||||
LDFLAGS+=-Wl,-T,m68k.ld
|
||||
endif
|
||||
|
||||
@ -34,7 +34,7 @@ $OpenBSD: patch-Makefile_target,v 1.9 2006/06/08 14:33:38 todd Exp $
|
||||
ifeq ($(HAVE_GCC3_OPTIONS),yes)
|
||||
# very important to generate a return at the end of every operation
|
||||
OP_CFLAGS+=-fno-reorder-blocks -fno-optimize-sibling-calls
|
||||
@@ -154,6 +161,7 @@ endif
|
||||
@@ -166,6 +173,7 @@ endif
|
||||
#########################################################
|
||||
|
||||
DEFINES+=-D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE
|
||||
@ -42,7 +42,7 @@ $OpenBSD: patch-Makefile_target,v 1.9 2006/06/08 14:33:38 todd Exp $
|
||||
LIBS+=-lm
|
||||
ifndef CONFIG_USER_ONLY
|
||||
LIBS+=-lz
|
||||
@@ -280,6 +288,9 @@ endif
|
||||
@@ -297,6 +305,9 @@ endif
|
||||
|
||||
SOUND_HW = sb16.o es1370.o
|
||||
AUDIODRV = audio.o noaudio.o wavaudio.o
|
||||
@ -52,21 +52,12 @@ $OpenBSD: patch-Makefile_target,v 1.9 2006/06/08 14:33:38 todd Exp $
|
||||
ifdef CONFIG_SDL
|
||||
AUDIODRV += sdlaudio.o
|
||||
endif
|
||||
@@ -316,7 +327,7 @@ ifeq ($(TARGET_BASE_ARCH), i386)
|
||||
# Hardware support
|
||||
VL_OBJS+= ide.o pckbd.o ps2.o vga.o $(SOUND_HW) dma.o $(AUDIODRV)
|
||||
VL_OBJS+= fdc.o mc146818rtc.o serial.o i8259.o i8254.o pcspk.o pc.o
|
||||
-VL_OBJS+= cirrus_vga.o mixeng.o apic.o parallel.o
|
||||
+VL_OBJS+= cirrus_vga.o mixeng.o apic.o parallel.o pcnet.o
|
||||
DEFINES += -DHAS_AUDIO
|
||||
@@ -403,7 +414,7 @@ endif
|
||||
ifndef CONFIG_DARWIN
|
||||
ifndef CONFIG_WIN32
|
||||
ifndef CONFIG_SOLARIS
|
||||
-VL_LIBS=-lutil -lrt
|
||||
+#VL_LIBS=-lutil -lrt
|
||||
endif
|
||||
endif
|
||||
ifeq ($(TARGET_BASE_ARCH), ppc)
|
||||
@@ -492,7 +503,7 @@ clean:
|
||||
|
||||
install: all
|
||||
ifneq ($(PROGS),)
|
||||
- $(INSTALL) -m 755 -s $(PROGS) "$(DESTDIR)$(bindir)"
|
||||
+ $(INSTALL) -m 755 -s $(PROGS) "${PREFIX}/bin/"
|
||||
endif
|
||||
|
||||
ifneq ($(wildcard .depend),)
|
||||
|
@ -1,6 +1,6 @@
|
||||
$OpenBSD: patch-configure,v 1.5 2006/06/08 14:33:38 todd Exp $
|
||||
--- configure.orig Wed May 3 15:32:58 2006
|
||||
+++ configure Fri May 5 22:07:38 2006
|
||||
$OpenBSD: patch-configure,v 1.6 2006/12/22 17:31:45 todd Exp $
|
||||
--- configure.orig Sat Jul 22 13:23:34 2006
|
||||
+++ configure Sun Nov 12 17:10:10 2006
|
||||
@@ -21,8 +21,8 @@ prefix=""
|
||||
interp_prefix="/usr/gnemul/qemu-%M"
|
||||
static="no"
|
||||
@ -31,7 +31,7 @@ $OpenBSD: patch-configure,v 1.5 2006/06/08 14:33:38 todd Exp $
|
||||
*)
|
||||
cpu="unknown"
|
||||
;;
|
||||
@@ -119,6 +122,7 @@ oss="yes"
|
||||
@@ -121,6 +124,7 @@ oss="yes"
|
||||
;;
|
||||
OpenBSD)
|
||||
bsd="yes"
|
||||
@ -39,7 +39,7 @@ $OpenBSD: patch-configure,v 1.5 2006/06/08 14:33:38 todd Exp $
|
||||
oss="yes"
|
||||
;;
|
||||
Darwin)
|
||||
@@ -495,7 +499,7 @@ else
|
||||
@@ -509,7 +513,7 @@ else
|
||||
if test -z "$prefix" ; then
|
||||
prefix="/usr/local"
|
||||
fi
|
||||
@ -48,7 +48,7 @@ $OpenBSD: patch-configure,v 1.5 2006/06/08 14:33:38 todd Exp $
|
||||
datadir="$prefix/share/qemu"
|
||||
docdir="$prefix/share/doc/qemu"
|
||||
bindir="$prefix/bin"
|
||||
@@ -523,9 +527,7 @@ if test "$darwin" = "yes" ; then
|
||||
@@ -537,9 +541,7 @@ if test "$darwin" = "yes" ; then
|
||||
echo "Cocoa support $cocoa"
|
||||
fi
|
||||
echo "SDL support $sdl"
|
||||
@ -59,7 +59,7 @@ $OpenBSD: patch-configure,v 1.5 2006/06/08 14:33:38 todd Exp $
|
||||
echo "mingw32 support $mingw32"
|
||||
echo "Adlib support $adlib"
|
||||
echo "CoreAudio support $coreaudio"
|
||||
@@ -586,6 +588,9 @@ if test "$cpu" = "i386" ; then
|
||||
@@ -602,6 +604,9 @@ if test "$cpu" = "i386" ; then
|
||||
elif test "$cpu" = "x86_64" ; then
|
||||
echo "ARCH=x86_64" >> $config_mak
|
||||
echo "#define HOST_X86_64 1" >> $config_h
|
||||
@ -69,7 +69,7 @@ $OpenBSD: patch-configure,v 1.5 2006/06/08 14:33:38 todd Exp $
|
||||
elif test "$cpu" = "armv4b" ; then
|
||||
echo "ARCH=arm" >> $config_mak
|
||||
echo "#define HOST_ARM 1" >> $config_h
|
||||
@@ -665,6 +670,9 @@ fi
|
||||
@@ -681,6 +686,9 @@ fi
|
||||
if test "$oss" = "yes" ; then
|
||||
echo "CONFIG_OSS=yes" >> $config_mak
|
||||
echo "#define CONFIG_OSS 1" >> $config_h
|
||||
@ -79,9 +79,9 @@ $OpenBSD: patch-configure,v 1.5 2006/06/08 14:33:38 todd Exp $
|
||||
fi
|
||||
if test "$coreaudio" = "yes" ; then
|
||||
echo "CONFIG_COREAUDIO=yes" >> $config_mak
|
||||
@@ -703,6 +711,13 @@ if [ "$bsd" = "yes" ] ; then
|
||||
echo "#define MAP_ANONYMOUS MAP_ANON" >> $config_h
|
||||
echo "#define _BSD 1" >> $config_h
|
||||
@@ -715,6 +723,13 @@ fi
|
||||
if [ "$build_acpi_tables" = "yes" ] ; then
|
||||
echo "BUILD_ACPI_TABLES=yes" >> $config_mak
|
||||
fi
|
||||
+
|
||||
+if [ "$openbsd" = "yes" ] ; then
|
||||
@ -91,5 +91,5 @@ $OpenBSD: patch-configure,v 1.5 2006/06/08 14:33:38 todd Exp $
|
||||
+ echo "#define qemu_siginfo struct siginfo" >> $config_h
|
||||
+fi
|
||||
|
||||
for target in $target_list; do
|
||||
target_dir="$target"
|
||||
# XXX: suppress that
|
||||
if [ "$bsd" = "yes" ] ; then
|
||||
|
@ -1,6 +1,6 @@
|
||||
$OpenBSD: patch-dyngen-exec_h,v 1.3 2006/06/08 14:33:38 todd Exp $
|
||||
--- dyngen-exec.h.orig Wed May 3 15:32:58 2006
|
||||
+++ dyngen-exec.h Fri May 5 22:07:38 2006
|
||||
$OpenBSD: patch-dyngen-exec_h,v 1.4 2006/12/22 17:31:45 todd Exp $
|
||||
--- dyngen-exec.h.orig Sat Jul 22 13:23:34 2006
|
||||
+++ dyngen-exec.h Sun Nov 12 17:10:10 2006
|
||||
@@ -27,11 +27,15 @@
|
||||
#define _FILEDEFED
|
||||
#endif
|
||||
@ -18,15 +18,15 @@ $OpenBSD: patch-dyngen-exec_h,v 1.3 2006/06/08 14:33:38 todd Exp $
|
||||
typedef unsigned char uint8_t;
|
||||
typedef unsigned short uint16_t;
|
||||
typedef unsigned int uint32_t;
|
||||
@@ -55,6 +59,7 @@ typedef signed long int64_t;
|
||||
#else
|
||||
@@ -61,6 +65,7 @@ typedef signed long int64_t;
|
||||
typedef signed long long int64_t;
|
||||
#endif
|
||||
#endif
|
||||
+#endif
|
||||
|
||||
#define INT8_MIN (-128)
|
||||
#define INT16_MIN (-32767-1)
|
||||
@@ -69,11 +74,15 @@ typedef signed long long int64_t;
|
||||
@@ -75,11 +80,15 @@ typedef signed long long int64_t;
|
||||
#define UINT32_MAX (4294967295U)
|
||||
#define UINT64_MAX ((uint64_t)(18446744073709551615))
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
$OpenBSD: patch-exec_c,v 1.4 2006/06/08 14:33:38 todd Exp $
|
||||
--- exec.c.orig Wed May 3 15:32:58 2006
|
||||
+++ exec.c Fri May 5 22:07:38 2006
|
||||
@@ -1999,7 +1999,7 @@ void cpu_physical_memory_rw(target_phys_
|
||||
$OpenBSD: patch-exec_c,v 1.5 2006/12/22 17:31:45 todd Exp $
|
||||
--- exec.c.orig Sat Jul 22 13:23:34 2006
|
||||
+++ exec.c Sun Nov 12 17:10:10 2006
|
||||
@@ -2010,7 +2010,7 @@ void cpu_physical_memory_rw(target_phys_
|
||||
target_phys_addr_t page;
|
||||
unsigned long pd;
|
||||
PhysPageDesc *p;
|
||||
|
@ -1,12 +0,0 @@
|
||||
$OpenBSD: patch-hw_ne2000_c,v 1.2 2006/06/08 14:33:38 todd Exp $
|
||||
--- hw/ne2000.c.orig Sun May 14 19:09:39 2006
|
||||
+++ hw/ne2000.c Sun May 14 19:09:12 2006
|
||||
@@ -206,7 +206,7 @@ static int ne2000_buffer_full(NE2000Stat
|
||||
|
||||
index = s->curpag << 8;
|
||||
boundary = s->boundary << 8;
|
||||
- if (index < boundary)
|
||||
+ if (index <= boundary)
|
||||
avail = boundary - index;
|
||||
else
|
||||
avail = (s->stop - s->start) - (index - boundary);
|
@ -1,34 +0,0 @@
|
||||
$OpenBSD: patch-hw_pc_c,v 1.4 2006/06/08 14:33:38 todd Exp $
|
||||
--- hw/pc.c.orig Wed May 3 15:32:58 2006
|
||||
+++ hw/pc.c Fri May 5 22:16:41 2006
|
||||
@@ -609,7 +609,7 @@ static void pc_init1(int ram_size, int v
|
||||
char buf[1024];
|
||||
int ret, linux_boot, initrd_size, i;
|
||||
unsigned long bios_offset, vga_bios_offset;
|
||||
- int bios_size, isa_bios_size;
|
||||
+ int bios_size, isa_bios_size, vga_bios_size;
|
||||
PCIBus *pci_bus;
|
||||
CPUState *env;
|
||||
NICInfo *nd;
|
||||
@@ -662,8 +662,12 @@ static void pc_init1(int ram_size, int v
|
||||
} else {
|
||||
snprintf(buf, sizeof(buf), "%s/%s", bios_dir, VGABIOS_FILENAME);
|
||||
}
|
||||
+ vga_bios_size = get_image_size(buf);
|
||||
+ if (vga_bios_size != 32768)
|
||||
+ goto bios_error;
|
||||
+
|
||||
ret = load_image(buf, phys_ram_base + vga_bios_offset);
|
||||
-
|
||||
+
|
||||
/* setup basic memory access */
|
||||
cpu_register_physical_memory(0xc0000, 0x10000,
|
||||
vga_bios_offset | IO_MEM_ROM);
|
||||
@@ -793,6 +797,7 @@ static void pc_init1(int ram_size, int v
|
||||
}
|
||||
}
|
||||
|
||||
+/* XXX where to insert pci_pcnet_init(pci_bus, &nd_table[i]); ??? */
|
||||
for(i = 0; i < nb_nics; i++) {
|
||||
nd = &nd_table[i];
|
||||
if (!nd->model) {
|
File diff suppressed because it is too large
Load Diff
@ -1,588 +0,0 @@
|
||||
--- hw/pcnet.h.orig Mon Feb 13 20:51:57 2006
|
||||
+++ hw/pcnet.h Mon Feb 13 20:57:36 2006
|
||||
@@ -0,0 +1,585 @@
|
||||
+/*
|
||||
+ * QEMU AMD PC-Net II (Am79C970A) emulation
|
||||
+ *
|
||||
+ * Copyright (c) 2004 Antony T Curtis
|
||||
+ *
|
||||
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
+ * of this software and associated documentation files (the "Software"), to deal
|
||||
+ * in the Software without restriction, including without limitation the rights
|
||||
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
+ * copies of the Software, and to permit persons to whom the Software is
|
||||
+ * furnished to do so, subject to the following conditions:
|
||||
+ *
|
||||
+ * The above copyright notice and this permission notice shall be included in
|
||||
+ * all copies or substantial portions of the Software.
|
||||
+ *
|
||||
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
+ * THE SOFTWARE.
|
||||
+ */
|
||||
+
|
||||
+/* This software was written to be compatible with the specification:
|
||||
+ * AMD Am79C970A PCnet-PCI II Ethernet Controller Data-Sheet
|
||||
+ * AMD Publication# 19436 Rev:E Amendment/0 Issue Date: June 2000
|
||||
+ */
|
||||
+
|
||||
+#ifdef __GNUC__
|
||||
+#define PACKED(A) A __attribute__ ((packed))
|
||||
+#else
|
||||
+#error FixMe
|
||||
+#endif
|
||||
+
|
||||
+/* BUS CONFIGURATION REGISTERS */
|
||||
+#define BCR_MSRDA 0
|
||||
+#define BCR_MSWRA 1
|
||||
+#define BCR_MC 2
|
||||
+#define BCR_LNKST 4
|
||||
+#define BCR_LED1 5
|
||||
+#define BCR_LED2 6
|
||||
+#define BCR_LED3 7
|
||||
+#define BCR_FDC 9
|
||||
+#define BCR_BSBC 18
|
||||
+#define BCR_EECAS 19
|
||||
+#define BCR_SWS 20
|
||||
+#define BCR_PLAT 22
|
||||
+
|
||||
+#define BCR_DWIO(S) !!((S)->bcr[BCR_BSBC] & 0x0080)
|
||||
+#define BCR_SSIZE32(S) !!((S)->bcr[BCR_SWS ] & 0x0100)
|
||||
+#define BCR_SWSTYLE(S) ((S)->bcr[BCR_SWS ] & 0x00FF)
|
||||
+
|
||||
+#define CSR_INIT(S) !!(((S)->csr[0])&0x0001)
|
||||
+#define CSR_STRT(S) !!(((S)->csr[0])&0x0002)
|
||||
+#define CSR_STOP(S) !!(((S)->csr[0])&0x0004)
|
||||
+#define CSR_TDMD(S) !!(((S)->csr[0])&0x0008)
|
||||
+#define CSR_TXON(S) !!(((S)->csr[0])&0x0010)
|
||||
+#define CSR_RXON(S) !!(((S)->csr[0])&0x0020)
|
||||
+#define CSR_INEA(S) !!(((S)->csr[0])&0x0040)
|
||||
+#define CSR_LAPPEN(S) !!(((S)->csr[3])&0x0020)
|
||||
+#define CSR_DXSUFLO(S) !!(((S)->csr[3])&0x0040)
|
||||
+#define CSR_ASTRP_RCV(S) !!(((S)->csr[4])&0x0800)
|
||||
+#define CSR_DPOLL(S) !!(((S)->csr[4])&0x1000)
|
||||
+#define CSR_SPND(S) !!(((S)->csr[5])&0x0001)
|
||||
+#define CSR_LTINTEN(S) !!(((S)->csr[5])&0x4000)
|
||||
+#define CSR_TOKINTD(S) !!(((S)->csr[5])&0x8000)
|
||||
+#define CSR_DRX(S) !!(((S)->csr[15])&0x0001)
|
||||
+#define CSR_DTX(S) !!(((S)->csr[15])&0x0002)
|
||||
+#define CSR_LOOP(S) !!(((S)->csr[15])&0x0004)
|
||||
+#define CSR_DRCVPA(S) !!(((S)->csr[15])&0x2000)
|
||||
+#define CSR_DRCVBC(S) !!(((S)->csr[15])&0x4000)
|
||||
+#define CSR_PROM(S) !!(((S)->csr[15])&0x8000)
|
||||
+
|
||||
+#define CSR_CRBC(S) ((S)->csr[40])
|
||||
+#define CSR_CRST(S) ((S)->csr[41])
|
||||
+#define CSR_CXBC(S) ((S)->csr[42])
|
||||
+#define CSR_CXST(S) ((S)->csr[43])
|
||||
+#define CSR_NRBC(S) ((S)->csr[44])
|
||||
+#define CSR_NRST(S) ((S)->csr[45])
|
||||
+#define CSR_POLL(S) ((S)->csr[46])
|
||||
+#define CSR_PINT(S) ((S)->csr[47])
|
||||
+#define CSR_RCVRC(S) ((S)->csr[72])
|
||||
+#define CSR_XMTRC(S) ((S)->csr[74])
|
||||
+#define CSR_RCVRL(S) ((S)->csr[76])
|
||||
+#define CSR_XMTRL(S) ((S)->csr[78])
|
||||
+#define CSR_MISSC(S) ((S)->csr[112])
|
||||
+
|
||||
+#define CSR_IADR(S) ((S)->csr[ 1] | ((S)->csr[ 2] << 16))
|
||||
+#define CSR_CRBA(S) ((S)->csr[18] | ((S)->csr[19] << 16))
|
||||
+#define CSR_CXBA(S) ((S)->csr[20] | ((S)->csr[21] << 16))
|
||||
+#define CSR_NRBA(S) ((S)->csr[22] | ((S)->csr[23] << 16))
|
||||
+#define CSR_BADR(S) ((S)->csr[24] | ((S)->csr[25] << 16))
|
||||
+#define CSR_NRDA(S) ((S)->csr[26] | ((S)->csr[27] << 16))
|
||||
+#define CSR_CRDA(S) ((S)->csr[28] | ((S)->csr[29] << 16))
|
||||
+#define CSR_BADX(S) ((S)->csr[30] | ((S)->csr[31] << 16))
|
||||
+#define CSR_NXDA(S) ((S)->csr[32] | ((S)->csr[33] << 16))
|
||||
+#define CSR_CXDA(S) ((S)->csr[34] | ((S)->csr[35] << 16))
|
||||
+#define CSR_NNRD(S) ((S)->csr[36] | ((S)->csr[37] << 16))
|
||||
+#define CSR_NNXD(S) ((S)->csr[38] | ((S)->csr[39] << 16))
|
||||
+#define CSR_PXDA(S) ((S)->csr[60] | ((S)->csr[61] << 16))
|
||||
+#define CSR_NXBA(S) ((S)->csr[64] | ((S)->csr[65] << 16))
|
||||
+
|
||||
+#define PHYSADDR(S,A) \
|
||||
+ (BCR_SSIZE32(S) ? (A) : (A) | ((0xff00 & (uint32_t)(s)->csr[2])<<16))
|
||||
+
|
||||
+struct pcnet_initblk16 {
|
||||
+ uint16_t mode;
|
||||
+ uint16_t padr1;
|
||||
+ uint16_t padr2;
|
||||
+ uint16_t padr3;
|
||||
+ uint16_t ladrf1;
|
||||
+ uint16_t ladrf2;
|
||||
+ uint16_t ladrf3;
|
||||
+ uint16_t ladrf4;
|
||||
+ unsigned PACKED(rdra:24);
|
||||
+ unsigned PACKED(res1:5);
|
||||
+ unsigned PACKED(rlen:3);
|
||||
+ unsigned PACKED(tdra:24);
|
||||
+ unsigned PACKED(res2:5);
|
||||
+ unsigned PACKED(tlen:3);
|
||||
+};
|
||||
+
|
||||
+struct pcnet_initblk32 {
|
||||
+ uint16_t mode;
|
||||
+ unsigned PACKED(res1:4);
|
||||
+ unsigned PACKED(rlen:4);
|
||||
+ unsigned PACKED(res2:4);
|
||||
+ unsigned PACKED(tlen:4);
|
||||
+ uint16_t padr1;
|
||||
+ uint16_t padr2;
|
||||
+ uint16_t padr3;
|
||||
+ uint16_t _res;
|
||||
+ uint16_t ladrf1;
|
||||
+ uint16_t ladrf2;
|
||||
+ uint16_t ladrf3;
|
||||
+ uint16_t ladrf4;
|
||||
+ uint32_t rdra;
|
||||
+ uint32_t tdra;
|
||||
+};
|
||||
+
|
||||
+struct pcnet_TMD {
|
||||
+ struct {
|
||||
+ unsigned tbadr:32;
|
||||
+ } tmd0;
|
||||
+ struct {
|
||||
+ unsigned PACKED(bcnt:12), PACKED(ones:4), PACKED(res:7), PACKED(bpe:1);
|
||||
+ unsigned PACKED(enp:1), PACKED(stp:1), PACKED(def:1), PACKED(one:1);
|
||||
+ unsigned PACKED(ltint:1), PACKED(nofcs:1), PACKED(err:1), PACKED(own:1);
|
||||
+ } tmd1;
|
||||
+ struct {
|
||||
+ unsigned PACKED(trc:4), PACKED(res:12);
|
||||
+ unsigned PACKED(tdr:10), PACKED(rtry:1), PACKED(lcar:1);
|
||||
+ unsigned PACKED(lcol:1), PACKED(exdef:1), PACKED(uflo:1), PACKED(buff:1);
|
||||
+ } tmd2;
|
||||
+ struct {
|
||||
+ unsigned res:32;
|
||||
+ } tmd3;
|
||||
+};
|
||||
+
|
||||
+struct pcnet_RMD {
|
||||
+ struct {
|
||||
+ unsigned rbadr:32;
|
||||
+ } rmd0;
|
||||
+ struct {
|
||||
+ unsigned PACKED(bcnt:12), PACKED(ones:4), PACKED(res:4);
|
||||
+ unsigned PACKED(bam:1), PACKED(lafm:1), PACKED(pam:1), PACKED(bpe:1);
|
||||
+ unsigned PACKED(enp:1), PACKED(stp:1), PACKED(buff:1), PACKED(crc:1);
|
||||
+ unsigned PACKED(oflo:1), PACKED(fram:1), PACKED(err:1), PACKED(own:1);
|
||||
+ } rmd1;
|
||||
+ struct {
|
||||
+ unsigned PACKED(mcnt:12), PACKED(zeros:4);
|
||||
+ unsigned PACKED(rpc:8), PACKED(rcc:8);
|
||||
+ } rmd2;
|
||||
+ struct {
|
||||
+ unsigned res:32;
|
||||
+ } rmd3;
|
||||
+};
|
||||
+
|
||||
+
|
||||
+#define PRINT_TMD(T) printf( \
|
||||
+ "TMD0 : TBADR=0x%08x\n" \
|
||||
+ "TMD1 : OWN=%d, ERR=%d, FCS=%d, LTI=%d, " \
|
||||
+ "ONE=%d, DEF=%d, STP=%d, ENP=%d,\n" \
|
||||
+ " BPE=%d, BCNT=%d\n" \
|
||||
+ "TMD2 : BUF=%d, UFL=%d, EXD=%d, LCO=%d, " \
|
||||
+ "LCA=%d, RTR=%d,\n" \
|
||||
+ " TDR=%d, TRC=%d\n", \
|
||||
+ (T)->tmd0.tbadr, \
|
||||
+ (T)->tmd1.own, (T)->tmd1.err, (T)->tmd1.nofcs, \
|
||||
+ (T)->tmd1.ltint, (T)->tmd1.one, (T)->tmd1.def, \
|
||||
+ (T)->tmd1.stp, (T)->tmd1.enp, (T)->tmd1.bpe, \
|
||||
+ 4096-(T)->tmd1.bcnt, \
|
||||
+ (T)->tmd2.buff, (T)->tmd2.uflo, (T)->tmd2.exdef,\
|
||||
+ (T)->tmd2.lcol, (T)->tmd2.lcar, (T)->tmd2.rtry, \
|
||||
+ (T)->tmd2.tdr, (T)->tmd2.trc)
|
||||
+
|
||||
+#define PRINT_RMD(R) printf( \
|
||||
+ "RMD0 : RBADR=0x%08x\n" \
|
||||
+ "RMD1 : OWN=%d, ERR=%d, FRAM=%d, OFLO=%d, " \
|
||||
+ "CRC=%d, BUFF=%d, STP=%d, ENP=%d,\n " \
|
||||
+ "BPE=%d, PAM=%d, LAFM=%d, BAM=%d, ONES=%d, BCNT=%d\n" \
|
||||
+ "RMD2 : RCC=%d, RPC=%d, MCNT=%d, ZEROS=%d\n", \
|
||||
+ (R)->rmd0.rbadr, \
|
||||
+ (R)->rmd1.own, (R)->rmd1.err, (R)->rmd1.fram, \
|
||||
+ (R)->rmd1.oflo, (R)->rmd1.crc, (R)->rmd1.buff, \
|
||||
+ (R)->rmd1.stp, (R)->rmd1.enp, (R)->rmd1.bpe, \
|
||||
+ (R)->rmd1.pam, (R)->rmd1.lafm, (R)->rmd1.bam, \
|
||||
+ (R)->rmd1.ones, 4096-(R)->rmd1.bcnt, \
|
||||
+ (R)->rmd2.rcc, (R)->rmd2.rpc, (R)->rmd2.mcnt, \
|
||||
+ (R)->rmd2.zeros)
|
||||
+
|
||||
+static inline void pcnet_tmd_load(PCNetState *s, struct pcnet_TMD *tmd, target_phys_addr_t addr)
|
||||
+{
|
||||
+ if (!BCR_SWSTYLE(s)) {
|
||||
+ uint16_t xda[4];
|
||||
+ cpu_physical_memory_read(addr,
|
||||
+ (void *)&xda[0], sizeof(xda));
|
||||
+ ((uint32_t *)tmd)[0] = (xda[0]&0xffff) |
|
||||
+ ((xda[1]&0x00ff) << 16);
|
||||
+ ((uint32_t *)tmd)[1] = (xda[2]&0xffff)|
|
||||
+ ((xda[1] & 0xff00) << 16);
|
||||
+ ((uint32_t *)tmd)[2] =
|
||||
+ (xda[3] & 0xffff) << 16;
|
||||
+ ((uint32_t *)tmd)[3] = 0;
|
||||
+ }
|
||||
+ else
|
||||
+ if (BCR_SWSTYLE(s) != 3)
|
||||
+ cpu_physical_memory_read(addr, (void *)tmd, 16);
|
||||
+ else {
|
||||
+ uint32_t xda[4];
|
||||
+ cpu_physical_memory_read(addr,
|
||||
+ (void *)&xda[0], sizeof(xda));
|
||||
+ ((uint32_t *)tmd)[0] = xda[2];
|
||||
+ ((uint32_t *)tmd)[1] = xda[1];
|
||||
+ ((uint32_t *)tmd)[2] = xda[0];
|
||||
+ ((uint32_t *)tmd)[3] = xda[3];
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static inline void pcnet_tmd_store(PCNetState *s, struct pcnet_TMD *tmd, target_phys_addr_t addr)
|
||||
+{
|
||||
+ cpu_physical_memory_set_dirty(addr);
|
||||
+ if (!BCR_SWSTYLE(s)) {
|
||||
+ uint16_t xda[4];
|
||||
+ xda[0] = ((uint32_t *)tmd)[0] & 0xffff;
|
||||
+ xda[1] = ((((uint32_t *)tmd)[0]>>16)&0x00ff) |
|
||||
+ ((((uint32_t *)tmd)[1]>>16)&0xff00);
|
||||
+ xda[2] = ((uint32_t *)tmd)[1] & 0xffff;
|
||||
+ xda[3] = ((uint32_t *)tmd)[2] >> 16;
|
||||
+ cpu_physical_memory_write(addr,
|
||||
+ (void *)&xda[0], sizeof(xda));
|
||||
+ cpu_physical_memory_set_dirty(addr+7);
|
||||
+ }
|
||||
+ else {
|
||||
+ if (BCR_SWSTYLE(s) != 3)
|
||||
+ cpu_physical_memory_write(addr, (void *)tmd, 16);
|
||||
+ else {
|
||||
+ uint32_t xda[4];
|
||||
+ xda[0] = ((uint32_t *)tmd)[2];
|
||||
+ xda[1] = ((uint32_t *)tmd)[1];
|
||||
+ xda[2] = ((uint32_t *)tmd)[0];
|
||||
+ xda[3] = ((uint32_t *)tmd)[3];
|
||||
+ cpu_physical_memory_write(addr,
|
||||
+ (void *)&xda[0], sizeof(xda));
|
||||
+ }
|
||||
+ cpu_physical_memory_set_dirty(addr+15);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static inline void pcnet_rmd_load(PCNetState *s, struct pcnet_RMD *rmd, target_phys_addr_t addr)
|
||||
+{
|
||||
+ if (!BCR_SWSTYLE(s)) {
|
||||
+ uint16_t rda[4];
|
||||
+ cpu_physical_memory_read(addr,
|
||||
+ (void *)&rda[0], sizeof(rda));
|
||||
+ ((uint32_t *)rmd)[0] = (rda[0]&0xffff)|
|
||||
+ ((rda[1] & 0x00ff) << 16);
|
||||
+ ((uint32_t *)rmd)[1] = (rda[2]&0xffff)|
|
||||
+ ((rda[1] & 0xff00) << 16);
|
||||
+ ((uint32_t *)rmd)[2] = rda[3] & 0xffff;
|
||||
+ ((uint32_t *)rmd)[3] = 0;
|
||||
+ }
|
||||
+ else
|
||||
+ if (BCR_SWSTYLE(s) != 3)
|
||||
+ cpu_physical_memory_read(addr, (void *)rmd, 16);
|
||||
+ else {
|
||||
+ uint32_t rda[4];
|
||||
+ cpu_physical_memory_read(addr,
|
||||
+ (void *)&rda[0], sizeof(rda));
|
||||
+ ((uint32_t *)rmd)[0] = rda[2];
|
||||
+ ((uint32_t *)rmd)[1] = rda[1];
|
||||
+ ((uint32_t *)rmd)[2] = rda[0];
|
||||
+ ((uint32_t *)rmd)[3] = rda[3];
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static inline void pcnet_rmd_store(PCNetState *s, struct pcnet_RMD *rmd, target_phys_addr_t addr)
|
||||
+{
|
||||
+ cpu_physical_memory_set_dirty(addr);
|
||||
+ if (!BCR_SWSTYLE(s)) {
|
||||
+ uint16_t rda[4]; \
|
||||
+ rda[0] = ((uint32_t *)rmd)[0] & 0xffff; \
|
||||
+ rda[1] = ((((uint32_t *)rmd)[0]>>16)&0xff)|\
|
||||
+ ((((uint32_t *)rmd)[1]>>16)&0xff00);\
|
||||
+ rda[2] = ((uint32_t *)rmd)[1] & 0xffff; \
|
||||
+ rda[3] = ((uint32_t *)rmd)[2] & 0xffff; \
|
||||
+ cpu_physical_memory_write(addr, \
|
||||
+ (void *)&rda[0], sizeof(rda)); \
|
||||
+ cpu_physical_memory_set_dirty(addr+7);
|
||||
+ }
|
||||
+ else {
|
||||
+ if (BCR_SWSTYLE(s) != 3)
|
||||
+ cpu_physical_memory_write(addr, (void *)rmd, 16);
|
||||
+ else {
|
||||
+ uint32_t rda[4];
|
||||
+ rda[0] = ((uint32_t *)rmd)[2];
|
||||
+ rda[1] = ((uint32_t *)rmd)[1];
|
||||
+ rda[2] = ((uint32_t *)rmd)[0];
|
||||
+ rda[3] = ((uint32_t *)rmd)[3];
|
||||
+ cpu_physical_memory_write(addr,
|
||||
+ (void *)&rda[0], sizeof(rda));
|
||||
+ }
|
||||
+ cpu_physical_memory_set_dirty(addr+15);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+
|
||||
+#define TMDLOAD(TMD,ADDR) pcnet_tmd_load(s,TMD,ADDR)
|
||||
+
|
||||
+#define TMDSTORE(TMD,ADDR) pcnet_tmd_store(s,TMD,ADDR)
|
||||
+
|
||||
+#define RMDLOAD(RMD,ADDR) pcnet_rmd_load(s,RMD,ADDR)
|
||||
+
|
||||
+#define RMDSTORE(RMD,ADDR) pcnet_rmd_store(s,RMD,ADDR)
|
||||
+
|
||||
+#if 1
|
||||
+
|
||||
+#define CHECK_RMD(ADDR,RES) do { \
|
||||
+ struct pcnet_RMD rmd; \
|
||||
+ RMDLOAD(&rmd,(ADDR)); \
|
||||
+ (RES) |= (rmd.rmd1.ones != 15) \
|
||||
+ || (rmd.rmd2.zeros != 0); \
|
||||
+} while (0)
|
||||
+
|
||||
+#define CHECK_TMD(ADDR,RES) do { \
|
||||
+ struct pcnet_TMD tmd; \
|
||||
+ TMDLOAD(&tmd,(ADDR)); \
|
||||
+ (RES) |= (tmd.tmd1.ones != 15); \
|
||||
+} while (0)
|
||||
+
|
||||
+#else
|
||||
+
|
||||
+#define CHECK_RMD(ADDR,RES) do { \
|
||||
+ switch (BCR_SWSTYLE(s)) { \
|
||||
+ case 0x00: \
|
||||
+ do { \
|
||||
+ uint16_t rda[4]; \
|
||||
+ cpu_physical_memory_read((ADDR), \
|
||||
+ (void *)&rda[0], sizeof(rda)); \
|
||||
+ (RES) |= (rda[2] & 0xf000)!=0xf000; \
|
||||
+ (RES) |= (rda[3] & 0xf000)!=0x0000; \
|
||||
+ } while (0); \
|
||||
+ break; \
|
||||
+ case 0x01: \
|
||||
+ case 0x02: \
|
||||
+ do { \
|
||||
+ uint32_t rda[4]; \
|
||||
+ cpu_physical_memory_read((ADDR), \
|
||||
+ (void *)&rda[0], sizeof(rda)); \
|
||||
+ (RES) |= (rda[1] & 0x0000f000L)!=0x0000f000L; \
|
||||
+ (RES) |= (rda[2] & 0x0000f000L)!=0x00000000L; \
|
||||
+ } while (0); \
|
||||
+ break; \
|
||||
+ case 0x03: \
|
||||
+ do { \
|
||||
+ uint32_t rda[4]; \
|
||||
+ cpu_physical_memory_read((ADDR), \
|
||||
+ (void *)&rda[0], sizeof(rda)); \
|
||||
+ (RES) |= (rda[0] & 0x0000f000L)!=0x00000000L; \
|
||||
+ (RES) |= (rda[1] & 0x0000f000L)!=0x0000f000L; \
|
||||
+ } while (0); \
|
||||
+ break; \
|
||||
+ } \
|
||||
+} while (0)
|
||||
+
|
||||
+#define CHECK_TMD(ADDR,RES) do { \
|
||||
+ switch (BCR_SWSTYLE(s)) { \
|
||||
+ case 0x00: \
|
||||
+ do { \
|
||||
+ uint16_t xda[4]; \
|
||||
+ cpu_physical_memory_read((ADDR), \
|
||||
+ (void *)&xda[0], sizeof(xda)); \
|
||||
+ (RES) |= (xda[2] & 0xf000)!=0xf000;\
|
||||
+ } while (0); \
|
||||
+ break; \
|
||||
+ case 0x01: \
|
||||
+ case 0x02: \
|
||||
+ case 0x03: \
|
||||
+ do { \
|
||||
+ uint32_t xda[4]; \
|
||||
+ cpu_physical_memory_read((ADDR), \
|
||||
+ (void *)&xda[0], sizeof(xda)); \
|
||||
+ (RES) |= (xda[1] & 0x0000f000L)!=0x0000f000L; \
|
||||
+ } while (0); \
|
||||
+ break; \
|
||||
+ } \
|
||||
+} while (0)
|
||||
+
|
||||
+#endif
|
||||
+
|
||||
+#define PRINT_PKTHDR(BUF) do { \
|
||||
+ struct ether_header *hdr = (void *)(BUF); \
|
||||
+ printf("packet dhost=%02x:%02x:%02x:%02x:%02x:%02x, " \
|
||||
+ "shost=%02x:%02x:%02x:%02x:%02x:%02x, " \
|
||||
+ "type=0x%04x (bcast=%d)\n", \
|
||||
+ hdr->ether_dhost[0],hdr->ether_dhost[1],hdr->ether_dhost[2], \
|
||||
+ hdr->ether_dhost[3],hdr->ether_dhost[4],hdr->ether_dhost[5], \
|
||||
+ hdr->ether_shost[0],hdr->ether_shost[1],hdr->ether_shost[2], \
|
||||
+ hdr->ether_shost[3],hdr->ether_shost[4],hdr->ether_shost[5], \
|
||||
+ htons(hdr->ether_type), \
|
||||
+ !!ETHER_IS_MULTICAST(hdr->ether_dhost)); \
|
||||
+} while (0)
|
||||
+
|
||||
+#define MULTICAST_FILTER_LEN 8
|
||||
+
|
||||
+static inline uint32_t lnc_mchash(const uint8_t *ether_addr)
|
||||
+{
|
||||
+#define LNC_POLYNOMIAL 0xEDB88320UL
|
||||
+ uint32_t crc = 0xFFFFFFFF;
|
||||
+ int idx, bit;
|
||||
+ uint8_t data;
|
||||
+
|
||||
+ for (idx = 0; idx < ETHER_ADDR_LEN; idx++) {
|
||||
+ for (data = *ether_addr++, bit = 0; bit < MULTICAST_FILTER_LEN; bit++) {
|
||||
+ crc = (crc >> 1) ^ (((crc ^ data) & 1) ? LNC_POLYNOMIAL : 0);
|
||||
+ data >>= 1;
|
||||
+ }
|
||||
+ }
|
||||
+ return crc;
|
||||
+#undef LNC_POLYNOMIAL
|
||||
+}
|
||||
+
|
||||
+#ifndef MIN
|
||||
+#define MIN(X,Y) ((X>Y) ? (Y) : (X))
|
||||
+#endif
|
||||
+
|
||||
+#define CRC(crc, ch) (crc = (crc >> 8) ^ crctab[(crc ^ (ch)) & 0xff])
|
||||
+
|
||||
+/* generated using the AUTODIN II polynomial
|
||||
+ * x^32 + x^26 + x^23 + x^22 + x^16 +
|
||||
+ * x^12 + x^11 + x^10 + x^8 + x^7 + x^5 + x^4 + x^2 + x^1 + 1
|
||||
+ */
|
||||
+static const uint32_t crctab[256] = {
|
||||
+ 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
|
||||
+ 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
|
||||
+ 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
|
||||
+ 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
|
||||
+ 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
|
||||
+ 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
|
||||
+ 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,
|
||||
+ 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
|
||||
+ 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
|
||||
+ 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
|
||||
+ 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940,
|
||||
+ 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
|
||||
+ 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116,
|
||||
+ 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
|
||||
+ 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
|
||||
+ 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
|
||||
+ 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a,
|
||||
+ 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
|
||||
+ 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818,
|
||||
+ 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
|
||||
+ 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
|
||||
+ 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
|
||||
+ 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c,
|
||||
+ 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
|
||||
+ 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
|
||||
+ 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
|
||||
+ 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
|
||||
+ 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
|
||||
+ 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086,
|
||||
+ 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
|
||||
+ 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4,
|
||||
+ 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
|
||||
+ 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
|
||||
+ 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
|
||||
+ 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
|
||||
+ 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
|
||||
+ 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe,
|
||||
+ 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
|
||||
+ 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
|
||||
+ 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
|
||||
+ 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252,
|
||||
+ 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
|
||||
+ 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60,
|
||||
+ 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
|
||||
+ 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
|
||||
+ 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
|
||||
+ 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04,
|
||||
+ 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
|
||||
+ 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,
|
||||
+ 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
|
||||
+ 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
|
||||
+ 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
|
||||
+ 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e,
|
||||
+ 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
|
||||
+ 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
|
||||
+ 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
|
||||
+ 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
|
||||
+ 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
|
||||
+ 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0,
|
||||
+ 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
|
||||
+ 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6,
|
||||
+ 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
|
||||
+ 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
|
||||
+ 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d,
|
||||
+};
|
||||
+
|
||||
+static inline int padr_match(PCNetState *s, const uint8_t *buf, int size)
|
||||
+{
|
||||
+ struct ether_header *hdr = (void *)buf;
|
||||
+ uint8_t padr[6] = {
|
||||
+ s->csr[12] & 0xff, s->csr[12] >> 8,
|
||||
+ s->csr[13] & 0xff, s->csr[13] >> 8,
|
||||
+ s->csr[14] & 0xff, s->csr[14] >> 8
|
||||
+ };
|
||||
+ int result = (!CSR_DRCVPA(s)) && !bcmp(hdr->ether_dhost, padr, 6);
|
||||
+#ifdef PCNET_DEBUG_MATCH
|
||||
+ printf("packet dhost=%02x:%02x:%02x:%02x:%02x:%02x, "
|
||||
+ "padr=%02x:%02x:%02x:%02x:%02x:%02x\n",
|
||||
+ hdr->ether_dhost[0],hdr->ether_dhost[1],hdr->ether_dhost[2],
|
||||
+ hdr->ether_dhost[3],hdr->ether_dhost[4],hdr->ether_dhost[5],
|
||||
+ padr[0],padr[1],padr[2],padr[3],padr[4],padr[5]);
|
||||
+ printf("padr_match result=%d\n", result);
|
||||
+#endif
|
||||
+ return result;
|
||||
+}
|
||||
+
|
||||
+static inline int padr_bcast(PCNetState *s, const uint8_t *buf, int size)
|
||||
+{
|
||||
+ static uint8_t BCAST[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
|
||||
+ struct ether_header *hdr = (void *)buf;
|
||||
+ int result = !CSR_DRCVBC(s) && !bcmp(hdr->ether_dhost, BCAST, 6);
|
||||
+#ifdef PCNET_DEBUG_MATCH
|
||||
+ printf("padr_bcast result=%d\n", result);
|
||||
+#endif
|
||||
+ return result;
|
||||
+}
|
||||
+
|
||||
+static inline int ladr_match(PCNetState *s, const uint8_t *buf, int size)
|
||||
+{
|
||||
+ struct ether_header *hdr = (void *)buf;
|
||||
+ if ((*(hdr->ether_dhost)&0x01) &&
|
||||
+ ((uint64_t *)&s->csr[8])[0] != 0LL) {
|
||||
+ uint8_t ladr[8] = {
|
||||
+ s->csr[8] & 0xff, s->csr[8] >> 8,
|
||||
+ s->csr[9] & 0xff, s->csr[9] >> 8,
|
||||
+ s->csr[10] & 0xff, s->csr[10] >> 8,
|
||||
+ s->csr[11] & 0xff, s->csr[11] >> 8
|
||||
+ };
|
||||
+ int index = lnc_mchash(hdr->ether_dhost) >> 26;
|
||||
+ return !!(ladr[index >> 3] & (1 << (index & 7)));
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static inline target_phys_addr_t pcnet_rdra_addr(PCNetState *s, int idx)
|
||||
+{
|
||||
+ while (idx < 1) idx += CSR_RCVRL(s);
|
||||
+ return s->rdra + ((CSR_RCVRL(s) - idx) * (BCR_SWSTYLE(s) ? 16 : 8));
|
||||
+}
|
||||
+
|
||||
+static inline int64_t pcnet_get_next_poll_time(PCNetState *s, int64_t current_time)
|
||||
+{
|
||||
+ int64_t next_time = current_time +
|
||||
+ muldiv64(65536 - (CSR_SPND(s) ? 0 : CSR_POLL(s)),
|
||||
+ ticks_per_sec, 33000000L);
|
||||
+ if (next_time <= current_time)
|
||||
+ next_time = current_time + 1;
|
||||
+ return next_time;
|
||||
+}
|
||||
+
|
||||
+
|
@ -1,413 +0,0 @@
|
||||
$OpenBSD: patch-hw_rtl8139_c,v 1.1 2006/06/08 14:33:38 todd Exp $
|
||||
--- hw/rtl8139.c.orig Wed May 3 15:32:58 2006
|
||||
+++ hw/rtl8139.c Thu May 11 22:17:23 2006
|
||||
@@ -32,6 +32,8 @@
|
||||
/* debug RTL8139 card */
|
||||
//#define DEBUG_RTL8139 1
|
||||
|
||||
+#define PCI_FREQUENCY 33000000L
|
||||
+
|
||||
/* debug RTL8139 card C+ mode only */
|
||||
//#define DEBUG_RTL8139CP 1
|
||||
|
||||
@@ -315,6 +317,11 @@ enum chip_flags {
|
||||
(b30<<30 | b29<<29 | b28<<28 | b27<<27 | b26<<26 | b23<<23 | b22<<22)
|
||||
#define HW_REVID_MASK HW_REVID(1, 1, 1, 1, 1, 1, 1)
|
||||
|
||||
+#define RTL8139_PCI_REVID_8139 0x10
|
||||
+#define RTL8139_PCI_REVID_8139CPLUS 0x20
|
||||
+
|
||||
+#define RTL8139_PCI_REVID RTL8139_PCI_REVID_8139CPLUS
|
||||
+
|
||||
/* Size is 64 * 16bit words */
|
||||
#define EEPROM_9346_ADDR_BITS 6
|
||||
#define EEPROM_9346_SIZE (1 << EEPROM_9346_ADDR_BITS)
|
||||
@@ -414,7 +421,13 @@ typedef struct RTL8139State {
|
||||
uint32_t RxRingAddrHI;
|
||||
|
||||
EEprom9346 eeprom;
|
||||
-
|
||||
+
|
||||
+ uint32_t TCTR;
|
||||
+ uint32_t TimerInt;
|
||||
+ int64_t TCTR_base;
|
||||
+
|
||||
+ QEMUTimer *timer;
|
||||
+
|
||||
} RTL8139State;
|
||||
|
||||
void prom9346_decode_command(EEprom9346 *eeprom, uint8_t command)
|
||||
@@ -512,6 +525,19 @@ void prom9346_shift_clock(EEprom9346 *ee
|
||||
eeprom->output <<= 1;
|
||||
if (eeprom->tick == 16)
|
||||
{
|
||||
+#if 1
|
||||
+ // the FreeBSD drivers (rl and re) don't explicitly toggle
|
||||
+ // CS between reads (or does setting Cfg9346 to 0 count too?),
|
||||
+ // so we need to enter wait-for-command state here
|
||||
+ eeprom->mode = Chip9346_enter_command_mode;
|
||||
+ eeprom->input = 0;
|
||||
+ eeprom->tick = 0;
|
||||
+
|
||||
+#if defined(DEBUG_RTL8139)
|
||||
+ printf("eeprom: +++ end of read, awaiting next command\n");
|
||||
+#endif
|
||||
+#else
|
||||
+ // original behaviour
|
||||
++eeprom->address;
|
||||
eeprom->address &= EEPROM_9346_ADDR_MASK;
|
||||
eeprom->output = eeprom->contents[eeprom->address];
|
||||
@@ -521,6 +547,7 @@ void prom9346_shift_clock(EEprom9346 *ee
|
||||
printf("eeprom: +++ read next address 0x%02x data=0x%04x\n",
|
||||
eeprom->address, eeprom->output);
|
||||
#endif
|
||||
+#endif
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -751,7 +778,7 @@ static int rtl8139_can_receive(void *opa
|
||||
}
|
||||
}
|
||||
|
||||
-static void rtl8139_receive(void *opaque, const uint8_t *buf, int size)
|
||||
+static void rtl8139_do_receive(void *opaque, const uint8_t *buf, int size, int do_interrupt)
|
||||
{
|
||||
RTL8139State *s = opaque;
|
||||
|
||||
@@ -1078,9 +1105,18 @@ static void rtl8139_receive(void *opaque
|
||||
}
|
||||
|
||||
s->IntrStatus |= RxOK;
|
||||
- rtl8139_update_irq(s);
|
||||
+
|
||||
+ if (do_interrupt)
|
||||
+ {
|
||||
+ rtl8139_update_irq(s);
|
||||
+ }
|
||||
}
|
||||
|
||||
+static void rtl8139_receive(void *opaque, const uint8_t *buf, int size)
|
||||
+{
|
||||
+ rtl8139_do_receive(opaque, buf, size, 1);
|
||||
+}
|
||||
+
|
||||
static void rtl8139_reset_rxring(RTL8139State *s, uint32_t bufferSize)
|
||||
{
|
||||
s->RxBufferSize = bufferSize;
|
||||
@@ -1103,6 +1139,11 @@ static void rtl8139_reset(RTL8139State *
|
||||
|
||||
/* prepare eeprom */
|
||||
s->eeprom.contents[0] = 0x8129;
|
||||
+#if 1
|
||||
+ // PCI vendor and device ID should be mirrored here
|
||||
+ s->eeprom.contents[1] = 0x10ec;
|
||||
+ s->eeprom.contents[2] = 0x8139;
|
||||
+#endif
|
||||
memcpy(&s->eeprom.contents[7], s->macaddr, 6);
|
||||
|
||||
/* mark all status registers as owned by host */
|
||||
@@ -1129,7 +1170,7 @@ static void rtl8139_reset(RTL8139State *
|
||||
// s->TxConfig |= HW_REVID(1, 0, 0, 0, 0, 0, 0); // RTL-8139 HasHltClk
|
||||
s->clock_enabled = 0;
|
||||
#else
|
||||
- s->TxConfig |= HW_REVID(1, 1, 1, 0, 1, 0, 0); // RTL-8139C HasLWake
|
||||
+ s->TxConfig |= HW_REVID(1, 1, 1, 0, 1, 1, 0); // RTL-8139C+ HasLWake
|
||||
s->clock_enabled = 1;
|
||||
#endif
|
||||
|
||||
@@ -1157,6 +1198,11 @@ static void rtl8139_reset(RTL8139State *
|
||||
s->NWayAdvert = 0x05e1; /* all modes, full duplex */
|
||||
s->NWayLPAR = 0x05e1; /* all modes, full duplex */
|
||||
s->NWayExpansion = 0x0001; /* autonegotiation supported */
|
||||
+
|
||||
+ /* also reset timer and disable timer interrupt */
|
||||
+ s->TCTR = 0;
|
||||
+ s->TimerInt = 0;
|
||||
+ s->TCTR_base = 0;
|
||||
}
|
||||
|
||||
static void rtl8139_ChipCmd_write(RTL8139State *s, uint32_t val)
|
||||
@@ -1622,13 +1668,23 @@ static int rtl8139_transmit_one(RTL8139S
|
||||
#endif
|
||||
cpu_physical_memory_read(s->TxAddr[descriptor], txbuffer, txsize);
|
||||
|
||||
- qemu_send_packet(s->vc, txbuffer, txsize);
|
||||
-
|
||||
/* Mark descriptor as transferred */
|
||||
s->TxStatus[descriptor] |= TxHostOwns;
|
||||
s->TxStatus[descriptor] |= TxStatOK;
|
||||
|
||||
+ if (TxLoopBack == (s->TxConfig & TxLoopBack))
|
||||
+ {
|
||||
#ifdef DEBUG_RTL8139
|
||||
+ printf("RTL8139: +++ transmit loopback mode\n");
|
||||
+#endif
|
||||
+ rtl8139_do_receive(s, txbuffer, txsize, 0);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ qemu_send_packet(s->vc, txbuffer, txsize);
|
||||
+ }
|
||||
+
|
||||
+#ifdef DEBUG_RTL8139
|
||||
printf("RTL8139: +++ transmitted %d bytes from descriptor %d\n", txsize, descriptor);
|
||||
#endif
|
||||
|
||||
@@ -1748,9 +1804,6 @@ static int rtl8139_cplus_transmit_one(RT
|
||||
#endif
|
||||
cpu_physical_memory_read(tx_addr, txbuffer, txsize);
|
||||
|
||||
- /* transmit the packet */
|
||||
- qemu_send_packet(s->vc, txbuffer, txsize);
|
||||
-
|
||||
/* transfer ownership to target */
|
||||
txdw0 &= ~CP_RX_OWN;
|
||||
|
||||
@@ -1777,7 +1830,20 @@ static int rtl8139_cplus_transmit_one(RT
|
||||
++s->currCPlusTxDesc;
|
||||
}
|
||||
|
||||
+ if (TxLoopBack == (s->TxConfig & TxLoopBack))
|
||||
+ {
|
||||
#ifdef DEBUG_RTL8139
|
||||
+ printf("RTL8139: +++ C+ transmit loopback mode\n");
|
||||
+#endif
|
||||
+ rtl8139_receive(s, txbuffer, txsize);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ /* transmit the packet */
|
||||
+ qemu_send_packet(s->vc, txbuffer, txsize);
|
||||
+ }
|
||||
+
|
||||
+#ifdef DEBUG_RTL8139
|
||||
printf("RTL8139: +++ C+ mode transmitted %d bytes from descriptor %d\n", txsize, descriptor);
|
||||
#endif
|
||||
return 1;
|
||||
@@ -1909,6 +1975,8 @@ static void rtl8139_TxAddr_write(RTL8139
|
||||
#endif
|
||||
|
||||
s->TxAddr[txAddrOffset/4] = le32_to_cpu(val);
|
||||
+
|
||||
+ s->currCPlusTxDesc = 0;
|
||||
}
|
||||
|
||||
static uint32_t rtl8139_TxAddr_read(RTL8139State *s, uint32_t txAddrOffset)
|
||||
@@ -1949,6 +2017,18 @@ static uint32_t rtl8139_RxBufPtr_read(RT
|
||||
return ret;
|
||||
}
|
||||
|
||||
+static uint32_t rtl8139_RxBufAddr_read(RTL8139State *s)
|
||||
+{
|
||||
+ /* this value is NOT off by 16 */
|
||||
+ uint32_t ret = s->RxBufAddr;
|
||||
+
|
||||
+#ifdef DEBUG_RTL8139
|
||||
+ printf("RTL8139: RxBufAddr read val=0x%04x\n", ret);
|
||||
+#endif
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
static void rtl8139_RxBuf_write(RTL8139State *s, uint32_t val)
|
||||
{
|
||||
#ifdef DEBUG_RTL8139
|
||||
@@ -2281,6 +2361,21 @@ static void rtl8139_io_writel(void *opaq
|
||||
s->RxRingAddrHI = val;
|
||||
break;
|
||||
|
||||
+ case Timer:
|
||||
+#ifdef DEBUG_RTL8139
|
||||
+ printf("RTL8139: TCTR Timer reset on write\n");
|
||||
+#endif
|
||||
+ s->TCTR = 0;
|
||||
+ s->TCTR_base = qemu_get_clock(vm_clock);
|
||||
+ break;
|
||||
+
|
||||
+ case FlashReg:
|
||||
+#ifdef DEBUG_RTL8139
|
||||
+ printf("RTL8139: FlashReg TimerInt write val=0x%08x\n", val);
|
||||
+#endif
|
||||
+ s->TimerInt = val;
|
||||
+ break;
|
||||
+
|
||||
default:
|
||||
#ifdef DEBUG_RTL8139
|
||||
printf("RTL8139: ioport write(l) addr=0x%x val=0x%08x via write(b)\n", addr, val);
|
||||
@@ -2355,7 +2450,7 @@ static uint32_t rtl8139_io_readb(void *o
|
||||
break;
|
||||
|
||||
case PCIRevisionID:
|
||||
- ret = 0x10;
|
||||
+ ret = RTL8139_PCI_REVID;
|
||||
#ifdef DEBUG_RTL8139
|
||||
printf("RTL8139: PCI Revision ID read 0x%x\n", ret);
|
||||
#endif
|
||||
@@ -2411,6 +2506,10 @@ static uint32_t rtl8139_io_readw(void *o
|
||||
ret = rtl8139_RxBufPtr_read(s);
|
||||
break;
|
||||
|
||||
+ case RxBufAddr:
|
||||
+ ret = rtl8139_RxBufAddr_read(s);
|
||||
+ break;
|
||||
+
|
||||
case BasicModeCtrl:
|
||||
ret = rtl8139_BasicModeCtrl_read(s);
|
||||
break;
|
||||
@@ -2521,6 +2620,20 @@ static uint32_t rtl8139_io_readl(void *o
|
||||
#endif
|
||||
break;
|
||||
|
||||
+ case Timer:
|
||||
+ ret = s->TCTR;
|
||||
+#ifdef DEBUG_RTL8139
|
||||
+ printf("RTL8139: TCTR Timer read val=0x%08x\n", ret);
|
||||
+#endif
|
||||
+ break;
|
||||
+
|
||||
+ case FlashReg:
|
||||
+ ret = s->TimerInt;
|
||||
+#ifdef DEBUG_RTL8139
|
||||
+ printf("RTL8139: FlashReg TimerInt read val=0x%08x\n", ret);
|
||||
+#endif
|
||||
+ break;
|
||||
+
|
||||
default:
|
||||
#ifdef DEBUG_RTL8139
|
||||
printf("RTL8139: ioport read(l) addr=0x%x via read(b)\n", addr);
|
||||
@@ -2688,6 +2801,10 @@ static void rtl8139_save(QEMUFile* f,voi
|
||||
qemu_put_8s(f, &s->eeprom.eesk);
|
||||
qemu_put_8s(f, &s->eeprom.eedi);
|
||||
qemu_put_8s(f, &s->eeprom.eedo);
|
||||
+
|
||||
+ qemu_put_be32s(f, &s->TCTR);
|
||||
+ qemu_put_be32s(f, &s->TimerInt);
|
||||
+ qemu_put_be64s(f, &s->TCTR_base);
|
||||
}
|
||||
|
||||
static int rtl8139_load(QEMUFile* f,void* opaque,int version_id)
|
||||
@@ -2695,9 +2812,11 @@ static int rtl8139_load(QEMUFile* f,void
|
||||
RTL8139State* s=(RTL8139State*)opaque;
|
||||
int i;
|
||||
|
||||
- if (version_id != 1)
|
||||
+ /* just 2 versions for now */
|
||||
+ if (version_id > 2)
|
||||
return -EINVAL;
|
||||
|
||||
+ /* saved since version 1 */
|
||||
qemu_get_buffer(f, s->phys, 6);
|
||||
qemu_get_buffer(f, s->mult, 8);
|
||||
|
||||
@@ -2769,7 +2888,22 @@ static int rtl8139_load(QEMUFile* f,void
|
||||
qemu_get_8s(f, &s->eeprom.eedi);
|
||||
qemu_get_8s(f, &s->eeprom.eedo);
|
||||
|
||||
- return 0;
|
||||
+ /* saved since version 2 */
|
||||
+ if (version_id >= 2)
|
||||
+ {
|
||||
+ qemu_get_be32s(f, &s->TCTR);
|
||||
+ qemu_get_be32s(f, &s->TimerInt);
|
||||
+ qemu_get_be64s(f, &s->TCTR_base);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ /* not saved, use default */
|
||||
+ s->TCTR = 0;
|
||||
+ s->TimerInt = 0;
|
||||
+ s->TCTR_base = 0;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
/***********************************************************/
|
||||
@@ -2817,6 +2951,63 @@ static CPUWriteMemoryFunc *rtl8139_mmio_
|
||||
rtl8139_mmio_writel,
|
||||
};
|
||||
|
||||
+static inline int64_t rtl8139_get_next_tctr_time(RTL8139State *s, int64_t current_time)
|
||||
+{
|
||||
+ int64_t next_time = current_time +
|
||||
+ muldiv64(1, ticks_per_sec, PCI_FREQUENCY);
|
||||
+ if (next_time <= current_time)
|
||||
+ next_time = current_time + 1;
|
||||
+ return next_time;
|
||||
+}
|
||||
+
|
||||
+static void rtl8139_timer(void *opaque)
|
||||
+{
|
||||
+ RTL8139State *s = opaque;
|
||||
+
|
||||
+ int is_timeout = 0;
|
||||
+
|
||||
+ int64_t curr_time;
|
||||
+ uint32_t curr_tick;
|
||||
+
|
||||
+ if (!s->clock_enabled)
|
||||
+ {
|
||||
+#ifdef DEBUG_RTL8139
|
||||
+ printf("RTL8139: >>> timer: clock is not running\n");
|
||||
+#endif
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ curr_time = qemu_get_clock(vm_clock);
|
||||
+
|
||||
+ curr_tick = muldiv64(curr_time - s->TCTR_base, PCI_FREQUENCY, ticks_per_sec);
|
||||
+
|
||||
+ if (s->TimerInt && curr_tick >= s->TimerInt)
|
||||
+ {
|
||||
+ if (s->TCTR < s->TimerInt || curr_tick < s->TCTR)
|
||||
+ {
|
||||
+ is_timeout = 1;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ s->TCTR = curr_tick;
|
||||
+
|
||||
+#ifdef DEBUG_RTL8139
|
||||
+ printf("RTL8139: >>> timer: tick=%08u\n", s->TCTR);
|
||||
+#endif
|
||||
+
|
||||
+ if (is_timeout)
|
||||
+ {
|
||||
+#ifdef DEBUG_RTL8139
|
||||
+ printf("RTL8139: >>> timer: timeout tick=%08u\n", s->TCTR);
|
||||
+#endif
|
||||
+ s->IntrStatus |= PCSTimeout;
|
||||
+ rtl8139_update_irq(s);
|
||||
+ }
|
||||
+
|
||||
+ qemu_mod_timer(s->timer,
|
||||
+ rtl8139_get_next_tctr_time(s,curr_time));
|
||||
+}
|
||||
+
|
||||
void pci_rtl8139_init(PCIBus *bus, NICInfo *nd)
|
||||
{
|
||||
PCIRTL8139State *d;
|
||||
@@ -2833,7 +3024,7 @@ void pci_rtl8139_init(PCIBus *bus, NICIn
|
||||
pci_conf[0x02] = 0x39;
|
||||
pci_conf[0x03] = 0x81;
|
||||
pci_conf[0x04] = 0x05; /* command = I/O space, Bus Master */
|
||||
- pci_conf[0x08] = 0x20; /* 0x10 */ /* PCI revision ID; >=0x20 is for 8139C+ */
|
||||
+ pci_conf[0x08] = RTL8139_PCI_REVID; /* PCI revision ID; >=0x20 is for 8139C+ */
|
||||
pci_conf[0x0a] = 0x00; /* ethernet network controller */
|
||||
pci_conf[0x0b] = 0x02;
|
||||
pci_conf[0x0e] = 0x00; /* header_type */
|
||||
@@ -2869,7 +3060,13 @@ void pci_rtl8139_init(PCIBus *bus, NICIn
|
||||
s->macaddr[5]);
|
||||
|
||||
/* XXX: instance number ? */
|
||||
- register_savevm("rtl8139", 0, 1, rtl8139_save, rtl8139_load, s);
|
||||
+ register_savevm("rtl8139", 0, 2, rtl8139_save, rtl8139_load, s);
|
||||
register_savevm("rtl8139_pci", 0, 1, generic_pci_save, generic_pci_load,
|
||||
&d->dev);
|
||||
+
|
||||
+ s->timer = qemu_new_timer(vm_clock, rtl8139_timer, s);
|
||||
+
|
||||
+ qemu_mod_timer(s->timer,
|
||||
+ rtl8139_get_next_tctr_time(s,qemu_get_clock(vm_clock)));
|
||||
}
|
||||
+
|
@ -1,6 +1,6 @@
|
||||
$OpenBSD: patch-osdep_h,v 1.1.1.1 2005/03/07 16:41:28 todd Exp $
|
||||
--- osdep.h.orig Thu Feb 10 15:59:25 2005
|
||||
+++ osdep.h Sun Feb 27 15:47:13 2005
|
||||
$OpenBSD: patch-osdep_h,v 1.2 2006/12/22 17:31:45 todd Exp $
|
||||
--- osdep.h.orig Sat Jul 22 13:23:34 2006
|
||||
+++ osdep.h Sun Nov 12 17:10:10 2006
|
||||
@@ -2,6 +2,10 @@
|
||||
#define QEMU_OSDEP_H
|
||||
|
||||
@ -12,7 +12,7 @@ $OpenBSD: patch-osdep_h,v 1.1.1.1 2005/03/07 16:41:28 todd Exp $
|
||||
|
||||
int qemu_vsnprintf(char *buf, int buflen, const char *fmt, va_list args);
|
||||
void qemu_vprintf(const char *fmt, va_list ap);
|
||||
@@ -31,7 +35,7 @@ extern void __longjmp(jmp_buf env, int v
|
||||
@@ -33,7 +37,7 @@ struct siginfo;
|
||||
struct qemu_sigaction {
|
||||
union {
|
||||
void (*_sa_handler)(int);
|
||||
|
@ -1,7 +1,7 @@
|
||||
$OpenBSD: patch-qemu-img_c,v 1.1 2006/04/10 21:10:05 todd Exp $
|
||||
--- qemu-img.c.orig Mon Feb 20 22:57:21 2006
|
||||
+++ qemu-img.c Mon Feb 20 22:56:51 2006
|
||||
@@ -58,7 +58,7 @@ char *qemu_strdup(const char *str)
|
||||
$OpenBSD: patch-qemu-img_c,v 1.2 2006/12/22 17:31:45 todd Exp $
|
||||
--- qemu-img.c.orig Sat Jul 22 13:23:34 2006
|
||||
+++ qemu-img.c Sun Nov 12 17:10:10 2006
|
||||
@@ -62,7 +62,7 @@ char *qemu_strdup(const char *str)
|
||||
return ptr;
|
||||
}
|
||||
|
||||
@ -10,7 +10,7 @@ $OpenBSD: patch-qemu-img_c,v 1.1 2006/04/10 21:10:05 todd Exp $
|
||||
{
|
||||
int c;
|
||||
char *q = buf;
|
||||
@@ -76,7 +76,7 @@ void pstrcpy(char *buf, int buf_size, co
|
||||
@@ -80,7 +80,7 @@ void pstrcpy(char *buf, int buf_size, co
|
||||
}
|
||||
|
||||
/* strcat and truncate. */
|
||||
|
@ -1,7 +1,7 @@
|
||||
$OpenBSD: patch-target-i386_helper2_c,v 1.3 2006/06/08 14:33:38 todd Exp $
|
||||
--- target-i386/helper2.c.orig Wed May 3 15:32:58 2006
|
||||
+++ target-i386/helper2.c Fri May 5 22:07:41 2006
|
||||
@@ -124,7 +124,7 @@ CPUX86State *cpu_x86_init(void)
|
||||
$OpenBSD: patch-target-i386_helper2_c,v 1.4 2006/12/22 17:31:45 todd Exp $
|
||||
--- target-i386/helper2.c.orig Sat Jul 22 13:23:34 2006
|
||||
+++ target-i386/helper2.c Sun Nov 12 17:10:10 2006
|
||||
@@ -127,7 +127,7 @@ CPUX86State *cpu_x86_init(void)
|
||||
env->cpuid_model[i >> 2] |= c << (8 * (i & 3));
|
||||
}
|
||||
}
|
||||
@ -10,7 +10,7 @@ $OpenBSD: patch-target-i386_helper2_c,v 1.3 2006/06/08 14:33:38 todd Exp $
|
||||
/* currently not enabled for std i386 because not fully tested */
|
||||
env->cpuid_ext2_features = (env->cpuid_features & 0x0183F3FF);
|
||||
env->cpuid_ext2_features |= CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX;
|
||||
@@ -132,7 +132,7 @@ CPUX86State *cpu_x86_init(void)
|
||||
@@ -135,7 +135,7 @@ CPUX86State *cpu_x86_init(void)
|
||||
|
||||
/* these features are needed for Win64 and aren't fully implemented */
|
||||
env->cpuid_features |= CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA;
|
||||
|
@ -1,5 +1,5 @@
|
||||
--- vl.c.orig Wed May 3 15:32:58 2006
|
||||
+++ vl.c Fri May 5 22:24:31 2006
|
||||
--- vl.c.orig Mon Dec 18 16:55:53 2006
|
||||
+++ vl.c Mon Dec 18 17:06:04 2006
|
||||
@@ -43,7 +43,8 @@
|
||||
#include <netdb.h>
|
||||
#ifdef _BSD
|
||||
@ -10,15 +10,7 @@
|
||||
#include <libutil.h>
|
||||
#endif
|
||||
#else
|
||||
@@ -130,6 +131,7 @@ QEMUTimer *gui_timer;
|
||||
int vm_running;
|
||||
int rtc_utc = 1;
|
||||
int cirrus_vga_enabled = 1;
|
||||
+int nic_pcnet = 0;
|
||||
#ifdef TARGET_SPARC
|
||||
int graphic_width = 1024;
|
||||
int graphic_height = 768;
|
||||
@@ -292,7 +294,7 @@ void isa_unassign_ioport(int start, int
|
||||
@@ -291,7 +292,7 @@ void isa_unassign_ioport(int start, int
|
||||
|
||||
/***********************************************************/
|
||||
|
||||
@ -27,7 +19,7 @@
|
||||
{
|
||||
int c;
|
||||
char *q = buf;
|
||||
@@ -310,7 +312,7 @@ void pstrcpy(char *buf, int buf_size, co
|
||||
@@ -309,7 +310,7 @@ void pstrcpy(char *buf, int buf_size, co
|
||||
}
|
||||
|
||||
/* strcat and truncate. */
|
||||
@ -36,32 +28,7 @@
|
||||
{
|
||||
int len;
|
||||
len = strlen(buf);
|
||||
@@ -561,7 +563,23 @@ int64_t cpu_get_real_ticks(void)
|
||||
}
|
||||
|
||||
#else
|
||||
-#error unsupported CPU
|
||||
+# warning non-optimized CPU
|
||||
+#include <sys/time.h>
|
||||
+#include <time.h>
|
||||
+
|
||||
+int64_t cpu_get_real_ticks(void)
|
||||
+{
|
||||
+ struct timeval tv;
|
||||
+ static int64_t i = 0;
|
||||
+ int64_t j;
|
||||
+
|
||||
+ gettimeofday(&tv, NULL);
|
||||
+ do {
|
||||
+ j = (tv.tv_sec * (uint64_t) 1000000) + tv.tv_usec;
|
||||
+ } while (i == j);
|
||||
+ i = j;
|
||||
+ return j;
|
||||
+}
|
||||
#endif
|
||||
|
||||
static int64_t cpu_ticks_prev;
|
||||
@@ -2201,7 +2219,7 @@ static int parse_macaddr(uint8_t *macadd
|
||||
@@ -2631,7 +2632,7 @@ static int parse_macaddr(uint8_t *macadd
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -70,17 +37,17 @@
|
||||
{
|
||||
const char *p, *p1;
|
||||
int len;
|
||||
@@ -2560,11 +2578,85 @@ static int tap_open(char *ifname, int if
|
||||
@@ -3029,11 +3030,85 @@ static int tap_open(char *ifname, int if
|
||||
char *dev;
|
||||
struct stat s;
|
||||
|
||||
+ /* If the device was specified on the command line, use it */
|
||||
+ if (ifname[0]) {
|
||||
+ fd = open(ifname, O_RDWR);
|
||||
+ if (fd < 0) {
|
||||
+ fprintf(stderr, "warning: could not open %s: no virtual network emulation\n", ifname);
|
||||
+ return -1;
|
||||
+ }
|
||||
+ fd = open(ifname, O_RDWR);
|
||||
+ if (fd < 0) {
|
||||
+ fprintf(stderr, "warning: could not open %s: no virtual network emulation\n", ifname);
|
||||
+ return -1;
|
||||
+ }
|
||||
+ } else {
|
||||
+#ifdef __OpenBSD__
|
||||
+ struct ifreq ifr;
|
||||
@ -94,13 +61,13 @@
|
||||
+ fd = open(dname, O_RDWR);
|
||||
+ } else {
|
||||
+ for (; i != -1; i++) {
|
||||
+ snprintf(dname, sizeof dname, "/dev/tun%d", i);
|
||||
+ snprintf(dname, sizeof dname, "/dev/tun%d", i);
|
||||
+ bzero(&ifr.ifr_name, sizeof(ifr.ifr_name));
|
||||
+ snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "tun%d", i);
|
||||
+ fd = open(dname, O_RDWR);
|
||||
+ if (fd >= 0)
|
||||
+ break;
|
||||
+ else if (errno != ENOENT || ++enoentcount > 3) {
|
||||
+ snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "tun%d", i);
|
||||
+ fd = open(dname, O_RDWR);
|
||||
+ if (fd >= 0)
|
||||
+ break;
|
||||
+ else if (errno != ENOENT || ++enoentcount > 3) {
|
||||
+ if (errno != EBUSY) {
|
||||
+ err = errno;
|
||||
+ break;
|
||||
@ -110,9 +77,9 @@
|
||||
+ }
|
||||
+ }
|
||||
+ if (fd < 0) {
|
||||
+ fprintf(stderr, "warning: could not open %s (%s): no virtual "
|
||||
+ "network emulation\n", dname, strerror(err));
|
||||
+ return -1;
|
||||
+ fprintf(stderr, "warning: could not open %s (%s): no virtual "
|
||||
+ "network emulation\n", dname, strerror(err));
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ /* Set the tunnel device operation mode */
|
||||
@ -156,7 +123,7 @@
|
||||
|
||||
fstat(fd, &s);
|
||||
dev = devname(s.st_rdev, S_IFCHR);
|
||||
@@ -3065,7 +3157,8 @@ static int net_socket_mcast_init(VLANSta
|
||||
@@ -3535,7 +3610,8 @@ static int net_socket_mcast_init(VLANSta
|
||||
|
||||
}
|
||||
|
||||
@ -166,12 +133,12 @@
|
||||
const char *tag, const char *str)
|
||||
{
|
||||
const char *p;
|
||||
@@ -3190,17 +3283,21 @@ int net_client_init(const char *str)
|
||||
@@ -3660,17 +3736,21 @@ int net_client_init(const char *str)
|
||||
char ifname[64];
|
||||
char setup_script[1024];
|
||||
int fd;
|
||||
+ bzero(&ifname,sizeof(ifname));
|
||||
+ bzero(&setup_script,sizeof(setup_script));
|
||||
+ bzero(&ifname,sizeof(ifname));
|
||||
+ bzero(&setup_script,sizeof(setup_script));
|
||||
if (get_param_value(buf, sizeof(buf), "fd", p) > 0) {
|
||||
fd = strtol(buf, NULL, 0);
|
||||
ret = -1;
|
||||
@ -184,37 +151,38 @@
|
||||
}
|
||||
- ret = net_tap_init(vlan, ifname, setup_script);
|
||||
+ if (get_param_value(ifname, sizeof(ifname), "ifname", p) == 0)
|
||||
+ ret = net_tap_init(vlan, NULL, setup_script);
|
||||
+ else
|
||||
+ ret = net_tap_init(vlan, ifname, setup_script);
|
||||
+ ret = net_tap_init(vlan, NULL, setup_script);
|
||||
+ else
|
||||
+ ret = net_tap_init(vlan, ifname, setup_script);
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
@@ -4623,6 +4720,7 @@ void help(void)
|
||||
#if defined(TARGET_PPC) || defined(TARGET_SPARC)
|
||||
"-g WxH[xDEPTH] Set the initial graphical resolution and depth\n"
|
||||
@@ -5453,7 +5533,23 @@ void register_machines(void)
|
||||
#elif defined(TARGET_SH4)
|
||||
qemu_register_machine(&shix_machine);
|
||||
#else
|
||||
-#error unsupported CPU
|
||||
+# warning non-optimized CPU
|
||||
+#include <sys/time.h>
|
||||
+#include <time.h>
|
||||
+
|
||||
+int64_t cpu_get_real_ticks(void)
|
||||
+{
|
||||
+ struct timeval tv;
|
||||
+ static int64_t i = 0;
|
||||
+ int64_t j;
|
||||
+
|
||||
+ gettimeofday(&tv, NULL);
|
||||
+ do {
|
||||
+ j = (tv.tv_sec * (uint64_t) 1000000) + tv.tv_usec;
|
||||
+ } while (i == j);
|
||||
+ i = j;
|
||||
+ return j;
|
||||
+}
|
||||
#endif
|
||||
+ "-nic-pcnet simulate an AMD PC-Net PCI ethernet adaptor\n"
|
||||
"\n"
|
||||
"Network options:\n"
|
||||
"-net nic[,vlan=n][,macaddr=addr][,model=type]\n"
|
||||
@@ -4735,6 +4833,7 @@ enum {
|
||||
QEMU_OPTION_audio_help,
|
||||
QEMU_OPTION_soundhw,
|
||||
#endif
|
||||
+ QEMU_OPTION_nic_pcnet,
|
||||
}
|
||||
|
||||
QEMU_OPTION_net,
|
||||
QEMU_OPTION_tftp,
|
||||
@@ -4841,6 +4940,7 @@ const QEMUOption qemu_options[] = {
|
||||
|
||||
/* temporary options */
|
||||
{ "usb", 0, QEMU_OPTION_usb },
|
||||
+ { "nic-pcnet", 0, QEMU_OPTION_nic_pcnet },
|
||||
{ "cirrusvga", 0, QEMU_OPTION_cirrusvga },
|
||||
{ NULL },
|
||||
};
|
||||
@@ -5101,7 +5201,7 @@ int main(int argc, char **argv)
|
||||
@@ -5671,7 +5767,7 @@ int main(int argc, char **argv)
|
||||
serial_devices[i][0] = '\0';
|
||||
serial_device_index = 0;
|
||||
|
||||
@ -223,13 +191,3 @@
|
||||
for(i = 1; i < MAX_PARALLEL_PORTS; i++)
|
||||
parallel_devices[i][0] = '\0';
|
||||
parallel_device_index = 0;
|
||||
@@ -5261,6 +5361,9 @@ int main(int argc, char **argv)
|
||||
optarg);
|
||||
nb_net_clients++;
|
||||
break;
|
||||
+ case QEMU_OPTION_nic_pcnet:
|
||||
+ nic_pcnet = 1;
|
||||
+ break;
|
||||
#ifdef CONFIG_SLIRP
|
||||
case QEMU_OPTION_tftp:
|
||||
tftp_prefix = optarg;
|
||||
|
@ -1,7 +1,7 @@
|
||||
$OpenBSD: patch-vl_h,v 1.5 2006/06/08 14:33:38 todd Exp $
|
||||
--- vl.h.orig Wed May 3 15:32:58 2006
|
||||
+++ vl.h Fri May 5 22:07:42 2006
|
||||
@@ -96,8 +96,8 @@ void hw_error(const char *fmt, ...);
|
||||
$OpenBSD: patch-vl_h,v 1.6 2006/12/22 17:31:45 todd Exp $
|
||||
--- vl.h.orig Sat Jul 22 13:23:34 2006
|
||||
+++ vl.h Sun Nov 12 17:10:10 2006
|
||||
@@ -104,8 +104,8 @@ void hw_error(const char *fmt, ...);
|
||||
|
||||
extern const char *bios_dir;
|
||||
|
||||
@ -12,16 +12,3 @@ $OpenBSD: patch-vl_h,v 1.5 2006/06/08 14:33:38 todd Exp $
|
||||
int strstart(const char *str, const char *val, const char **ptr);
|
||||
|
||||
extern int vm_running;
|
||||
@@ -769,6 +769,12 @@ int fdctrl_get_drive_type(fdctrl_t *fdct
|
||||
|
||||
void isa_ne2000_init(int base, int irq, NICInfo *nd);
|
||||
void pci_ne2000_init(PCIBus *bus, NICInfo *nd);
|
||||
+
|
||||
+/* pcnet.c */
|
||||
+
|
||||
+extern int nic_pcnet;
|
||||
+
|
||||
+void pci_pcnet_init(PCIBus *bus, NICInfo *nd);
|
||||
|
||||
/* rtl8139.c */
|
||||
|
||||
|
@ -1,294 +0,0 @@
|
||||
$OpenBSD: patch-vnc_c,v 1.1 2006/06/08 14:33:38 todd Exp $
|
||||
--- vnc.c.orig Wed May 3 15:32:58 2006
|
||||
+++ vnc.c Fri May 12 18:46:20 2006
|
||||
@@ -42,6 +42,14 @@ typedef struct VncState VncState;
|
||||
|
||||
typedef int VncReadEvent(VncState *vs, char *data, size_t len);
|
||||
|
||||
+typedef void VncWritePixels(VncState *vs, void *data, int size);
|
||||
+
|
||||
+typedef void VncSendHextileTile(VncState *vs,
|
||||
+ int x, int y, int w, int h,
|
||||
+ uint32_t *last_bg,
|
||||
+ uint32_t *last_fg,
|
||||
+ int *has_bg, int *has_fg);
|
||||
+
|
||||
struct VncState
|
||||
{
|
||||
QEMUTimer *timer;
|
||||
@@ -53,12 +61,19 @@ struct VncState
|
||||
int height;
|
||||
uint64_t dirty_row[768];
|
||||
char *old_data;
|
||||
- int depth;
|
||||
+ int depth; /* internal VNC frame buffer byte per pixel */
|
||||
int has_resize;
|
||||
int has_hextile;
|
||||
Buffer output;
|
||||
Buffer input;
|
||||
kbd_layout_t *kbd_layout;
|
||||
+ /* current output mode information */
|
||||
+ VncWritePixels *write_pixels;
|
||||
+ VncSendHextileTile *send_hextile_tile;
|
||||
+ int pix_bpp, pix_big_endian;
|
||||
+ int red_shift, red_max, red_shift1;
|
||||
+ int green_shift, green_max, green_shift1;
|
||||
+ int blue_shift, blue_max, blue_shift1;
|
||||
|
||||
VncReadEvent *read_handler;
|
||||
size_t read_handler_expect;
|
||||
@@ -130,6 +145,66 @@ static void vnc_dpy_resize(DisplayState
|
||||
}
|
||||
}
|
||||
|
||||
+/* fastest code */
|
||||
+static void vnc_write_pixels_copy(VncState *vs, void *pixels, int size)
|
||||
+{
|
||||
+ vnc_write(vs, pixels, size);
|
||||
+}
|
||||
+
|
||||
+/* slowest but generic code. */
|
||||
+static void vnc_convert_pixel(VncState *vs, uint8_t *buf, uint32_t v)
|
||||
+{
|
||||
+ unsigned int r, g, b;
|
||||
+
|
||||
+ r = (v >> vs->red_shift1) & vs->red_max;
|
||||
+ g = (v >> vs->green_shift1) & vs->green_max;
|
||||
+ b = (v >> vs->blue_shift1) & vs->blue_max;
|
||||
+ v = (r << vs->red_shift) |
|
||||
+ (g << vs->green_shift) |
|
||||
+ (b << vs->blue_shift);
|
||||
+ switch(vs->pix_bpp) {
|
||||
+ case 1:
|
||||
+ buf[0] = v;
|
||||
+ break;
|
||||
+ case 2:
|
||||
+ if (vs->pix_big_endian) {
|
||||
+ buf[0] = v >> 8;
|
||||
+ buf[1] = v;
|
||||
+ } else {
|
||||
+ buf[1] = v >> 8;
|
||||
+ buf[0] = v;
|
||||
+ }
|
||||
+ break;
|
||||
+ default:
|
||||
+ case 4:
|
||||
+ if (vs->pix_big_endian) {
|
||||
+ buf[0] = v >> 24;
|
||||
+ buf[1] = v >> 16;
|
||||
+ buf[2] = v >> 8;
|
||||
+ buf[3] = v;
|
||||
+ } else {
|
||||
+ buf[3] = v >> 24;
|
||||
+ buf[2] = v >> 16;
|
||||
+ buf[1] = v >> 8;
|
||||
+ buf[0] = v;
|
||||
+ }
|
||||
+ break;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void vnc_write_pixels_generic(VncState *vs, void *pixels1, int size)
|
||||
+{
|
||||
+ uint32_t *pixels = pixels1;
|
||||
+ uint8_t buf[4];
|
||||
+ int n, i;
|
||||
+
|
||||
+ n = size >> 2;
|
||||
+ for(i = 0; i < n; i++) {
|
||||
+ vnc_convert_pixel(vs, buf, pixels[i]);
|
||||
+ vnc_write(vs, buf, vs->pix_bpp);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static void send_framebuffer_update_raw(VncState *vs, int x, int y, int w, int h)
|
||||
{
|
||||
int i;
|
||||
@@ -139,7 +214,7 @@ static void send_framebuffer_update_raw(
|
||||
|
||||
row = vs->ds->data + y * vs->ds->linesize + x * vs->depth;
|
||||
for (i = 0; i < h; i++) {
|
||||
- vnc_write(vs, row, w * vs->depth);
|
||||
+ vs->write_pixels(vs, row, w * vs->depth);
|
||||
row += vs->ds->linesize;
|
||||
}
|
||||
}
|
||||
@@ -162,35 +237,26 @@ static void hextile_enc_cord(uint8_t *pt
|
||||
#include "vnchextile.h"
|
||||
#undef BPP
|
||||
|
||||
+#define GENERIC
|
||||
+#define BPP 32
|
||||
+#include "vnchextile.h"
|
||||
+#undef BPP
|
||||
+#undef GENERIC
|
||||
+
|
||||
static void send_framebuffer_update_hextile(VncState *vs, int x, int y, int w, int h)
|
||||
{
|
||||
int i, j;
|
||||
int has_fg, has_bg;
|
||||
uint32_t last_fg32, last_bg32;
|
||||
- uint16_t last_fg16, last_bg16;
|
||||
- uint8_t last_fg8, last_bg8;
|
||||
|
||||
vnc_framebuffer_update(vs, x, y, w, h, 5);
|
||||
|
||||
has_fg = has_bg = 0;
|
||||
for (j = y; j < (y + h); j += 16) {
|
||||
for (i = x; i < (x + w); i += 16) {
|
||||
- switch (vs->depth) {
|
||||
- case 1:
|
||||
- send_hextile_tile_8(vs, i, j, MIN(16, x + w - i), MIN(16, y + h - j),
|
||||
- &last_bg8, &last_fg8, &has_bg, &has_fg);
|
||||
- break;
|
||||
- case 2:
|
||||
- send_hextile_tile_16(vs, i, j, MIN(16, x + w - i), MIN(16, y + h - j),
|
||||
- &last_bg16, &last_fg16, &has_bg, &has_fg);
|
||||
- break;
|
||||
- case 4:
|
||||
- send_hextile_tile_32(vs, i, j, MIN(16, x + w - i), MIN(16, y + h - j),
|
||||
+ vs->send_hextile_tile(vs, i, j,
|
||||
+ MIN(16, x + w - i), MIN(16, y + h - j),
|
||||
&last_bg32, &last_fg32, &has_bg, &has_fg);
|
||||
- break;
|
||||
- default:
|
||||
- break;
|
||||
- }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -660,31 +726,80 @@ static void set_encodings(VncState *vs,
|
||||
}
|
||||
}
|
||||
|
||||
+static int compute_nbits(unsigned int val)
|
||||
+{
|
||||
+ int n;
|
||||
+ n = 0;
|
||||
+ while (val != 0) {
|
||||
+ n++;
|
||||
+ val >>= 1;
|
||||
+ }
|
||||
+ return n;
|
||||
+}
|
||||
+
|
||||
static void set_pixel_format(VncState *vs,
|
||||
int bits_per_pixel, int depth,
|
||||
int big_endian_flag, int true_color_flag,
|
||||
int red_max, int green_max, int blue_max,
|
||||
int red_shift, int green_shift, int blue_shift)
|
||||
{
|
||||
- switch (bits_per_pixel) {
|
||||
- case 32:
|
||||
- case 24:
|
||||
+ int host_big_endian_flag;
|
||||
+
|
||||
+#ifdef WORDS_BIGENDIAN
|
||||
+ host_big_endian_flag = 1;
|
||||
+#else
|
||||
+ host_big_endian_flag = 0;
|
||||
+#endif
|
||||
+ if (!true_color_flag) {
|
||||
+ fail:
|
||||
+ vnc_client_error(vs);
|
||||
+ return;
|
||||
+ }
|
||||
+ if (bits_per_pixel == 32 &&
|
||||
+ host_big_endian_flag == big_endian_flag &&
|
||||
+ red_max == 0xff && green_max == 0xff && blue_max == 0xff &&
|
||||
+ red_shift == 16 && green_shift == 8 && blue_shift == 0) {
|
||||
vs->depth = 4;
|
||||
- break;
|
||||
- case 16:
|
||||
+ vs->write_pixels = vnc_write_pixels_copy;
|
||||
+ vs->send_hextile_tile = send_hextile_tile_32;
|
||||
+ } else
|
||||
+ if (bits_per_pixel == 16 &&
|
||||
+ host_big_endian_flag == big_endian_flag &&
|
||||
+ red_max == 31 && green_max == 63 && blue_max == 31 &&
|
||||
+ red_shift == 11 && green_shift == 5 && blue_shift == 0) {
|
||||
vs->depth = 2;
|
||||
- break;
|
||||
- case 8:
|
||||
+ vs->write_pixels = vnc_write_pixels_copy;
|
||||
+ vs->send_hextile_tile = send_hextile_tile_16;
|
||||
+ } else
|
||||
+ if (bits_per_pixel == 8 &&
|
||||
+ red_max == 7 && green_max == 7 && blue_max == 3 &&
|
||||
+ red_shift == 5 && green_shift == 2 && blue_shift == 0) {
|
||||
vs->depth = 1;
|
||||
- break;
|
||||
- default:
|
||||
- vnc_client_error(vs);
|
||||
- break;
|
||||
+ vs->write_pixels = vnc_write_pixels_copy;
|
||||
+ vs->send_hextile_tile = send_hextile_tile_8;
|
||||
+ } else
|
||||
+ {
|
||||
+ /* generic and slower case */
|
||||
+ if (bits_per_pixel != 8 &&
|
||||
+ bits_per_pixel != 16 &&
|
||||
+ bits_per_pixel != 32)
|
||||
+ goto fail;
|
||||
+ vs->depth = 4;
|
||||
+ vs->red_shift = red_shift;
|
||||
+ vs->red_max = red_max;
|
||||
+ vs->red_shift1 = 24 - compute_nbits(red_max);
|
||||
+ vs->green_shift = green_shift;
|
||||
+ vs->green_max = green_max;
|
||||
+ vs->green_shift1 = 16 - compute_nbits(green_max);
|
||||
+ vs->blue_shift = blue_shift;
|
||||
+ vs->blue_max = blue_max;
|
||||
+ vs->blue_shift1 = 8 - compute_nbits(blue_max);
|
||||
+ vs->pix_bpp = bits_per_pixel / 8;
|
||||
+ vs->pix_big_endian = big_endian_flag;
|
||||
+ vs->write_pixels = vnc_write_pixels_generic;
|
||||
+ vs->send_hextile_tile = send_hextile_tile_generic;
|
||||
}
|
||||
|
||||
- if (!true_color_flag)
|
||||
- vnc_client_error(vs);
|
||||
-
|
||||
vnc_dpy_resize(vs->ds, vs->ds->width, vs->ds->height);
|
||||
memset(vs->dirty_row, 0xFF, sizeof(vs->dirty_row));
|
||||
memset(vs->old_data, 42, vs->ds->linesize * vs->ds->height);
|
||||
@@ -774,7 +889,11 @@ static int protocol_client_init(VncState
|
||||
|
||||
vnc_write_u8(vs, vs->depth * 8); /* bits-per-pixel */
|
||||
vnc_write_u8(vs, vs->depth * 8); /* depth */
|
||||
+#ifdef WORDS_BIGENDIAN
|
||||
+ vnc_write_u8(vs, 1); /* big-endian-flag */
|
||||
+#else
|
||||
vnc_write_u8(vs, 0); /* big-endian-flag */
|
||||
+#endif
|
||||
vnc_write_u8(vs, 1); /* true-color-flag */
|
||||
if (vs->depth == 4) {
|
||||
vnc_write_u16(vs, 0xFF); /* red-max */
|
||||
@@ -783,6 +902,7 @@ static int protocol_client_init(VncState
|
||||
vnc_write_u8(vs, 16); /* red-shift */
|
||||
vnc_write_u8(vs, 8); /* green-shift */
|
||||
vnc_write_u8(vs, 0); /* blue-shift */
|
||||
+ vs->send_hextile_tile = send_hextile_tile_32;
|
||||
} else if (vs->depth == 2) {
|
||||
vnc_write_u16(vs, 31); /* red-max */
|
||||
vnc_write_u16(vs, 63); /* green-max */
|
||||
@@ -790,14 +910,18 @@ static int protocol_client_init(VncState
|
||||
vnc_write_u8(vs, 11); /* red-shift */
|
||||
vnc_write_u8(vs, 5); /* green-shift */
|
||||
vnc_write_u8(vs, 0); /* blue-shift */
|
||||
+ vs->send_hextile_tile = send_hextile_tile_16;
|
||||
} else if (vs->depth == 1) {
|
||||
- vnc_write_u16(vs, 3); /* red-max */
|
||||
+ /* XXX: change QEMU pixel 8 bit pixel format to match the VNC one ? */
|
||||
+ vnc_write_u16(vs, 7); /* red-max */
|
||||
vnc_write_u16(vs, 7); /* green-max */
|
||||
vnc_write_u16(vs, 3); /* blue-max */
|
||||
vnc_write_u8(vs, 5); /* red-shift */
|
||||
vnc_write_u8(vs, 2); /* green-shift */
|
||||
vnc_write_u8(vs, 0); /* blue-shift */
|
||||
+ vs->send_hextile_tile = send_hextile_tile_8;
|
||||
}
|
||||
+ vs->write_pixels = vnc_write_pixels_copy;
|
||||
|
||||
vnc_write(vs, pad, 3); /* padding */
|
||||
|
@ -1,92 +0,0 @@
|
||||
$OpenBSD: patch-vnchextile_h,v 1.1 2006/06/08 14:33:38 todd Exp $
|
||||
--- vnchextile.h.orig Wed May 3 15:32:58 2006
|
||||
+++ vnchextile.h Fri May 12 18:46:20 2006
|
||||
@@ -1,15 +1,23 @@
|
||||
#define CONCAT_I(a, b) a ## b
|
||||
#define CONCAT(a, b) CONCAT_I(a, b)
|
||||
#define pixel_t CONCAT(uint, CONCAT(BPP, _t))
|
||||
+#ifdef GENERIC
|
||||
+#define NAME generic
|
||||
+#else
|
||||
+#define NAME BPP
|
||||
+#endif
|
||||
|
||||
-static void CONCAT(send_hextile_tile_, BPP)(VncState *vs,
|
||||
+static void CONCAT(send_hextile_tile_, NAME)(VncState *vs,
|
||||
int x, int y, int w, int h,
|
||||
- pixel_t *last_bg, pixel_t *last_fg,
|
||||
+ uint32_t *last_bg32,
|
||||
+ uint32_t *last_fg32,
|
||||
int *has_bg, int *has_fg)
|
||||
{
|
||||
char *row = (vs->ds->data + y * vs->ds->linesize + x * vs->depth);
|
||||
pixel_t *irow = (pixel_t *)row;
|
||||
int j, i;
|
||||
+ pixel_t *last_bg = (pixel_t *)last_bg32;
|
||||
+ pixel_t *last_fg = (pixel_t *)last_fg32;
|
||||
pixel_t bg = 0;
|
||||
pixel_t fg = 0;
|
||||
int n_colors = 0;
|
||||
@@ -122,10 +130,15 @@ static void CONCAT(send_hextile_tile_, B
|
||||
has_color = 1;
|
||||
} else if (irow[i] != color) {
|
||||
has_color = 0;
|
||||
-
|
||||
+#ifdef GENERIC
|
||||
+ vnc_convert_pixel(vs, data + n_data, color);
|
||||
+ n_data += vs->pix_bpp;
|
||||
+#else
|
||||
memcpy(data + n_data, &color, sizeof(color));
|
||||
- hextile_enc_cord(data + n_data + sizeof(pixel_t), min_x, j, i - min_x, 1);
|
||||
- n_data += 2 + sizeof(pixel_t);
|
||||
+ n_data += sizeof(pixel_t);
|
||||
+#endif
|
||||
+ hextile_enc_cord(data + n_data, min_x, j, i - min_x, 1);
|
||||
+ n_data += 2;
|
||||
n_subtiles++;
|
||||
|
||||
min_x = -1;
|
||||
@@ -137,9 +150,15 @@ static void CONCAT(send_hextile_tile_, B
|
||||
}
|
||||
}
|
||||
if (has_color) {
|
||||
+#ifdef GENERIC
|
||||
+ vnc_convert_pixel(vs, data + n_data, color);
|
||||
+ n_data += vs->pix_bpp;
|
||||
+#else
|
||||
memcpy(data + n_data, &color, sizeof(color));
|
||||
- hextile_enc_cord(data + n_data + sizeof(pixel_t), min_x, j, i - min_x, 1);
|
||||
- n_data += 2 + sizeof(pixel_t);
|
||||
+ n_data += sizeof(pixel_t);
|
||||
+#endif
|
||||
+ hextile_enc_cord(data + n_data, min_x, j, i - min_x, 1);
|
||||
+ n_data += 2;
|
||||
n_subtiles++;
|
||||
}
|
||||
irow += vs->ds->linesize / sizeof(pixel_t);
|
||||
@@ -169,21 +188,22 @@ static void CONCAT(send_hextile_tile_, B
|
||||
vnc_write_u8(vs, flags);
|
||||
if (n_colors < 4) {
|
||||
if (flags & 0x02)
|
||||
- vnc_write(vs, last_bg, sizeof(pixel_t));
|
||||
+ vs->write_pixels(vs, last_bg, sizeof(pixel_t));
|
||||
if (flags & 0x04)
|
||||
- vnc_write(vs, last_fg, sizeof(pixel_t));
|
||||
+ vs->write_pixels(vs, last_fg, sizeof(pixel_t));
|
||||
if (n_subtiles) {
|
||||
vnc_write_u8(vs, n_subtiles);
|
||||
vnc_write(vs, data, n_data);
|
||||
}
|
||||
} else {
|
||||
for (j = 0; j < h; j++) {
|
||||
- vnc_write(vs, row, w * vs->depth);
|
||||
+ vs->write_pixels(vs, row, w * vs->depth);
|
||||
row += vs->ds->linesize;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+#undef NAME
|
||||
#undef pixel_t
|
||||
#undef CONCAT_I
|
||||
#undef CONCAT
|
@ -1,4 +1,4 @@
|
||||
@comment $OpenBSD: PLIST,v 1.6 2006/06/08 14:33:38 todd Exp $
|
||||
@comment $OpenBSD: PLIST,v 1.7 2006/12/22 17:31:45 todd Exp $
|
||||
bin/qemu
|
||||
bin/qemu-img
|
||||
bin/qemu-system-arm
|
||||
@ -56,8 +56,8 @@ share/qemu/keymaps/sv
|
||||
share/qemu/keymaps/th
|
||||
share/qemu/keymaps/tr
|
||||
share/qemu/linux_boot.bin
|
||||
share/qemu/openbios-sparc32
|
||||
share/qemu/ppc_rom.bin
|
||||
share/qemu/proll.elf
|
||||
share/qemu/vgabios-cirrus.bin
|
||||
share/qemu/vgabios.bin
|
||||
share/qemu/video.x
|
||||
|
Loading…
x
Reference in New Issue
Block a user