Hello community, here is the log from the commit of package kvm for openSUSE:Factory checked in at Mon Sep 21 21:14:00 CEST 2009. -------- --- kvm/kvm.changes 2009-08-20 20:43:45.000000000 +0200 +++ /mounts/work_src_done/STABLE/kvm/kvm.changes 2009-09-14 16:52:27.000000000 +0200 @@ -1,0 +2,9 @@ +Wed Sep 9 11:07:56 CEST 2009 - agraf@suse.de + +- Update to 0.11.0-rc2 + - no changelog provided upstream, will hopefully follow for 0.11.0 +- Include Mac OS X patches again +- Include dictzip patches (Studio related) +- Split KMP out, we'll take the kernel module as of now + +------------------------------------------------------------------- calling whatdependson for head-i586 Old: ---- kvm-88.tar.bz2 kvm-preXX-fix-build-for-ESD-audio.patch kvm-preXX-fix-serious-regression.patch kvm-preXX-fix-virtio-hd.patch kvm-preXX-init-on-demand.patch kvm-preXX-tracepoint-for-latest-kernel.patch kvm-remove-trace-calls.patch New: ---- IA64-compile-fix-suse.patch kvm-bios.patch kvm-qemu-applesmc.patch kvm-qemu-ide-ich6.patch kvm-qemu-lpc.patch kvm-qemu-macmodel.patch kvm-qemu-preXX-dictzip1.patch kvm-qemu-preXX-dictzip2.patch kvm-qemu-preXX-dictzip3.patch kvm-qemu-rtl8139-link.patch qemu-kvm-0.11.0-rc2.tar.bz2 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ kvm.spec ++++++ --- /var/tmp/diff_new_pack.t80iEH/_old 2009-09-21 21:13:31.000000000 +0200 +++ /var/tmp/diff_new_pack.t80iEH/_new 2009-09-21 21:13:31.000000000 +0200 @@ -1,5 +1,5 @@ # -# spec file for package kvm (Version 88) +# spec file for package kvm (Version 0.11.0) # # Copyright (c) 2009 SUSE LINUX Products GmbH, Nuernberg, Germany. # @@ -19,7 +19,6 @@ # icecream 0 %bcond_with vde -%define kernel_version %(echo `rpm -q --queryformat '%{VERSION}-%{RELEASE}' kernel-source`|sed 's/_/-/g;') Name: kvm BuildRequires: SDL-devel alsa alsa-devel gnutls-devel ncurses-devel pciutils-devel perl texinfo @@ -33,26 +32,27 @@ %ifarch %ix86 x86_64 BuildRequires: dev86 %endif -#%if %suse_version > 1110 -#%ifarch %ix86 x86_64 -#BuildRequires: kernel-syms-rt -#%endif -#%endif %if %suse_version >= 1100 -BuildRequires: libpulse-devel +BuildRequires: libcurl-devel libpulse-devel %endif %if %{with vde} BuildRequires: vde2-devel %endif Requires: python-curses +%if %suse_version <= 1110 +Requires: kvm-kmp +%else +Conflicts: kernel < 2.6.31 +%endif License: BSD 3-clause (or similar) ; GPL v2 only ; GPL v2 or later ; LGPL v2.1 or later ; MIT License (or similar) Group: System/Kernel Summary: Kernel-based Virtual Machine -Url: http://kvm.qumranet.com/ -Version: 88 -Release: 3 -Source0: %name-%version.tar.bz2 -ExclusiveArch: %ix86 x86_64 ia64 s390 +Url: http://www.linux-kvm.org +Version: 0.11.0 +Release: 1 +%define subversion -rc2 +Source0: qemu-%name-%{version}%{subversion}.tar.bz2 +ExclusiveArch: %ix86 x86_64 ia64 Source1: 60-kvm.rules Source2: NETKVM-20081229.iso Source3: qemu-ifup @@ -60,26 +60,25 @@ Patch01: qemu-datadir.diff Patch02: kvm-qemu-default-memsize.patch Patch03: kvm-qemu-no-fallback-if-open-kvm-fails.patch +# Mac OS X patches +Patch11: kvm-qemu-lpc.patch +Patch12: kvm-qemu-applesmc.patch +Patch14: kvm-qemu-ide-ich6.patch +Patch15: kvm-qemu-macmodel.patch +Patch16: kvm-qemu-rtl8139-link.patch +Patch90: kvm-bios.patch # Post-release upstream patches -Patch100: kvm-preXX-init-on-demand.patch -Patch101: kvm-preXX-fix-build-for-ESD-audio.patch -Patch102: kvm-preXX-fix-serious-regression.patch -Patch103: kvm-preXX-fix-virtio-hd.patch -Patch104: kvm-preXX-tracepoint-for-latest-kernel.patch -Patch105: kvm-remove-trace-calls.patch -Patch106: kvm-no-pp-directives-in-macros.patch +Patch100: kvm-no-pp-directives-in-macros.patch +Patch101: kvm-qemu-preXX-dictzip1.patch +Patch102: kvm-qemu-preXX-dictzip2.patch +Patch103: kvm-qemu-preXX-dictzip3.patch # for IA64 Source500: ia64-fix-pagesize.pl Patch500: IA64-kvm-suse.patch +Patch501: IA64-compile-fix-suse.patch # For upstream patches: BuildRoot: %{_tmppath}/%{name}-%{version}-build PreReq: /usr/sbin/groupadd -%define use_kmp 1 -%if %use_kmp -BuildRequires: module-init-tools -Requires: kvm-kmp -%suse_kernel_module_package debug kdump um xen xenpae -%endif BuildRequires: kernel-syms %description @@ -114,63 +113,37 @@ Yaniv Kamay <yaniv@qumranet.com> Dor Laor <dor.laor@qumranet.com> -%package KMP -License: BSD 3-clause (or similar) ; GPL v2 only ; GPL v2 or later ; LGPL v2.1 or later ; MIT License (or similar) -Summary: Updated kernel modules for KVM (Kernel-based Virtual Machine) -Group: System/Kernel - -%description KMP -This package contains updated kernel modules which are recommended for -enhanced functionality of KVM. The Linux kernel rpm already contains -kvm modules, but with this package installed and the modules of this -package loaded, certain fixes which are not yet available in the kernel -rpm. - -To verify the kernel to which this package is built for, compare the -postfix of this package has after "kvm-kmp-" with the postfix after -"kernel-", e.g. kvm-kmp-default contains updated modules for the -kernel-default with the exact same version number. - -To take advantage of KVM in general, you need qemu-kvm (which is -included in the package kvm) which contains the PC hardware simulation -that is needed for full virtualisation. - -KVM guests implemented using qemu-kvm can be monitored using libvirt -which contains a hypervisor for managing multible QEMU and KVM and Xen -virtual machines. virt-manager provides a graphical application for -connecting to and controlling virtual machines based on libvirt. - - - -Authors: --------- - Avi Kivity <avi@qumranet.com> - Yaniv Kamay <yaniv@qumranet.com> - Dor Laor <dor.laor@qumranet.com> - %prep -# build the BIOS on x86 platforms +# build the Mac BIOS on x86 platforms %ifarch %ix86 x86_64 %define vanilla 0 -# build no BIOS on others +# build no Mac BIOS on others %else %define vanilla 1 %endif -%setup -q +%setup -q -n qemu-%{name}-%{version}%{subversion} %patch01 -p1 %patch02 -p1 %patch03 -p1 +# Mac OS X guest +%if !%{vanilla} +%patch11 -p1 +%patch12 -p1 +%patch14 -p1 +%patch15 -p1 +%patch16 -p1 +cp -a kvm/bios kvm/bios-mac +%patch90 -p1 -b .bios-mac +%endif # Post-release patches %patch100 -p1 %patch101 -p1 %patch102 -p1 %patch103 -p1 -%patch104 -p1 -%patch105 -p1 -%patch106 -p1 # IA64 support %ifarch ia64 %patch500 -p1 +%patch501 -p1 %endif %build @@ -181,52 +154,39 @@ %else --audio-drv-list="alsa sdl oss" \ %endif +%ifarch ia64 + --target-list="ia64-softmmu" --disable-cpu-emulation \ +%endif --extra-cflags="%{optflags}" +# Aborts if curses support is not enabled: +grep "^CONFIG_CURSES=y" config-host.mak # Patch kvm/user Makefile to accept inital CFLAGS: +# XXX why? we don't install anything from kvm/user/ sed -i 's/CFLAGS =/CFLAGS +=/' kvm/user/Makefile echo "CFLAGS=%optflags" >> kvm/user/config.mak -# Patch the module version, so we know which kmp was installed: -for i in `find . -name "*.c"`; do - sed -i "s|kvm-%{version}|kvm-%{version}-%{release}|" "$i" -done -# kernel modules: -%if %use_kmp -mkdir kvm/suse-kernel -for flavor in %flavors_to_build; do - rm -rf kvm/suse-kernel/$flavor - cp -r kvm/kernel kvm/suse-kernel/$flavor - cd kvm/suse-kernel/$flavor - kver=$(line < /usr/src/linux-obj/%_target_cpu/$flavor/Makefile | cut -f4 -d/) - # old kernels have different Makefiles - if [ "${kver:0:1}" = "#" ]; then - kver=$(grep "KERNELSRC " /usr/src/linux-obj/%_target_cpu/$flavor/Makefile | cut -f4 -d/) - fi - kernel_source_dir=/usr/src/$kver - sed -i "s|KERNELDIR=.*|KERNELDIR=/usr/src/linux-obj/%_target_cpu/$flavor| -s|KERNELSOURCEDIR=.*|KERNELSOURCEDIR=$kernel_source_dir|" config.mak - make %{?jobs:-j%jobs} - cd ../../.. -done -%endif +# Patch the version, so we know which revision was installed: +sed -i "s|kvm-%{version}|kvm-%{version}-%{release}|" config-host.h # userspace: make KVM_KMOD="no" %{?jobs:-j%jobs} -%if !%{vanilla} +# Firmware +%ifarch %ix86 x86_64 make -C kvm/bios +cp kvm/bios/BIOS-bochs-latest pc-bios/bios.bin make -C kvm/vgabios +cp kvm/vgabios/VGABIOS-lgpl-latest.cirrus.bin pc-bios/vgabios-cirrus.bin +cp kvm/vgabios/VGABIOS-lgpl-latest.bin pc-bios/vgabios.bin +cp pc-bios/optionrom/extboot.bin pc-bios/ +%endif +%if !%{vanilla} +make -C kvm/bios-mac %endif %install -# kernel modules -%if %use_kmp -export INSTALL_MOD_PATH=$RPM_BUILD_ROOT -export INSTALL_MOD_DIR=updates -for flavor in %flavors_to_build; do - make -C /usr/src/linux-obj/%_target_cpu/$flavor modules_install \ - M=$PWD/kvm/suse-kernel/$flavor -done -%endif make DESTDIR=%{buildroot} KVM_KMOD="no" install mv qemu-doc.html qemu-kvm.html +%if !%{vanilla} +install -m 644 kvm/bios-mac/BIOS-bochs-latest %{buildroot}/%{_datadir}/qemu-kvm/bios-mac.bin +%endif mkdir -p %{buildroot}%{_docdir}/kvm install -m 644 qemu-kvm.html %{buildroot}%{_docdir}/kvm/qemu-kvm.html install -m 755 kvm/kvm_stat %{buildroot}%_bindir/kvm_stat @@ -249,25 +209,6 @@ %pre /usr/sbin/groupadd -r kvm 2>/dev/null || : -# XXX KMPs can not do post scripts for now -#%if %suse_version <= 1100 -#%define modprobe /sbin/modprobe -#%else -#%define modprobe /sbin/modprobe --allow-unsupported-modules -#%endif -#%post KMP -#/sbin/depmod -a || : -#if [ ! -e /.buildenv ]; then -# case `uname -r` in -# %{kernel_version}*) -# /sbin/rmmod kvm-intel || : -# /sbin/rmmod kvm-amd || : -# /sbin/rmmod kvm || : -# %{modprobe} kvm-amd || : -# %{modprobe} kvm-intel || : -# ;; -# esac -#fi %files %defattr(-,root,root) ++++++ IA64-compile-fix-suse.patch ++++++ Only in qemu-kvm-0.10.5: config-host.h~ Index: qemu-kvm-0.10.5/hw/i8259.c =================================================================== --- qemu-kvm-0.10.5.orig/hw/i8259.c +++ qemu-kvm-0.10.5/hw/i8259.c @@ -189,8 +189,10 @@ static void i8259_set_irq(void *opaque, if (kvm_enabled()) { int pic_ret; if (kvm_set_irq(irq, level, &pic_ret)) { +#if 0 if (pic_ret != 0) apic_set_irq_delivered(); +#endif return; } } Index: qemu-kvm-0.10.5/hw/ipf.c =================================================================== --- qemu-kvm-0.10.5.orig/hw/ipf.c +++ qemu-kvm-0.10.5/hw/ipf.c @@ -690,6 +690,7 @@ static int ioapic_map_irq(int devfn, int void ioapic_set_irq(void *opaque, int irq_num, int level) { int vector; + int pic_ret; PCIDevice *pci_dev = (PCIDevice *)opaque; vector = ioapic_map_irq(pci_dev->devfn, irq_num); @@ -700,7 +701,7 @@ void ioapic_set_irq(void *opaque, int ir ioapic_irq_count[vector] -= 1; if (kvm_enabled()) { - if (kvm_set_irq(vector, ioapic_irq_count[vector] == 0)) + if (kvm_set_irq(vector, ioapic_irq_count[vector] == 0, &pic_ret)) return; } } Index: qemu-kvm-0.10.5/monitor.c =================================================================== --- qemu-kvm-0.10.5.orig/monitor.c +++ qemu-kvm-0.10.5/monitor.c @@ -1598,10 +1598,12 @@ static const term_cmd_t term_cmds[] = { { "host_net_remove", "is", net_host_device_remove, "vlan_id name", "remove host VLAN client" }, #endif +#ifdef CONFIG_SLIRP { "host_net_redir", "ss?", net_slirp_redir, "[tcp|udp]:host-port:[guest-host]:guest-port", "redirect TCP or UDP connections from host to guest (requires -net user)\n" "host_net_redir remove [tcp:|udp:]host-port -- remove redirection\n" "host_net_redir list -- show all redirections" }, +#endif { "balloon", "i", do_balloon, "target", "request VM to change it's memory allocation (in MB)" }, { "set_link", "ss", do_set_link, Index: qemu-kvm-0.10.5/qemu-kvm.c =================================================================== --- qemu-kvm-0.10.5.orig/qemu-kvm.c +++ qemu-kvm-0.10.5/qemu-kvm.c @@ -750,7 +750,7 @@ static struct kvm_callbacks qemu_kvm_ops .shutdown = kvm_shutdown, .io_window = kvm_io_window, .try_push_interrupts = try_push_interrupts, -#ifdef KVM_CAP_USER_NMI +#if 0 .push_nmi = kvm_arch_push_nmi, #endif .post_kvm_run = post_kvm_run, @@ -917,7 +917,6 @@ void kvm_cpu_register_physical_memory(ta } if (must_use_aliases_target(start_addr)) return; -#endif while (size > 0) { p = find_mapping(start_addr); if (p) { @@ -931,6 +930,7 @@ void kvm_cpu_register_physical_memory(ta size = 0; } } +#endif return; } Index: qemu-kvm-0.10.5/configure =================================================================== --- qemu-kvm-0.10.5.orig/configure +++ qemu-kvm-0.10.5/configure @@ -502,7 +502,7 @@ if test "$werror" = "yes" ; then CFLAGS="$CFLAGS -Werror" fi -CFLAGS="$CFLAGS -I$(readlink -f "$source_path/kvm/libkvm")" +CFLAGS="$CFLAGS -I$(readlink -f "$source_path/kvm/libkvm") -I$(pwd)/kvm/kernel/arch/x86/include/" if test "$solaris" = "no" ; then if ld --version 2>/dev/null | grep "GNU ld" >/dev/null 2>/dev/null ; then @@ -542,6 +542,9 @@ case "$cpu" in ARCH_CFLAGS="-m64" ARCH_LDFLAGS="-m64" ;; + ia64) + ARCH_CFLAGS="-I$(pwd)/kvm/kernel/arch/x86/include/" + ;; esac if test x"$show_help" = x"yes" ; then ++++++ IA64-kvm-suse.patch ++++++ --- /var/tmp/diff_new_pack.t80iEH/_old 2009-09-21 21:13:31.000000000 +0200 +++ /var/tmp/diff_new_pack.t80iEH/_new 2009-09-21 21:13:31.000000000 +0200 @@ -8,27 +8,24 @@ qemu/target-ia64/cpu.h | 2 +- 3 files changed, 6 insertions(+), 4 deletions(-) -Index: kvm-83/qemu/Makefile.target +Index: qemu-kvm-0.10.5/Makefile.target =================================================================== ---- kvm-83.orig/qemu/Makefile.target -+++ kvm-83/qemu/Makefile.target -@@ -144,8 +144,10 @@ BASE_LDFLAGS+=-Wl,-T,$(SRC_PATH)/$(ARCH) +--- qemu-kvm-0.10.5.orig/Makefile.target ++++ qemu-kvm-0.10.5/Makefile.target +@@ -117,7 +117,8 @@ BASE_LDFLAGS+=-Wl,-T,$(SRC_PATH)/$(ARCH) endif ifeq ($(ARCH),ia64) -CFLAGS+=-mno-sdata --OP_CFLAGS+=-mno-sdata +#CFLAGS+=-mno-sdata -+#OP_CFLAGS+=-mno-sdata +CFLAGS+=-msdata -+OP_CFLAGS+=-msdata endif - ifeq ($(ARCH),arm) -Index: kvm-83/qemu/ia64.ld + CFLAGS+=$(OS_CFLAGS) $(ARCH_CFLAGS) +Index: qemu-kvm-0.10.5/ia64.ld =================================================================== ---- kvm-83.orig/qemu/ia64.ld -+++ kvm-83/qemu/ia64.ld +--- qemu-kvm-0.10.5.orig/ia64.ld ++++ qemu-kvm-0.10.5/ia64.ld @@ -3,7 +3,7 @@ OUTPUT_FORMAT("elf64-ia64-little", "elf6 "elf64-ia64-little") OUTPUT_ARCH(ia64) @@ -38,69 +35,3 @@ /* Do we need any of these for elf? __DYNAMIC = 0; */ SECTIONS -Index: kvm-83/kernel/ia64/Makefile.pre -=================================================================== ---- kvm-83.orig/kernel/ia64/Makefile.pre -+++ kvm-83/kernel/ia64/Makefile.pre -@@ -1,9 +1,9 @@ - prerequisite: asm-offsets.h ia64/memset.S ia64/memcpy.S -- cp -f $(KERNELDIR)/arch/ia64/lib/memcpy.S ia64/memcpy.S -- cp -f $(KERNELDIR)/arch/ia64/lib/memset.S ia64/memset.S -+ cp -f /usr/src/linux/arch/ia64/lib/memcpy.S ia64/memcpy.S -+ cp -f /usr/src/linux/arch/ia64/lib/memset.S ia64/memset.S - cmp -s asm-offset.h ia64/asm-offset.h || mv -f asm-offsets.* ia64/ -- cp -f $(KERNELDIR)/lib/vsprintf.c ia64/vsprintf.c -- cp -f $(KERNELDIR)/lib/ctype.c ia64/ctype.c -+ cp -f /usr/src/linux/lib/vsprintf.c ia64/vsprintf.c -+ cp -f /usr/src/linux/lib/ctype.c ia64/ctype.c - sed -i /^EXPORT_SYMBOL/d ia64/vsprintf.c - sed -i /^EXPORT_SYMBOL/d ia64/ctype.c - -@@ -24,4 +24,4 @@ asm-offsets.h: asm-offsets.s - echo "#endif") <$< >$@ - - asm-offsets.s: ia64/asm-offsets.c -- gcc -S -D__KERNEL__ -I./include -I$(KERNELDIR)/include -I$(KERNELDIR)/arch/ia64/include ia64/asm-offsets.c -+ gcc -S -D__KERNEL__ -I./include -I$(KERNELDIR)/include -I$(KERNELDIR)/arch/ia64/include -Iinclude2 -I/usr/src/linux/include -I/usr/src/linux/arch/ia64/include ia64/asm-offsets.c -Index: kvm-83/kernel/include/asm-ia64/nr-irqs.h -=================================================================== ---- /dev/null -+++ kvm-83/kernel/include/asm-ia64/nr-irqs.h -@@ -0,0 +1,12 @@ -+#ifndef __ASM_NR_IRQS_H__ -+#define __ASM_NR_IRQS_H__ -+/* -+ * DO NOT MODIFY. -+ * -+ * This file was generated by Kbuild -+ * -+ */ -+ -+#define NR_IRQS 1024 /* sizeof (union paravirt_nr_irqs_max) // */ -+ -+#endif -Index: kvm-83/kernel/ia64/kvm-ia64.c -=================================================================== ---- kvm-83.orig/kernel/ia64/kvm-ia64.c -+++ kvm-83/kernel/ia64/kvm-ia64.c -@@ -1142,7 +1142,7 @@ static void kvm_migrate_hlt_timer(struct - struct hrtimer *p_ht = &vcpu->arch.hlt_timer; - - if (hrtimer_cancel(p_ht)) -- hrtimer_start_expires(p_ht, HRTIMER_MODE_ABS); -+ kvm_hrtimer_start_expires(p_ht, HRTIMER_MODE_ABS); - } - - static enum hrtimer_restart hlt_timer_fn(struct hrtimer *data) -Index: kvm-83/qemu/Makefile -=================================================================== ---- kvm-83.orig/qemu/Makefile -+++ kvm-83/qemu/Makefile -@@ -227,7 +227,6 @@ ifdef INSTALL_BLOBS - BLOBS=bios.bin vgabios.bin vgabios-cirrus.bin ppc_rom.bin \ - video.x openbios-sparc32 openbios-sparc64 pxe-ne2k_pci.bin \ - pxe-rtl8139.bin pxe-pcnet.bin pxe-e1000.bin bamboo.dtb --BLOBS += extboot.bin - else - BLOBS= - endif ++++++ kvm-bios.patch ++++++ # Send to upstream BOCHS This ACPI BIOS patch provides: - The PCI bus definition for PIC, HPET, RTC, SMC and OSYS and SMIF - An PBLK which provides the size of the L2 and L3 caches - If newer hardware like ICH6 IDE is found, init it Signed-off-by: Alex Graf - http://alex.csgraf.de Index: kvm-86/kvm/bios-mac/acpi-dsdt.dsl =================================================================== --- kvm-86.orig/kvm/bios-mac/acpi-dsdt.dsl +++ kvm-86/kvm/bios-mac/acpi-dsdt.dsl @@ -152,6 +152,47 @@ DefinitionBlock ( /* PCI Bus definition */ Scope(\_SB) { + Device (HPET) + { + Name (_HID, EisaId ("PNP0103")) + Name (_CID, 0x010CD041) + Name (BUF0, ResourceTemplate () + { + IRQNoFlags () + {2} + IRQNoFlags () + {8} + Memory32Fixed (ReadOnly, + 0xFED00000, // Address Base + 0x00000400, // Address Length + _Y16) + }) + Method (_STA, 0, NotSerialized) + { + Return (0x0F) + } + Method (_CRS, 0, Serialized) + { + Return (BUF0) + } + } + Device (SMC) + { + Name (_HID, EisaId ("APP0001")) + Name (_CID, "smc-napa") + Name (_STA, 0x0B) + Name (_CRS, ResourceTemplate () + { + IO (Decode16, + 0x0300, // Range Minimum + 0x0300, // Range Maximum + 0x01, // Alignment + 0x20, // Length + ) + IRQNoFlags () + {6} + }) + } Device(PCI0) { Name (_HID, EisaId ("PNP0A03")) Name (_ADR, 0x00) Index: kvm-86/kvm/bios-mac/rombios32.c =================================================================== --- kvm-86.orig/kvm/bios-mac/rombios32.c +++ kvm-86/kvm/bios-mac/rombios32.c @@ -707,6 +707,9 @@ void smp_probe(void) #define PCI_DEVICE_ID_INTEL_82371AB_0 0x7110 #define PCI_DEVICE_ID_INTEL_82371AB 0x7111 #define PCI_DEVICE_ID_INTEL_82371AB_3 0x7113 +#define PCI_DEVICE_ID_INTEL_874079 0x27a0 /* i945GM Express Chipset */ +#define PCI_DEVICE_ID_INTEL_945GL 0x27b9 /* ICH7 LPC */ +#define PCI_DEVICE_ID_INTEL_ICH6IDE 0x269e #define PCI_VENDOR_ID_IBM 0x1014 #define PCI_VENDOR_ID_APPLE 0x106b @@ -720,7 +723,9 @@ static uint32_t pci_bios_io_addr; static uint32_t pci_bios_mem_addr; static uint32_t pci_bios_bigmem_addr; /* host irqs corresponding to PCI irqs A-D */ -static uint8_t pci_irqs[4] = { 10, 10, 11, 11 }; +static uint8_t pci_irqs[4] = { 11, 10, 11, 10 }; +//static uint8_t pci_irqs[4] = { 10, 10, 11, 11 }; +//static uint8_t pci_irqs[4] = { 0x10, 0x11, 0x12, 0x13 }; static PCIDevice i440_pcidev; static void pci_config_writel(PCIDevice *d, uint32_t addr, uint32_t val) @@ -851,7 +856,9 @@ static void pci_bios_init_bridges(PCIDev if (vendor_id == PCI_VENDOR_ID_INTEL && (device_id == PCI_DEVICE_ID_INTEL_82371SB_0 || - device_id == PCI_DEVICE_ID_INTEL_82371AB_0)) { + device_id == PCI_DEVICE_ID_INTEL_82371AB_0 || + device_id == PCI_DEVICE_ID_INTEL_874079 || + device_id == PCI_DEVICE_ID_INTEL_945GL)) { int i, irq; uint8_t elcr[2]; @@ -951,8 +958,9 @@ static void pci_bios_init_device(PCIDevi case 0x0101: /* Mass storage controller - IDE interface */ if (vendor_id == PCI_VENDOR_ID_INTEL && (device_id == PCI_DEVICE_ID_INTEL_82371SB_1 || - device_id == PCI_DEVICE_ID_INTEL_82371AB)) { - /* PIIX3/PIIX4 IDE */ + device_id == PCI_DEVICE_ID_INTEL_82371AB || + device_id == PCI_DEVICE_ID_INTEL_ICH6IDE)) { + /* PIIX3/PIIX4/ICH6 IDE */ pci_config_writew(d, 0x40, 0x8000); // enable IDE0 pci_config_writew(d, 0x42, 0x8000); // enable IDE1 goto default_map; @@ -1057,6 +1065,13 @@ void pci_for_each_device(void (*init_fun } } } + /* PBLK (CPU information structure) */ + { + uint32_t *pblk = (void*) (0x410); + *pblk = 0; + ((char*)pblk)[4] = 64; /* size of the Level 2 cache */ + ((char*)pblk)[5] = 0; /* size of the Level 3 cache */ + } } void pci_bios_init(void) ++++++ kvm-qemu-applesmc.patch ++++++ #qemu-only -> submit upstream qemu Index: qemu-kvm-0.11.0-rc1/Makefile.target =================================================================== --- qemu-kvm-0.11.0-rc1.orig/Makefile.target +++ qemu-kvm-0.11.0-rc1/Makefile.target @@ -529,7 +529,7 @@ obj-y += wdt_ib700.o wdt_i6300esb.o obj-i386-y = ide.o pckbd.o vga.o $(sound-obj-y) dma.o obj-i386-y += fdc.o mc146818rtc.o serial.o i8259.o i8254.o pcspk.o pc.o obj-i386-y += cirrus_vga.o apic.o ioapic.o parallel.o acpi.o piix_pci.o -obj-i386-y += usb-uhci.o vmmouse.o vmport.o vmware_vga.o hpet.o lpc.o +obj-i386-y += usb-uhci.o vmmouse.o vmport.o vmware_vga.o hpet.o lpc.o applesmc.o obj-i386-y += device-hotplug.o pci-hotplug.o smbios.o obj-i386-y += extboot.o ifeq ($(USE_KVM_PIT), 1) Index: qemu-kvm-0.11.0-rc1/hw/applesmc.c =================================================================== --- /dev/null +++ qemu-kvm-0.11.0-rc1/hw/applesmc.c @@ -0,0 +1,171 @@ +/* + * Apple SMC controller + * + * Copyright (c) 2007 Alexander Graf + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * ***************************************************************** + * + * In all Intel-based Apple hardware there is an SMC chip to control the + * backlight, fans and several other generic device parameters. It also + * contains the magic keys used to dongle Mac OS X to the device. + * + * This driver was mostly created by looking at the Linux AppleSMC driver + * implementation and does not support IRQ. + * + */ + +#include "hw.h" +#include "pci.h" +#include "console.h" +#include "qemu-timer.h" + +/* data port used by Apple SMC */ +#define APPLESMC_DATA_PORT 0x300 +/* command/status port used by Apple SMC */ +#define APPLESMC_CMD_PORT 0x304 +#define APPLESMC_NR_PORTS 32 /* 0x300-0x31f */ +#define APPLESMC_MAX_DATA_LENGTH 32 + +#define APPLESMC_READ_CMD 0x10 +#define APPLESMC_WRITE_CMD 0x11 +#define APPLESMC_GET_KEY_BY_INDEX_CMD 0x12 +#define APPLESMC_GET_KEY_TYPE_CMD 0x13 + +static char osk[64] = "This is a dummy key. Enter the real key using the -osk parameter"; + +struct AppleSMCData { + uint8_t len; + char *key; + char *data; +}; + +static struct AppleSMCData data[] = { + { .key = "REV ", .len=6, .data="\0x01\0x13\0x0f\0x00\0x00\0x03" }, + { .key = "OSK0", .len=32, .data=osk }, + { .key = "OSK1", .len=32, .data=osk+32 }, + { .key = "NATJ", .len=1, .data="\0" }, + { .key = "MSSP", .len=1, .data="\0" }, + { .key = "MSSD", .len=1, .data="\0x3" }, + { .len=0 } +}; + +struct AppleSMCStatus { + uint8_t cmd; + uint8_t status; + uint8_t key[4]; + uint8_t read_pos; + uint8_t data_len; + uint8_t data_pos; + uint8_t data[255]; + uint8_t charactic[4]; +}; + +static void applesmc_io_cmd_writeb(void *opaque, uint32_t addr, uint32_t val) +{ + struct AppleSMCStatus *s = (struct AppleSMCStatus *)opaque; + printf("APPLESMC: CMD Write B: %#x = %#x\n", addr, val); + switch(val) { + case APPLESMC_READ_CMD: + s->status = 0x0c; + break; + } + s->cmd = val; + s->read_pos = 0; + s->data_pos = 0; +} + +static void applesmc_fill_data(struct AppleSMCStatus *s) +{ + struct AppleSMCData *d; + for(d=data; d->len; d++) { + uint32_t key_data = *((uint32_t*)d->key); + uint32_t key_current = *((uint32_t*)s->key); + if(key_data == key_current) { + printf("APPLESMC: Key matched (%s Len=%d Data=%s)\n", d->key, d->len, d->data); + memcpy(s->data, d->data, d->len); + return; + } + } +} + +static void applesmc_io_data_writeb(void *opaque, uint32_t addr, uint32_t val) +{ + struct AppleSMCStatus *s = (struct AppleSMCStatus *)opaque; + printf("APPLESMC: DATA Write B: %#x = %#x\n", addr, val); + switch(s->cmd) { + case APPLESMC_READ_CMD: + if(s->read_pos < 4) { + s->key[s->read_pos] = val; + s->status = 0x04; + } else if(s->read_pos == 4) { + s->data_len = val; + s->status = 0x05; + s->data_pos = 0; + printf("APPLESMC: Key = %c%c%c%c Len = %d\n", s->key[0], s->key[1], s->key[2], s->key[3], val); + applesmc_fill_data(s); + } + s->read_pos++; + break; + } +} + +static uint32_t applesmc_io_data_readb(void *opaque, uint32_t addr1) +{ + struct AppleSMCStatus *s = (struct AppleSMCStatus *)opaque; + uint8_t retval = 0; + switch(s->cmd) { + case APPLESMC_READ_CMD: + if(s->data_pos < s->data_len) { + retval = s->data[s->data_pos]; + printf("APPLESMC: READ_DATA[%d] = %#hhx\n", s->data_pos, retval); + s->data_pos++; + if(s->data_pos == s->data_len) { + s->status = 0x00; + printf("APPLESMC: EOF\n"); + } else + s->status = 0x05; + } + } + printf("APPLESMC: DATA Read b: %#x = %#x\n", addr1, retval); + return retval; +} + +static uint32_t applesmc_io_cmd_readb(void *opaque, uint32_t addr1) +{ + printf("APPLESMC: CMD Read B: %#x\n", addr1); + return ((struct AppleSMCStatus*)opaque)->status; +} + +void applesmc_setkey(char *key) { + if(strlen(key) == 64) { + memcpy(osk, key, 64); + } +} + +void applesmc_init() { + struct ApleSMCStatus *s; + s = qemu_mallocz(sizeof(struct AppleSMCStatus)); + + if(osk[0] == 'T') { + printf("WARNING: Using AppleSMC with invalid key\n"); + } + register_ioport_read(APPLESMC_DATA_PORT, 4, 1, applesmc_io_data_readb, s); + register_ioport_read(APPLESMC_CMD_PORT, 4, 1, applesmc_io_cmd_readb, s); + register_ioport_write(APPLESMC_DATA_PORT, 4, 1, applesmc_io_data_writeb, s); + register_ioport_write(APPLESMC_CMD_PORT, 4, 1, applesmc_io_cmd_writeb, s); +} + Index: qemu-kvm-0.11.0-rc1/hw/pc.h =================================================================== --- qemu-kvm-0.11.0-rc1.orig/hw/pc.h +++ qemu-kvm-0.11.0-rc1/hw/pc.h @@ -179,6 +179,10 @@ void pci_piix4_ide_init(PCIBus *bus, Blo void isa_ne2000_init(int base, qemu_irq irq, NICInfo *nd); +/* applesmc.c */ +void applesmc_init(void); +void applesmc_setkey(char *key); + /* lpc.c */ void lpc_init(PCIBus *bus, int devfn, qemu_irq *pic); Index: qemu-kvm-0.11.0-rc1/vl.c =================================================================== --- qemu-kvm-0.11.0-rc1.orig/vl.c +++ qemu-kvm-0.11.0-rc1/vl.c @@ -5251,6 +5251,9 @@ int main(int argc, char **argv, char **e case QEMU_OPTION_no_fd_bootchk: fd_bootchk = 0; break; + case QEMU_OPTION_osk: + applesmc_setkey(optarg); + break; #endif case QEMU_OPTION_net: if (nb_net_clients >= MAX_NET_CLIENTS) { Index: qemu-kvm-0.11.0-rc1/qemu-options.hx =================================================================== --- qemu-kvm-0.11.0-rc1.orig/qemu-options.hx +++ qemu-kvm-0.11.0-rc1/qemu-options.hx @@ -684,6 +684,15 @@ be needed to boot from old floppy disks. ETEXI #ifdef TARGET_I386 +DEF("osk", HAS_ARG, QEMU_OPTION_osk, + "-osk set AppleSMC dongle key\n") +#endif +STEXI +@item -osk +Set the dongle key for Apple's SMC chip that is used to decrypt Mac OS X binaries. +ETEXI + +#ifdef TARGET_I386 DEF("no-acpi", 0, QEMU_OPTION_no_acpi, "-no-acpi disable ACPI\n") #endif ++++++ kvm-qemu-ide-ich6.patch ++++++ #qemu-only -> submit upstream qemu Index: qemu-kvm-0.11.0-rc1/hw/ide.c =================================================================== --- qemu-kvm-0.11.0-rc1.orig/hw/ide.c +++ qemu-kvm-0.11.0-rc1/hw/ide.c @@ -473,6 +473,7 @@ static inline int media_is_cd(IDEState * #define IDE_TYPE_PIIX3 0 #define IDE_TYPE_CMD646 1 #define IDE_TYPE_PIIX4 2 +#define IDE_TYPE_ICH6 3 /* CMD646 specific */ #define MRDMODE 0x71 @@ -3385,6 +3386,57 @@ void pci_piix3_ide_init(PCIBus *bus, Blo qemu_register_reset(piix3_reset, d); piix3_reset(d); + + pci_register_bar((PCIDevice *)d, 4, 0x10, + PCI_ADDRESS_SPACE_IO, bmdma_map); + + ide_init2(&d->ide_if[0], hd_table[0], hd_table[1], pic[14]); + ide_init2(&d->ide_if[2], hd_table[2], hd_table[3], pic[15]); + ide_init_ioport(&d->ide_if[0], 0x1f0, 0x3f6); + ide_init_ioport(&d->ide_if[2], 0x170, 0x376); + + for (i = 0; i < 4; i++) + if (hd_table[i]) + hd_table[i]->private = &d->dev; + + register_savevm("ide", 0, 2, pci_ide_save, pci_ide_load, d); +} + + +/* hd_table must contain 4 block drivers */ +/* NOTE: for the ICH-6, the IRQs and IOports are hardcoded */ +void pci_ich6_ide_init(PCIBus *bus, BlockDriverState **hd_table, int devfn, + qemu_irq *pic) +{ + PCIIDEState *d; + uint8_t *pci_conf; + int i; + + /* register a function 1 of ICH-6 */ + d = (PCIIDEState *)pci_register_device(bus, "ICH-6 IDE", + sizeof(PCIIDEState), + devfn, + NULL, NULL); + d->type = IDE_TYPE_ICH6; + + pci_conf = d->dev.config; + pci_conf[0x00] = 0x86; // Intel + pci_conf[0x01] = 0x80; + pci_conf[0x02] = 0x9e; + pci_conf[0x03] = 0x26; + + pci_conf[0x09] = 0x80; // legacy ATA mode + pci_conf[0x0a] = 0x01; // class_sub = PCI_IDE + pci_conf[0x0b] = 0x01; // class_base = PCI_mass_storage + pci_conf[0x0e] = 0x00; // header_type + + pci_conf[0x40] = 0; + pci_conf[0x41] = 0xf0; // primary port enabled + pci_conf[0x42] = 0; + pci_conf[0x43] = 0x00; // secondary port disabled + + qemu_register_reset(piix3_reset, d); + piix3_reset(d); pci_register_bar((PCIDevice *)d, 4, 0x10, PCI_ADDRESS_SPACE_IO, bmdma_map); Index: qemu-kvm-0.11.0-rc1/hw/irq.c =================================================================== --- qemu-kvm-0.11.0-rc1.orig/hw/irq.c +++ qemu-kvm-0.11.0-rc1/hw/irq.c @@ -35,6 +35,7 @@ void qemu_set_irq(qemu_irq irq, int leve if (!irq) return; +//printf("IRQ set %#hhx = %#hhd using %p\n", irq->n, level, irq->handler); irq->handler(irq->opaque, irq->n, level); } Index: qemu-kvm-0.11.0-rc1/hw/pc.h =================================================================== --- qemu-kvm-0.11.0-rc1.orig/hw/pc.h +++ qemu-kvm-0.11.0-rc1/hw/pc.h @@ -174,6 +174,8 @@ void pci_piix3_ide_init(PCIBus *bus, Blo qemu_irq *pic); void pci_piix4_ide_init(PCIBus *bus, BlockDriverState **hd_table, int devfn, qemu_irq *pic); +void pci_ich6_ide_init(PCIBus *bus, BlockDriverState **hd_table, int devfn, + qemu_irq *pic); /* ne2000.c */ ++++++ kvm-qemu-lpc.patch ++++++ #qemu-only -> submit upstream qemu Index: qemu-kvm-0.11.0-rc1/Makefile.target =================================================================== --- qemu-kvm-0.11.0-rc1.orig/Makefile.target +++ qemu-kvm-0.11.0-rc1/Makefile.target @@ -529,7 +529,7 @@ obj-y += wdt_ib700.o wdt_i6300esb.o obj-i386-y = ide.o pckbd.o vga.o $(sound-obj-y) dma.o obj-i386-y += fdc.o mc146818rtc.o serial.o i8259.o i8254.o pcspk.o pc.o obj-i386-y += cirrus_vga.o apic.o ioapic.o parallel.o acpi.o piix_pci.o -obj-i386-y += usb-uhci.o vmmouse.o vmport.o vmware_vga.o hpet.o +obj-i386-y += usb-uhci.o vmmouse.o vmport.o vmware_vga.o hpet.o lpc.o obj-i386-y += device-hotplug.o pci-hotplug.o smbios.o obj-i386-y += extboot.o ifeq ($(USE_KVM_PIT), 1) Index: qemu-kvm-0.11.0-rc1/hw/lpc.c =================================================================== --- /dev/null +++ qemu-kvm-0.11.0-rc1/hw/lpc.c @@ -0,0 +1,162 @@ +/* + * Low Pin Count emulation + * + * Copyright (c) 2007 Alexander Graf + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * ***************************************************************** + * + * This driver emulates an ICH-7 LPC partially. The LPC is basically the + * same as the ISA-bridge in the existing PIIX implementation, but + * more recent and includes support for HPET and Power Management. + * + */ +#include "hw.h" +#include "pci.h" +#include "console.h" + +#define RCBA_BASE 0xFED1C000 + +void hpet_init(qemu_irq irq); + +static uint32_t rcba_ram_readl(void *opaque, target_phys_addr_t addr) +{ + printf("qemu: rcba_read l at %#lx\n", addr); + if(addr == RCBA_BASE + 0x3404) { /* This is the HPET config pointer */ + printf("qemu: rcba_read HPET_CONFIG_POINTER\n"); + return 0xf0; // enabled at 0xfed00000 + } else if(addr == RCBA_BASE + 0x3410) { /* This is the HPET config pointer */ + printf("qemu: rcba_read GCS\n"); + return 0; + } else { + return 0x0; + } +} + +static void rcba_ram_writel(void *opaque, target_phys_addr_t addr, + uint32_t value) +{ + printf("qemu: rcba_write l %#lx = %#x\n", addr, value); +} + +static CPUReadMemoryFunc *rcba_ram_read[] = { + NULL, + NULL, + rcba_ram_readl, +}; + +static CPUWriteMemoryFunc *rcba_ram_write[] = { + NULL, + NULL, + rcba_ram_writel, +}; + +void lpc_init(PCIBus *bus, int devfn, qemu_irq *pic) { + int iomemtype; + uint8_t *pci_conf; + PCIDevice *d; + + /* register a function 1 of PIIX3 */ + d = (PCIDevice *)pci_register_device(bus, "LPC", + sizeof(PCIDevice), + 31 << 3, + NULL, NULL); + pci_conf = d->config; + pci_conf[0x00] = 0x86; + pci_conf[0x01] = 0x80; + pci_conf[0x02] = 0xb9; + pci_conf[0x03] = 0x27; + pci_conf[0x08] = 0x02; // Revision 2 + + pci_conf[0x0a] = 0x01; // PCI-to-ISA Bridge + pci_conf[0x0b] = 0x06; // Bridge + + pci_conf[0x0e] = 0xf0; + + // Subsystem + pci_conf[0x2c] = 0x86; + pci_conf[0x2d] = 0x80; + pci_conf[0x2e] = 0x70; + pci_conf[0x2f] = 0x72; + + pci_conf[0x3d] = 0x03; + + // PMBASE + pci_conf[0x40] = 0x01; + pci_conf[0x41] = 0x0b; + + pci_conf[0xf0] = RCBA_BASE | 1; // enabled + pci_conf[0xf1] = RCBA_BASE << 8; + pci_conf[0xf2] = RCBA_BASE << 16; + pci_conf[0xf3] = RCBA_BASE << 24; + + + /* RCBA Area */ + + iomemtype = cpu_register_io_memory(rcba_ram_read, rcba_ram_write, d); + + cpu_register_physical_memory(RCBA_BASE, 0x4000, iomemtype); +#if 0 + cpu_register_physical_memory(0x00CDA000, 0x4000, iomemtype); +#endif + + + + pci_conf[0x04] = 0x07; // master, memory and I/O + pci_conf[0x05] = 0x00; + pci_conf[0x06] = 0x00; + pci_conf[0x07] = 0x02; // PCI_status_devsel_medium + pci_conf[0x4c] = 0x4d; + pci_conf[0x4e] = 0x03; + pci_conf[0x4f] = 0x00; + pci_conf[0x60] = 0x0a; // PCI A -> IRQ 10 + pci_conf[0x61] = 0x0a; // PCI B -> IRQ 10 + pci_conf[0x62] = 0x0b; // PCI C -> IRQ 11 + pci_conf[0x63] = 0x0b; // PCI D -> IRQ 11 + pci_conf[0x69] = 0x02; + pci_conf[0x70] = 0x80; + pci_conf[0x76] = 0x0c; + pci_conf[0x77] = 0x0c; + pci_conf[0x78] = 0x02; + pci_conf[0x79] = 0x00; + pci_conf[0x80] = 0x00; + pci_conf[0x82] = 0x00; + pci_conf[0xa0] = 0x08; + pci_conf[0xa2] = 0x00; + pci_conf[0xa3] = 0x00; + pci_conf[0xa4] = 0x00; + pci_conf[0xa5] = 0x00; + pci_conf[0xa6] = 0x00; + pci_conf[0xa7] = 0x00; + pci_conf[0xa8] = 0x0f; + pci_conf[0xaa] = 0x00; + pci_conf[0xab] = 0x00; + pci_conf[0xac] = 0x00; + pci_conf[0xae] = 0x00; + +// XXX hpet goes via apic + hpet_init(pic); + +#if 0 + register_ioport_read(0x1000, 128, 1, pmbase_readb, d); + register_ioport_write(0x1000, 128, 1, pmbase_writeb, d); + register_ioport_read(0x1000, 64, 2, pmbase_readw, d); + register_ioport_write(0x1000, 64, 2, pmbase_writew, d); + register_ioport_read(0x1000, 32, 4, pmbase_readl, d); + register_ioport_write(0x1000, 32, 5, pmbase_writel, d); +#endif +} + Index: qemu-kvm-0.11.0-rc1/hw/pc.h =================================================================== --- qemu-kvm-0.11.0-rc1.orig/hw/pc.h +++ qemu-kvm-0.11.0-rc1/hw/pc.h @@ -179,6 +179,9 @@ void pci_piix4_ide_init(PCIBus *bus, Blo void isa_ne2000_init(int base, qemu_irq irq, NICInfo *nd); +/* lpc.c */ +void lpc_init(PCIBus *bus, int devfn, qemu_irq *pic); + /* extboot.c */ void extboot_init(BlockDriverState *bs, int cmd); ++++++ kvm-qemu-macmodel.patch ++++++ #qemu-only -> submit upstream qemu, but improve first: # undo rather hacky pci_enabled -> model > MODEL_ISA changes # and replace checks wether to enable newer emulated Mac hardware # depending in the bits in a bitfield which is passed pc_init1() # like this: pc_init1(.... , ISA, ...) # pc_init1(.... , PCI | IOAPIC | PIIX, ..... # pc_init1(.... , PCI | ICH6, LPC, SMC , ...) Index: qemu-kvm-0.11.0-rc2/hw/pc.c =================================================================== --- qemu-kvm-0.11.0-rc2.orig/hw/pc.c +++ qemu-kvm-0.11.0-rc2/hw/pc.c @@ -92,6 +92,12 @@ static void option_rom_setup_reset(targe qemu_register_reset(option_rom_reset, rrd); } +enum pc_model { + MODEL_ISA = 0, + MODEL_PCI = 1, + MODEL_MAC = 2 +}; + static void ioport80_write(void *opaque, uint32_t addr, uint32_t data) { } @@ -1116,7 +1122,7 @@ static void pc_init1(ram_addr_t ram_size const char *kernel_cmdline, const char *initrd_filename, const char *cpu_model, - int pci_enabled) + int model) { char *filename; int ret, linux_boot, i; @@ -1147,11 +1153,15 @@ static void pc_init1(ram_addr_t ram_size /* init CPUs */ if (cpu_model == NULL) { + if(model == MODEL_MAC) { + cpu_model = "coreduo,vendor=GenuineIntel"; + } else { #ifdef TARGET_X86_64 - cpu_model = "qemu64"; + cpu_model = "qemu64"; #else - cpu_model = "qemu32"; + cpu_model = "qemu32"; #endif + } } if (kvm_enabled()) { @@ -1184,8 +1194,16 @@ static void pc_init1(ram_addr_t ram_size /* BIOS load */ - if (bios_name == NULL) - bios_name = BIOS_FILENAME; + if (bios_name == NULL) { + switch(model) { + case MODEL_MAC: + bios_name = "bios-mac.bin"; + break; + default: + bios_name = BIOS_FILENAME; + break; + } + } filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name); if (filename) { bios_size = get_image_size(filename); @@ -1283,7 +1301,7 @@ static void pc_init1(ram_addr_t ram_size i8259 = i8259_init(cpu_irq[0]); ferr_irq = i8259[13]; - if (pci_enabled) { + if (model > MODEL_ISA) { pci_bus = i440fx_init(&i440fx_state, i8259); piix3_devfn = piix3_init(pci_bus, -1); } else { @@ -1296,18 +1314,18 @@ static void pc_init1(ram_addr_t ram_size register_ioport_write(0xf0, 1, 1, ioportF0_write, NULL); if (cirrus_vga_enabled) { - if (pci_enabled) { + if (model >= MODEL_PCI) { pci_cirrus_vga_init(pci_bus); } else { isa_cirrus_vga_init(); } } else if (vmsvga_enabled) { - if (pci_enabled) + if (model >= MODEL_PCI) pci_vmsvga_init(pci_bus); else fprintf(stderr, "%s: vmware_vga: no PCI bus\n", __FUNCTION__); } else if (std_vga_enabled) { - if (pci_enabled) { + if (model >= MODEL_PCI) { pci_vga_init(pci_bus, 0, 0); } else { isa_vga_init(); @@ -1321,8 +1339,13 @@ static void pc_init1(ram_addr_t ram_size register_ioport_read(0x92, 1, 1, ioport92_read, NULL); register_ioport_write(0x92, 1, 1, ioport92_write, NULL); - if (pci_enabled) { - ioapic = ioapic_init(); + switch (model) { + case MODEL_MAC: + applesmc_init(); + lpc_init(pci_bus, piix3_devfn, i8259); + case MODEL_PCI: + ioapic = ioapic_init(); + break; } #ifdef USE_KVM_PIT if (kvm_enabled() && qemu_kvm_pit_in_kernel()) @@ -1334,7 +1357,7 @@ static void pc_init1(ram_addr_t ram_size if (!no_hpet) { hpet_init(i8259); } - if (pci_enabled) { + if (model > MODEL_ISA) { pic_set_alt_irq_func(isa_pic, ioapic_set_irq, ioapic); } @@ -1357,7 +1380,7 @@ static void pc_init1(ram_addr_t ram_size for(i = 0; i < nb_nics; i++) { NICInfo *nd = &nd_table[i]; - if (!pci_enabled || (nd->model && strcmp(nd->model, "ne2k_isa") == 0)) + if (model == MODEL_ISA || (nd->model && strcmp(nd->model, "ne2k_isa") == 0)) pc_init_ne2k_isa(nd, i8259); else pci_nic_init(nd, "rtl8139", NULL); @@ -1378,19 +1401,25 @@ static void pc_init1(ram_addr_t ram_size hd[i] = NULL; } - if (pci_enabled) { - pci_piix3_ide_init(pci_bus, hd, piix3_devfn + 1, i8259); - } else { - for(i = 0; i < MAX_IDE_BUS; i++) { - isa_ide_init(ide_iobase[i], ide_iobase2[i], i8259[ide_irq[i]], - hd[MAX_IDE_DEVS * i], hd[MAX_IDE_DEVS * i + 1]); - } + switch(model) { + case MODEL_MAC: + pci_ich6_ide_init(pci_bus, hd, piix3_devfn + 1, i8259); + break; + case MODEL_PCI: + pci_piix3_ide_init(pci_bus, hd, piix3_devfn + 1, i8259); + break; + default: + for(i = 0; i < 2; i++) { + isa_ide_init(ide_iobase[i], ide_iobase2[i], i8259[ide_irq[i]], + hd[MAX_IDE_DEVS * i], hd[MAX_IDE_DEVS * i + 1]); + } + break; } i8042_init(i8259[1], i8259[12], 0x60); DMA_init(0); #ifdef HAS_AUDIO - audio_init(pci_enabled ? pci_bus : NULL, i8259); + audio_init((model > MODEL_ISA) ? pci_bus : NULL, i8259); #endif for(i = 0; i < MAX_FD; i++) { @@ -1404,11 +1433,11 @@ static void pc_init1(ram_addr_t ram_size cmos_init(below_4g_mem_size, above_4g_mem_size, boot_device, hd); - if (pci_enabled && usb_enabled) { + if ((model > MODEL_ISA) && usb_enabled) { usb_uhci_piix3_init(pci_bus, piix3_devfn + 2); } - if (pci_enabled && acpi_enabled) { + if ((model > MODEL_ISA) && acpi_enabled) { uint8_t *eeprom_buf = qemu_mallocz(8 * 256); /* XXX: make this persistent */ i2c_bus *smbus; @@ -1427,7 +1456,7 @@ static void pc_init1(ram_addr_t ram_size i440fx_init_memory_mappings(i440fx_state); } - if (pci_enabled) { + if (model > MODEL_ISA) { int max_bus; int bus; @@ -1438,7 +1467,7 @@ static void pc_init1(ram_addr_t ram_size } /* Add virtio block devices */ - if (pci_enabled) { + if (model > MODEL_ISA) { int index; int unit_id = 0; @@ -1463,13 +1492,13 @@ static void pc_init1(ram_addr_t ram_size } /* Add virtio balloon device */ - if (pci_enabled && virtio_balloon) { + if ((model >= MODEL_PCI) && virtio_balloon) { pci_dev = pci_create("virtio-balloon-pci", virtio_balloon_devaddr); qdev_init(&pci_dev->qdev); } /* Add virtio console devices */ - if (pci_enabled) { + if (model >= MODEL_PCI) { for(i = 0; i < MAX_VIRTIO_CONSOLES; i++) { if (virtcon_hds[i]) { pci_create_simple(pci_bus, -1, "virtio-console-pci"); @@ -1485,6 +1514,19 @@ static void pc_init1(ram_addr_t ram_size #endif /* USE_KVM_DEVICE_ASSIGNMENT */ } +static void pc_init_mac(ram_addr_t ram_size, + const char *boot_device, + const char *kernel_filename, + const char *kernel_cmdline, + const char *initrd_filename, + const char *cpu_model) +{ + pc_init1(ram_size, boot_device, + kernel_filename, kernel_cmdline, + initrd_filename, cpu_model, + MODEL_MAC); +} + static void pc_init_pci(ram_addr_t ram_size, const char *boot_device, const char *kernel_filename, @@ -1494,7 +1536,7 @@ static void pc_init_pci(ram_addr_t ram_s { pc_init1(ram_size, boot_device, kernel_filename, kernel_cmdline, - initrd_filename, cpu_model, 1); + initrd_filename, cpu_model, MODEL_PCI); } static void pc_init_isa(ram_addr_t ram_size, @@ -1506,7 +1548,7 @@ static void pc_init_isa(ram_addr_t ram_s { pc_init1(ram_size, boot_device, kernel_filename, kernel_cmdline, - initrd_filename, cpu_model, 0); + initrd_filename, cpu_model, MODEL_ISA); } /* set CMOS shutdown status register (index 0xF) as S3_resume(0xFE) @@ -1526,6 +1568,13 @@ static QEMUMachine pc_machine = { .is_default = 1, }; +static QEMUMachine mac_machine = { + .name = "mac", + .desc = "Intel-Mac", + .init = pc_init_mac, + .max_cpus = 255, +}; + static QEMUMachine pc_machine_v0_10 = { .name = "pc-0.10", .desc = "Standard PC, qemu 0.10", @@ -1561,6 +1610,7 @@ static void pc_machine_init(void) qemu_register_machine(&pc_machine); qemu_register_machine(&pc_machine_v0_10); qemu_register_machine(&isapc_machine); + qemu_register_machine(&mac_machine); } machine_init(pc_machine_init); Index: qemu-kvm-0.11.0-rc2/vl.c =================================================================== --- qemu-kvm-0.11.0-rc2.orig/vl.c +++ qemu-kvm-0.11.0-rc2/vl.c @@ -6008,6 +6008,10 @@ int main(int argc, char **argv, char **e if (kvm_enabled()) { int ret; + if (machine == find_machine("mac")) { + kvm_pit = 0; + } + ret = kvm_init(smp_cpus); if (ret < 0) { #if defined(KVM_UPSTREAM) || defined(NO_CPU_EMULATION) ++++++ kvm-qemu-no-fallback-if-open-kvm-fails.patch ++++++ --- /var/tmp/diff_new_pack.t80iEH/_old 2009-09-21 21:13:31.000000000 +0200 +++ /var/tmp/diff_new_pack.t80iEH/_new 2009-09-21 21:13:31.000000000 +0200 @@ -1,14 +1,13 @@ -Index: kvm-88/vl.c +Index: qemu-kvm-0.11.0-rc1/vl.c =================================================================== ---- kvm-88.orig/vl.c -+++ kvm-88/vl.c -@@ -5951,7 +5951,8 @@ int main(int argc, char **argv, char **e - #ifdef USE_KVM - if (kvm_enabled()) { - if (kvm_qemu_init() < 0) { -- fprintf(stderr, "Could not initialize KVM, will disable KVM support\n"); -+ fprintf(stderr, "Could not initialize KVM. Do you have kvm-amd or kvm-intel modprobe'd?\nIf you want to use CPU emulation, start with -no-kvm.\n"); -+ exit(1); - #ifdef NO_CPU_EMULATION - fprintf(stderr, "Compiled with --disable-cpu-emulation, exiting.\n"); - exit(1); +--- qemu-kvm-0.11.0-rc1.orig/vl.c ++++ qemu-kvm-0.11.0-rc1/vl.c +@@ -6017,6 +6017,8 @@ int main(int argc, char **argv, char **e + fprintf(stderr, "failed to initialize KVM\n"); + exit(1); + #endif ++ fprintf(stderr, "Could not initialize KVM. Do you have kvm-amd or kvm-intel modprobe'd?\nIf you want to use CPU emulation, start with -no-kvm.\n"); ++ exit(1); + fprintf(stderr, "Could not initialize KVM, will disable KVM support\n"); + kvm_allowed = 0; + } ++++++ kvm-qemu-preXX-dictzip1.patch ++++++ ++++ 611 lines (skipped) ++++++ kvm-qemu-preXX-dictzip2.patch ++++++
From 728c772ee9d56404ebb475d2fcf029447cf5190a Mon Sep 17 00:00:00 2001 From: Alexander Graf <agraf@suse.de> Date: Wed, 5 Aug 2009 17:28:38 +0200 Subject: [PATCH 2/3] Add tar container format
Tar is a very widely used format to store data in. Sometimes people even put virtual machine images in there. So it makes sense for qemu to be able to read from tar files. I implemented a written from scratch reader that also knows about the GNU sparse format, which is what pigz creates. This version checks for filenames that end on well-known extensions. The logic could be changed to search for filenames given on the command line, but that would require changes to more parts of qemu. The tar reader in conjunctiuon with dzip gives us the chance to download tar'ed up virtual machine images (even via http) and instantly make use of them. Signed-off-by: Alexander Graf <agraf@suse.de> --- Makefile | 2 +- block/tar.c | 333 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 334 insertions(+), 1 deletions(-) create mode 100644 block/tar.c Index: qemu-kvm-0.11.0-rc1/Makefile =================================================================== --- qemu-kvm-0.11.0-rc1.orig/Makefile +++ qemu-kvm-0.11.0-rc1/Makefile @@ -79,7 +79,7 @@ block-obj-y += nbd.o block.o aio.o aes.o block-nested-y += cow.o qcow.o vmdk.o cloop.o dmg.o bochs.o vpc.o vvfat.o block-nested-y += qcow2.o qcow2-refcount.o qcow2-cluster.o qcow2-snapshot.o -block-nested-y += parallels.o nbd.o dictzip.o +block-nested-y += parallels.o nbd.o dictzip.o tar.o ifdef CONFIG_WIN32 Index: qemu-kvm-0.11.0-rc1/block/tar.c =================================================================== --- /dev/null +++ qemu-kvm-0.11.0-rc1/block/tar.c @@ -0,0 +1,338 @@ +/* + * Tar block driver + * + * Copyright (c) 2009 Alexander Graf <agraf@suse.de> + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "qemu-common.h" +#include "block_int.h" + +// #define DEBUG + +#ifdef DEBUG +#define dprintf(fmt, ...) do { printf("tar: " fmt, ## __VA_ARGS__); } while (0) +#else +#define dprintf(fmt, ...) do { } while (0) +#endif + +#define SECTOR_SIZE 512 + +#define POSIX_TAR_MAGIC "ustar" +#define OFFS_LENGTH 0x7c +#define OFFS_TYPE 0x9c +#define OFFS_MAGIC 0x101 + +#define OFFS_S_SP 0x182 +#define OFFS_S_EXT 0x1e2 +#define OFFS_S_LENGTH 0x1e3 +#define OFFS_SX_EXT 0x1f8 + +typedef struct SparseCache { + uint64_t start; + uint64_t end; +} SparseCache; + +typedef struct BDRVTarState { + BlockDriverState *hd; + size_t file_sec; + uint64_t file_len; + SparseCache *sparse; + int sparse_num; + uint64_t last_end; +} BDRVTarState; + +static int tar_probe(const uint8_t *buf, int buf_size, const char *filename) +{ + if (buf_size < OFFS_MAGIC + 5) + return 0; + + /* we only support newer tar */ + if (!strncmp((char*)buf + OFFS_MAGIC, POSIX_TAR_MAGIC, 5)) + return 100; + + return 0; +} + +static int str_ends(char *str, const char *end) +{ + int end_len = strlen(end); + int str_len = strlen(str); + + if (str_len < end_len) + return 0; + + return !strncmp(str + str_len - end_len, end, end_len); +} + +static int is_target_file(BlockDriverState *bs, char *filename) +{ + int retval = 0; + + if (str_ends(filename, ".raw")) + retval = 1; + + if (str_ends(filename, ".qcow")) + retval = 1; + + if (str_ends(filename, ".qcow2")) + retval = 1; + + if (str_ends(filename, ".vmdk")) + retval = 1; + + dprintf("does filename %s match? %s\n", filename, retval ? "yes" : "no"); + return retval; +} + +static uint64_t tar2u64(char *ptr) +{ + uint64_t retval; + char oldend = ptr[12]; + + ptr[12] = '\0'; + if (*ptr & 0x80) + retval = be64_to_cpu(*(uint64_t *)ptr); + else + retval = strtol(ptr, NULL, 8); + + ptr[12] = oldend; + + dprintf("Convert %s -> %#lx\n", ptr, retval); + return retval; +} + +static void tar_sparse(BDRVTarState *s, uint64_t offs, uint64_t len) +{ + SparseCache *sparse; + + if (!len) + return; + if (!(offs - s->last_end)) { + s->last_end += len; + return; + } + if (s->last_end > offs) + return; + + dprintf("Last chunk until %lx new chunk at %lx\n", s->last_end, offs); + + s->sparse = qemu_realloc(s->sparse, (s->sparse_num + 1) * sizeof(SparseCache)); + sparse = &s->sparse[s->sparse_num]; + sparse->start = s->last_end; + sparse->end = offs; + s->last_end = offs + len; + s->sparse_num++; + dprintf("Sparse at %lx end=%lx\n", sparse->start, + sparse->end); +} + +static int tar_open(BlockDriverState *bs, const char *filename, int flags) +{ + BDRVTarState *s = bs->opaque; + char header[SECTOR_SIZE]; + char *magic; + const char *fname = filename; + size_t header_offs = 0; + int ret; + + if (!strncmp(filename, "tar://", 6)) + fname += 6; + else if (!strncmp(filename, "tar:", 4)) + fname += 4; + + ret = bdrv_file_open(&s->hd, fname, flags); + if (ret < 0) + return ret; + + /* Search the file for an image */ + + do { + /* tar header */ + if (bdrv_pread(s->hd, header_offs, header, SECTOR_SIZE) != SECTOR_SIZE) + goto fail; + + if ((header_offs > 1) && !header[0]) { + fprintf(stderr, "Tar: No image file found in archive\n"); + goto fail; + } + + magic = &header[OFFS_MAGIC]; + if (strncmp(magic, POSIX_TAR_MAGIC, 5)) { + fprintf(stderr, "Tar: Invalid magic: %s\n", magic); + goto fail; + } + + dprintf("file type: %c\n", header[OFFS_TYPE]); + + /* file length*/ + s->file_len = (tar2u64(&header[OFFS_LENGTH]) + (SECTOR_SIZE - 1)) & + ~(SECTOR_SIZE - 1); + s->file_sec = (header_offs / SECTOR_SIZE) + 1; + + header_offs += s->file_len + SECTOR_SIZE; + } while(!is_target_file(bs, header)); + + /* We found an image! */ + + if (header[OFFS_TYPE] == 'S') { + uint8_t isextended; + int i; + + for (i = OFFS_S_SP; i < (OFFS_S_SP + (4 * 24)); i += 24) + tar_sparse(s, tar2u64(&header[i]), tar2u64(&header[i+12])); + + s->file_len = tar2u64(&header[OFFS_S_LENGTH]); + isextended = header[OFFS_S_EXT]; + + while (isextended) { + if (bdrv_pread(s->hd, s->file_sec * SECTOR_SIZE, header, + SECTOR_SIZE) != SECTOR_SIZE) + goto fail; + + for (i = 0; i < (21 * 24); i += 24) + tar_sparse(s, tar2u64(&header[i]), tar2u64(&header[i+12])); + isextended = header[OFFS_SX_EXT]; + s->file_sec++; + } + tar_sparse(s, s->file_len, 1); + } + + return 0; + +fail: + fprintf(stderr, "Tar: Error opening file\n"); + bdrv_delete(s->hd); + return -EINVAL; +} + +typedef struct TarAIOCB { + BlockDriverAIOCB common; + QEMUBH *bh; +} TarAIOCB; + +/* This callback gets invoked when we have pure sparseness */ +static void tar_sparse_cb(void *opaque) +{ + TarAIOCB *acb = (TarAIOCB *)opaque; + + acb->common.cb(acb->common.opaque, 0); + qemu_bh_delete(acb->bh); + qemu_aio_release(acb); +} + +static void tar_aio_cancel(BlockDriverAIOCB *blockacb) +{ +} + +static AIOPool tar_aio_pool = { + .aiocb_size = sizeof(TarAIOCB), + .cancel = tar_aio_cancel, +}; + +/* This is where we get a request from a caller to read something */ +static BlockDriverAIOCB *tar_aio_readv(BlockDriverState *bs, + int64_t sector_num, QEMUIOVector *qiov, int nb_sectors, + BlockDriverCompletionFunc *cb, void *opaque) +{ + BDRVTarState *s = bs->opaque; + SparseCache *sparse; + int64_t sec_file = sector_num + s->file_sec; + int64_t start = sector_num * SECTOR_SIZE; + int64_t end = start + (nb_sectors * SECTOR_SIZE); + int i; + TarAIOCB *acb; + + for (i = 0; i < s->sparse_num; i++) { + sparse = &s->sparse[i]; + if (sparse->start > end) { + /* We expect the cache to be start increasing */ + break; + } else if ((sparse->start < start) && (sparse->end <= start)) { + /* sparse before our offset */ + sec_file -= (sparse->end - sparse->start) / SECTOR_SIZE; + } else if ((sparse->start <= start) && (sparse->end >= end)) { + /* all our sectors are sparse */ + char *buf = qemu_mallocz(nb_sectors * SECTOR_SIZE); + + acb = qemu_aio_get(&tar_aio_pool, bs, cb, opaque); + qemu_iovec_from_buffer(qiov, buf, nb_sectors * SECTOR_SIZE); + qemu_free(buf); + acb->bh = qemu_bh_new(tar_sparse_cb, acb); + qemu_bh_schedule(acb->bh); + + return &acb->common; + } else if (((sparse->start >= start) && (sparse->start < end)) || + ((sparse->end >= start) && (sparse->end < end))) { + /* we're semi-sparse (worst case) */ + /* let's go synchronous and read all sectors individually */ + char *buf = qemu_malloc(nb_sectors * SECTOR_SIZE); + uint64_t offs; + + for (offs = 0; offs < (nb_sectors * SECTOR_SIZE); + offs += SECTOR_SIZE) { + bdrv_pread(bs, (sector_num * SECTOR_SIZE) + offs, + buf + offs, SECTOR_SIZE); + } + + qemu_iovec_from_buffer(qiov, buf, nb_sectors * SECTOR_SIZE); + acb = qemu_aio_get(&tar_aio_pool, bs, cb, opaque); + acb->bh = qemu_bh_new(tar_sparse_cb, acb); + qemu_bh_schedule(acb->bh); + + return &acb->common; + } + } + + return bdrv_aio_readv(s->hd, sec_file, qiov, nb_sectors, + cb, opaque); +} + +static void tar_close(BlockDriverState *bs) +{ + dprintf("Close\n"); +} + +static int64_t tar_getlength(BlockDriverState *bs) +{ + BDRVTarState *s = bs->opaque; + dprintf("getlength -> %ld\n", s->file_len); + return s->file_len; +} + +static BlockDriver bdrv_tar = { + .format_name = "tar", + .protocol_name = "tar", + + .instance_size = sizeof(BDRVTarState), + .bdrv_open = tar_open, + .bdrv_close = tar_close, + .bdrv_getlength = tar_getlength, + .bdrv_probe = tar_probe, + + .bdrv_aio_readv = tar_aio_readv, +}; + +static void tar_block_init(void) +{ + bdrv_register(&bdrv_tar); +} + +block_init(tar_block_init); ++++++ kvm-qemu-preXX-dictzip3.patch ++++++
From 4c894a7a5cde4a5e8d8d3aa8c644030efdf77e3a Mon Sep 17 00:00:00 2001 From: Alexander Graf <agraf@suse.de> Date: Fri, 14 Aug 2009 00:30:53 +0200 Subject: [PATCH 3/3] Enable protocol layering
--- block.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) Index: qemu-kvm-0.10.5/block.c =================================================================== --- qemu-kvm-0.10.5.orig/block.c +++ qemu-kvm-0.10.5/block.c @@ -357,11 +357,11 @@ int bdrv_open2(BlockDriverState *bs, con return ret; } total_size = bdrv_getlength(bs1) >> SECTOR_BITS; + bdrv_delete(bs1); - if (bs1->drv && bs1->drv->protocol_name) + if (find_protocol(filename) != bdrv_find_format("raw")) is_protocol = 1; - bdrv_delete(bs1); get_tmp_filename(tmp_filename, sizeof(tmp_filename)); ++++++ kvm-qemu-rtl8139-link.patch ++++++ # Fix the Link detection in MacOS # Author Alex Graf - agraf@suse Index: qemu-kvm-0.11.0-rc1/hw/rtl8139.c =================================================================== --- qemu-kvm-0.11.0-rc1.orig/hw/rtl8139.c +++ qemu-kvm-0.11.0-rc1/hw/rtl8139.c @@ -422,6 +422,9 @@ static void RTL8139TallyCounters_load(QE /* Saves values of tally counters to VM state file */ static void RTL8139TallyCounters_save(QEMUFile* f, RTL8139TallyCounters *tally_counters); +static uint32_t rtl8139_io_readb(void *opaque, uint8_t addr); +static uint32_t rtl8139_io_readw(void *opaque, uint8_t addr); + typedef struct RTL8139State { uint8_t phys[8]; /* mac address */ uint8_t mult[8]; /* multicast mask array */ @@ -462,6 +465,7 @@ typedef struct RTL8139State { uint16_t CpCmd; uint8_t TxThresh; + enum NICLink link; PCIDevice *pci_dev; VLANClientState *vc; @@ -1233,7 +1237,7 @@ static void rtl8139_reset(void *opaque) s->Config0 = 0x0; /* No boot ROM */ s->Config1 = 0xC; /* IO mapped and MEM mapped registers available */ s->Config3 = 0x1; /* fast back-to-back compatible */ - s->Config5 = 0x0; + s->Config5 = Cfg5_LDPS; s->CSCR = CSCR_F_LINK_100 | CSCR_HEART_BIT | CSCR_LD; @@ -1259,6 +1263,13 @@ static void rtl8139_reset(void *opaque) s->TimerInt = 0; s->TCTR_base = 0; + s->eeprom.contents[10] = s->Config0 | s->Config1 << 8; + s->eeprom.contents[6] = (rtl8139_io_readb(s, MediaStatus) & 0xc0) | ((rtl8139_io_readw(s, BasicModeCtrl) >> 8) & 0x23) + | (s->Config3 << 8); + s->eeprom.contents[12] = s->Config4 << 8; + + s->eeprom.contents[15] = s->Config5 << 8; + /* reset tally counters */ RTL8139TallyCounters_clear(&s->tally_counters); } @@ -2856,7 +2867,7 @@ static uint32_t rtl8139_io_readb(void *o break; case MediaStatus: - ret = 0xd0; + ret = 0xd0 | ((s->link == Link_10mbps) << 3); DEBUG_PRINT(("RTL8139: MediaStatus read 0x%x\n", ret)); break; @@ -3478,6 +3489,15 @@ static void pci_rtl8139_init(PCIDevice * s->pci_dev = (PCIDevice *)d; qdev_get_macaddr(&dev->qdev, s->macaddr); qemu_register_reset(rtl8139_reset, s); + switch(dev->qdev.nd->link) { + case Link_10mbps: + case Link_100mbps: + s->link = dev->qdev.nd->link; + break; + default: + s->link = Link_100mbps; + break; + } rtl8139_reset(s); s->vc = qdev_get_vlan_client(&dev->qdev, rtl8139_can_receive, rtl8139_receive, NULL, Index: qemu-kvm-0.11.0-rc1/net.h =================================================================== --- qemu-kvm-0.11.0-rc1.orig/net.h +++ qemu-kvm-0.11.0-rc1/net.h @@ -98,6 +98,13 @@ enum { NIC_NVECTORS_UNSPECIFIED = -1 }; +enum NICLink { + Link_default, + Link_10mbps, + Link_100mbps, + Link_1000mbps, +}; + struct NICInfo { uint8_t macaddr[6]; const char *model; @@ -108,6 +115,7 @@ struct NICInfo { VLANClientState *vc; void *private; int used; + enum NICLink link; int bootable; int nvectors; }; Index: qemu-kvm-0.11.0-rc1/net.c =================================================================== --- qemu-kvm-0.11.0-rc1.orig/net.c +++ qemu-kvm-0.11.0-rc1/net.c @@ -2670,6 +2670,7 @@ int net_client_init(Monitor *mon, const } nd->vlan = vlan; nd->name = name; + nd->link = Link_default; nd->used = 1; name = NULL; nb_nics++; Index: qemu-kvm-0.11.0-rc1/hw/pc.c =================================================================== --- qemu-kvm-0.11.0-rc1.orig/hw/pc.c +++ qemu-kvm-0.11.0-rc1/hw/pc.c @@ -1389,7 +1389,10 @@ static void pc_init1(ram_addr_t ram_size if (model == MODEL_ISA || (nd->model && strcmp(nd->model, "ne2k_isa") == 0)) pc_init_ne2k_isa(nd, i8259); - else + else if (model == MODEL_MAC) { + nd->link = Link_10mbps; + pci_nic_init(nd, "rtl8139", NULL); + } else pci_nic_init(nd, "rtl8139", NULL); } ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Remember to have fun... -- To unsubscribe, e-mail: opensuse-commit+unsubscribe@opensuse.org For additional commands, e-mail: opensuse-commit+help@opensuse.org