Message ID | 1244731365-32069-1-git-send-email-eak@us.ibm.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Beth Kon wrote: > These patches resolve the irq0->inti2 override issue, and get the hpet working > on kvm. > > Override and HPET changes are sent as a series because HPET depends on the > override. Win2k8 expects the HPET interrupt on inti2, regardless of whether > an override exists in the BIOS. And the HPET spec states that in legacy mode, > timer interrupt is on inti2. > > The irq0->inti2 override will always be used unless the kernel cannot do irq > routing (i.e., compatibility with old kernels). So if the kernel is capable, > userspace sets up irq0->inti2 via the irq routing interface, and adds the > irq0->inti2 override to the MADT interrupt source override table, > and the mp table (for the no-acpi case). > > Changes from v3: > > - changes based on comments from Avi and Gleb. > - corrected legacy enable/disable for in-kernel PIT. The code now best > approximates a multiplexer that disables PIT interrupts when HPET is > in legacy mode (as described by HPET spec). Any changes to the PIT that > may occur while HPET is operating in legacy mode are saved, so if > HPET leaves legacy mode, the PIT is just reenabled, with mode set > to whatever the last setting from guest was. Legacy mode is disabled > at least during crash and shutdown (in Linux), so this needs to be > handled properly. > > > --- > kvm/bios/rombios32.c | 60 ++++++++++++++++++++++++++++++++++++------------- > 1 files changed, 44 insertions(+), 16 deletions(-) What about the mptable entry count? Think it would need something like #ifdef BX_QEMU if (irq0_override) putle16(&q, smp_cpus + 17); /* entry count */ else putle16(&q, smp_cpus + 18); /* entry count */ #else putle16(&q, smp_cpus + 18); /* entry count */ #endif Your patch "Fix non-ACPI Timer Interrupt Routing - v3" [1] included such a change. [1] http://lists.gnu.org/archive/html/qemu-devel/2009-04/msg01396.html - Sebastian -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Sebastian Herbszt wrote: > Beth Kon wrote: >> These patches resolve the irq0->inti2 override issue, and get the >> hpet working >> on kvm. >> >> Override and HPET changes are sent as a series because HPET depends >> on the >> override. Win2k8 expects the HPET interrupt on inti2, regardless of >> whether >> an override exists in the BIOS. And the HPET spec states that in >> legacy mode, >> timer interrupt is on inti2. >> >> The irq0->inti2 override will always be used unless the kernel cannot >> do irq >> routing (i.e., compatibility with old kernels). So if the kernel is >> capable, >> userspace sets up irq0->inti2 via the irq routing interface, and adds >> the >> irq0->inti2 override to the MADT interrupt source override table, >> and the mp table (for the no-acpi case). >> >> Changes from v3: >> >> - changes based on comments from Avi and Gleb. >> - corrected legacy enable/disable for in-kernel PIT. The code now best >> approximates a multiplexer that disables PIT interrupts when HPET is >> in legacy mode (as described by HPET spec). Any changes to the PIT >> that may occur while HPET is operating in legacy mode are saved, so >> if HPET leaves legacy mode, the PIT is just reenabled, with mode >> set to whatever the last setting from guest was. Legacy mode is >> disabled >> at least during crash and shutdown (in Linux), so this needs to be >> handled properly. >> >> >> --- >> kvm/bios/rombios32.c | 60 >> ++++++++++++++++++++++++++++++++++++------------- >> 1 files changed, 44 insertions(+), 16 deletions(-) > > What about the mptable entry count? > Think it would need something like > > #ifdef BX_QEMU > if (irq0_override) > putle16(&q, smp_cpus + 17); /* entry count */ > else > putle16(&q, smp_cpus + 18); /* entry count */ > #else > putle16(&q, smp_cpus + 18); /* entry count */ > #endif > > Your patch "Fix non-ACPI Timer Interrupt Routing - v3" [1] included > such a change. > > [1] http://lists.gnu.org/archive/html/qemu-devel/2009-04/msg01396.html Yes, I lost that somehow! Thanks (again!). > > - Sebastian > -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Beth Kon wrote: > Sebastian Herbszt wrote: >> Beth Kon wrote: >>> These patches resolve the irq0->inti2 override issue, and get the >>> hpet working >>> on kvm. >>> >>> Override and HPET changes are sent as a series because HPET depends >>> on the >>> override. Win2k8 expects the HPET interrupt on inti2, regardless of >>> whether >>> an override exists in the BIOS. And the HPET spec states that in >>> legacy mode, >>> timer interrupt is on inti2. >>> >>> The irq0->inti2 override will always be used unless the kernel >>> cannot do irq >>> routing (i.e., compatibility with old kernels). So if the kernel is >>> capable, >>> userspace sets up irq0->inti2 via the irq routing interface, and >>> adds the >>> irq0->inti2 override to the MADT interrupt source override table, >>> and the mp table (for the no-acpi case). >>> >>> Changes from v3: >>> >>> - changes based on comments from Avi and Gleb. >>> - corrected legacy enable/disable for in-kernel PIT. The code now best >>> approximates a multiplexer that disables PIT interrupts when HPET >>> is in legacy mode (as described by HPET spec). Any changes to the >>> PIT that may occur while HPET is operating in legacy mode are >>> saved, so if HPET leaves legacy mode, the PIT is just reenabled, >>> with mode set to whatever the last setting from guest was. >>> Legacy mode is disabled >>> at least during crash and shutdown (in Linux), so this needs to be >>> handled properly. >>> >>> >>> --- >>> kvm/bios/rombios32.c | 60 >>> ++++++++++++++++++++++++++++++++++++------------- >>> 1 files changed, 44 insertions(+), 16 deletions(-) >> >> What about the mptable entry count? >> Think it would need something like >> >> #ifdef BX_QEMU >> if (irq0_override) >> putle16(&q, smp_cpus + 17); /* entry count */ >> else >> putle16(&q, smp_cpus + 18); /* entry count */ >> #else >> putle16(&q, smp_cpus + 18); /* entry count */ >> #endif >> >> Your patch "Fix non-ACPI Timer Interrupt Routing - v3" [1] included >> such a change. >> >> [1] http://lists.gnu.org/archive/html/qemu-devel/2009-04/msg01396.html > Yes, I lost that somehow! Thanks (again!). Actually, it isn't that simple. That patch that you referred to was a qemu patch. But I still don't see it in qemu-patched bochs bios. Apparently, I did neglect to add it to the kvm bios patches that I had waiting. Anthony, do you know what happened to this patch? > >> >> - Sebastian >> > > -- > To unsubscribe from this list: send the line "unsubscribe kvm" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/kvm/bios/rombios32.c b/kvm/bios/rombios32.c index 369cbef..9d6910e 100755 --- a/kvm/bios/rombios32.c +++ b/kvm/bios/rombios32.c @@ -444,6 +444,9 @@ uint32_t cpuid_features; uint32_t cpuid_ext_features; unsigned long ram_size; uint64_t ram_end; +#ifdef BX_QEMU +uint8_t irq0_override; +#endif #ifdef BX_USE_EBDA_TABLES unsigned long ebda_cur_addr; #endif @@ -485,6 +488,7 @@ void wrmsr_smp(uint32_t index, uint64_t val) #define QEMU_CFG_ARCH_LOCAL 0x8000 #define QEMU_CFG_ACPI_TABLES (QEMU_CFG_ARCH_LOCAL + 0) #define QEMU_CFG_SMBIOS_ENTRIES (QEMU_CFG_ARCH_LOCAL + 1) +#define QEMU_CFG_IRQ0_OVERRIDE (QEMU_CFG_ARCH_LOCAL + 2) int qemu_cfg_port; @@ -553,6 +557,17 @@ uint64_t qemu_cfg_get64 (void) } #endif +#ifdef BX_QEMU +void irq0_override_probe(void) +{ + if(qemu_cfg_port) { + qemu_cfg_select(QEMU_CFG_IRQ0_OVERRIDE); + qemu_cfg_read(&irq0_override, 1); + return; + } +} +#endif + void cpu_probe(void) { uint32_t eax, ebx, ecx, edx; @@ -1195,6 +1210,13 @@ static void mptable_init(void) /* irqs */ for(i = 0; i < 16; i++) { +#ifdef BX_QEMU + /* One entry per ioapic interrupt destination. Destination 2 is covered + * by irq0->inti2 override (i == 0). Source IRQ 2 is unused + */ + if (irq0_override && i == 2) + continue; +#endif putb(&q, 3); /* entry type = I/O interrupt */ putb(&q, 0); /* interrupt type = vectored interrupt */ putb(&q, 0); /* flags: po=0, el=0 */ @@ -1202,7 +1224,12 @@ static void mptable_init(void) putb(&q, 0); /* source bus ID = ISA */ putb(&q, i); /* source bus IRQ */ putb(&q, ioapic_id); /* dest I/O APIC ID */ - putb(&q, i); /* dest I/O APIC interrupt in */ +#ifdef BX_QEMU + if (irq0_override && i == 0) + putb(&q, 2); /* dest I/O APIC interrupt in */ + else +#endif + putb(&q, i); /* dest I/O APIC interrupt in */ } /* patch length */ len = q - mp_config_table; @@ -1758,23 +1785,21 @@ void acpi_bios_init(void) io_apic->io_apic_id = smp_cpus; io_apic->address = cpu_to_le32(0xfec00000); io_apic->interrupt = cpu_to_le32(0); -#ifdef BX_QEMU -#ifdef HPET_WORKS_IN_KVM 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 + int_override = (struct madt_int_override*)(io_apic); +#ifdef BX_QEMU + if (irq0_override) { + memset(int_override, 0, sizeof(*int_override)); + int_override->type = APIC_XRUPT_OVERRIDE; + int_override->length = sizeof(*int_override); + int_override->source = 0; + int_override->gsi = 2; + int_override->flags = 0; /* conforms to bus specifications */ + int_override++; + } #endif - - int_override = (struct madt_int_override*)(io_apic + 1); - for ( i = 0; i < 16; i++ ) { - if ( PCI_ISA_IRQ_MASK & (1U << i) ) { + for (i = 0; i < 16; i++) { + if (PCI_ISA_IRQ_MASK & (1U << i)) { memset(int_override, 0, sizeof(*int_override)); int_override->type = APIC_XRUPT_OVERRIDE; int_override->length = sizeof(*int_override); @@ -2697,6 +2722,9 @@ void rombios32_init(uint32_t *s3_resume_vector, uint8_t *shutdown_flag) if (bios_table_cur_addr != 0) { +#ifdef BX_QEMU + irq0_override_probe(); +#endif mptable_init(); smbios_init();