delete kvm
git-svn-id: https://svn.disconnected-by-peer.at/svn/linamh/trunk/linamh@714 6952d904-891a-0410-993b-d76249ca496b
This commit is contained in:
parent
9d45f1936c
commit
3af6aa9354
@ -1,217 +0,0 @@
|
||||
# ChangeLog for app-emulation/kvm
|
||||
# Copyright 1999-2009 Gentoo Foundation; Distributed under the GPL v2
|
||||
# $Header: /var/cvsroot/gentoo-x86/app-emulation/kvm/ChangeLog,v 1.25 2009/01/05 01:30:01 dang Exp $
|
||||
|
||||
*kvm-82 (05 Jan 2009)
|
||||
|
||||
05 Jan 2009; Daniel Gryniewicz <dang@gentoo.org> kvm-81.ebuild,
|
||||
+kvm-82.ebuild:
|
||||
Bump to 82
|
||||
|
||||
This release adds support for nested virtualization, a feature which
|
||||
allows you to run kvm (and possibly other hypervisors) inside a guest.
|
||||
This is an experimental feature and is only available on AMD hosts.
|
||||
|
||||
Also fixes bug #251903
|
||||
|
||||
*kvm-81 (16 Dec 2008)
|
||||
|
||||
16 Dec 2008; Daniel Gryniewicz <dang@gentoo.org> +kvm-79-r1.ebuild,
|
||||
+kvm-81.ebuild:
|
||||
Bump to kvm-81
|
||||
- Fixed performance regression in qcow2 files
|
||||
- Several display fixes
|
||||
- Several virtio fixes/cleanups/speedups
|
||||
- Clock fixes
|
||||
|
||||
*kvm-79-r1 (10 Dec 2008)
|
||||
|
||||
10 Dec 2008; Daniel Gryniewicz <dang@gentoo.org> +kvm-79-r1.ebuild:
|
||||
Bump to kvm-79-r1
|
||||
- Fix bug #250283: make kvm-ifup/kvm-ifdown not fail if there are
|
||||
multiple bridges on the host
|
||||
- Add patch from ubuntu to make non-alphabet keys work with evdev
|
||||
|
||||
25 Nov 2008; Daniel Gryniewicz <dang@gentoo.org> kvm-79.ebuild:
|
||||
New patch tarball: remove 06, update 02 (bug #248252)
|
||||
|
||||
*kvm-79 (19 Nov 2008)
|
||||
|
||||
19 Nov 2008; Daniel Gryniewicz <dang@gentoo.org> +kvm-79.ebuild:
|
||||
Bump to kvm-79
|
||||
|
||||
This is the first release to fully support pci device assignment. You can
|
||||
assign a pci device to qemu on the command line, or hot-plug it in via the
|
||||
monitor. Note that at this time, Linux 2.6.28 is required on the host.
|
||||
Note that, at this time, it requires VT-d hardware support from Intel.
|
||||
|
||||
11 Nov 2008; Daniel Gryniewicz <dang@gentoo.org> kvm-78.ebuild:
|
||||
Fix kernel build dir. bug #239189
|
||||
|
||||
*kvm-78 (06 Nov 2008)
|
||||
|
||||
06 Nov 2008; Daniel Gryniewicz <dang@gentoo.org> -kvm-74.ebuild,
|
||||
kvm-77.ebuild, +kvm-78.ebuild:
|
||||
Bump to kvm-78
|
||||
|
||||
21 Oct 2008; Daniel Gryniewicz <dang@gentoo.org> kvm-77.ebuild:
|
||||
Turn on modules by default; that's what most people want
|
||||
|
||||
*kvm-77 (21 Oct 2008)
|
||||
|
||||
21 Oct 2008; Daniel Gryniewicz <dang@gentoo.org> -kvm-73.ebuild,
|
||||
+kvm-77.ebuild:
|
||||
Bump kvm to 77
|
||||
- 2 important changes from a user's point of view:
|
||||
- The minimum version of the kernel for non-module installs is now
|
||||
2.6.25.
|
||||
- If you're building the modules, you need to have CONFIG_KVM enabled
|
||||
in your kernel. This is because a type is not defined unless
|
||||
CONFIG_KVM is set, and the compat code won't kick in unless you're
|
||||
building completely outside the kernel tree (which we're not).
|
||||
- Important upstream changes:
|
||||
- Faster disk emulation
|
||||
- Better handling of >4G of RAM
|
||||
- Improved VNC
|
||||
- Improved USB
|
||||
- live migration fixes
|
||||
- Speed improvements on 2.6.27+ hosts
|
||||
|
||||
15 Sep 2008; Daniel Gryniewicz <dang@gentoo.org> -kvm-71-r2.ebuild,
|
||||
-kvm-72.ebuild, -kvm-72-r1.ebuild:
|
||||
Nuke old versions
|
||||
|
||||
*kvm-75 (15 Sep 2008)
|
||||
|
||||
15 Sep 2008; Daniel Gryniewicz <dang@gentoo.org> +kvm-75.ebuild:
|
||||
Bump to kvm-75
|
||||
|
||||
Ballooning is finally enabled in kvm-75. You will need a 2.6.27+ host for
|
||||
ballooning to work properly.
|
||||
|
||||
*kvm-74 (09 Sep 2008)
|
||||
|
||||
09 Sep 2008; Daniel Gryniewicz <dang@gentoo.org> -kvm-73.ebuild,
|
||||
+kvm-74.ebuild:
|
||||
Bump to kvm-74
|
||||
Changes from kvm-73:
|
||||
- make real-mode startup state conform to spec
|
||||
- fix scheduling error in experimental big real mode support
|
||||
- fix reboot fault handler exception table entry (Eduardo Habkost)
|
||||
- x86 emulator code cleanup (Roel Kluin)
|
||||
- fix 'neg r/m' instruction emulation forced to byte size
|
||||
- fix shadow ptes corruption on i386 hosts running smp guests
|
||||
- fix kvmtrace ABI breakage (Adrian Bunk)
|
||||
- enable virtio for ia64
|
||||
- add generic shadow page table walker
|
||||
- allocate internal guest memory as MAP_PRIVATE
|
||||
- don't call get_user_pages(.force=1)
|
||||
- paves the way for get_user_pages_fast()
|
||||
- add mov r, imm instructions to the emulator (Mohammed Gamal)
|
||||
- realmode emulator testsuite
|
||||
- ia64 external module support (Xiantao Zhang)
|
||||
- support tap IFF_VNET_HDR (Mark McLoughlin)
|
||||
- merge qemu-svn
|
||||
- improved usb support
|
||||
- usb auto connect/disconnect
|
||||
- protect against possible corruption during qemu fork() on older hosts
|
||||
|
||||
(Marcelo Tosatti)
|
||||
|
||||
09 Sep 2008; Daniel Gryniewicz <dang@gentoo.org> -kvm-70.ebuild,
|
||||
-kvm-70-r1.ebuild:
|
||||
Remove old versions referencing removed patches; bug #236890
|
||||
|
||||
23 Aug 2008; Daniel Gryniewicz <dang@gentoo.org> kvm-73.ebuild:
|
||||
Fix some whitespace
|
||||
|
||||
*kvm-73 (23 Aug 2008)
|
||||
|
||||
23 Aug 2008; Daniel Gryniewicz <dang@gentoo.org> metadata.xml,
|
||||
+kvm-73.ebuild:
|
||||
Bump to kvm-73
|
||||
|
||||
- Add a "modules" USE flag to build the kvm kernel modules
|
||||
|
||||
*kvm-72-r1 (07 Aug 2008)
|
||||
|
||||
07 Aug 2008; Daniel Gryniewicz <dang@gentoo.org> metadata.xml,
|
||||
+kvm-72-r1.ebuild:
|
||||
Add vde flag to expose new VDE support
|
||||
|
||||
04 Aug 2008; Daniel Gryniewicz <dang@gentoo.org> metadata.xml,
|
||||
+kvm-72.ebuild:
|
||||
Bump to 72
|
||||
|
||||
*kvm-72 (04 Aug 2008)
|
||||
|
||||
04 Aug 2008; Daniel Gryniewicz <dang@gentoo.org> metadata.xml,
|
||||
+kvm-72.ebuild:
|
||||
Bump to kvm-72
|
||||
|
||||
28 Jul 2008; Doug Goldstein <cardoe@gentoo.org> metadata.xml:
|
||||
add GLEP 56 USE flag desc from use.local.desc
|
||||
|
||||
17 Jul 2008; Daniel Gryniewicz <dang@gentoo.org>
|
||||
-files/kvm-45-qemu-configure.patch, -files/kvm-57-kernel-longmode.patch,
|
||||
-files/kvm-57-qemu-kvm-cmdline.patch, -files/kvm-61-qemu-kvm.patch,
|
||||
-files/kvm-68-libkvm-no-kernel.patch,
|
||||
-files/kvm-69-qemu-ifup_ifdown.patch, -files/kvm-69-qemu-no-blobs.patch,
|
||||
-files/kvm-70-block-rw-range-check.patch,
|
||||
-files/kvm-70-qemu-kvm-doc.patch, -files/kvm-71-qemu-configure.patch,
|
||||
-files/kvm-71-qemu-kvm-doc.patch, kvm-71-r2.ebuild:
|
||||
Move patches into external tarball on mirrors. Git repo is hosted at
|
||||
http://github.com/dang/kvm-patches/tree/master
|
||||
|
||||
*kvm-71-r2 (16 Jul 2008)
|
||||
|
||||
16 Jul 2008; Daniel Gryniewicz <dang@gentoo.org>
|
||||
files/kvm-71-qemu-configure.patch, -kvm-71-r1.ebuild, +kvm-71-r2.ebuild:
|
||||
Fix audio configuration again.
|
||||
|
||||
- Add OSS by default (bug #231926)
|
||||
|
||||
- make the sdl flag enable sdl audio (bug #231925)
|
||||
|
||||
- Make it possible to enable multiple outputs (kvm configure was broken
|
||||
|
||||
before)
|
||||
|
||||
*kvm-71-r1 (15 Jul 2008)
|
||||
|
||||
15 Jul 2008; Daniel Gryniewicz <dang@gentoo.org>
|
||||
+files/kvm-71-qemu-configure.patch, -kvm-71.ebuild, +kvm-71-r1.ebuild:
|
||||
Fix sound configuration broken in 71, and add pulseaudio
|
||||
|
||||
15 Jul 2008; Daniel Gryniewicz <dang@gentoo.org> -files/kvm-48-kvm.patch,
|
||||
+files/kvm-71-qemu-kvm-doc.patch, kvm-70.ebuild, kvm-70-r1.ebuild,
|
||||
+kvm-71.ebuild:
|
||||
Bump to 71
|
||||
|
||||
*kvm-71 (15 Jul 2008)
|
||||
|
||||
15 Jul 2008; Daniel Gryniewicz <dang@gentoo.org> +kvm-71.ebuild:
|
||||
Bump to 71
|
||||
|
||||
*kvm-70-r1 (14 Jul 2008)
|
||||
|
||||
14 Jul 2008; Daniel Gryniewicz <dang@gentoo.org>
|
||||
+files/kvm-70-block-rw-range-check.patch, +kvm-70-r1.ebuild:
|
||||
Add block device bounds checking; bug #231753
|
||||
|
||||
10 Jul 2008; Daniel Gryniewicz <dang@gentoo.org> kvm-70.ebuild:
|
||||
Disable the bios flag for now, it doesn't build. Bug #231343
|
||||
|
||||
10 Jul 2008; Daniel Gryniewicz <dang@gentoo.org> metadata.xml:
|
||||
I guess virtualization isn't a herd yet
|
||||
|
||||
*kvm-70 (09 Jul 2008)
|
||||
|
||||
09 Jul 2008; Daniel Gryniewicz <dang@gentoo.org>
|
||||
+files/kvm-45-qemu-configure.patch, +files/kvm-48-kvm.patch,
|
||||
+files/kvm-57-kernel-longmode.patch, +files/kvm-57-qemu-kvm-cmdline.patch,
|
||||
+files/kvm-61-qemu-kvm.patch, +files/kvm-68-libkvm-no-kernel.patch,
|
||||
+files/kvm-69-qemu-ifup_ifdown.patch, +files/kvm-69-qemu-no-blobs.patch,
|
||||
+files/kvm-70-qemu-kvm-doc.patch, +metadata.xml, +kvm-70.ebuild:
|
||||
Add kvm to the tree
|
||||
|
@ -1,32 +0,0 @@
|
||||
-----BEGIN PGP SIGNED MESSAGE-----
|
||||
Hash: SHA1
|
||||
|
||||
DIST kvm-75.tar.gz 4108859 RMD160 e536cce39653111c1eb4d9eda8e908ae381362b8 SHA1 6b86df5554748998a31a1609cd8b4593af7cd3f0 SHA256 fff3add1e16b3ece8edfb29b10cbdcefed95d8a18ceac77b008a241a2427d0bf
|
||||
DIST kvm-77.tar.gz 7320987 RMD160 3bb7cf48af0af2062769b95485c4a504a1274cd7 SHA1 bb3d0d09b369a4561e4cfe5de58bdf77b1d6a16e SHA256 9b6c1d61d27e5e67daea751b908927fc7290e0f15b3f4bbe391e154404d8abca
|
||||
DIST kvm-78.tar.gz 4231476 RMD160 b4b06a717f6d9212feebd2b2744f3fc89a586a45 SHA1 18d0cb5958d9d3968710cd7a62349ae3d23ca830 SHA256 1ade8847ea3f72b662eedb01f7447325915ca243c3ea86b22ecbb5fafbed6217
|
||||
DIST kvm-79.tar.gz 4263614 RMD160 006ed209cea5eb1936ce93fb773783b93cbd08fa SHA1 7e97f7f71b6891ecbe0daf3b0af30e124ecd1dd4 SHA256 8b3c43cf559308a30cef0152323c99d9398ab8ba1754a7b16cedb1601462383e
|
||||
DIST kvm-81.tar.gz 4292487 RMD160 726abaf75da51d391c59e73669e9013035b178ce SHA1 3982fd20e3469d1279b5e70efcef9682758eb839 SHA256 19d71a028af2d019ed713a3a74d52a20ccbbe73ae6426ec256b7c71ddbecf9ad
|
||||
DIST kvm-82.tar.gz 4301055 RMD160 c463160047f4de95b2d9ad45456a3166e754793e SHA1 9b4ea2c910683667d787ff623d001aa98d0d009e SHA256 fa9bc496db07d4eef738b0feaf3f72986a24b006f89be3b720ffecf4d14365ba
|
||||
DIST kvm-patches-20080822.tar.gz 25178 RMD160 4640f1da457b3ab2da66f8ef6dc98f83464b741e SHA1 827f7a932968e4027902892191cf29cafc5f662a SHA256 811d8541f395c682d98384c7304486e0b47d8fcf6e3df2e02f5ccd7dee353dfb
|
||||
DIST kvm-patches-20081020.tar.gz 21961 RMD160 8c51fa76fb0ec7b8bc4734c6b42e7dcd078bedcd SHA1 470678a4ffe7a25f2ab957ce5eaf5ab6fd730920 SHA256 424d13f264a65de2919bb37af3059391dcaf5fc82e304c6f4366f619c38cd478
|
||||
DIST kvm-patches-20081106.tar.gz 21997 RMD160 f5585a2a3d8bb6e55827a85a689699e10c3338a6 SHA1 0b72d22b65bb01d3d1f4d190290bb0ee59a47f6b SHA256 3077741aff3aaf3b114fc9dd6bc15633ca043c6161ca58535bff0bd5bc21cc73
|
||||
DIST kvm-patches-20081124.tar.gz 20255 RMD160 2af97b634060f5107b73534b7cc1d3de4f7e7b73 SHA1 93d64ba64c7cb0a5e1231b74514a809e4f2e8fd5 SHA256 67dbee0682df543e3cf9a67b8743b154af0e30fbb7caebdcbb7f329f6e870df1
|
||||
DIST kvm-patches-20081210.tar.gz 22522 RMD160 4fe324a5913c1e951e4660cbcb0cd29102b923ba SHA1 803085a476d1228ace5a4ebe712b9f7a7a77281a SHA256 77f235dda72df526f824712e314d108777d8d6fd6f7bf7617662496feea786cd
|
||||
DIST kvm-patches-20081216.tar.gz 23095 RMD160 f82d44f6eff2e49a59ff391e197f3b2fb8e951c6 SHA1 b49b82813162218ab8f08aa1905f63ee4f4d277b SHA256 e8197f8176756d9d8352f4d6eae7443b8977cefc92435c30538a7095d4704be8
|
||||
DIST kvm-patches-20090104.tar.gz 23149 RMD160 1ce67d586a2a93cd7bf3e45161c24daeff9f1314 SHA1 b0013ddf9a2faeb35a519d263ffadaa795cff50d SHA256 384dfbf579aa3adef52e8050e29806cbf0bf6bc36c27dbd08f7584c5c8a2286f
|
||||
EBUILD kvm-75.ebuild 6884 RMD160 aa189a1a1bd03e5088377742697a7ce8987de42c SHA1 e16a3d60e9e3be82e2d2c919eeb90c16e728d341 SHA256 f3561a33882a46235ea57a770a327449fd62dab95ddb38f4e892f28aac988ef6
|
||||
EBUILD kvm-77.ebuild 6785 RMD160 4a95b99f9327c01d6b42ad2d97761208fd137e43 SHA1 a439d709ded61094c89a6a283a020c338da76436 SHA256 17f4905e61b79c41640ad411f96237ae20158af5331a6db0840e30075a6ceda1
|
||||
EBUILD kvm-78.ebuild 6844 RMD160 de0d0f759f9d5d335bbdad908313099395bbb20b SHA1 858b87435a03f2940158b0ab6dae17dacb22d349 SHA256 e88f89f9b038d107a71d221f64047e3a41530421c2731ba5725a376df797bb4e
|
||||
EBUILD kvm-79-r1.ebuild 6847 RMD160 6c956f6eee0253e0fb12b86235b7c87cdc1a582d SHA1 c19d6e9f23ca41aad34b6990ad5890d93eb10c12 SHA256 8aff31e884111e554303a4e8d9f1350da3ca33f7080e3aea1fd6d3fd1330af88
|
||||
EBUILD kvm-79.ebuild 6844 RMD160 b81124ea07c87970460fc62168f7d6be46d50596 SHA1 4a2c098cdf52ddcbc720df5b3d18ccfedbd332c2 SHA256 4a9f9461f5acd8f53cd59b39a21420cde59a3f7257ae35d5e66c2f2d101c12eb
|
||||
EBUILD kvm-81.ebuild 6994 RMD160 4ad0d79d6543c836f6d9c6b4f0d34daf400b1f1d SHA1 33d30a519f6ff405ea89351691b28a271adad931 SHA256 241a3422de81b30b083969c9ece3d34f55af89affeb4b3af3dd430ca04f999fd
|
||||
EBUILD kvm-82.ebuild 6950 RMD160 f379ec52f9ca2957bef915c507195a2ce6fff45c SHA1 30c211ef5f192fbb0438d036d44a9fc28ceffcdf SHA256 02b34f93f24b5ce9245dce2e8ac8e77bb3b5b6af6f2c98cd80b5ac1a09dc59e3
|
||||
MISC ChangeLog 7426 RMD160 bd16943d02c679d07ce1596c0e00f90ed0665d76 SHA1 a2fc49c842bb3c0626421d71629412a1a5df331a SHA256 9df749ff0a987b732270b97dda7cce6d37e6aaf1f537f4954cd4f5d1b168ed86
|
||||
MISC metadata.xml 1282 RMD160 2c8cc65da23f96cfd73f757000192d4af7b29e9f SHA1 3b84cbafe2190715df0310fe8bde8dc6d483e6df SHA256 af8ea32fd7dedeb7401d4df31016c3e6a4a12d9720577bbb9673d4ae22b3dc54
|
||||
-----BEGIN PGP SIGNATURE-----
|
||||
Version: GnuPG v2.0.9 (GNU/Linux)
|
||||
|
||||
iD8DBQFJYWKnomPajV0RnrERAt/OAJ993C6xXsdpu1bkH5GVZGq/YvdB/wCfU72R
|
||||
WFs+nU4Ly9hPrO7q7uJ74Gc=
|
||||
=r9qk
|
||||
-----END PGP SIGNATURE-----
|
@ -1,120 +0,0 @@
|
||||
# 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-77/bios-mac/acpi-dsdt.dsl
|
||||
===================================================================
|
||||
--- kvm-77.orig/bios-mac/acpi-dsdt.dsl
|
||||
+++ kvm-77/bios-mac/acpi-dsdt.dsl
|
||||
@@ -78,6 +78,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-77/bios-mac/rombios32.c
|
||||
===================================================================
|
||||
--- kvm-77.orig/bios-mac/rombios32.c
|
||||
+++ kvm-77/bios-mac/rombios32.c
|
||||
@@ -628,6 +628,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
|
||||
@@ -641,7 +644,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)
|
||||
@@ -772,7 +777,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];
|
||||
|
||||
@@ -854,8 +861,9 @@ static void pci_bios_init_device(PCIDevi
|
||||
case 0x0101:
|
||||
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;
|
||||
@@ -1559,6 +1567,13 @@ void acpi_bios_init(void)
|
||||
acpi_build_table_header((struct acpi_table_header *)madt,
|
||||
"APIC", madt_size, 1);
|
||||
}
|
||||
+ /* 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 */
|
||||
+ }
|
||||
}
|
||||
|
||||
/* SMBIOS entry point -- must be written to a 16-bit aligned address
|
@ -1,13 +0,0 @@
|
||||
Index: kvm-77/kernel/x86/preempt.c
|
||||
===================================================================
|
||||
--- kvm-77.orig/kernel/x86/preempt.c
|
||||
+++ kvm-77/kernel/x86/preempt.c
|
||||
@@ -251,7 +251,7 @@ void preempt_notifier_sys_exit(void)
|
||||
struct idt_desc idt_desc;
|
||||
|
||||
dprintk("\n");
|
||||
- on_each_cpu(do_disable, NULL, 1, 1);
|
||||
+ kvm_on_each_cpu(do_disable, NULL, 1);
|
||||
asm ("sidt %0" : "=m"(idt_desc));
|
||||
idt_desc.gates[1] = orig_int1_gate;
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
--- a/user/test/x86/vmexit.c
|
||||
+++ b/user/test/x86/vmexit.c
|
||||
@@ -1,4 +1,4 @@
|
||||
-
|
||||
+int printf(const char *,...);
|
||||
#include "printf.h"
|
||||
|
||||
static inline unsigned long long rdtsc()
|
@ -1,130 +0,0 @@
|
||||
# Fixes boot with gfxboot of SUSE 10.0 till openSUSE 10.3 and other
|
||||
# distributions which use this version of gfxboot.
|
||||
# Has been discussed upstream, but upstream does not seem to care
|
||||
# much and wants to go for full emulation of this, but it's a project
|
||||
# for multible months to do that.
|
||||
# Room for improvement: Should use an explicitly defined illegal
|
||||
# instruction, not just one which happens to be illegal with current
|
||||
# CPUs.
|
||||
# Signed-off-by: Alex Graf - agraf@suse
|
||||
===================================================================
|
||||
Index: kernel/include/asm-x86/kvm_host.h
|
||||
===================================================================
|
||||
--- kernel/include/asm-x86/kvm_host.h.orig
|
||||
+++ kernel/include/asm-x86/kvm_host.h
|
||||
@@ -240,6 +240,7 @@ struct kvm_vcpu_arch {
|
||||
u32 regs_avail;
|
||||
u32 regs_dirty;
|
||||
|
||||
+ u16 backup_ss;
|
||||
unsigned long cr0;
|
||||
unsigned long cr2;
|
||||
unsigned long cr3;
|
||||
Index: kernel/x86/vmx.c
|
||||
===================================================================
|
||||
--- kernel/x86/vmx.c.orig
|
||||
+++ kernel/x86/vmx.c
|
||||
@@ -1301,8 +1301,10 @@ static void fix_pmode_dataseg(int seg, s
|
||||
static void enter_pmode(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
unsigned long flags;
|
||||
+ unsigned long rip;
|
||||
+ u8 opcodes[2];
|
||||
struct vcpu_vmx *vmx = to_vmx(vcpu);
|
||||
-
|
||||
+
|
||||
vmx->emulation_required = 1;
|
||||
vcpu->arch.rmode.active = 0;
|
||||
|
||||
@@ -1328,12 +1330,39 @@ static void enter_pmode(struct kvm_vcpu
|
||||
fix_pmode_dataseg(VCPU_SREG_GS, &vcpu->arch.rmode.gs);
|
||||
fix_pmode_dataseg(VCPU_SREG_FS, &vcpu->arch.rmode.fs);
|
||||
|
||||
+ /* Save real mode SS */
|
||||
+ vcpu->arch.backup_ss = vmcs_read16(GUEST_SS_SELECTOR);
|
||||
+
|
||||
vmcs_write16(GUEST_SS_SELECTOR, 0);
|
||||
vmcs_write32(GUEST_SS_AR_BYTES, 0x93);
|
||||
|
||||
vmcs_write16(GUEST_CS_SELECTOR,
|
||||
vmcs_read16(GUEST_CS_SELECTOR) & ~SELECTOR_RPL_MASK);
|
||||
vmcs_write32(GUEST_CS_AR_BYTES, 0x9b);
|
||||
+
|
||||
+ /* VMX checks for SS.CPL = CS.CPL on VM entry, if we are in
|
||||
+ * protected mode. This fails on the transistion from real mode
|
||||
+ * to protected mode, as just after that, SS still contains the
|
||||
+ * real mode segment, which does not know anything about CPLs.
|
||||
+ *
|
||||
+ * As far as I know only gfxboot exploits this feature, by using
|
||||
+ * the old real mode SS value to find a new SS selector in protected
|
||||
+ * mode. This happens using a mov %ss, %eax instruction, which we
|
||||
+ * can patch to an invalid opcode and emulate later on, giving eax
|
||||
+ * the real SS value, that existed before the protected mode
|
||||
+ * switch. */
|
||||
+ rip = kvm_rip_read(vcpu) + vmcs_readl(GUEST_CS_BASE) + 14;
|
||||
+ emulator_read_std(rip, (void *)opcodes, 2, vcpu);
|
||||
+
|
||||
+ if ( opcodes[0] == 0x8c && opcodes[1] == 0xd0 ) {
|
||||
+ vcpu_printf(vcpu, "%s: patching mov SS\n", __FUNCTION__);
|
||||
+ opcodes[0] = 0x0f;
|
||||
+ opcodes[1] = 0x0c;
|
||||
+ if (emulator_write_emulated(rip, opcodes,
|
||||
+ 2, vcpu) != X86EMUL_CONTINUE)
|
||||
+ vcpu_printf(vcpu, "%s: unable to patch mov SS\n",
|
||||
+ __FUNCTION__);
|
||||
+ }
|
||||
}
|
||||
|
||||
static gva_t rmode_tss_base(struct kvm *kvm)
|
||||
Index: kernel/x86/x86.c
|
||||
===================================================================
|
||||
--- kernel/x86/x86.c.orig
|
||||
+++ kernel/x86/x86.c
|
||||
@@ -2444,13 +2444,14 @@ int emulate_instruction(struct kvm_vcpu
|
||||
|
||||
r = x86_decode_insn(&vcpu->arch.emulate_ctxt, &emulate_ops);
|
||||
|
||||
- /* Reject the instructions other than VMCALL/VMMCALL when
|
||||
+ /* Reject the instructions other than VMCALL/VMMCALL/HACKS when
|
||||
* try to emulate invalid opcode */
|
||||
c = &vcpu->arch.emulate_ctxt.decode;
|
||||
if ((emulation_type & EMULTYPE_TRAP_UD) &&
|
||||
- (!(c->twobyte && c->b == 0x01 &&
|
||||
+ ((!(c->twobyte && c->b == 0x01 &&
|
||||
(c->modrm_reg == 0 || c->modrm_reg == 3) &&
|
||||
- c->modrm_mod == 3 && c->modrm_rm == 1)))
|
||||
+ c->modrm_mod == 3 && c->modrm_rm == 1)) &&
|
||||
+ c->b != 0x0c))
|
||||
return EMULATE_FAIL;
|
||||
|
||||
++vcpu->stat.insn_emulation;
|
||||
Index: kernel/x86/x86_emulate.c
|
||||
===================================================================
|
||||
--- kernel/x86/x86_emulate.c.orig
|
||||
+++ kernel/x86/x86_emulate.c
|
||||
@@ -196,7 +196,7 @@ static u16 opcode_table[256] = {
|
||||
static u16 twobyte_table[256] = {
|
||||
/* 0x00 - 0x0F */
|
||||
0, Group | GroupDual | Group7, 0, 0, 0, 0, ImplicitOps, 0,
|
||||
- ImplicitOps, ImplicitOps, 0, 0, 0, ImplicitOps | ModRM, 0, 0,
|
||||
+ ImplicitOps, ImplicitOps, 0, 0, ImplicitOps, ImplicitOps | ModRM, 0, 0,
|
||||
/* 0x10 - 0x1F */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, ImplicitOps | ModRM, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x20 - 0x2F */
|
||||
@@ -1898,6 +1898,16 @@ twobyte_insn:
|
||||
case 0x18: /* Grp16 (prefetch/nop) */
|
||||
c->dst.type = OP_NONE;
|
||||
break;
|
||||
+ case 0x0c: /* Invalid (used to patch mov %ss, %eax) */
|
||||
+ /* This opcode is declared invalid, according to the Intel
|
||||
+ * specification. As it is only used on VMX, we do not have
|
||||
+ * to take AMD instructions into account. For more
|
||||
+ * information, why this is needed, please see
|
||||
+ * vmx.c:enter_pmode.
|
||||
+ */
|
||||
+ c->dst.type = OP_NONE;
|
||||
+ c->regs[VCPU_REGS_RAX] = ctxt->vcpu->arch.backup_ss;
|
||||
+ break;
|
||||
case 0x20: /* mov cr, reg */
|
||||
if (c->modrm_mod != 3)
|
||||
goto cannot_emulate;
|
@ -1,14 +0,0 @@
|
||||
Index: kvm-75/kernel/x86/ioapic.c
|
||||
===================================================================
|
||||
--- kvm-75.orig/kernel/x86/ioapic.c
|
||||
+++ kvm-75/kernel/x86/ioapic.c
|
||||
@@ -274,7 +274,8 @@ void kvm_ioapic_set_irq(struct kvm_ioapi
|
||||
|
||||
if (irq >= 0 && irq < IOAPIC_NUM_PINS) {
|
||||
entry = ioapic->redirtbl[irq];
|
||||
- level ^= entry.fields.polarity;
|
||||
+// polarity is always active high in qemu
|
||||
+// level ^= entry.fields.polarity;
|
||||
if (!level)
|
||||
ioapic->irr &= ~mask;
|
||||
else {
|
@ -1,35 +0,0 @@
|
||||
# Quick patch until proper version is upstream, but is safe.
|
||||
# Signed-off-by: Alex Graf - agraf@suse
|
||||
Index: kvm-75/kernel/x86/x86.c
|
||||
===================================================================
|
||||
--- kvm-75.orig/kernel/x86/x86.c
|
||||
+++ kvm-75/kernel/x86/x86.c
|
||||
@@ -1260,7 +1260,7 @@ static int kvm_vcpu_ioctl_set_cpuid(stru
|
||||
struct kvm_cpuid *cpuid,
|
||||
struct kvm_cpuid_entry *entries)
|
||||
{
|
||||
- int r, i;
|
||||
+ int r, i, n = 0;
|
||||
struct kvm_cpuid_entry *cpuid_entries;
|
||||
|
||||
r = -E2BIG;
|
||||
@@ -1280,8 +1280,17 @@ static int kvm_vcpu_ioctl_set_cpuid(stru
|
||||
vcpu->arch.cpuid_entries[i].ebx = cpuid_entries[i].ebx;
|
||||
vcpu->arch.cpuid_entries[i].ecx = cpuid_entries[i].ecx;
|
||||
vcpu->arch.cpuid_entries[i].edx = cpuid_entries[i].edx;
|
||||
- vcpu->arch.cpuid_entries[i].index = 0;
|
||||
- vcpu->arch.cpuid_entries[i].flags = 0;
|
||||
+ switch(vcpu->arch.cpuid_entries[i].function) {
|
||||
+ case 4:
|
||||
+ vcpu->arch.cpuid_entries[i].index = n;
|
||||
+ vcpu->arch.cpuid_entries[i].flags = KVM_CPUID_FLAG_SIGNIFCANT_INDEX;
|
||||
+ n++;
|
||||
+ break;
|
||||
+ default:
|
||||
+ vcpu->arch.cpuid_entries[i].index = 0;
|
||||
+ vcpu->arch.cpuid_entries[i].flags = 0;
|
||||
+ break;
|
||||
+ }
|
||||
vcpu->arch.cpuid_entries[i].padding[0] = 0;
|
||||
vcpu->arch.cpuid_entries[i].padding[1] = 0;
|
||||
vcpu->arch.cpuid_entries[i].padding[2] = 0;
|
@ -1,27 +0,0 @@
|
||||
Index: kvm-75/kernel/x86/x86.c
|
||||
===================================================================
|
||||
--- kvm-75.orig/kernel/x86/x86.c
|
||||
+++ kvm-75/kernel/x86/x86.c
|
||||
@@ -874,7 +874,11 @@ static int set_msr_mtrr(struct kvm_vcpu
|
||||
|
||||
int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data)
|
||||
{
|
||||
+printk(KERN_INFO "MSR write: 0x%lx = 0x%llx\n", msr, data);
|
||||
switch (msr) {
|
||||
+ case 0xe2:
|
||||
+ printk(KERN_INFO "CState MSR write: 0x%llx\n", data);
|
||||
+ break;
|
||||
case MSR_EFER:
|
||||
set_efer(vcpu, data);
|
||||
break;
|
||||
@@ -1025,6 +1029,10 @@ int kvm_get_msr_common(struct kvm_vcpu *
|
||||
case MSR_EFER:
|
||||
data = vcpu->arch.shadow_efer;
|
||||
break;
|
||||
+ case 0xe2:
|
||||
+ printk(KERN_INFO "CState MSR read: 0x0\n");
|
||||
+ data = 0;
|
||||
+ break;
|
||||
case MSR_KVM_WALL_CLOCK:
|
||||
data = vcpu->kvm->arch.wall_clock;
|
||||
break;
|
@ -1,21 +0,0 @@
|
||||
Index: kvm-75/qemu/qemu-kvm-x86.c
|
||||
===================================================================
|
||||
--- kvm-75.orig/qemu/qemu-kvm-x86.c
|
||||
+++ kvm-75/qemu/qemu-kvm-x86.c
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
#include <string.h>
|
||||
#include "hw/hw.h"
|
||||
+#include "hw/boards.h"
|
||||
|
||||
#include "qemu-kvm.h"
|
||||
#include <libkvm.h>
|
||||
@@ -498,7 +499,7 @@ static void do_cpuid_ent(struct kvm_cpui
|
||||
// isn't supported in compatibility mode on Intel. so advertise the
|
||||
// actuall cpu, and say goodbye to migration between different vendors
|
||||
// is you use compatibility mode.
|
||||
- if (function == 0) {
|
||||
+ if (function == 0 && current_machine != &mac_machine) {
|
||||
uint32_t bcd[3];
|
||||
|
||||
host_cpuid(0, NULL, &bcd[0], &bcd[1], &bcd[2]);
|
@ -1,44 +0,0 @@
|
||||
Index: kvm-75/kernel/x86/svm.c
|
||||
===================================================================
|
||||
--- kvm-75.orig/kernel/x86/svm.c
|
||||
+++ kvm-75/kernel/x86/svm.c
|
||||
@@ -50,12 +50,8 @@ MODULE_LICENSE("GPL");
|
||||
#define DEBUGCTL_RESERVED_BITS (~(0x3fULL))
|
||||
|
||||
/* enable NPT for AMD64 and X86 with PAE */
|
||||
-#if defined(CONFIG_X86_64) || defined(CONFIG_X86_PAE)
|
||||
-static bool npt_enabled = true;
|
||||
-#else
|
||||
static bool npt_enabled = false;
|
||||
-#endif
|
||||
-static int npt = 1;
|
||||
+static int npt = 0;
|
||||
|
||||
module_param(npt, int, S_IRUGO);
|
||||
|
||||
@@ -439,19 +435,19 @@ static __init int svm_hardware_setup(voi
|
||||
|
||||
svm_features = cpuid_edx(SVM_CPUID_FUNC);
|
||||
|
||||
- if (!svm_has(SVM_FEATURE_NPT))
|
||||
- npt_enabled = false;
|
||||
+ if (npt)
|
||||
+ npt_enabled = true;
|
||||
|
||||
- if (npt_enabled && !npt) {
|
||||
- printk(KERN_INFO "kvm: Nested Paging disabled\n");
|
||||
+ if (!svm_has(SVM_FEATURE_NPT))
|
||||
npt_enabled = false;
|
||||
- }
|
||||
|
||||
if (npt_enabled) {
|
||||
printk(KERN_INFO "kvm: Nested Paging enabled\n");
|
||||
kvm_enable_tdp();
|
||||
- } else
|
||||
+ } else {
|
||||
+ printk(KERN_INFO "kvm: Nested Paging disabled\n");
|
||||
kvm_disable_tdp();
|
||||
+ }
|
||||
|
||||
return 0;
|
||||
|
@ -1,62 +0,0 @@
|
||||
From: "Marcel Zumstein" <marcel.zumstein@oxinia.ch>
|
||||
Subject: [Qemu-devel] AltGr and dead keys with VNC
|
||||
|
||||
In VNC mode, my AltGr key (mapped to ISO_Level3_Shift) and the dead keys
|
||||
aren't supported. This patch adds XK_ISO_Level3_Shift (keysym 0xfe03) to
|
||||
the keymap. Furthermore, it adds support for the dead keys, which were
|
||||
for some reason present in the keymaps, but not in vnc_keysym.h. This is
|
||||
relevant for VNC viewers that pass dead keys on to the guest system
|
||||
(e.g. tightvnc does) and don't compose the accented letters themselves.
|
||||
|
||||
Index: qemu/keymaps/modifiers
|
||||
===================================================================
|
||||
--- qemu/keymaps/modifiers.orig
|
||||
+++ qemu/keymaps/modifiers
|
||||
@@ -3,6 +3,7 @@ Shift_L 0x2a
|
||||
|
||||
Alt_R 0xb8
|
||||
Mode_switch 0xb8
|
||||
+ISO_Level3_Shift 0xb8
|
||||
Alt_L 0x38
|
||||
|
||||
Control_R 0x9d
|
||||
Index: qemu/vnc_keysym.h
|
||||
===================================================================
|
||||
--- qemu/vnc_keysym.h.orig
|
||||
+++ qemu/vnc_keysym.h
|
||||
@@ -204,6 +204,7 @@ static const name2keysym_t name2keysym[]
|
||||
{"EuroSign", 0x20ac}, /* XK_EuroSign */
|
||||
|
||||
/* modifiers */
|
||||
+{"ISO_Level3_Shift", 0xfe03}, /* XK_ISO_Level3_Shift */
|
||||
{"Control_L", 0xffe3}, /* XK_Control_L */
|
||||
{"Control_R", 0xffe4}, /* XK_Control_R */
|
||||
{"Alt_L", 0xffe9}, /* XK_Alt_L */
|
||||
@@ -286,6 +287,27 @@ static const name2keysym_t name2keysym[]
|
||||
{"Pause", 0xff13}, /* XK_Pause */
|
||||
{"Escape", 0xff1b}, /* XK_Escape */
|
||||
|
||||
+/* dead keys */
|
||||
+{"dead_grave", 0xfe50}, /* XK_dead_grave */
|
||||
+{"dead_acute", 0xfe51}, /* XK_dead_acute */
|
||||
+{"dead_circumflex", 0xfe52}, /* XK_dead_circumflex */
|
||||
+{"dead_tilde", 0xfe53}, /* XK_dead_tilde */
|
||||
+{"dead_macron", 0xfe54}, /* XK_dead_macron */
|
||||
+{"dead_breve", 0xfe55}, /* XK_dead_breve */
|
||||
+{"dead_abovedot", 0xfe56}, /* XK_dead_abovedot */
|
||||
+{"dead_diaeresis", 0xfe57}, /* XK_dead_diaeresis */
|
||||
+{"dead_abovering", 0xfe58}, /* XK_dead_abovering */
|
||||
+{"dead_doubleacute", 0xfe59}, /* XK_dead_doubleacute */
|
||||
+{"dead_caron", 0xfe5a}, /* XK_dead_caron */
|
||||
+{"dead_cedilla", 0xfe5b}, /* XK_dead_cedilla */
|
||||
+{"dead_ogonek", 0xfe5c}, /* XK_dead_ogonek */
|
||||
+{"dead_iota", 0xfe5d}, /* XK_dead_iota */
|
||||
+{"dead_voiced_sound", 0xfe5e}, /* XK_dead_voiced_sound */
|
||||
+{"dead_semivoiced_sound", 0xfe5f}, /* XK_dead_semivoiced_sound */
|
||||
+{"dead_belowdot", 0xfe60}, /* XK_dead_belowdot */
|
||||
+{"dead_hook", 0xfe61}, /* XK_dead_hook */
|
||||
+{"dead_horn", 0xfe62}, /* XK_dead_horn */
|
||||
+
|
||||
/* localized keys */
|
||||
{"BackApostrophe", 0xff21},
|
||||
{"Muhenkan", 0xff22},
|
@ -1,545 +0,0 @@
|
||||
From 3be490091c2503d8b50f4a0ce1efe68004f65d3e Mon Sep 17 00:00:00 2001
|
||||
From: Alexander Graf <agraf@suse.de>
|
||||
Date: Tue, 4 Nov 2008 18:48:21 +0100
|
||||
Subject: [PATCH] Activate Virtualization On Demand v3
|
||||
|
||||
X86 CPUs need to have some magic happening to enable the virtualization
|
||||
extensions on them. This magic can result in unpleasant results for
|
||||
users, like blocking other VMMs from working (vmx) or using invalid TLB
|
||||
entries (svm).
|
||||
|
||||
Currently KVM activates virtualization when the respective kernel module
|
||||
is loaded. This blocks us from autoloading KVM modules without breaking
|
||||
other VMMs.
|
||||
|
||||
To circumvent this problem at least a bit, this patch introduces on
|
||||
demand activation of virtualization. This means, that instead
|
||||
virtualization is enabled on creation of the first virtual machine
|
||||
and disabled on removal of the last one.
|
||||
|
||||
So using this, KVM can be easily autoloaded, while keeping other
|
||||
hypervisors usable.
|
||||
|
||||
v2 adds returns to non-x86 hardware_enables and adds IA64 change
|
||||
v3 changes:
|
||||
- use spin_lock instead of atomics
|
||||
- put locking to new functions hardware_{en,dis}able_all that get called
|
||||
on VM creation/destruction
|
||||
- remove usage counter checks where not necessary
|
||||
- return -EINVAL for IA64 slot < 0 case
|
||||
|
||||
Signed-off-by: Alexander Graf <agraf@suse.de>
|
||||
---
|
||||
arch/ia64/kvm/kvm-ia64.c | 8 +++--
|
||||
arch/powerpc/kvm/powerpc.c | 3 +-
|
||||
arch/s390/kvm/kvm-s390.c | 3 +-
|
||||
kernel/x86/svm.c | 13 +++++--
|
||||
kernel/x86/vmx.c | 7 +++-
|
||||
kernel/x86/x86.c | 4 +-
|
||||
kernel/include/asm-x86/kvm_host.h | 2 +-
|
||||
kernel/include/linux/kvm_host.h | 2 +-
|
||||
virt/kvm/kvm_main.c | 75 ++++++++++++++++++++++++++++++++++++-------
|
||||
9 files changed, 90 insertions(+), 27 deletions(-)
|
||||
|
||||
Index: kvm-78/kernel/ia64/kvm-ia64.c
|
||||
===================================================================
|
||||
--- kvm-78.orig/kernel/ia64/kvm-ia64.c
|
||||
+++ kvm-78/kernel/ia64/kvm-ia64.c
|
||||
@@ -138,7 +138,7 @@ long ia64_pal_vp_create(u64 *vpd, u64 *h
|
||||
|
||||
static DEFINE_SPINLOCK(vp_lock);
|
||||
|
||||
-void kvm_arch_hardware_enable(void *garbage)
|
||||
+int kvm_arch_hardware_enable(void *garbage)
|
||||
{
|
||||
long status;
|
||||
long tmp_base;
|
||||
@@ -152,7 +152,7 @@ void kvm_arch_hardware_enable(void *garb
|
||||
slot = ia64_itr_entry(0x3, KVM_VMM_BASE, pte, KVM_VMM_SHIFT);
|
||||
local_irq_restore(saved_psr);
|
||||
if (slot < 0)
|
||||
- return;
|
||||
+ return -EINVAL;
|
||||
|
||||
spin_lock(&vp_lock);
|
||||
status = ia64_pal_vp_init_env(kvm_vsa_base ?
|
||||
@@ -160,7 +160,7 @@ void kvm_arch_hardware_enable(void *garb
|
||||
__pa(kvm_vm_buffer), KVM_VM_BUFFER_BASE, &tmp_base);
|
||||
if (status != 0) {
|
||||
printk(KERN_WARNING"kvm: Failed to Enable VT Support!!!!\n");
|
||||
- return ;
|
||||
+ return -EINVAL;
|
||||
}
|
||||
|
||||
if (!kvm_vsa_base) {
|
||||
@@ -169,6 +169,8 @@ void kvm_arch_hardware_enable(void *garb
|
||||
}
|
||||
spin_unlock(&vp_lock);
|
||||
ia64_ptr_entry(0x3, slot);
|
||||
+
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
void kvm_arch_hardware_disable(void *garbage)
|
||||
Index: kvm-78/kernel/x86/svm.c
|
||||
===================================================================
|
||||
--- kvm-78.orig/kernel/x86/svm.c
|
||||
+++ kvm-78/kernel/x86/svm.c
|
||||
@@ -300,7 +300,7 @@ static void svm_hardware_disable(void *g
|
||||
wrmsrl(MSR_EFER, efer & ~MSR_EFER_SVME_MASK);
|
||||
}
|
||||
|
||||
-static void svm_hardware_enable(void *garbage)
|
||||
+static int svm_hardware_enable(void *garbage)
|
||||
{
|
||||
|
||||
struct svm_cpu_data *svm_data;
|
||||
@@ -309,16 +309,20 @@ static void svm_hardware_enable(void *ga
|
||||
struct kvm_desc_struct *gdt;
|
||||
int me = raw_smp_processor_id();
|
||||
|
||||
+ rdmsrl(MSR_EFER, efer);
|
||||
+ if (efer & MSR_EFER_SVME_MASK)
|
||||
+ return -EBUSY;
|
||||
+
|
||||
if (!has_svm()) {
|
||||
printk(KERN_ERR "svm_cpu_init: err EOPNOTSUPP on %d\n", me);
|
||||
- return;
|
||||
+ return -EINVAL;
|
||||
}
|
||||
svm_data = per_cpu(svm_data, me);
|
||||
|
||||
if (!svm_data) {
|
||||
printk(KERN_ERR "svm_cpu_init: svm_data is NULL on %d\n",
|
||||
me);
|
||||
- return;
|
||||
+ return -EINVAL;
|
||||
}
|
||||
|
||||
svm_data->asid_generation = 1;
|
||||
@@ -329,11 +333,12 @@ static void svm_hardware_enable(void *ga
|
||||
gdt = (struct kvm_desc_struct *)gdt_descr.address;
|
||||
svm_data->tss_desc = (struct kvm_ldttss_desc *)(gdt + GDT_ENTRY_TSS);
|
||||
|
||||
- rdmsrl(MSR_EFER, efer);
|
||||
wrmsrl(MSR_EFER, efer | MSR_EFER_SVME_MASK);
|
||||
|
||||
wrmsrl(MSR_VM_HSAVE_PA,
|
||||
page_to_pfn(svm_data->save_area) << PAGE_SHIFT);
|
||||
+
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
static void svm_cpu_uninit(int cpu)
|
||||
Index: kvm-78/kernel/x86/vmx.c
|
||||
===================================================================
|
||||
--- kvm-78.orig/kernel/x86/vmx.c
|
||||
+++ kvm-78/kernel/x86/vmx.c
|
||||
@@ -1090,12 +1090,15 @@ static __init int vmx_disabled_by_bios(v
|
||||
/* locked but not enabled */
|
||||
}
|
||||
|
||||
-static void hardware_enable(void *garbage)
|
||||
+static int hardware_enable(void *garbage)
|
||||
{
|
||||
int cpu = raw_smp_processor_id();
|
||||
u64 phys_addr = __pa(per_cpu(vmxarea, cpu));
|
||||
u64 old;
|
||||
|
||||
+ if (read_cr4() & X86_CR4_VMXE)
|
||||
+ return -EBUSY;
|
||||
+
|
||||
INIT_LIST_HEAD(&per_cpu(vcpus_on_cpu, cpu));
|
||||
rdmsrl(MSR_IA32_FEATURE_CONTROL, old);
|
||||
if ((old & (FEATURE_CONTROL_LOCKED |
|
||||
@@ -1110,6 +1113,8 @@ static void hardware_enable(void *garbag
|
||||
asm volatile (ASM_VMX_VMXON_RAX
|
||||
: : "a"(&phys_addr), "m"(phys_addr)
|
||||
: "memory", "cc");
|
||||
+
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
static void vmclear_local_vcpus(void)
|
||||
Index: kvm-78/kernel/x86/x86.c
|
||||
===================================================================
|
||||
--- kvm-78.orig/kernel/x86/x86.c
|
||||
+++ kvm-78/kernel/x86/x86.c
|
||||
@@ -4077,9 +4077,9 @@ int kvm_arch_vcpu_reset(struct kvm_vcpu
|
||||
return kvm_x86_ops->vcpu_reset(vcpu);
|
||||
}
|
||||
|
||||
-void kvm_arch_hardware_enable(void *garbage)
|
||||
+int kvm_arch_hardware_enable(void *garbage)
|
||||
{
|
||||
- kvm_x86_ops->hardware_enable(garbage);
|
||||
+ return kvm_x86_ops->hardware_enable(garbage);
|
||||
}
|
||||
|
||||
void kvm_arch_hardware_disable(void *garbage)
|
||||
Index: kvm-78/kernel/include/asm-x86/kvm_host.h
|
||||
===================================================================
|
||||
--- kvm-78.orig/kernel/include/asm-x86/kvm_host.h
|
||||
+++ kvm-78/kernel/include/asm-x86/kvm_host.h
|
||||
@@ -453,7 +453,7 @@ struct descriptor_table {
|
||||
struct kvm_x86_ops {
|
||||
int (*cpu_has_kvm_support)(void); /* __init */
|
||||
int (*disabled_by_bios)(void); /* __init */
|
||||
- void (*hardware_enable)(void *dummy); /* __init */
|
||||
+ int (*hardware_enable)(void *dummy); /* __init */
|
||||
void (*hardware_disable)(void *dummy);
|
||||
void (*check_processor_compatibility)(void *rtn);
|
||||
int (*hardware_setup)(void); /* __init */
|
||||
Index: kvm-78/kernel/include/linux/kvm_host.h
|
||||
===================================================================
|
||||
--- kvm-78.orig/kernel/include/linux/kvm_host.h
|
||||
+++ kvm-78/kernel/include/linux/kvm_host.h
|
||||
@@ -300,7 +300,7 @@ int kvm_arch_vcpu_setup(struct kvm_vcpu
|
||||
void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu);
|
||||
|
||||
int kvm_arch_vcpu_reset(struct kvm_vcpu *vcpu);
|
||||
-void kvm_arch_hardware_enable(void *garbage);
|
||||
+int kvm_arch_hardware_enable(void *garbage);
|
||||
void kvm_arch_hardware_disable(void *garbage);
|
||||
int kvm_arch_hardware_setup(void);
|
||||
void kvm_arch_hardware_unsetup(void);
|
||||
Index: kvm-78/kernel/x86/kvm_main.c
|
||||
===================================================================
|
||||
--- kvm-78.orig/kernel/x86/kvm_main.c
|
||||
+++ kvm-78/kernel/x86/kvm_main.c
|
||||
@@ -93,6 +93,8 @@ DEFINE_SPINLOCK(kvm_lock);
|
||||
LIST_HEAD(vm_list);
|
||||
|
||||
static cpumask_t cpus_hardware_enabled;
|
||||
+static int kvm_usage_count = 0;
|
||||
+static DEFINE_SPINLOCK(kvm_usage_lock);
|
||||
|
||||
struct kmem_cache *kvm_vcpu_cache;
|
||||
EXPORT_SYMBOL_GPL(kvm_vcpu_cache);
|
||||
@@ -103,6 +105,8 @@ struct dentry *kvm_debugfs_dir;
|
||||
|
||||
static long kvm_vcpu_ioctl(struct file *file, unsigned int ioctl,
|
||||
unsigned long arg);
|
||||
+static int hardware_enable_all(void);
|
||||
+static void hardware_disable_all(void);
|
||||
|
||||
bool kvm_rebooting;
|
||||
|
||||
@@ -592,19 +596,25 @@ static const struct mmu_notifier_ops kvm
|
||||
|
||||
static struct kvm *kvm_create_vm(void)
|
||||
{
|
||||
+ int r = 0;
|
||||
struct kvm *kvm = kvm_arch_create_vm();
|
||||
#ifdef KVM_COALESCED_MMIO_PAGE_OFFSET
|
||||
struct page *page;
|
||||
#endif
|
||||
|
||||
if (IS_ERR(kvm))
|
||||
- goto out;
|
||||
+ return kvm;
|
||||
+
|
||||
+ r = hardware_enable_all();
|
||||
+ if (r) {
|
||||
+ goto out_err;
|
||||
+ }
|
||||
|
||||
#ifdef KVM_COALESCED_MMIO_PAGE_OFFSET
|
||||
page = alloc_page(GFP_KERNEL | __GFP_ZERO);
|
||||
if (!page) {
|
||||
- kfree(kvm);
|
||||
- return ERR_PTR(-ENOMEM);
|
||||
+ r = -ENOMEM;
|
||||
+ goto out_err;
|
||||
}
|
||||
kvm->coalesced_mmio_ring =
|
||||
(struct kvm_coalesced_mmio_ring *)page_address(page);
|
||||
@@ -612,15 +622,13 @@ static struct kvm *kvm_create_vm(void)
|
||||
|
||||
#if defined(CONFIG_MMU_NOTIFIER) && defined(KVM_ARCH_WANT_MMU_NOTIFIER)
|
||||
{
|
||||
- int err;
|
||||
kvm->mmu_notifier.ops = &kvm_mmu_notifier_ops;
|
||||
- err = mmu_notifier_register(&kvm->mmu_notifier, current->mm);
|
||||
- if (err) {
|
||||
+ r = mmu_notifier_register(&kvm->mmu_notifier, current->mm);
|
||||
+ if (r) {
|
||||
#ifdef KVM_COALESCED_MMIO_PAGE_OFFSET
|
||||
put_page(page);
|
||||
#endif
|
||||
- kfree(kvm);
|
||||
- return ERR_PTR(err);
|
||||
+ goto out_err;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -639,8 +647,12 @@ mmget(&kvm->mm->mm_count);
|
||||
#ifdef KVM_COALESCED_MMIO_PAGE_OFFSET
|
||||
kvm_coalesced_mmio_init(kvm);
|
||||
#endif
|
||||
-out:
|
||||
return kvm;
|
||||
+
|
||||
+out_err:
|
||||
+ hardware_disable_all();
|
||||
+ kfree(kvm);
|
||||
+ return ERR_PTR(r);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -689,6 +701,7 @@ static void kvm_destroy_vm(struct kvm *k
|
||||
mmu_notifier_unregister(&kvm->mmu_notifier, kvm->mm);
|
||||
#endif
|
||||
kvm_arch_destroy_vm(kvm);
|
||||
+ hardware_disable_all();
|
||||
mmdrop(mm);
|
||||
}
|
||||
|
||||
@@ -1796,14 +1809,40 @@ static struct miscdevice kvm_dev = {
|
||||
&kvm_chardev_ops,
|
||||
};
|
||||
|
||||
-static void hardware_enable(void *junk)
|
||||
+static void hardware_enable(void *_r)
|
||||
{
|
||||
int cpu = raw_smp_processor_id();
|
||||
+ int r;
|
||||
+
|
||||
+ /* If enabling a previous CPU failed already, let's not continue */
|
||||
+ if (_r && *((int*)_r))
|
||||
+ return;
|
||||
|
||||
if (cpu_isset(cpu, cpus_hardware_enabled))
|
||||
return;
|
||||
+ r = kvm_arch_hardware_enable(NULL);
|
||||
+ if (_r)
|
||||
+ *((int*)_r) = r;
|
||||
+ if (r) {
|
||||
+ printk(KERN_INFO "kvm: enabling virtualization on "
|
||||
+ "CPU%d failed\n", cpu);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
cpu_set(cpu, cpus_hardware_enabled);
|
||||
- kvm_arch_hardware_enable(NULL);
|
||||
+}
|
||||
+
|
||||
+static int hardware_enable_all(void)
|
||||
+{
|
||||
+ int r = 0;
|
||||
+
|
||||
+ spin_lock(&kvm_usage_lock);
|
||||
+ kvm_usage_count++;
|
||||
+ if (kvm_usage_count == 1)
|
||||
+ kvm_on_each_cpu(hardware_enable, &r, 1);
|
||||
+ spin_unlock(&kvm_usage_lock);
|
||||
+
|
||||
+ return r;
|
||||
}
|
||||
|
||||
static void hardware_disable(void *junk)
|
||||
@@ -1816,6 +1855,18 @@ static void hardware_disable(void *junk)
|
||||
kvm_arch_hardware_disable(NULL);
|
||||
}
|
||||
|
||||
+static void hardware_disable_all(void)
|
||||
+{
|
||||
+ if (!kvm_usage_count)
|
||||
+ return;
|
||||
+
|
||||
+ spin_lock(&kvm_usage_lock);
|
||||
+ kvm_usage_count--;
|
||||
+ if (!kvm_usage_count)
|
||||
+ kvm_on_each_cpu(hardware_disable, NULL, 1);
|
||||
+ spin_unlock(&kvm_usage_lock);
|
||||
+}
|
||||
+
|
||||
static int kvm_cpu_hotplug(struct notifier_block *notifier, unsigned long val,
|
||||
void *v)
|
||||
{
|
||||
@@ -2061,7 +2112,6 @@ int kvm_init(void *opaque, unsigned int
|
||||
goto out_free_1;
|
||||
}
|
||||
|
||||
- kvm_on_each_cpu(hardware_enable, NULL, 1);
|
||||
r = register_cpu_notifier(&kvm_cpu_notifier);
|
||||
if (r)
|
||||
goto out_free_2;
|
||||
@@ -2114,7 +2164,6 @@ out_free_3:
|
||||
unregister_reboot_notifier(&kvm_reboot_notifier);
|
||||
unregister_cpu_notifier(&kvm_cpu_notifier);
|
||||
out_free_2:
|
||||
- kvm_on_each_cpu(hardware_disable, NULL, 1);
|
||||
out_free_1:
|
||||
kvm_arch_hardware_unsetup();
|
||||
out_free_0:
|
||||
Index: kvm-78/kernel/ia64/kvm_main.c
|
||||
===================================================================
|
||||
--- kvm-78.orig/kernel/ia64/kvm_main.c
|
||||
+++ kvm-78/kernel/ia64/kvm_main.c
|
||||
@@ -93,6 +93,8 @@ DEFINE_SPINLOCK(kvm_lock);
|
||||
LIST_HEAD(vm_list);
|
||||
|
||||
static cpumask_t cpus_hardware_enabled;
|
||||
+static int kvm_usage_count = 0;
|
||||
+static DEFINE_SPINLOCK(kvm_usage_lock);
|
||||
|
||||
struct kmem_cache *kvm_vcpu_cache;
|
||||
EXPORT_SYMBOL_GPL(kvm_vcpu_cache);
|
||||
@@ -103,6 +105,8 @@ struct dentry *kvm_debugfs_dir;
|
||||
|
||||
static long kvm_vcpu_ioctl(struct file *file, unsigned int ioctl,
|
||||
unsigned long arg);
|
||||
+static int hardware_enable_all(void);
|
||||
+static void hardware_disable_all(void);
|
||||
|
||||
bool kvm_rebooting;
|
||||
|
||||
@@ -592,19 +596,25 @@ static const struct mmu_notifier_ops kvm
|
||||
|
||||
static struct kvm *kvm_create_vm(void)
|
||||
{
|
||||
+ int r = 0;
|
||||
struct kvm *kvm = kvm_arch_create_vm();
|
||||
#ifdef KVM_COALESCED_MMIO_PAGE_OFFSET
|
||||
struct page *page;
|
||||
#endif
|
||||
|
||||
if (IS_ERR(kvm))
|
||||
- goto out;
|
||||
+ return kvm;
|
||||
+
|
||||
+ r = hardware_enable_all();
|
||||
+ if (r) {
|
||||
+ goto out_err;
|
||||
+ }
|
||||
|
||||
#ifdef KVM_COALESCED_MMIO_PAGE_OFFSET
|
||||
page = alloc_page(GFP_KERNEL | __GFP_ZERO);
|
||||
if (!page) {
|
||||
- kfree(kvm);
|
||||
- return ERR_PTR(-ENOMEM);
|
||||
+ r = -ENOMEM;
|
||||
+ goto out_err;
|
||||
}
|
||||
kvm->coalesced_mmio_ring =
|
||||
(struct kvm_coalesced_mmio_ring *)page_address(page);
|
||||
@@ -612,15 +622,13 @@ static struct kvm *kvm_create_vm(void)
|
||||
|
||||
#if defined(CONFIG_MMU_NOTIFIER) && defined(KVM_ARCH_WANT_MMU_NOTIFIER)
|
||||
{
|
||||
- int err;
|
||||
kvm->mmu_notifier.ops = &kvm_mmu_notifier_ops;
|
||||
- err = mmu_notifier_register(&kvm->mmu_notifier, current->mm);
|
||||
- if (err) {
|
||||
+ r = mmu_notifier_register(&kvm->mmu_notifier, current->mm);
|
||||
+ if (r) {
|
||||
#ifdef KVM_COALESCED_MMIO_PAGE_OFFSET
|
||||
put_page(page);
|
||||
#endif
|
||||
- kfree(kvm);
|
||||
- return ERR_PTR(err);
|
||||
+ goto out_err;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -639,8 +647,12 @@ static struct kvm *kvm_create_vm(void)
|
||||
#ifdef KVM_COALESCED_MMIO_PAGE_OFFSET
|
||||
kvm_coalesced_mmio_init(kvm);
|
||||
#endif
|
||||
-out:
|
||||
return kvm;
|
||||
+
|
||||
+out_err:
|
||||
+ hardware_disable_all();
|
||||
+ kfree(kvm);
|
||||
+ return ERR_PTR(r);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -689,6 +701,7 @@ static void kvm_destroy_vm(struct kvm *k
|
||||
mmu_notifier_unregister(&kvm->mmu_notifier, kvm->mm);
|
||||
#endif
|
||||
kvm_arch_destroy_vm(kvm);
|
||||
+ hardware_disable_all();
|
||||
mmdrop(mm);
|
||||
}
|
||||
|
||||
@@ -1796,14 +1809,40 @@ static struct miscdevice kvm_dev = {
|
||||
&kvm_chardev_ops,
|
||||
};
|
||||
|
||||
-static void hardware_enable(void *junk)
|
||||
+static void hardware_enable(void *_r)
|
||||
{
|
||||
int cpu = raw_smp_processor_id();
|
||||
+ int r;
|
||||
+
|
||||
+ /* If enabling a previous CPU failed already, let's not continue */
|
||||
+ if (_r && *((int*)_r))
|
||||
+ return;
|
||||
|
||||
if (cpu_isset(cpu, cpus_hardware_enabled))
|
||||
return;
|
||||
+ r = kvm_arch_hardware_enable(NULL);
|
||||
+ if (_r)
|
||||
+ *((int*)_r) = r;
|
||||
+ if (r) {
|
||||
+ printk(KERN_INFO "kvm: enabling virtualization on "
|
||||
+ "CPU%d failed\n", cpu);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
cpu_set(cpu, cpus_hardware_enabled);
|
||||
- kvm_arch_hardware_enable(NULL);
|
||||
+}
|
||||
+
|
||||
+static int hardware_enable_all(void)
|
||||
+{
|
||||
+ int r = 0;
|
||||
+
|
||||
+ spin_lock(&kvm_usage_lock);
|
||||
+ kvm_usage_count++;
|
||||
+ if (kvm_usage_count == 1)
|
||||
+ on_each_cpu(hardware_enable, &r, 1);
|
||||
+ spin_unlock(&kvm_usage_lock);
|
||||
+
|
||||
+ return r;
|
||||
}
|
||||
|
||||
static void hardware_disable(void *junk)
|
||||
@@ -1816,6 +1855,18 @@ static void hardware_disable(void *junk)
|
||||
kvm_arch_hardware_disable(NULL);
|
||||
}
|
||||
|
||||
+static void hardware_disable_all(void)
|
||||
+{
|
||||
+ if (!kvm_usage_count)
|
||||
+ return;
|
||||
+
|
||||
+ spin_lock(&kvm_usage_lock);
|
||||
+ kvm_usage_count--;
|
||||
+ if (!kvm_usage_count)
|
||||
+ on_each_cpu(hardware_disable, NULL, 1);
|
||||
+ spin_unlock(&kvm_usage_lock);
|
||||
+}
|
||||
+
|
||||
static int kvm_cpu_hotplug(struct notifier_block *notifier, unsigned long val,
|
||||
void *v)
|
||||
{
|
||||
@@ -2058,7 +2109,6 @@ int kvm_init(void *opaque, unsigned int
|
||||
goto out_free_1;
|
||||
}
|
||||
|
||||
- kvm_on_each_cpu(hardware_enable, NULL, 1);
|
||||
r = register_cpu_notifier(&kvm_cpu_notifier);
|
||||
if (r)
|
||||
goto out_free_2;
|
||||
@@ -2104,7 +2154,6 @@ out_free_3:
|
||||
unregister_reboot_notifier(&kvm_reboot_notifier);
|
||||
unregister_cpu_notifier(&kvm_cpu_notifier);
|
||||
out_free_2:
|
||||
- kvm_on_each_cpu(hardware_disable, NULL, 1);
|
||||
out_free_1:
|
||||
kvm_arch_hardware_unsetup();
|
||||
out_free_0:
|
@ -1,243 +0,0 @@
|
||||
#qemu-only -> submit upstream qemu
|
||||
Index: kvm-75/qemu/Makefile.target
|
||||
===================================================================
|
||||
--- kvm-75.orig/qemu/Makefile.target
|
||||
+++ kvm-75/qemu/Makefile.target
|
||||
@@ -610,7 +610,7 @@ ifeq ($(TARGET_BASE_ARCH), i386)
|
||||
OBJS+= ide.o pckbd.o ps2.o vga.o $(SOUND_HW) dma.o
|
||||
OBJS+= fdc.o mc146818rtc.o serial.o i8259.o i8254.o pcspk.o pc.o
|
||||
OBJS+= cirrus_vga.o apic.o parallel.o acpi.o piix_pci.o
|
||||
-OBJS+= usb-uhci.o vmmouse.o vmport.o vmware_vga.o extboot.o hpet.o lpc.o
|
||||
+OBJS+= usb-uhci.o vmmouse.o vmport.o vmware_vga.o extboot.o hpet.o lpc.o applesmc.o
|
||||
ifeq ($(USE_KVM_PIT), 1)
|
||||
OBJS+= i8254-kvm.o
|
||||
endif
|
||||
Index: kvm-75/qemu/hw/applesmc.c
|
||||
===================================================================
|
||||
--- /dev/null
|
||||
+++ kvm-75/qemu/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: kvm-75/qemu/hw/pc.h
|
||||
===================================================================
|
||||
--- kvm-75.orig/qemu/hw/pc.h
|
||||
+++ kvm-75/qemu/hw/pc.h
|
||||
@@ -150,6 +150,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: kvm-75/qemu/vl.c
|
||||
===================================================================
|
||||
--- kvm-75.orig/qemu/vl.c
|
||||
+++ kvm-75/qemu/vl.c
|
||||
@@ -8381,6 +8381,7 @@ static void help(int exitcode)
|
||||
#endif
|
||||
#ifdef TARGET_I386
|
||||
"-no-fd-bootchk disable boot signature checking for floppy disks\n"
|
||||
+ "-osk key set AppleSMC key\n"
|
||||
#endif
|
||||
"-m megs set virtual RAM size to megs MB [default=%d]\n"
|
||||
"-smp n set the number of CPUs to 'n' [default=1]\n"
|
||||
@@ -8547,6 +8548,7 @@ enum {
|
||||
QEMU_OPTION_snapshot,
|
||||
#ifdef TARGET_I386
|
||||
QEMU_OPTION_no_fd_bootchk,
|
||||
+ QEMU_OPTION_osk,
|
||||
#endif
|
||||
QEMU_OPTION_m,
|
||||
QEMU_OPTION_nographic,
|
||||
@@ -8648,6 +8650,7 @@ const QEMUOption qemu_options[] = {
|
||||
{ "snapshot", 0, QEMU_OPTION_snapshot },
|
||||
#ifdef TARGET_I386
|
||||
{ "no-fd-bootchk", 0, QEMU_OPTION_no_fd_bootchk },
|
||||
+ { "osk", HAS_ARG, QEMU_OPTION_osk },
|
||||
#endif
|
||||
{ "m", HAS_ARG, QEMU_OPTION_m },
|
||||
{ "nographic", 0, QEMU_OPTION_nographic },
|
||||
@@ -9360,6 +9363,9 @@ int main(int argc, char **argv)
|
||||
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) {
|
@ -1,58 +0,0 @@
|
||||
# Quick patch until proper version is upstream, but is safe.
|
||||
# Signed-off-by: Alex Graf - agraf@suse
|
||||
Index: kvm-75/qemu/qemu-kvm-x86.c
|
||||
===================================================================
|
||||
--- kvm-75.orig/qemu/qemu-kvm-x86.c
|
||||
+++ kvm-75/qemu/qemu-kvm-x86.c
|
||||
@@ -465,10 +465,11 @@ static void host_cpuid(uint32_t function
|
||||
}
|
||||
|
||||
|
||||
-static void do_cpuid_ent(struct kvm_cpuid_entry *e, uint32_t function,
|
||||
+static void do_cpuid_ent(struct kvm_cpuid_entry *e, uint32_t function, uint32_t index,
|
||||
CPUState *env)
|
||||
{
|
||||
env->regs[R_EAX] = function;
|
||||
+ env->regs[R_ECX] = index;
|
||||
qemu_kvm_cpuid_on_env(env);
|
||||
e->function = function;
|
||||
e->eax = env->regs[R_EAX];
|
||||
@@ -554,7 +555,7 @@ int kvm_arch_qemu_init_env(CPUState *cen
|
||||
#endif
|
||||
int cpuid_nent = 0;
|
||||
CPUState copy;
|
||||
- uint32_t i, limit;
|
||||
+ uint32_t i, j, limit;
|
||||
|
||||
copy = *cenv;
|
||||
|
||||
@@ -579,15 +580,26 @@ int kvm_arch_qemu_init_env(CPUState *cen
|
||||
qemu_kvm_cpuid_on_env(©);
|
||||
limit = copy.regs[R_EAX];
|
||||
|
||||
- for (i = 0; i <= limit; ++i)
|
||||
- do_cpuid_ent(&cpuid_ent[cpuid_nent++], i, ©);
|
||||
+ for (i = 0; i <= limit; ++i) {
|
||||
+ switch(i) {
|
||||
+ case 4:
|
||||
+ for(j = 0; ; j++) {
|
||||
+ do_cpuid_ent(&cpuid_ent[cpuid_nent++], i, j, ©);
|
||||
+ if(!copy.regs[R_EAX]) break;
|
||||
+ }
|
||||
+ break;
|
||||
+ default:
|
||||
+ do_cpuid_ent(&cpuid_ent[cpuid_nent++], i, 0, ©);
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
|
||||
copy.regs[R_EAX] = 0x80000000;
|
||||
qemu_kvm_cpuid_on_env(©);
|
||||
limit = copy.regs[R_EAX];
|
||||
|
||||
for (i = 0x80000000; i <= limit; ++i)
|
||||
- do_cpuid_ent(&cpuid_ent[cpuid_nent++], i, ©);
|
||||
+ do_cpuid_ent(&cpuid_ent[cpuid_nent++], i, 0, ©);
|
||||
|
||||
kvm_setup_cpuid(kvm_context, cenv->cpu_index, cpuid_nent, cpuid_ent);
|
||||
return 0;
|
@ -1,13 +0,0 @@
|
||||
Index: kvm-77/qemu/vl.c
|
||||
===================================================================
|
||||
--- kvm-77.orig/qemu/vl.c
|
||||
+++ kvm-77/qemu/vl.c
|
||||
@@ -162,7 +162,7 @@
|
||||
#ifdef TARGET_PPC
|
||||
#define DEFAULT_RAM_SIZE 144
|
||||
#else
|
||||
-#define DEFAULT_RAM_SIZE 128
|
||||
+#define DEFAULT_RAM_SIZE 384
|
||||
#endif
|
||||
|
||||
/* Max number of USB devices that can be specified on the commandline. */
|
@ -1,341 +0,0 @@
|
||||
#qemu-only -> submit upstream qemu
|
||||
Index: kvm-75/qemu/Makefile.target
|
||||
===================================================================
|
||||
--- kvm-75.orig/qemu/Makefile.target
|
||||
+++ kvm-75/qemu/Makefile.target
|
||||
@@ -610,7 +610,7 @@ ifeq ($(TARGET_BASE_ARCH), i386)
|
||||
OBJS+= ide.o pckbd.o ps2.o vga.o $(SOUND_HW) dma.o
|
||||
OBJS+= fdc.o mc146818rtc.o serial.o i8259.o i8254.o pcspk.o pc.o
|
||||
OBJS+= cirrus_vga.o apic.o parallel.o acpi.o piix_pci.o
|
||||
-OBJS+= usb-uhci.o vmmouse.o vmport.o vmware_vga.o extboot.o
|
||||
+OBJS+= usb-uhci.o vmmouse.o vmport.o vmware_vga.o extboot.o hpet.o
|
||||
ifeq ($(USE_KVM_PIT), 1)
|
||||
OBJS+= i8254-kvm.o
|
||||
endif
|
||||
Index: kvm-75/qemu/hw/hpet.c
|
||||
===================================================================
|
||||
--- /dev/null
|
||||
+++ kvm-75/qemu/hw/hpet.c
|
||||
@@ -0,0 +1,322 @@
|
||||
+/*
|
||||
+ * High Precisition Event Timer 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 attempts to emulate an HPET device in software. It is by no
|
||||
+ * means complete and is prone to break on certain conditions.
|
||||
+ *
|
||||
+ */
|
||||
+#include "hw.h"
|
||||
+#include "console.h"
|
||||
+#include "qemu-timer.h"
|
||||
+
|
||||
+#define HPET_DEBUG
|
||||
+
|
||||
+#define HPET_BASE 0xfed00000
|
||||
+
|
||||
+#define HPET_NUM_TIMERS 3
|
||||
+#define HPET_TIMER_TYPE_LEVEL 1
|
||||
+#define HPET_TIMER_TYPE_EDGE 0
|
||||
+#define HPET_TIMER_DELIVERY_APIC 0
|
||||
+#define HPET_TIMER_DELIVERY_FSB 1
|
||||
+#define HPET_TIMER_CAP_FSB_INT_DEL (1 << 15)
|
||||
+#define HPET_TIMER_CAP_PER_INT (1 << 4)
|
||||
+
|
||||
+struct HPETState;
|
||||
+typedef struct HPETTimer {
|
||||
+ QEMUTimer *timer;
|
||||
+ struct HPETState *state;
|
||||
+ uint8_t type;
|
||||
+ uint8_t active;
|
||||
+ uint8_t delivery;
|
||||
+ uint8_t apic_port;
|
||||
+ uint8_t periodic;
|
||||
+ uint8_t enabled;
|
||||
+ uint32_t comparator; // if(hpet_counter == comparator) IRQ();
|
||||
+ qemu_irq irq;
|
||||
+} HPETTimer;
|
||||
+
|
||||
+typedef struct HPETState {
|
||||
+ uint64_t hpet_counter;
|
||||
+ int64_t next_periodic_time;
|
||||
+ uint8_t active;
|
||||
+ qemu_irq *irqs;
|
||||
+ HPETTimer timer[HPET_NUM_TIMERS];
|
||||
+} HPETState;
|
||||
+
|
||||
+static void update_irq(struct HPETTimer *timer)
|
||||
+{
|
||||
+ qemu_set_irq(timer->irq, timer->active && timer->state->active);
|
||||
+}
|
||||
+
|
||||
+static void update_irq_all(struct HPETState *s)
|
||||
+{
|
||||
+ int i;
|
||||
+ for(i=0; i<HPET_NUM_TIMERS; i++)
|
||||
+ update_irq(&s->timer[i]);
|
||||
+}
|
||||
+
|
||||
+static void hpet_timer(void *opaque)
|
||||
+{
|
||||
+ HPETTimer *s = (HPETTimer*)opaque;
|
||||
+ printf("hpet i!\n");
|
||||
+ if(s->periodic) {
|
||||
+ printf("periodic hpet!\n");
|
||||
+ qemu_mod_timer(s->timer, qemu_get_clock(vm_clock) + ((s->comparator) * (ticks_per_sec * 99) / 100));
|
||||
+ }
|
||||
+ s->active = 1;
|
||||
+ update_irq(s);
|
||||
+}
|
||||
+
|
||||
+static void hpet_check(HPETTimer *s)
|
||||
+{
|
||||
+ if(s->enabled) {
|
||||
+ if(s->periodic)
|
||||
+ qemu_mod_timer(s->timer, qemu_get_clock(vm_clock) + s->comparator * (ticks_per_sec * 99) / 100);
|
||||
+ else
|
||||
+ qemu_mod_timer(s->timer, qemu_get_clock(vm_clock) + ((s->comparator - s->state->hpet_counter) * (ticks_per_sec * 99) / 100));
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static uint32_t hpet_ram_readb(void *opaque, target_phys_addr_t addr)
|
||||
+{
|
||||
+#ifdef HPET_DEBUG
|
||||
+ printf("qemu: hpet_read b at %#lx\n", addr);
|
||||
+#endif
|
||||
+ return 10;
|
||||
+}
|
||||
+
|
||||
+static uint32_t hpet_ram_readw(void *opaque, target_phys_addr_t addr)
|
||||
+{
|
||||
+#ifdef HPET_DEBUG
|
||||
+ printf("qemu: hpet_read w at %#lx\n", addr);
|
||||
+#endif
|
||||
+ return 10;
|
||||
+}
|
||||
+
|
||||
+static uint32_t hpet_ram_readl(void *opaque, target_phys_addr_t addr)
|
||||
+{
|
||||
+ HPETState *s = (HPETState *)opaque;
|
||||
+#ifdef HPET_DEBUG
|
||||
+ printf("qemu: hpet_read l at %#lx\n", addr);
|
||||
+#endif
|
||||
+ switch(addr - HPET_BASE) {
|
||||
+ case 0x00:
|
||||
+ return 0x8086a201;
|
||||
+ case 0x04:
|
||||
+ return 0x0429b17f;
|
||||
+ case 0x10:
|
||||
+ case 0x14:
|
||||
+ return 0;
|
||||
+ case 0xf0:
|
||||
+ return s->hpet_counter;
|
||||
+ case 0xf4:
|
||||
+ return 0;
|
||||
+ case 0x20:
|
||||
+ {
|
||||
+ uint32_t retval = 0;
|
||||
+ int i;
|
||||
+ for(i=0; i<HPET_NUM_TIMERS; i++) {
|
||||
+ if(s->timer[i].type == HPET_TIMER_TYPE_LEVEL)
|
||||
+ retval |= s->timer[i].active << i;
|
||||
+ }
|
||||
+ return retval;
|
||||
+ }
|
||||
+ case 0x100 ... 0x3ff:
|
||||
+ {
|
||||
+ uint8_t timer_id = (addr - HPET_BASE - 0x100) / 0x20;
|
||||
+ HPETTimer *timer = &s->timer[timer_id];
|
||||
+
|
||||
+ switch((addr - HPET_BASE - 0x100) % 0x20) {
|
||||
+ case 0x0:
|
||||
+ return ((timer->delivery == HPET_TIMER_DELIVERY_FSB) << 14)
|
||||
+ | (timer->apic_port << 9)
|
||||
+ | HPET_TIMER_CAP_PER_INT
|
||||
+ | (timer->periodic << 3)
|
||||
+ | (timer->enabled << 2)
|
||||
+ | (timer->type << 1);
|
||||
+ case 0x4: // Interrupt capabilities
|
||||
+ return 0x00ff;
|
||||
+ case 0x8: // comparator register
|
||||
+ return timer->comparator;
|
||||
+ case 0xc:
|
||||
+ return 0x0;
|
||||
+ }
|
||||
+ }
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+#ifdef HPET_DEBUG
|
||||
+ printf("qemu: invalid hpet_read l at %#x\n", addr);
|
||||
+#endif
|
||||
+ return 10;
|
||||
+}
|
||||
+
|
||||
+static void hpet_ram_writeb(void *opaque, target_phys_addr_t addr,
|
||||
+ uint32_t value)
|
||||
+{
|
||||
+#ifdef HPET_DEBUG
|
||||
+ printf("qemu: invalid hpet_write b at %#x = %#x\n", addr, value);
|
||||
+#endif
|
||||
+}
|
||||
+
|
||||
+static void hpet_ram_writew(void *opaque, target_phys_addr_t addr,
|
||||
+ uint32_t value)
|
||||
+{
|
||||
+#ifdef HPET_DEBUG
|
||||
+ printf("qemu: invalid hpet_write w at %#x = %#x\n", addr, value);
|
||||
+#endif
|
||||
+}
|
||||
+
|
||||
+static void hpet_ram_writel(void *opaque, target_phys_addr_t addr,
|
||||
+ uint32_t value)
|
||||
+{
|
||||
+ HPETState *s = (HPETState *)opaque;
|
||||
+#ifdef HPET_DEBUG
|
||||
+ printf("qemu: hpet_write l at %#x = %#x\n", addr, value);
|
||||
+#endif
|
||||
+ switch(addr - HPET_BASE) {
|
||||
+ case 0x00:
|
||||
+ return;
|
||||
+ case 0x10:
|
||||
+ case 0x14: // set interrupt enabled flag
|
||||
+ if(value < 2) {
|
||||
+ s->active = value;
|
||||
+ update_irq_all(s);
|
||||
+ } else {
|
||||
+#ifdef HPET_DEBUG
|
||||
+ printf("qemu: invalid hpet_write l at %#x = %#x\n", addr, value);
|
||||
+#endif
|
||||
+ }
|
||||
+ break;
|
||||
+ case 0x20:
|
||||
+ {
|
||||
+ int i;
|
||||
+ for(i=0; i<HPET_NUM_TIMERS; i++) {
|
||||
+ if(s->timer[i].type == HPET_TIMER_TYPE_LEVEL) {
|
||||
+ if(value & (1 << i)) {
|
||||
+ s->timer[i].active = 0;
|
||||
+ update_irq(&s->timer[i]);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ break;
|
||||
+ case 0xf0:
|
||||
+ s->hpet_counter = (s->hpet_counter & (0xffffffffULL << 32)) | value;
|
||||
+#ifdef HPET_DEBUG
|
||||
+ printf("qemu: HPET counter 0xf0 set to %#x -> %#llx\n", value, s->hpet_counter);
|
||||
+#endif
|
||||
+ break;
|
||||
+ case 0xf4:
|
||||
+ s->hpet_counter = (s->hpet_counter & 0xffffffffULL) | (((uint64_t)value) << 32);
|
||||
+#ifdef HPET_DEBUG
|
||||
+ printf("qemu: HPET counter 0xf4 set to %#x -> %#llx\n", value, s->hpet_counter);
|
||||
+#endif
|
||||
+ break;
|
||||
+ case 0x100 ... 0x3ff:
|
||||
+ {
|
||||
+ uint8_t timer_id = (addr - HPET_BASE - 0x100) / 0x20;
|
||||
+ HPETTimer *timer = &s->timer[timer_id];
|
||||
+
|
||||
+ switch((addr - HPET_BASE - 0x100) % 0x20) {
|
||||
+ case 0x0:
|
||||
+ if(value & 1) break; // reserved
|
||||
+ timer->delivery = (value >> 14) & 1;
|
||||
+ timer->apic_port = (value >> 9) & 16;
|
||||
+ timer->irq = s->irqs[timer->apic_port];
|
||||
+ timer->periodic = (value >> 3) & 1;
|
||||
+ timer->enabled = (value >> 2) & 1;
|
||||
+ timer->type = (value >> 1) & 1;
|
||||
+#ifdef HPET_DEBUG
|
||||
+ printf("qemu: hpet_write l at %#x = %#x\n", addr, value);
|
||||
+#endif
|
||||
+ hpet_check(timer);
|
||||
+ break;
|
||||
+#ifdef HPET_DEBUG
|
||||
+ case 0x4: // Interrupt capabilities
|
||||
+ printf("qemu: invalid hpet_write l at %#x = %#x\n", addr, value);
|
||||
+ break;
|
||||
+#endif
|
||||
+ case 0x8: // comparator register
|
||||
+ timer->comparator = value;
|
||||
+ hpet_check(timer);
|
||||
+ break;
|
||||
+ case 0xc:
|
||||
+#ifdef HPET_DEBUG
|
||||
+ printf("qemu: invalid hpet_write l at %#x = %#x\n", addr, value);
|
||||
+#endif
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ default:
|
||||
+ printf("qemu: invalid hpet_write l at %#x = %#x\n", addr, value);
|
||||
+ }
|
||||
+
|
||||
+}
|
||||
+
|
||||
+static CPUReadMemoryFunc *hpet_ram_read[] = {
|
||||
+ hpet_ram_readb,
|
||||
+ hpet_ram_readw,
|
||||
+ hpet_ram_readl,
|
||||
+};
|
||||
+
|
||||
+static CPUWriteMemoryFunc *hpet_ram_write[] = {
|
||||
+ hpet_ram_writeb,
|
||||
+ hpet_ram_writew,
|
||||
+ hpet_ram_writel,
|
||||
+};
|
||||
+
|
||||
+
|
||||
+void hpet_init(qemu_irq *irq) {
|
||||
+ int iomemtype, i;
|
||||
+ HPETState *s;
|
||||
+
|
||||
+ /* XXX this is a dirty hack for HPET support w/o LPC
|
||||
+ Actually this is a config descriptor for the RCBA */
|
||||
+ s = qemu_mallocz(sizeof(HPETState));
|
||||
+ s->irqs = irq;
|
||||
+
|
||||
+ for(i=0; i<HPET_NUM_TIMERS; i++) {
|
||||
+ HPETTimer *timer = &s->timer[i];
|
||||
+ timer->comparator = 0xffffffff;
|
||||
+ timer->state = s;
|
||||
+ timer->timer = qemu_new_timer(vm_clock, hpet_timer, s->timer+i);
|
||||
+ switch(i) {
|
||||
+ case 0:
|
||||
+ timer->apic_port = 2;
|
||||
+ break;
|
||||
+ case 1:
|
||||
+ timer->apic_port = 8;
|
||||
+ break;
|
||||
+ default:
|
||||
+ timer->apic_port = 0;
|
||||
+ break;
|
||||
+ }
|
||||
+ s->timer[i].irq = irq[timer->apic_port];
|
||||
+ }
|
||||
+
|
||||
+ /* HPET Area */
|
||||
+
|
||||
+ iomemtype = cpu_register_io_memory(0, hpet_ram_read,
|
||||
+ hpet_ram_write, s);
|
||||
+
|
||||
+ cpu_register_physical_memory(HPET_BASE, 0x400, iomemtype);
|
||||
+}
|
@ -1,96 +0,0 @@
|
||||
#qemu-only -> submit upstream qemu
|
||||
Index: kvm-75/qemu/hw/ide.c
|
||||
===================================================================
|
||||
--- kvm-75.orig/qemu/hw/ide.c
|
||||
+++ kvm-75/qemu/hw/ide.c
|
||||
@@ -462,6 +462,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
|
||||
@@ -3164,6 +3165,57 @@ void pci_piix3_ide_init(PCIBus *bus, Blo
|
||||
|
||||
qemu_register_reset(piix3_reset, d);
|
||||
piix3_reset(d);
|
||||
+
|
||||
+ pci_register_io_region((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]->devfn = d->dev.devfn;
|
||||
+
|
||||
+ register_savevm("ide", 0, 1, 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_io_region((PCIDevice *)d, 4, 0x10,
|
||||
PCI_ADDRESS_SPACE_IO, bmdma_map);
|
||||
Index: kvm-75/qemu/hw/irq.c
|
||||
===================================================================
|
||||
--- kvm-75.orig/qemu/hw/irq.c
|
||||
+++ kvm-75/qemu/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: kvm-75/qemu/hw/pc.h
|
||||
===================================================================
|
||||
--- kvm-75.orig/qemu/hw/pc.h
|
||||
+++ kvm-75/qemu/hw/pc.h
|
||||
@@ -145,6 +145,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 */
|
||||
|
@ -1,196 +0,0 @@
|
||||
#qemu-only -> submit upstream qemu
|
||||
Index: kvm-75/qemu/Makefile.target
|
||||
===================================================================
|
||||
--- kvm-75.orig/qemu/Makefile.target
|
||||
+++ kvm-75/qemu/Makefile.target
|
||||
@@ -610,7 +610,7 @@ ifeq ($(TARGET_BASE_ARCH), i386)
|
||||
OBJS+= ide.o pckbd.o ps2.o vga.o $(SOUND_HW) dma.o
|
||||
OBJS+= fdc.o mc146818rtc.o serial.o i8259.o i8254.o pcspk.o pc.o
|
||||
OBJS+= cirrus_vga.o apic.o parallel.o acpi.o piix_pci.o
|
||||
-OBJS+= usb-uhci.o vmmouse.o vmport.o vmware_vga.o extboot.o hpet.o
|
||||
+OBJS+= usb-uhci.o vmmouse.o vmport.o vmware_vga.o extboot.o hpet.o lpc.o
|
||||
ifeq ($(USE_KVM_PIT), 1)
|
||||
OBJS+= i8254-kvm.o
|
||||
endif
|
||||
Index: kvm-75/qemu/hw/lpc.c
|
||||
===================================================================
|
||||
--- /dev/null
|
||||
+++ kvm-75/qemu/hw/lpc.c
|
||||
@@ -0,0 +1,163 @@
|
||||
+/*
|
||||
+ * 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(0, 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: kvm-75/qemu/hw/pc.h
|
||||
===================================================================
|
||||
--- kvm-75.orig/qemu/hw/pc.h
|
||||
+++ kvm-75/qemu/hw/pc.h
|
||||
@@ -150,6 +150,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);
|
||||
+
|
||||
/* virtio-net.c */
|
||||
|
||||
PCIDevice *virtio_net_init(PCIBus *bus, NICInfo *nd, int devfn);
|
@ -1,309 +0,0 @@
|
||||
#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: kvm-78/qemu/hw/pc.c
|
||||
===================================================================
|
||||
--- kvm-78.orig/qemu/hw/pc.c
|
||||
+++ kvm-78/qemu/hw/pc.c
|
||||
@@ -58,6 +58,12 @@ static PITState *pit;
|
||||
static IOAPICState *ioapic;
|
||||
static PCIDevice *i440fx_state;
|
||||
|
||||
+enum pc_model {
|
||||
+ MODEL_ISA = 0,
|
||||
+ MODEL_PCI = 1,
|
||||
+ MODEL_MAC = 2
|
||||
+};
|
||||
+
|
||||
static void ioport80_write(void *opaque, uint32_t addr, uint32_t data)
|
||||
{
|
||||
}
|
||||
@@ -805,7 +811,7 @@ static void pc_init1(ram_addr_t ram_size
|
||||
const char *boot_device, DisplayState *ds,
|
||||
const char *kernel_filename, const char *kernel_cmdline,
|
||||
const char *initrd_filename,
|
||||
- int pci_enabled, const char *cpu_model)
|
||||
+ int model, const char *cpu_model)
|
||||
{
|
||||
char buf[1024];
|
||||
int ret, linux_boot, i;
|
||||
@@ -833,15 +839,19 @@ static void pc_init1(ram_addr_t ram_size
|
||||
|
||||
/* init CPUs */
|
||||
if (cpu_model == NULL) {
|
||||
+ if(model == MODEL_MAC) {
|
||||
+ cpu_model = "coreduo";
|
||||
+ } else {
|
||||
#ifdef TARGET_X86_64
|
||||
- cpu_model = "qemu64";
|
||||
+ cpu_model = "qemu64";
|
||||
#else
|
||||
- cpu_model = "qemu32";
|
||||
+ cpu_model = "qemu32";
|
||||
#endif
|
||||
+ }
|
||||
}
|
||||
|
||||
for(i = 0; i < smp_cpus; i++) {
|
||||
- env = pc_new_cpu(i, cpu_model, pci_enabled);
|
||||
+ env = pc_new_cpu(i, cpu_model, model > MODEL_ISA);
|
||||
}
|
||||
|
||||
vmport_init();
|
||||
@@ -880,8 +890,16 @@ static void pc_init1(ram_addr_t ram_size
|
||||
vga_ram_addr = qemu_ram_alloc(vga_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;
|
||||
+ }
|
||||
+ }
|
||||
snprintf(buf, sizeof(buf), "%s/%s", bios_dir, bios_name);
|
||||
bios_size = get_image_size(buf);
|
||||
if (bios_size <= 0 ||
|
||||
@@ -956,7 +974,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 {
|
||||
@@ -969,7 +987,7 @@ 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_ISA) {
|
||||
pci_cirrus_vga_init(pci_bus,
|
||||
ds, phys_ram_base + vga_ram_addr,
|
||||
vga_ram_addr, vga_ram_size);
|
||||
@@ -978,13 +996,13 @@ static void pc_init1(ram_addr_t ram_size
|
||||
vga_ram_addr, vga_ram_size);
|
||||
}
|
||||
} else if (vmsvga_enabled) {
|
||||
- if (pci_enabled)
|
||||
+ if (model > MODEL_ISA)
|
||||
pci_vmsvga_init(pci_bus, ds, phys_ram_base + vga_ram_addr,
|
||||
vga_ram_addr, vga_ram_size);
|
||||
else
|
||||
fprintf(stderr, "%s: vmware_vga: no PCI bus\n", __FUNCTION__);
|
||||
} else {
|
||||
- if (pci_enabled) {
|
||||
+ if (model > MODEL_ISA) {
|
||||
pci_vga_init(pci_bus, ds, phys_ram_base + vga_ram_addr,
|
||||
vga_ram_addr, vga_ram_size, 0, 0);
|
||||
} else {
|
||||
@@ -1000,8 +1018,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())
|
||||
@@ -1010,7 +1033,7 @@ static void pc_init1(ram_addr_t ram_size
|
||||
#endif
|
||||
pit = pit_init(0x40, i8259[0]);
|
||||
pcspk_init(pit);
|
||||
- if (pci_enabled) {
|
||||
+ if (model > MODEL_ISA) {
|
||||
pic_set_alt_irq_func(isa_pic, ioapic_set_irq, ioapic);
|
||||
}
|
||||
|
||||
@@ -1031,15 +1054,22 @@ static void pc_init1(ram_addr_t ram_size
|
||||
for(i = 0; i < nb_nics; i++) {
|
||||
nd = &nd_table[i];
|
||||
if (!nd->model) {
|
||||
- if (pci_enabled) {
|
||||
- nd->model = "rtl8139";
|
||||
- } else {
|
||||
- nd->model = "ne2k_isa";
|
||||
+ switch(model) {
|
||||
+ case MODEL_ISA:
|
||||
+ nd->model = "ne2k_isa";
|
||||
+ break;
|
||||
+ case MODEL_MAC:
|
||||
+ nd->model = "rtl8139";
|
||||
+ nd->link = Link_10mbps;
|
||||
+ break;
|
||||
+ default:
|
||||
+ nd->model = "ne2k_pci";
|
||||
+ break;
|
||||
}
|
||||
}
|
||||
if (strcmp(nd->model, "ne2k_isa") == 0) {
|
||||
pc_init_ne2k_isa(nd, i8259);
|
||||
- } else if (pci_enabled) {
|
||||
+ } else if (model > MODEL_ISA) {
|
||||
if (strcmp(nd->model, "?") == 0)
|
||||
fprintf(stderr, "qemu: Supported ISA NICs: ne2k_isa\n");
|
||||
if (!pci_nic_init(pci_bus, nd, -1))
|
||||
@@ -1068,19 +1098,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++) {
|
||||
@@ -1094,11 +1130,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;
|
||||
|
||||
@@ -1113,7 +1149,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, unit;
|
||||
void *scsi;
|
||||
@@ -1132,7 +1168,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;
|
||||
|
||||
@@ -1155,10 +1191,22 @@ static void pc_init1(ram_addr_t ram_size
|
||||
extboot_init(info->bdrv, 1);
|
||||
}
|
||||
|
||||
- if (pci_enabled)
|
||||
+ if (model > MODEL_ISA)
|
||||
virtio_balloon_init(pci_bus);
|
||||
}
|
||||
|
||||
+static void pc_init_mac(ram_addr_t ram_size, int vga_ram_size,
|
||||
+ const char *boot_device, DisplayState *ds,
|
||||
+ const char *kernel_filename,
|
||||
+ const char *kernel_cmdline,
|
||||
+ const char *initrd_filename,
|
||||
+ const char *cpu_model)
|
||||
+{
|
||||
+ pc_init1(ram_size, vga_ram_size, boot_device, ds,
|
||||
+ kernel_filename, kernel_cmdline,
|
||||
+ initrd_filename, MODEL_MAC, cpu_model);
|
||||
+}
|
||||
+
|
||||
static void pc_init_pci(ram_addr_t ram_size, int vga_ram_size,
|
||||
const char *boot_device, DisplayState *ds,
|
||||
const char *kernel_filename,
|
||||
@@ -1168,7 +1216,7 @@ static void pc_init_pci(ram_addr_t ram_s
|
||||
{
|
||||
pc_init1(ram_size, vga_ram_size, boot_device, ds,
|
||||
kernel_filename, kernel_cmdline,
|
||||
- initrd_filename, 1, cpu_model);
|
||||
+ initrd_filename, MODEL_PCI, cpu_model);
|
||||
}
|
||||
|
||||
static void pc_init_isa(ram_addr_t ram_size, int vga_ram_size,
|
||||
@@ -1180,7 +1228,7 @@ static void pc_init_isa(ram_addr_t ram_s
|
||||
{
|
||||
pc_init1(ram_size, vga_ram_size, boot_device, ds,
|
||||
kernel_filename, kernel_cmdline,
|
||||
- initrd_filename, 0, cpu_model);
|
||||
+ initrd_filename, MODEL_ISA, cpu_model);
|
||||
}
|
||||
|
||||
QEMUMachine pc_machine = {
|
||||
@@ -1190,6 +1238,14 @@ QEMUMachine pc_machine = {
|
||||
.ram_require = VGA_RAM_SIZE + PC_MAX_BIOS_SIZE,
|
||||
.max_cpus = 255,
|
||||
};
|
||||
+
|
||||
+QEMUMachine mac_machine = {
|
||||
+ .name = "mac",
|
||||
+ .desc = "Intel-Mac",
|
||||
+ .init = pc_init_mac,
|
||||
+ .ram_require = VGA_RAM_SIZE + PC_MAX_BIOS_SIZE,
|
||||
+ .max_cpus = 255,
|
||||
+};
|
||||
|
||||
QEMUMachine isapc_machine = {
|
||||
.name = "isapc",
|
||||
Index: kvm-78/qemu/hw/boards.h
|
||||
===================================================================
|
||||
--- kvm-78.orig/qemu/hw/boards.h
|
||||
+++ kvm-78/qemu/hw/boards.h
|
||||
@@ -33,6 +33,7 @@ extern QEMUMachine bareetraxfs_machine;
|
||||
/* pc.c */
|
||||
extern QEMUMachine pc_machine;
|
||||
extern QEMUMachine isapc_machine;
|
||||
+extern QEMUMachine mac_machine;
|
||||
|
||||
/* ppc.c */
|
||||
extern QEMUMachine prep_machine;
|
||||
Index: kvm-78/qemu/target-i386/machine.c
|
||||
===================================================================
|
||||
--- kvm-78.orig/qemu/target-i386/machine.c
|
||||
+++ kvm-78/qemu/target-i386/machine.c
|
||||
@@ -10,6 +10,7 @@ void register_machines(void)
|
||||
{
|
||||
qemu_register_machine(&pc_machine);
|
||||
qemu_register_machine(&isapc_machine);
|
||||
+ qemu_register_machine(&mac_machine);
|
||||
}
|
||||
|
||||
static void cpu_put_seg(QEMUFile *f, SegmentCache *dt)
|
@ -1,492 +0,0 @@
|
||||
Index: kvm-75/qemu/elf_ops.h
|
||||
===================================================================
|
||||
--- kvm-75.orig/qemu/elf_ops.h
|
||||
+++ kvm-75/qemu/elf_ops.h
|
||||
@@ -156,6 +156,10 @@ static int glue(load_elf, SZ)(int fd, in
|
||||
}
|
||||
|
||||
if (ELF_MACHINE != ehdr.e_machine)
|
||||
+#if (ELF_MACHINE == EM_X86_64) && !CONFIG_USER_ONLY
|
||||
+ /* x86_64 systems can run i386 code as well */
|
||||
+ if(ehdr.e_machine != EM_386)
|
||||
+#endif
|
||||
goto fail;
|
||||
|
||||
if (pentry)
|
||||
Index: kvm-75/qemu/hw/pc.c
|
||||
===================================================================
|
||||
--- kvm-75.orig/qemu/hw/pc.c
|
||||
+++ kvm-75/qemu/hw/pc.c
|
||||
@@ -512,6 +512,416 @@ static long get_file_size(FILE *f)
|
||||
return size;
|
||||
}
|
||||
|
||||
+/* Generate an initial boot sector which sets state and jump to
|
||||
+ a specified vector */
|
||||
+static void generate_bootsect_multiboot(uint32_t mh_entry_addr, uint32_t bootinfo)
|
||||
+{
|
||||
+ uint8_t bootsect[512], *p, *pgdt, *pmmaploop;
|
||||
+ uint32_t ip;
|
||||
+ int i;
|
||||
+ int hda;
|
||||
+ int mmaploop;
|
||||
+
|
||||
+ hda = drive_get_index(IF_IDE, 0, 0);
|
||||
+ if (hda == -1) {
|
||||
+ fprintf(stderr, "A disk image must be given for 'hda' when booting "
|
||||
+ "a Multiboot kernel\n");
|
||||
+ exit(1);
|
||||
+ }
|
||||
+
|
||||
+ memset(bootsect, 0, sizeof(bootsect));
|
||||
+
|
||||
+ /* Copy the MSDOS partition table if possible */
|
||||
+ bdrv_read(drives_table[hda].bdrv, 0, bootsect, 1);
|
||||
+
|
||||
+ /* Make sure we have a partition signature */
|
||||
+ bootsect[510] = 0x55;
|
||||
+ bootsect[511] = 0xaa;
|
||||
+
|
||||
+ /* Actual code */
|
||||
+ p = bootsect;
|
||||
+ *p++ = 0xfa; /* CLI */
|
||||
+ *p++ = 0xfc; /* CLD */
|
||||
+
|
||||
+ // 660f011528000000 lgdt [0x28]
|
||||
+ *p++ = 0x66; /* 32-bit operand size */
|
||||
+ *p++ = 0x67; /* 32-bit addr size */
|
||||
+ *p++ = 0x0f; /* LGDT [0x128] */
|
||||
+ *p++ = 0x01;
|
||||
+ *p++ = 0x15;
|
||||
+ pgdt=p; /* we calculate the gdt position later */
|
||||
+ p+=4;
|
||||
+
|
||||
+ /* Initialize multiboot mmap structs using the 0x15(e820) */
|
||||
+ *p++ = 0x31; /* XOR BX,BX */
|
||||
+ *p++ = 0xdb;
|
||||
+
|
||||
+ *p++ = 0x66; /* 32-bit operand size */
|
||||
+ *p++ = 0x67; /* 32-bit addr size */
|
||||
+ *p++ = 0xbf; /* MOV EDI,0x9004 */
|
||||
+ *p++ = 0x04;
|
||||
+ *p++ = 0x90;
|
||||
+ *p++ = 0x00;
|
||||
+ *p++ = 0x00;
|
||||
+
|
||||
+ pmmaploop = p;
|
||||
+ *p++ = 0x66; /* 32-bit operand size */
|
||||
+ *p++ = 0x67; /* 32-bit addr size */
|
||||
+ *p++ = 0xb8; /* MOV EAX,0x20 */
|
||||
+ *p++ = 0x20;
|
||||
+ *p++ = 0x00;
|
||||
+ *p++ = 0x00;
|
||||
+ *p++ = 0x00;
|
||||
+
|
||||
+ *p++ = 0x66; /* 32-bit operand size */
|
||||
+ *p++ = 0x67; /* 32-bit addr size */
|
||||
+ *p++ = 0x89; /* MOV -4(EDI),EAX */
|
||||
+ *p++ = 0x47;
|
||||
+ *p++ = 0xfc;
|
||||
+
|
||||
+ *p++ = 0x66; /* 32-bit operand size */
|
||||
+ *p++ = 0x67; /* 32-bit addr size */
|
||||
+ *p++ = 0xb8; /* MOV EAX,0x0000e820 */
|
||||
+ *p++ = 0x20;
|
||||
+ *p++ = 0xe8;
|
||||
+ *p++ = 0x00;
|
||||
+ *p++ = 0x00;
|
||||
+
|
||||
+ *p++ = 0x66; /* 32-bit operand size */
|
||||
+ *p++ = 0x67; /* 32-bit addr size */
|
||||
+ *p++ = 0xba; /* MOV EDX,0x534d4150 */
|
||||
+ *p++ = 0x50;
|
||||
+ *p++ = 0x41;
|
||||
+ *p++ = 0x4d;
|
||||
+ *p++ = 0x53;
|
||||
+
|
||||
+ *p++ = 0x66; /* 32-bit operand size */
|
||||
+ *p++ = 0x67; /* 32-bit addr size */
|
||||
+ *p++ = 0xb9; /* MOV ECX,0x20 */
|
||||
+ *p++ = 0x20;
|
||||
+ *p++ = 0x00;
|
||||
+ *p++ = 0x00;
|
||||
+ *p++ = 0x00;
|
||||
+
|
||||
+ *p++ = 0xcd; /* INT 0x15 */
|
||||
+ *p++ = 0x15;
|
||||
+
|
||||
+ *p++ = 0x66; /* 32-bit operand size */
|
||||
+ *p++ = 0x67; /* 32-bit addr size */
|
||||
+ *p++ = 0xb8; /* MOV EAX, 0x24 */
|
||||
+ *p++ = 0x24;
|
||||
+ *p++ = 0x00;
|
||||
+ *p++ = 0x00;
|
||||
+ *p++ = 0x00;
|
||||
+
|
||||
+ *p++ = 0xf7; /* MUL AX, BX */
|
||||
+ *p++ = 0xe3;
|
||||
+
|
||||
+ *p++ = 0x66; /* 32-bit operand size */
|
||||
+ *p++ = 0x67; /* 32-bit addr size */
|
||||
+ *p++ = 0x21; /* AND EBX, EBX */
|
||||
+ *p++ = 0xdb;
|
||||
+
|
||||
+ /* don't store if bx = 0 */
|
||||
+ *p++ = 0x66; /* 32-bit operand size */
|
||||
+ *p++ = 0x67; /* 32-bit addr size */
|
||||
+ *p++ = 0x0f; /* JZ next instruction */
|
||||
+ *p++ = 0x84;
|
||||
+ *p++ = 0x07;
|
||||
+ *p++ = 0x00;
|
||||
+ *p++ = 0x00;
|
||||
+ *p++ = 0x00;
|
||||
+
|
||||
+ /* store the amount of blocks in the bootinfo struct */
|
||||
+ *p++ = 0x66; /* 32-bit operand size */
|
||||
+ *p++ = 0x67; /* 32-bit addr size */
|
||||
+ *p++ = 0xa3; /* MOV [bootinfo+0x2c], EAX */
|
||||
+ *p++ = (bootinfo+0x2c);
|
||||
+ *p++ = (bootinfo+0x2c) >> 8;
|
||||
+ *p++ = (bootinfo+0x2c) >> 16;
|
||||
+ *p++ = (bootinfo+0x2c) >> 24;
|
||||
+
|
||||
+ *p++ = 0x66; /* 32-bit operand size */
|
||||
+ *p++ = 0x67; /* 32-bit addr size */
|
||||
+ *p++ = 0x05; /* ADD EAX, 0x9004 */
|
||||
+ *p++ = 0x04;
|
||||
+ *p++ = 0x90;
|
||||
+ *p++ = 0x00;
|
||||
+ *p++ = 0x00;
|
||||
+
|
||||
+ *p++ = 0x89; /* MOV DI, AX */
|
||||
+ *p++ = 0xc7;
|
||||
+
|
||||
+ *p++ = 0x66; /* 32-bit operand size */
|
||||
+ *p++ = 0x67; /* 32-bit addr size */
|
||||
+ *p++ = 0x21; /* AND EBX, EBX */
|
||||
+ *p++ = 0xdb;
|
||||
+
|
||||
+ /* process next entry */
|
||||
+ *p++ = 0x66; /* 32-bit operand size */
|
||||
+ *p++ = 0x67; /* 32-bit addr size */
|
||||
+ *p++ = 0x0f; /* JNZ mmaploop */
|
||||
+ *p++ = 0x85;
|
||||
+ mmaploop = (int)((long)pmmaploop) - ((long)p) - 4;
|
||||
+ *p++ = mmaploop;
|
||||
+ *p++ = mmaploop >> 8;
|
||||
+ *p++ = mmaploop >> 16;
|
||||
+ *p++ = mmaploop >> 24;
|
||||
+
|
||||
+ /* get us to protected mode now */
|
||||
+
|
||||
+ *p++ = 0x66;
|
||||
+ *p++ = 0xb8; /* MOV EAX,0x01 */
|
||||
+ *p++ = 0x01;
|
||||
+ *p++ = 0x00;
|
||||
+ *p++ = 0x00;
|
||||
+ *p++ = 0x00;
|
||||
+
|
||||
+ *p++ = 0x0f; /* MOV CR0,EAX */
|
||||
+ *p++ = 0x22;
|
||||
+ *p++ = 0xc0;
|
||||
+
|
||||
+ /* the JMP sets CS for us and gets us to 32-bit */
|
||||
+ ip = 0x00007c00 + (p - bootsect) + 8; // set i to the IP after the JMP
|
||||
+ *p++ = 0x66; /* 32-bit operand size */
|
||||
+ *p++ = 0xea; /* JMP */
|
||||
+ *p++ = ip; /* IP */
|
||||
+ *p++ = ip >> 8;
|
||||
+ *p++ = ip >> 16;
|
||||
+ *p++ = ip >> 24;
|
||||
+ *p++ = 0x08;
|
||||
+ *p++ = 0x00;
|
||||
+
|
||||
+ /* initialize all other segments */
|
||||
+ *p++ = 0xb8; /* MOV EAX,0x10 */
|
||||
+ *p++ = 0x10;
|
||||
+ *p++ = 0x00;
|
||||
+ *p++ = 0x00;
|
||||
+ *p++ = 0x00;
|
||||
+ for (i = 0; i < 6; i++) {
|
||||
+ if (i == 1) /* Skip CS */
|
||||
+ continue;
|
||||
+
|
||||
+ *p++ = 0x8e; /* MOV <seg>,EAX */
|
||||
+ *p++ = 0xc0 + (i << 3);
|
||||
+ }
|
||||
+
|
||||
+ /* EBX contains a pointer to the bootinfo struct */
|
||||
+ *p++ = 0xbb; /* MOV EBX,imm32 */
|
||||
+ *p++ = bootinfo;
|
||||
+ *p++ = bootinfo >> 8;
|
||||
+ *p++ = bootinfo >> 16;
|
||||
+ *p++ = bootinfo >> 24;
|
||||
+
|
||||
+ /* EAX has to contain the following magic */
|
||||
+ *p++ = 0xb8; /* MOV EAX,0x2badb002 */
|
||||
+ *p++ = 0x02;
|
||||
+ *p++ = 0xb0;
|
||||
+ *p++ = 0xad;
|
||||
+ *p++ = 0x2b;
|
||||
+
|
||||
+ /* Jump off to the kernel */
|
||||
+ *p++ = 0xea; /* JMP */
|
||||
+ *p++ = mh_entry_addr; /* IP */
|
||||
+ *p++ = mh_entry_addr >> 8;
|
||||
+ *p++ = mh_entry_addr >> 16;
|
||||
+ *p++ = mh_entry_addr >> 24;
|
||||
+ *p++ = 0x08;
|
||||
+ *p++ = 0x00;
|
||||
+
|
||||
+ { /* GDT loading */
|
||||
+ uint32_t gdt_base = 0x00007c00 + (p - bootsect); // 0x00007c00 is the first IP;
|
||||
+ uint32_t gdtr = gdt_base + 0x28;
|
||||
+ uint8_t gdt[] = { // GDT base: 0x00000100
|
||||
+ // 0x00
|
||||
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
+ // 0x08: code segment (base=0, limit=0xfffff, type=32bit code exec/read, DPL=0, 4k)
|
||||
+ 0xff, 0xff, 0x00, 0x00, 0x00, 0x9a, 0xcf, 0x00,
|
||||
+ // 0x10: data segment (base=0, limit=0xfffff, type=32bit data read/write, DPL=0, 4k)
|
||||
+ 0xff, 0xff, 0x00, 0x00, 0x00, 0x92, 0xcf, 0x00,
|
||||
+ // 0x18: code segment (base=0, limit=0x0ffff, type=16bit code exec/read/conf, DPL=0, 1b)
|
||||
+ 0xff, 0xff, 0x00, 0x00, 0x00, 0x9e, 0x00, 0x00,
|
||||
+ // 0x20: data segment (base=0, limit=0x0ffff, type=16bit data read/write, DPL=0, 1b)
|
||||
+ 0xff, 0xff, 0x00, 0x00, 0x00, 0x92, 0x00, 0x00,
|
||||
+ // 0x28: gdtdesc
|
||||
+ 0x27, 0x00, gdt_base, gdt_base >> 8, gdt_base >> 16, gdt_base >> 24
|
||||
+ };
|
||||
+
|
||||
+ memcpy(p, gdt, sizeof(gdt));
|
||||
+ p+=sizeof(gdt);
|
||||
+ *pgdt++ = gdtr;
|
||||
+ *pgdt++ = gdtr >> 8;
|
||||
+ *pgdt++ = gdtr >> 16;
|
||||
+ *pgdt++ = gdtr >> 24;
|
||||
+ }
|
||||
+
|
||||
+ fprintf(stderr, "qemu: multiboot loader code is %d bytes long.\n", (int)(p-bootsect));
|
||||
+
|
||||
+ bdrv_set_boot_sector(drives_table[hda].bdrv, bootsect, sizeof(bootsect));
|
||||
+}
|
||||
+
|
||||
+static int load_multiboot(FILE *f,
|
||||
+ const char *kernel_filename,
|
||||
+ const char *initrd_filename,
|
||||
+ const char *kernel_cmdline,
|
||||
+ uint8_t *header)
|
||||
+{
|
||||
+ int i, is_multiboot = 0;
|
||||
+ uint32_t flags = 0;
|
||||
+ uint32_t mh_entry_addr;
|
||||
+ uint32_t mh_load_addr;
|
||||
+ uint32_t mb_kernel_size;
|
||||
+ uint32_t mb_bootinfo = 0x90000;
|
||||
+ uint32_t tmp_size;
|
||||
+
|
||||
+ // Ok, let's see if it is a multiboot image
|
||||
+ for(i = 0; i < 8144; i += 4) { // the header is 12x32bit long, so
|
||||
+ // the latest entry may be 8192 - 48
|
||||
+ if(ldl_p(header+i) == 0x1BADB002) {
|
||||
+ uint32_t checksum = ldl_p(header+i+8);
|
||||
+ flags = ldl_p(header+i+4);
|
||||
+ checksum += flags;
|
||||
+ checksum += (uint32_t)0x1BADB002;
|
||||
+ if(!checksum) {
|
||||
+ is_multiboot = 1;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if(!is_multiboot) return 0; // no multiboot
|
||||
+ fprintf(stderr, "qemu: I believe we found a multiboot image!\n");
|
||||
+
|
||||
+ if(flags & 0x00000004) { // MULTIBOOT_HEADER_HAS_VBE
|
||||
+ fprintf(stderr, "qemu: multiboot knows VBE. we don't.\n");
|
||||
+ }
|
||||
+ if(!(flags & 0x00010000)) { // MULTIBOOT_HEADER_HAS_ADDR
|
||||
+ uint64_t elf_entry;
|
||||
+ int kernel_size;
|
||||
+ fclose(f);
|
||||
+ kernel_size = load_elf(kernel_filename, 0, &elf_entry, NULL, NULL);
|
||||
+ if(kernel_size < 0) {
|
||||
+ fprintf(stderr, "Error while loading elf kernel\n");
|
||||
+ exit(1);
|
||||
+ }
|
||||
+ mh_load_addr = mh_entry_addr = elf_entry;
|
||||
+ mb_kernel_size = kernel_size;
|
||||
+
|
||||
+ fprintf(stderr, "qemu: loading multiboot-elf kernel (%#x bytes) with entry %#zx\n",
|
||||
+ mb_kernel_size, (size_t)mh_entry_addr);
|
||||
+ } else {
|
||||
+ /* Valid if mh_flags sets MULTIBOOT_HEADER_HAS_ADDR. */
|
||||
+ uint32_t mh_header_addr = ldl_p(header+i+12);
|
||||
+ mh_load_addr = ldl_p(header+i+16);
|
||||
+ uint32_t mh_load_end_addr = ldl_p(header+i+20);
|
||||
+ uint32_t mh_bss_end_addr = ldl_p(header+i+24);
|
||||
+ uint8_t *mb_kernel_addr = phys_ram_base + (mh_load_addr);
|
||||
+ uint32_t mb_kernel_text_offset = i - (mh_header_addr - mh_load_addr);
|
||||
+
|
||||
+ mh_entry_addr = ldl_p(header+i+28);
|
||||
+ mb_kernel_size = get_file_size(f) - mb_kernel_text_offset;
|
||||
+
|
||||
+ /* Valid if mh_flags sets MULTIBOOT_HEADER_HAS_VBE.
|
||||
+ uint32_t mh_mode_type = ldl_p(header+i+32);
|
||||
+ uint32_t mh_width = ldl_p(header+i+36);
|
||||
+ uint32_t mh_height = ldl_p(header+i+40);
|
||||
+ uint32_t mh_depth = ldl_p(header+i+44); */
|
||||
+
|
||||
+ fprintf(stderr, "multiboot: mh_header_addr = %#x\n", mh_header_addr);
|
||||
+ fprintf(stderr, "multiboot: mh_load_addr = %#x\n", mh_load_addr);
|
||||
+ fprintf(stderr, "multiboot: mh_load_end_addr = %#x\n", mh_load_end_addr);
|
||||
+ fprintf(stderr, "multiboot: mh_bss_end_addr = %#x\n", mh_bss_end_addr);
|
||||
+
|
||||
+ fseek(f, mb_kernel_text_offset, SEEK_SET);
|
||||
+
|
||||
+ fprintf(stderr, "qemu: loading multiboot kernel (%#x bytes) at %#zx\n",
|
||||
+ mb_kernel_size, mb_kernel_addr - phys_ram_base);
|
||||
+
|
||||
+ if ((tmp_size=fread(mb_kernel_addr, 1, mb_kernel_size, f)) != mb_kernel_size) {
|
||||
+ fprintf(stderr, "qemu: read error on multiboot kernel '%s' (%#x != %#x)\n", kernel_filename, tmp_size, mb_kernel_size);
|
||||
+ exit(1);
|
||||
+ }
|
||||
+ fclose(f);
|
||||
+ }
|
||||
+
|
||||
+
|
||||
+ // load modules
|
||||
+
|
||||
+ stl_p(phys_ram_base + mb_bootinfo + 20, 0x0); // mods_count
|
||||
+ if(initrd_filename) {
|
||||
+ uint32_t mb_mod_info = mb_bootinfo + 0x100;
|
||||
+ uint32_t mb_mod_cmdline = mb_bootinfo+ 0x300;
|
||||
+ uint32_t mb_mod_start = mh_load_addr;
|
||||
+ uint32_t mb_mod_length = mb_kernel_size;
|
||||
+ char *next_initrd;
|
||||
+ char *next_space;
|
||||
+ int mb_mod_count = 0;
|
||||
+
|
||||
+ do {
|
||||
+ next_initrd = strchr(initrd_filename, ',');
|
||||
+ if(next_initrd)
|
||||
+ *next_initrd = '\0';
|
||||
+ /* if a space comes after the module filename, treat everything after that as parameters */
|
||||
+ strcpy(phys_ram_base + mb_mod_cmdline, initrd_filename);
|
||||
+ stl_p(phys_ram_base + mb_mod_info + 8, mb_mod_cmdline); // string
|
||||
+ mb_mod_cmdline += strlen(initrd_filename) + 1;
|
||||
+ if(next_space = strchr(initrd_filename, ' '))
|
||||
+ *next_space = '\0';
|
||||
+printf("multiboot loading module: %s\n", initrd_filename);
|
||||
+ f = fopen(initrd_filename, "rb");
|
||||
+ if(f) {
|
||||
+ mb_mod_start = (mb_mod_start + mb_mod_length + (TARGET_PAGE_SIZE - 1))
|
||||
+ & (TARGET_PAGE_MASK);
|
||||
+ mb_mod_length = get_file_size(f);
|
||||
+
|
||||
+ if ((tmp_size=fread((phys_ram_base + mb_mod_start), 1, mb_mod_length, f))
|
||||
+ != mb_mod_length) {
|
||||
+ fprintf(stderr, "qemu: read error on multiboot module '%s' (%#x != %#x)\n",
|
||||
+ initrd_filename, tmp_size, mb_mod_length);
|
||||
+ exit(1);
|
||||
+ }
|
||||
+
|
||||
+ mb_mod_count++;
|
||||
+ stl_p(phys_ram_base + mb_mod_info + 0, mb_mod_start);
|
||||
+ stl_p(phys_ram_base + mb_mod_info + 4, mb_mod_start + mb_mod_length);
|
||||
+printf("mod_start: %#x\nmod_end: %#x\n", mb_mod_start, mb_mod_start + mb_mod_length);
|
||||
+ stl_p(phys_ram_base + mb_mod_info + 12, 0x0); // reserved
|
||||
+ }
|
||||
+ initrd_filename = next_initrd+1;
|
||||
+ mb_mod_info += 16;
|
||||
+ } while(next_initrd);
|
||||
+ stl_p(phys_ram_base + mb_bootinfo + 20, mb_mod_count); // mods_count
|
||||
+ stl_p(phys_ram_base + mb_bootinfo + 24, mb_bootinfo + 0x100); // mods_addr
|
||||
+ }
|
||||
+
|
||||
+ /* Commandline support */
|
||||
+ stl_p(phys_ram_base + mb_bootinfo + 16, mb_bootinfo + 0x200);
|
||||
+ strcpy((char*)(phys_ram_base + mb_bootinfo + 0x200), kernel_cmdline);
|
||||
+
|
||||
+ // the kernel is where we want it to be now
|
||||
+
|
||||
+#define MULTIBOOT_FLAGS_MEMORY (1 << 0)
|
||||
+#define MULTIBOOT_FLAGS_BOOT_DEVICE (1 << 1)
|
||||
+#define MULTIBOOT_FLAGS_CMDLINE (1 << 2)
|
||||
+#define MULTIBOOT_FLAGS_MODULES (1 << 3)
|
||||
+#define MULTIBOOT_FLAGS_MMAP (1 << 6)
|
||||
+ stl_p(phys_ram_base + mb_bootinfo, MULTIBOOT_FLAGS_MEMORY
|
||||
+ | MULTIBOOT_FLAGS_BOOT_DEVICE
|
||||
+ | MULTIBOOT_FLAGS_CMDLINE
|
||||
+ | MULTIBOOT_FLAGS_MODULES
|
||||
+ | MULTIBOOT_FLAGS_MMAP);
|
||||
+ stl_p(phys_ram_base + mb_bootinfo + 4, 640 * 1024); // mem_lower
|
||||
+ stl_p(phys_ram_base + mb_bootinfo + 8, ram_size); // mem_upper
|
||||
+ stl_p(phys_ram_base + mb_bootinfo + 12, 0x8001ffff); // XXX: use the -boot switch?
|
||||
+ stl_p(phys_ram_base + mb_bootinfo + 48, 0x9000); // mmap_addr
|
||||
+
|
||||
+ fprintf(stderr, "multiboot: mh_entry_addr = %#x\n", mh_entry_addr);
|
||||
+
|
||||
+ generate_bootsect_multiboot(mh_entry_addr, mb_bootinfo);
|
||||
+
|
||||
+ return 1; // yes, we are multiboot
|
||||
+}
|
||||
+
|
||||
static void load_linux(const char *kernel_filename,
|
||||
const char *initrd_filename,
|
||||
const char *kernel_cmdline)
|
||||
@@ -522,7 +932,7 @@ static void load_linux(const char *kerne
|
||||
uint16_t real_seg;
|
||||
int setup_size, kernel_size, initrd_size, cmdline_size;
|
||||
uint32_t initrd_max;
|
||||
- uint8_t header[1024];
|
||||
+ uint8_t header[8192];
|
||||
target_phys_addr_t real_addr, prot_addr, cmdline_addr, initrd_addr;
|
||||
FILE *f, *fi;
|
||||
|
||||
@@ -532,7 +942,7 @@ static void load_linux(const char *kerne
|
||||
/* load the kernel header */
|
||||
f = fopen(kernel_filename, "rb");
|
||||
if (!f || !(kernel_size = get_file_size(f)) ||
|
||||
- fread(header, 1, 1024, f) != 1024) {
|
||||
+ fread(header, 1, 8192, f) != 8192) {
|
||||
fprintf(stderr, "qemu: could not load kernel '%s'\n",
|
||||
kernel_filename);
|
||||
exit(1);
|
||||
@@ -542,10 +952,15 @@ static void load_linux(const char *kerne
|
||||
#if 0
|
||||
fprintf(stderr, "header magic: %#x\n", ldl_p(header+0x202));
|
||||
#endif
|
||||
- if (ldl_p(header+0x202) == 0x53726448)
|
||||
- protocol = lduw_p(header+0x206);
|
||||
- else
|
||||
- protocol = 0;
|
||||
+ if (ldl_p(header+0x202) == 0x53726448) {
|
||||
+ protocol = lduw_p(header+0x206);
|
||||
+ } else {
|
||||
+ // This looks like a multiboot kernel. If it is, let's stop
|
||||
+ // treating it like Linux.
|
||||
+ if(load_multiboot(f,kernel_filename,initrd_filename, kernel_cmdline, header))
|
||||
+ return;
|
||||
+ protocol = 0;
|
||||
+ }
|
||||
|
||||
if (protocol < 0x200 || !(header[0x211] & 0x01)) {
|
||||
/* Low kernel */
|
||||
@@ -638,7 +1053,7 @@ static void load_linux(const char *kerne
|
||||
}
|
||||
|
||||
/* store the finalized header and load the rest of the kernel */
|
||||
- cpu_physical_memory_write(real_addr, header, 1024);
|
||||
+ cpu_physical_memory_write(real_addr, header, 8192);
|
||||
|
||||
setup_size = header[0x1f1];
|
||||
if (setup_size == 0)
|
||||
@@ -647,7 +1062,7 @@ static void load_linux(const char *kerne
|
||||
setup_size = (setup_size+1)*512;
|
||||
kernel_size -= setup_size; /* Size of protected-mode code */
|
||||
|
||||
- if (!fread_targphys_ok(real_addr+1024, setup_size-1024, f) ||
|
||||
+ if (!fread_targphys_ok(real_addr+8192, setup_size-8192, f) ||
|
||||
!fread_targphys_ok(prot_addr, kernel_size, f)) {
|
||||
fprintf(stderr, "qemu: read error on kernel '%s'\n",
|
||||
kernel_filename);
|
@ -1,14 +0,0 @@
|
||||
Index: kvm-78/qemu/vl.c
|
||||
===================================================================
|
||||
--- kvm-78.orig/qemu/vl.c
|
||||
+++ kvm-78/qemu/vl.c
|
||||
@@ -10057,7 +10057,8 @@ int main(int argc, char **argv)
|
||||
if (kvm_enabled()) {
|
||||
if (kvm_qemu_init() < 0) {
|
||||
extern int kvm_allowed;
|
||||
- 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);
|
@ -1,109 +0,0 @@
|
||||
# Fix the Link detection in MacOS
|
||||
# Author Alex Graf - agraf@suse
|
||||
Index: kvm-75/qemu/hw/rtl8139.c
|
||||
===================================================================
|
||||
--- kvm-75.orig/qemu/hw/rtl8139.c
|
||||
+++ kvm-75/qemu/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;
|
||||
@@ -1227,7 +1231,7 @@ static void rtl8139_reset(RTL8139State *
|
||||
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;
|
||||
|
||||
@@ -1251,6 +1255,13 @@ static void rtl8139_reset(RTL8139State *
|
||||
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);
|
||||
}
|
||||
@@ -2846,7 +2857,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;
|
||||
|
||||
@@ -3440,6 +3451,15 @@ PCIDevice *pci_rtl8139_init(PCIBus *bus,
|
||||
|
||||
s->pci_dev = (PCIDevice *)d;
|
||||
memcpy(s->macaddr, nd->macaddr, 6);
|
||||
+ switch(nd->link) {
|
||||
+ case Link_10mbps:
|
||||
+ case Link_100mbps:
|
||||
+ s->link = nd->link;
|
||||
+ break;
|
||||
+ default:
|
||||
+ s->link = Link_100mbps;
|
||||
+ break;
|
||||
+ }
|
||||
rtl8139_reset(s);
|
||||
s->vc = qemu_new_vlan_client(nd->vlan, rtl8139_receive,
|
||||
rtl8139_can_receive, s);
|
||||
Index: kvm-75/qemu/net.h
|
||||
===================================================================
|
||||
--- kvm-75.orig/qemu/net.h
|
||||
+++ kvm-75/qemu/net.h
|
||||
@@ -55,12 +55,20 @@ void net_client_uninit(NICInfo *nd);
|
||||
|
||||
#define MAX_NICS 8
|
||||
|
||||
+enum NICLink {
|
||||
+ Link_default,
|
||||
+ Link_10mbps,
|
||||
+ Link_100mbps,
|
||||
+ Link_1000mbps,
|
||||
+};
|
||||
+
|
||||
struct NICInfo {
|
||||
uint8_t macaddr[6];
|
||||
const char *model;
|
||||
VLANState *vlan;
|
||||
int devfn;
|
||||
int used;
|
||||
+ enum NICLink link;
|
||||
};
|
||||
|
||||
extern int nb_nics;
|
||||
Index: kvm-75/qemu/vl.c
|
||||
===================================================================
|
||||
--- kvm-75.orig/qemu/vl.c
|
||||
+++ kvm-75/qemu/vl.c
|
||||
@@ -5555,6 +5555,7 @@ int net_client_init(const char *device,
|
||||
}
|
||||
nd->vlan = vlan;
|
||||
nd->used = 1;
|
||||
+ nd->link = Link_default;
|
||||
nb_nics++;
|
||||
vlan->nb_guest_devs++;
|
||||
ret = idx;
|
@ -1,13 +0,0 @@
|
||||
# Revert default caching mode back to write-back for now
|
||||
# Signed-off-by: Bruce Rogers <brogers@novell.com>
|
||||
--- kvm-78.orig/qemu/vl.c
|
||||
+++ kvm-78/qemu/vl.c
|
||||
@@ -5892,7 +5892,7 @@ int drive_init(struct drive_opt *arg, in
|
||||
unit_id = -1;
|
||||
translation = BIOS_ATA_TRANSLATION_AUTO;
|
||||
index = -1;
|
||||
- cache = 1;
|
||||
+ cache = 2;
|
||||
|
||||
if (machine->use_scsi) {
|
||||
type = IF_SCSI;
|
@ -1,215 +0,0 @@
|
||||
# Copyright 1999-2009 Gentoo Foundation
|
||||
# Distributed under the terms of the GNU General Public License v2
|
||||
# $Header: /var/cvsroot/gentoo-x86/app-emulation/kvm/kvm-82.ebuild,v 1.1 2009/01/05 01:30:01 dang Exp $
|
||||
|
||||
inherit eutils flag-o-matic toolchain-funcs linux-mod
|
||||
|
||||
EAPI="1"
|
||||
|
||||
# Patchset git repo is at http://github.com/dang/kvm-patches/tree/master
|
||||
PATCHSET="kvm-patches-20090104"
|
||||
SRC_URI="mirror://sourceforge/${PN}/${P}.tar.gz
|
||||
http://apollo.fprintf.net/downloads/${PATCHSET}.tar.gz"
|
||||
|
||||
DESCRIPTION="Kernel-based Virtual Machine userland tools"
|
||||
HOMEPAGE="http://kvm.qumranet.com/kvmwiki"
|
||||
|
||||
LICENSE="GPL-2"
|
||||
SLOT="0"
|
||||
KEYWORDS="-* ~amd64 ~x86"
|
||||
# Add bios back when it builds again
|
||||
IUSE="alsa esd gnutls havekernel +modules ncurses pulseaudio +sdl test vde"
|
||||
RESTRICT="test"
|
||||
|
||||
RDEPEND="sys-libs/zlib
|
||||
alsa? ( >=media-libs/alsa-lib-1.0.13 )
|
||||
esd? ( media-sound/esound )
|
||||
pulseaudio? ( media-sound/pulseaudio )
|
||||
gnutls? ( net-libs/gnutls )
|
||||
ncurses? ( sys-libs/ncurses )
|
||||
sdl? ( >=media-libs/libsdl-1.2.11 )
|
||||
vde? ( net-misc/vde )"
|
||||
|
||||
# bios? (
|
||||
# sys-devel/dev86
|
||||
# dev-lang/perl
|
||||
# sys-power/iasl
|
||||
# )
|
||||
DEPEND="${RDEPEND}
|
||||
gnutls? ( dev-util/pkgconfig )
|
||||
app-text/texi2html"
|
||||
|
||||
QA_TEXTRELS="usr/bin/kvm"
|
||||
|
||||
pkg_setup() {
|
||||
linux-info_pkg_setup
|
||||
if use havekernel && use modules ; then
|
||||
ewarn "You have the 'havekernel' and 'modules' use flags enabled."
|
||||
ewarn "'havekernel' trumps 'modules'; the kvm modules will not"
|
||||
ewarn "be built. You must ensure you have a compatible kernel"
|
||||
ewarn "with the kvm modules on your own"
|
||||
elif use havekernel ; then
|
||||
ewarn "You have the 'havekernel' use flag set. This means you"
|
||||
ewarn "must ensure you have a compatible kernel on your own."
|
||||
elif use modules ; then
|
||||
if ! linux_chkconfig_present KVM; then
|
||||
eerror "KVM now needs CONFIG_KVM built into your kernel, even"
|
||||
eerror "if you're using the external modules from this package."
|
||||
eerror "Please enable KVM support in your kernel, found at:"
|
||||
eerror
|
||||
eerror " Virtualization"
|
||||
eerror " Kernel-based Virtual Machine (KVM) support"
|
||||
eerror
|
||||
die "KVM support not detected!"
|
||||
fi
|
||||
BUILD_TARGETS="all"
|
||||
MODULE_NAMES="kvm(kvm:${S}/kernel:${S}/kernel/x86)"
|
||||
MODULE_NAMES="${MODULE_NAMES} kvm-intel(kvm:${S}/kernel:${S}/kernel/x86)"
|
||||
MODULE_NAMES="${MODULE_NAMES} kvm-amd(kvm:${S}/kernel:${S}/kernel/x86)"
|
||||
linux-mod_pkg_setup
|
||||
elif kernel_is lt 2 6 25; then
|
||||
eerror "This version of KVM requres a host kernel of 2.6.25 or higher."
|
||||
eerror "Either upgrade your kernel, or enable the 'modules' USE flag."
|
||||
die "kvm version not compatible"
|
||||
elif ! linux_chkconfig_present KVM; then
|
||||
eerror "Please enable KVM support in your kernel, found at:"
|
||||
eerror
|
||||
eerror " Virtualization"
|
||||
eerror " Kernel-based Virtual Machine (KVM) support"
|
||||
eerror
|
||||
eerror "or enable the 'modules' USE flag."
|
||||
die "KVM support not detected!"
|
||||
fi
|
||||
|
||||
if use sdl && ! built_with_use media-libs/libsdl X ; then
|
||||
die "You need to rebuild media-libs/libsdl with the X use flag"
|
||||
fi
|
||||
|
||||
enewgroup kvm
|
||||
}
|
||||
|
||||
src_unpack() {
|
||||
unpack ${A}
|
||||
|
||||
cd "${S}"
|
||||
# prevent docs to get automatically installed
|
||||
sed -i '/$(DESTDIR)$(docdir)/d' qemu/Makefile
|
||||
# Alter target makefiles to accept CFLAGS set via flag-o
|
||||
sed -i 's/^\(C\|OP_C\|HELPER_C\)FLAGS=/\1FLAGS+=/' \
|
||||
qemu/Makefile qemu/Makefile.target
|
||||
[[ -x /sbin/paxctl ]] && \
|
||||
sed -i 's/^VL_LDFLAGS=$/VL_LDFLAGS=-Wl,-z,execheap/' \
|
||||
qemu/Makefile.target
|
||||
# avoid strip
|
||||
sed -i 's/$(INSTALL) -m 755 -s/$(INSTALL) -m 755/' qemu/Makefile
|
||||
|
||||
# apply patchset
|
||||
EPATCH_SOURCE="${WORKDIR}/${PATCHSET}"
|
||||
EPATCH_SUFFIX="patch"
|
||||
epatch
|
||||
}
|
||||
|
||||
src_compile() {
|
||||
local mycc conf_opts audio_opts
|
||||
|
||||
audio_opts="oss"
|
||||
use gnutls || conf_opts="$conf_opts --disable-vnc-tls"
|
||||
use ncurses || conf_opts="$conf_opts --disable-curses"
|
||||
use sdl || conf_opts="$conf_opts --disable-gfx-check --disable-sdl"
|
||||
use vde || conf_opts="$conf_opts --disable-vde"
|
||||
use alsa && audio_opts="alsa $audio_opts"
|
||||
use esd && audio_opts="esd $audio_opts"
|
||||
use pulseaudio && audio_opts="pa $audio_opts"
|
||||
use sdl && audio_opts="sdl $audio_opts"
|
||||
use modules && conf_opts="$conf_opts --kerneldir=$KV_DIR"
|
||||
conf_opts="$conf_opts --prefix=/usr"
|
||||
#conf_opts="$conf_opts --audio-drv-list=\"$audio_opts\""
|
||||
|
||||
./configure ${conf_opts} --audio-drv-list="$audio_opts" || die "econf failed"
|
||||
|
||||
emake libkvm || die "emake libkvm failed"
|
||||
|
||||
if use test; then
|
||||
emake user || die "emake user failed"
|
||||
fi
|
||||
|
||||
mycc=$(cat qemu/config-host.mak | egrep "^CC=" | cut -d "=" -f 2)
|
||||
|
||||
filter-flags -fpie -fstack-protector
|
||||
|
||||
# If using gentoo's compiler set the SPEC to non-hardened
|
||||
if [ ! -z ${GCC_SPECS} -a -f ${GCC_SPECS} ]; then
|
||||
local myccver=$(${mycc} -dumpversion)
|
||||
local gccver=$($(tc-getBUILD_CC) -dumpversion)
|
||||
|
||||
#Is this a SPEC for the right compiler version?
|
||||
myspec="${GCC_SPECS/${gccver}/${myccver}}"
|
||||
if [ "${myspec}" == "${GCC_SPECS}" ]; then
|
||||
shopt -s extglob
|
||||
GCC_SPECS="${GCC_SPECS/%hardened*specs/vanilla.specs}"
|
||||
shopt -u extglob
|
||||
else
|
||||
unset GCC_SPECS
|
||||
fi
|
||||
fi
|
||||
|
||||
# if use bios; then
|
||||
# emake bios || die "emake bios failed"
|
||||
# emake vgabios || die "emake vgabios failed"
|
||||
# fi
|
||||
|
||||
emake qemu || die "emake qemu failed"
|
||||
|
||||
if use modules && ! use havekernel ; then
|
||||
linux-mod_src_compile
|
||||
fi
|
||||
}
|
||||
|
||||
src_install() {
|
||||
# kcmd so we don't install kernel modules which weren't build
|
||||
emake DESTDIR="${D}" kcmd='#' install || die "make install failed"
|
||||
|
||||
exeinto /usr/bin/
|
||||
doexe "${S}/kvm_stat"
|
||||
|
||||
mv "${D}"/usr/share/man/man1/qemu.1 "${D}"/usr/share/man/man1/kvm.1
|
||||
mv "${D}"/usr/share/man/man1/qemu-img.1 "${D}"/usr/share/man/man1/kvm-img.1
|
||||
mv "${D}"/usr/share/man/man8/qemu-nbd.8 "${D}"/usr/share/man/man8/kvm-nbd.8
|
||||
mv "${D}"/usr/bin/qemu-img "${D}"/usr/bin/kvm-img
|
||||
mv "${D}"/usr/bin/qemu-nbd "${D}"/usr/bin/kvm-nbd
|
||||
|
||||
insinto /etc/udev/rules.d/
|
||||
doins scripts/65-kvm.rules
|
||||
|
||||
insinto /etc/kvm/
|
||||
insopts -m0755
|
||||
newins scripts/qemu-ifup kvm-ifup
|
||||
newins scripts/qemu-ifdown kvm-ifdown
|
||||
|
||||
dodoc qemu/pc-bios/README
|
||||
newdoc qemu/qemu-doc.html kvm-doc.html
|
||||
newdoc qemu/qemu-tech.html kvm-tech.html
|
||||
|
||||
if use modules && ! use havekernel ; then
|
||||
linux-mod_src_install
|
||||
fi
|
||||
}
|
||||
|
||||
pkg_postinst() {
|
||||
elog "If you don't have kvm compiled into the kernel, make sure you have"
|
||||
elog "the kernel module loaded before running kvm. The easiest way to"
|
||||
elog "ensure that the kernel module is loaded is to load it on boot."
|
||||
elog "For AMD CPUs the module is called 'kvm-amd'"
|
||||
elog "For Intel CPUs the module is called 'kvm-intel'"
|
||||
elog "Please review /etc/conf.d/modules for how to load these"
|
||||
elog
|
||||
elog "Make sure your user is in the 'kvm' group"
|
||||
elog "Just run 'gpasswd -a <USER> kvm', then have <USER> re-login."
|
||||
elog
|
||||
elog "You will need the Universal TUN/TAP driver compiled into your"
|
||||
elog "kernel or loaded as a module to use the virtual network device"
|
||||
elog "if using -net tap. You will also need support for 802.1d"
|
||||
elog "Ethernet Bridging and a configured bridge if using the provided"
|
||||
elog "kvm-ifup script from /etc/kvm."
|
||||
echo
|
||||
}
|
@ -1,32 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE pkgmetadata SYSTEM "http://www.gentoo.org/dtd/metadata.dtd">
|
||||
<pkgmetadata>
|
||||
<herd>none</herd>
|
||||
<maintainer>
|
||||
<email>dang@gentoo.org</email>
|
||||
<name>Daniel Gryniewicz</name>
|
||||
</maintainer>
|
||||
<maintainer>
|
||||
<email>cardoe@gentoo.org</email>
|
||||
<name>Doug Goldstein</name>
|
||||
</maintainer>
|
||||
<longdescription lang="en">
|
||||
KVM (for Kernel-based Virtual Machine) is a full virtualization solution
|
||||
for Linux on x86 hardware containing virtualization extensions (Intel VT
|
||||
or AMD-V)
|
||||
</longdescription>
|
||||
<use>
|
||||
<flag name='alsa'>Enable alsa output for sound emulation</flag>
|
||||
<flag name='esd'>Enable esound output for sound emulation</flag>
|
||||
<flag name='gnutls'>Enable TLS support for the VNC console server</flag>
|
||||
<flag name='havekernel'>Don't require a kernel build tree (useful if
|
||||
using a binary distrbuted kernel aka binary packages)</flag>
|
||||
<flag name='modules'>Build the kernel modules from the kvm package</flag>
|
||||
<flag name='ncurses'>Enable the ncurses-based console</flag>
|
||||
<flag name='pulseaudio'>Enable pulseaudio output for sound emulation</flag>
|
||||
<flag name='sdl'>Enable the SDL-based console</flag>
|
||||
<flag name='test'>Build tests</flag>
|
||||
<flag name='vde'>Enable VDE-based networking</flag>
|
||||
</use>
|
||||
</pkgmetadata>
|
||||
|
Loading…
Reference in New Issue
Block a user