x86/HPET: include FSB interrupt information in 'M' debug key output Signed-off-by: Jan Beulich --- a/xen/arch/x86/hpet.c +++ b/xen/arch/x86/hpet.c @@ -239,6 +239,7 @@ static void hpet_msi_unmask(struct irq_d cfg = hpet_read32(HPET_Tn_CFG(ch->idx)); cfg |= HPET_TN_FSB; hpet_write32(cfg, HPET_Tn_CFG(ch->idx)); + ch->msi.msi_attrib.masked = 0; } static void hpet_msi_mask(struct irq_desc *desc) @@ -249,6 +250,7 @@ static void hpet_msi_mask(struct irq_des cfg = hpet_read32(HPET_Tn_CFG(ch->idx)); cfg &= ~HPET_TN_FSB; hpet_write32(cfg, HPET_Tn_CFG(ch->idx)); + ch->msi.msi_attrib.masked = 1; } static void hpet_msi_write(struct hpet_event_channel *ch, struct msi_msg *msg) @@ -346,6 +348,7 @@ static int __init hpet_setup_msi_irq(str } __hpet_setup_msi_irq(desc); + desc->msi_desc = &ch->msi; return 0; } @@ -390,6 +393,17 @@ static void __init hpet_fsb_cap_lookup(v if ( !(cfg & HPET_TN_FSB_CAP) ) continue; + /* hpet_setup(), via hpet_resume(), attempted to clear HPET_TN_FSB, so + * if it is still set... */ + if ( !(cfg & HPET_TN_FSB) ) + ch->msi.msi_attrib.maskbit = 1; + else + { + ch->msi.msi_attrib.maskbit = 0; + printk(XENLOG_WARNING "HPET: channel %u is not maskable (%04x)\n", + i, cfg); + } + if ( !zalloc_cpumask_var(&ch->cpumask) ) { if ( !num_hpets_used ) @@ -573,6 +587,8 @@ void __init hpet_broadcast_init(void) spin_lock_init(&hpet_events[i].lock); wmb(); hpet_events[i].event_handler = handle_hpet_broadcast; + + hpet_events[i].msi.msi_attrib.pos = MSI_TYPE_HPET; } if ( !num_hpets_used ) @@ -795,7 +811,10 @@ void hpet_resume(u32 *boot_cfg) { cfg = hpet_read32(HPET_Tn_CFG(i)); if ( boot_cfg ) + { boot_cfg[i + 1] = cfg; + cfg &= ~HPET_TN_FSB; + } cfg &= ~HPET_TN_ENABLE; if ( cfg & HPET_TN_RESERVED ) { --- a/xen/arch/x86/msi.c +++ b/xen/arch/x86/msi.c @@ -1119,17 +1119,17 @@ static void dump_msi(unsigned char key) { unsigned int irq; - printk("PCI-MSI interrupt information:\n"); + printk("MSI information:\n"); for ( irq = 0; irq < nr_irqs; irq++ ) { struct irq_desc *desc = irq_to_desc(irq); const struct msi_desc *entry; u32 addr, data, dest32; - int mask; + char mask; struct msi_attrib attr; unsigned long flags; - char type; + const char *type = "???"; if ( !irq_desc_initialized(desc) ) continue; @@ -1145,21 +1145,30 @@ static void dump_msi(unsigned char key) switch ( entry->msi_attrib.type ) { - case PCI_CAP_ID_MSI: type = ' '; break; - case PCI_CAP_ID_MSIX: type = 'X'; break; - default: type = '?'; break; + case PCI_CAP_ID_MSI: type = "MSI"; break; + case PCI_CAP_ID_MSIX: type = "MSI-X"; break; + case 0: + switch ( entry->msi_attrib.pos ) + { + case MSI_TYPE_HPET: type = "HPET"; break; + case MSI_TYPE_IOMMU: type = "IOMMU"; break; + } + break; } data = entry->msg.data; addr = entry->msg.address_lo; dest32 = entry->msg.dest32; attr = entry->msi_attrib; - mask = msi_get_mask_bit(entry); + if ( entry->msi_attrib.type ) + mask = msi_get_mask_bit(entry) ? '1' : '0'; + else + mask = '?'; spin_unlock_irqrestore(&desc->lock, flags); - printk(" MSI%c %4u vec=%02x%7s%6s%3sassert%5s%7s" - " dest=%08x mask=%d/%d/%d\n", + printk(" %-6s%4u vec=%02x%7s%6s%3sassert%5s%7s" + " dest=%08x mask=%d/%d/%c\n", type, irq, (data & MSI_DATA_VECTOR_MASK) >> MSI_DATA_VECTOR_SHIFT, data & MSI_DATA_DELIVERY_LOWPRI ? "lowest" : "fixed", --- a/xen/include/asm-x86/msi.h +++ b/xen/include/asm-x86/msi.h @@ -109,6 +109,14 @@ struct msi_desc { int remap_index; /* index in interrupt remapping table */ }; +/* + * Values stored into msi_desc.msi_attrib.pos for non-PCI devices + * (msi_desc.msi_attrib.type is zero): + */ +#define MSI_TYPE_UNKNOWN 0 +#define MSI_TYPE_HPET 1 +#define MSI_TYPE_IOMMU 2 + int msi_maskable_irq(const struct msi_desc *); int msi_free_irq(struct msi_desc *entry);