ia64/xen-unstable
changeset 13195:d752d8ccd282
[HVM] Route ISA IRQ 0 to IOAPIC GSI 2, just like 99% of native systems.
This is a built-in assumption of HPET 'legacy' IRQ routing, which is
why we have changed to this routing strategy now.
Signed-off-by: Keir Fraser <keir@xensource.com>
This is a built-in assumption of HPET 'legacy' IRQ routing, which is
why we have changed to this routing strategy now.
Signed-off-by: Keir Fraser <keir@xensource.com>
author | kaf24@localhost.localdomain |
---|---|
date | Tue Dec 26 19:49:11 2006 +0000 (2006-12-26) |
parents | ce4e548f42b8 |
children | 6f8d650f3ab1 |
files | tools/firmware/hvmloader/acpi/build.c tools/firmware/hvmloader/mp_tables.c xen/arch/x86/hvm/hpet.c xen/arch/x86/hvm/irq.c |
line diff
1.1 --- a/tools/firmware/hvmloader/acpi/build.c Mon Dec 25 19:29:05 2006 +0000 1.2 +++ b/tools/firmware/hvmloader/acpi/build.c Tue Dec 26 19:49:11 2006 +0000 1.3 @@ -69,16 +69,28 @@ int construct_madt(struct acpi_20_madt * 1.4 intsrcovr = (struct acpi_20_madt_intsrcovr *)(madt + 1); 1.5 for ( i = 0; i < 16; i++ ) 1.6 { 1.7 - if ( !(PCI_ISA_IRQ_MASK & (1U << i)) ) 1.8 - continue; 1.9 - 1.10 - /* PCI: active-low level-triggered */ 1.11 memset(intsrcovr, 0, sizeof(*intsrcovr)); 1.12 intsrcovr->type = ACPI_INTERRUPT_SOURCE_OVERRIDE; 1.13 intsrcovr->length = sizeof(*intsrcovr); 1.14 intsrcovr->source = i; 1.15 - intsrcovr->gsi = i; 1.16 - intsrcovr->flags = 0xf; 1.17 + 1.18 + if ( i == 0 ) 1.19 + { 1.20 + /* ISA IRQ0 routed to IOAPIC GSI 2. */ 1.21 + intsrcovr->gsi = 2; 1.22 + intsrcovr->flags = 0x0; 1.23 + } 1.24 + else if ( PCI_ISA_IRQ_MASK & (1U << i) ) 1.25 + { 1.26 + /* PCI: active-low level-triggered. */ 1.27 + intsrcovr->gsi = i; 1.28 + intsrcovr->flags = 0xf; 1.29 + } 1.30 + else 1.31 + { 1.32 + /* No need for a INT source override structure. */ 1.33 + continue; 1.34 + } 1.35 1.36 offset += sizeof(*intsrcovr); 1.37 intsrcovr++;
2.1 --- a/tools/firmware/hvmloader/mp_tables.c Mon Dec 25 19:29:05 2006 +0000 2.2 +++ b/tools/firmware/hvmloader/mp_tables.c Tue Dec 26 19:49:11 2006 +0000 2.3 @@ -373,7 +373,7 @@ void create_mp_tables(void) 2.4 { 2.5 if ( i == 2 ) continue; /* skip the slave PIC connection */ 2.6 fill_mp_io_intr_entry((struct mp_io_intr_entry *)p, 2.7 - BUS_ID_ISA, i, IOAPIC_ID, i); 2.8 + BUS_ID_ISA, i, IOAPIC_ID, (i == 0) ? 2 : i); 2.9 p += sizeof(struct mp_io_intr_entry); 2.10 } 2.11
3.1 --- a/xen/arch/x86/hvm/hpet.c Mon Dec 25 19:29:05 2006 +0000 3.2 +++ b/xen/arch/x86/hvm/hpet.c Tue Dec 26 19:49:11 2006 +0000 3.3 @@ -97,9 +97,6 @@ 3.4 ((timer_config(h, n) & HPET_TN_INT_ROUTE_CAP_MASK) \ 3.5 >> HPET_TN_INT_ROUTE_CAP_SHIFT) 3.6 3.7 -#define timer_int_route_valid(h, n) \ 3.8 - (timer_int_route_cap(h, n) & (1 << timer_int_route(h, n))) 3.9 - 3.10 #define hpet_time_after(a, b) ((int32_t)(b) -(int32_t)(a) < 0) 3.11 #define hpet_time_after64(a, b) ((int64_t)(b) -(int64_t)(a) < 0) 3.12 3.13 @@ -409,54 +406,14 @@ struct hvm_mmio_handler hpet_mmio_handle 3.14 .write_handler = hpet_write 3.15 }; 3.16 3.17 -static void hpet_irq_assert(struct domain *d, 3.18 - unsigned int isa_irq, unsigned int intr) 3.19 -{ 3.20 - struct hvm_irq *hvm_irq = &d->arch.hvm_domain.irq; 3.21 - 3.22 - spin_lock(&hvm_irq->lock); 3.23 - 3.24 - if ( !__test_and_set_bit(isa_irq, &hvm_irq->isa_irq) && 3.25 - (hvm_irq->gsi_assert_count[isa_irq]++ == 0) ) 3.26 - { 3.27 - vioapic_irq_positive_edge(d, intr); 3.28 - vpic_irq_positive_edge(d, isa_irq); 3.29 - } 3.30 - 3.31 - spin_unlock(&hvm_irq->lock); 3.32 -} 3.33 - 3.34 -static void hpet_irq_deassert(struct domain *d, 3.35 - unsigned int isa_irq, unsigned int intr) 3.36 -{ 3.37 - hvm_isa_irq_deassert(d, isa_irq); 3.38 -} 3.39 - 3.40 static void hpet_set_irq(struct domain *d, int hpet_tn) 3.41 { 3.42 - int irq, intr; 3.43 - 3.44 - if ( (hpet_tn != 0) && (hpet_tn != 1) ) 3.45 - return; 3.46 - 3.47 /* if LegacyReplacementRoute bit is set, HPET specification requires 3.48 timer0 be routed to IRQ0 in NON-APIC or IRQ2 in the I/O APIC, 3.49 - timer1 be routed to IRQ8 in NON-APIC or IRQ8 in the I/O APIC. 3.50 - It's hard to distinguish NON-APIC and I/O APIC, so we set both PIC 3.51 - and I/O APIC here. Guest OS shall make proper mask setting to ensure 3.52 - only one interrupt is injected into it. */ 3.53 - if ( hpet_tn == 0 ) 3.54 - { 3.55 - irq = 0; 3.56 - intr = 2; 3.57 - } 3.58 - else 3.59 - { 3.60 - irq = intr = 8; 3.61 - } 3.62 - 3.63 - hpet_irq_deassert(d, irq, intr); 3.64 - hpet_irq_assert(d, irq, intr); 3.65 + timer1 be routed to IRQ8 in NON-APIC or IRQ8 in the I/O APIC. */ 3.66 + int isa_irq = (hpet_tn == 0) ? 0 : 8; 3.67 + hvm_isa_irq_deassert(d, isa_irq); 3.68 + hvm_isa_irq_assert(d, isa_irq); 3.69 } 3.70 3.71 static void hpet_route_interrupt(HPETState *h, unsigned int tn) 3.72 @@ -465,7 +422,7 @@ static void hpet_route_interrupt(HPETSta 3.73 struct domain *d = h->vcpu->domain; 3.74 struct hvm_irq *hvm_irq = &d->arch.hvm_domain.irq; 3.75 3.76 - if ( (tn_int_route >= VIOAPIC_NUM_PINS) || !timer_int_route_valid(h, tn) ) 3.77 + if ( !(timer_int_route_cap(h, tn) & (1U << tn_int_route)) ) 3.78 { 3.79 gdprintk(XENLOG_ERR, 3.80 "HPET: timer%u: invalid interrupt route config\n", tn);
4.1 --- a/xen/arch/x86/hvm/irq.c Mon Dec 25 19:29:05 2006 +0000 4.2 +++ b/xen/arch/x86/hvm/irq.c Tue Dec 26 19:49:11 2006 +0000 4.3 @@ -85,15 +85,16 @@ void hvm_isa_irq_assert( 4.4 struct domain *d, unsigned int isa_irq) 4.5 { 4.6 struct hvm_irq *hvm_irq = &d->arch.hvm_domain.irq; 4.7 + unsigned int gsi = (isa_irq == 0) ? 2 : isa_irq; 4.8 4.9 ASSERT(isa_irq <= 15); 4.10 4.11 spin_lock(&hvm_irq->lock); 4.12 4.13 if ( !__test_and_set_bit(isa_irq, &hvm_irq->isa_irq) && 4.14 - (hvm_irq->gsi_assert_count[isa_irq]++ == 0) ) 4.15 + (hvm_irq->gsi_assert_count[gsi]++ == 0) ) 4.16 { 4.17 - vioapic_irq_positive_edge(d, isa_irq); 4.18 + vioapic_irq_positive_edge(d, gsi); 4.19 vpic_irq_positive_edge(d, isa_irq); 4.20 } 4.21 4.22 @@ -104,13 +105,14 @@ void hvm_isa_irq_deassert( 4.23 struct domain *d, unsigned int isa_irq) 4.24 { 4.25 struct hvm_irq *hvm_irq = &d->arch.hvm_domain.irq; 4.26 + unsigned int gsi = (isa_irq == 0) ? 2 : isa_irq; 4.27 4.28 ASSERT(isa_irq <= 15); 4.29 4.30 spin_lock(&hvm_irq->lock); 4.31 4.32 if ( __test_and_clear_bit(isa_irq, &hvm_irq->isa_irq) && 4.33 - (--hvm_irq->gsi_assert_count[isa_irq] == 0) ) 4.34 + (--hvm_irq->gsi_assert_count[gsi] == 0) ) 4.35 vpic_irq_negative_edge(d, isa_irq); 4.36 4.37 spin_unlock(&hvm_irq->lock);