From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1KuWhY-0006tM-5Q for qemu-devel@nongnu.org; Mon, 27 Oct 2008 14:20:28 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1KuWhU-0006pX-MA for qemu-devel@nongnu.org; Mon, 27 Oct 2008 14:20:27 -0400 Received: from [199.232.76.173] (port=45200 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1KuWhU-0006pR-If for qemu-devel@nongnu.org; Mon, 27 Oct 2008 14:20:24 -0400 Received: from e38.co.us.ibm.com ([32.97.110.159]:35737) by monty-python.gnu.org with esmtps (TLS-1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.60) (envelope-from ) id 1KuWhU-0002mJ-6j for qemu-devel@nongnu.org; Mon, 27 Oct 2008 14:20:24 -0400 Received: from d03relay04.boulder.ibm.com (d03relay04.boulder.ibm.com [9.17.195.106]) by e38.co.us.ibm.com (8.13.1/8.13.1) with ESMTP id m9RIJe2w001147 for ; Mon, 27 Oct 2008 12:19:40 -0600 Received: from d03av04.boulder.ibm.com (d03av04.boulder.ibm.com [9.17.195.170]) by d03relay04.boulder.ibm.com (8.13.8/8.13.8/NCO v9.1) with ESMTP id m9RIKMsi112896 for ; Mon, 27 Oct 2008 12:20:22 -0600 Received: from d03av04.boulder.ibm.com (loopback [127.0.0.1]) by d03av04.boulder.ibm.com (8.12.11.20060308/8.13.3) with ESMTP id m9RIKLE4004367 for ; Mon, 27 Oct 2008 12:20:21 -0600 Received: from [9.65.94.29] (sig-9-65-94-29.mts.ibm.com [9.65.94.29]) by d03av04.boulder.ibm.com (8.12.11.20060308/8.12.11) with ESMTP id m9RIKKZN004091 for ; Mon, 27 Oct 2008 12:20:20 -0600 From: Beth Kon Content-Type: multipart/mixed; boundary="=-XlfpDhBSgTfVZVr9/bc9" Date: Mon, 27 Oct 2008 14:20:23 -0400 Message-Id: <1225131623.7555.72.camel@beth-laptop> Mime-Version: 1.0 Subject: [Qemu-devel] [PATCH 1/2] Add Interrupt Source Override Structure to BIOS Reply-To: qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org --=-XlfpDhBSgTfVZVr9/bc9 Content-Type: text/plain Content-Transfer-Encoding: 7bit Looking into a problem with getting the HPET to work for both Windows and Linux revealed what appears to be a problem with QEMU's interrupt generation. Since QEMU supports both APIC and dual 8259 mode (as indicated by bit 0 of the MADT flags - PCAT COMPAT), the BIOS should include the Interrupt Source Override structure to inform the OS that IRQ0 is mapped to interrupt 2 in APIC mode, which is the standard scheme for the PIT. What must be happening is that Linux is abiding by what the BIOS says and expecting INTI0 from the APIC (since there is no Interrupt Source Override). Windows must be ignoring the Interrupt Source Override information and just expecting to see the timer interrupt on INTI2. So the HPET had to raise both 0 and 2 to keep them both happy. Patch 1 adds the Interrupt Source Override to BIOS, and Patch 2 modifies ioapic_set_irq to change vector 0 to 2. Making this change allowed Windows and Linux to both work with HPET code that just raised IRQ0. That said, I don't understand why the PIT was working with the code as it was in the case of Windows, unless in that case windows was honoring the Interrupt Source Override (or the lack of one, I should say). I'm not sure these patches are the right solution for all cases, but they work for the HPET. I should add that KVM does have an Interrupt Source Override structure in their BIOS but they do not remap 0 to 2, so maybe I'm missing something here. Comments appreciated. -- Elizabeth Kon (Beth) IBM Linux Technology Center Open Hypervisor Team email: eak@us.ibm.com --=-XlfpDhBSgTfVZVr9/bc9 Content-Disposition: attachment; filename=bios_int_override.patch Content-Type: text/x-patch; name=bios_int_override.patch; charset=UTF-8 Content-Transfer-Encoding: 7bit Index: bochs-2.3.7/bios/rombios32.c =================================================================== --- bochs-2.3.7.orig/bios/rombios32.c 2008-10-24 08:07:00.000000000 -0500 +++ bochs-2.3.7/bios/rombios32.c 2008-10-27 09:36:17.000000000 -0500 @@ -1262,6 +1262,17 @@ * lines start */ }; +#ifdef BX_QEMU +struct madt_int_override +{ + APIC_HEADER_DEF + uint8_t bus; /* Identifies ISA Bus */ + uint8_t source; /* Bus-relative interrupt source */ + uint32_t gsi; /* GSI that source will signal */ + uint16_t flags; /* MPS INTI flags */ +}; +#endif + #include "acpi-dsdt.hex" static inline uint16_t cpu_to_le16(uint16_t x) @@ -1410,7 +1421,11 @@ madt_addr = addr; madt_size = sizeof(*madt) + sizeof(struct madt_processor_apic) * smp_cpus + +#ifdef BX_QEMU + sizeof(struct madt_io_apic) + sizeof(struct madt_int_override); +#else sizeof(struct madt_io_apic); +#endif madt = (void *)(addr); addr += madt_size; @@ -1480,6 +1495,9 @@ { struct madt_processor_apic *apic; struct madt_io_apic *io_apic; +#ifdef BX_QEMU + struct madt_int_override *int_override; +#endif memset(madt, 0, madt_size); madt->local_apic_address = cpu_to_le32(0xfee00000); @@ -1499,6 +1517,17 @@ io_apic->io_apic_id = smp_cpus; io_apic->address = cpu_to_le32(0xfec00000); io_apic->interrupt = cpu_to_le32(0); +#ifdef BX_QEMU + io_apic++; + + int_override = (void *)io_apic; + int_override->type = APIC_XRUPT_OVERRIDE; + int_override->length = sizeof(*int_override); + int_override->bus = cpu_to_le32(0); + int_override->source = cpu_to_le32(0); + int_override->gsi = cpu_to_le32(2); + int_override->flags = cpu_to_le32(0); +#endif acpi_build_table_header((struct acpi_table_header *)madt, "APIC", madt_size, 1); --=-XlfpDhBSgTfVZVr9/bc9--