[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH WIP v1 01/10] xen: arm: Add debug keyhandler to dump the physical GIC state.
Rename the existing gic_dump_info to gic_dump_info_guest reduce confusion. Signed-off-by: Ian Campbell <ian.campbell@xxxxxxxxxx> --- v2: s/gic_dump_info/gic_dump_info_guest/ --- xen/arch/arm/domain.c | 2 +- xen/arch/arm/gic-v2.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++- xen/arch/arm/gic-v3.c | 5 ++-- xen/arch/arm/gic.c | 25 ++++++++++++++++-- xen/include/asm-arm/gic.h | 6 +++-- 5 files changed, 96 insertions(+), 8 deletions(-) diff --git a/xen/arch/arm/domain.c b/xen/arch/arm/domain.c index fdba081..bec1082 100644 --- a/xen/arch/arm/domain.c +++ b/xen/arch/arm/domain.c @@ -803,7 +803,7 @@ long arch_do_vcpu_op(int cmd, struct vcpu *v, XEN_GUEST_HANDLE_PARAM(void) arg) void arch_dump_vcpu_info(struct vcpu *v) { - gic_dump_info(v); + gic_dump_info_guest(v); } void vcpu_mark_events_pending(struct vcpu *v) diff --git a/xen/arch/arm/gic-v2.c b/xen/arch/arm/gic-v2.c index 20cdbc9..2f5d33b 100644 --- a/xen/arch/arm/gic-v2.c +++ b/xen/arch/arm/gic-v2.c @@ -94,6 +94,11 @@ static inline void writel_gicd(uint32_t val, unsigned int offset) writel_relaxed(val, gicv2.map_dbase + offset); } +static inline uint8_t readb_gicd(unsigned int offset) +{ + return readb_relaxed(gicv2.map_dbase + offset); +} + static inline uint32_t readl_gicd(unsigned int offset) { return readl_relaxed(gicv2.map_dbase + offset); @@ -168,7 +173,7 @@ static void gicv2_restore_state(const struct vcpu *v) writel_gich(GICH_HCR_EN, GICH_HCR); } -static void gicv2_dump_state(const struct vcpu *v) +static void gicv2_dump_state_guest(const struct vcpu *v) { int i; @@ -651,6 +656,64 @@ static int gicv2_make_dt_node(const struct domain *d, return res; } +static void gicv2_dump_state(void) +{ + int irq; + + for ( irq = 0; irq < gicv2_info.nr_lines; irq++ ) + { + const char *type; + int type_nr, enable, pend, active, priority, target; + struct irq_desc *desc = irq_to_desc(irq); + uint32_t wordreg; + + target = readb_gicd(GICD_ITARGETSR + irq); + priority = readb_gicd(GICD_IPRIORITYR + irq); + + switch ( irq ) + { + case 0 ... 15: + type = "SGI"; + type_nr = irq; + target = 0x00; /* these are per-CPU */ + break; + case 16 ... 31: + type = "PPI"; + type_nr = irq - 16; + break; + default: + type = "SPI"; + type_nr = irq - 32; + break; + } + + wordreg = readl_gicd(GICD_ISENABLER + (irq / 32) * 4); + enable = !!(wordreg & (1u << (irq % 32))); + wordreg = readl_gicd(GICD_ISPENDR + (irq / 32) * 4); + pend = !!(wordreg & (1u << (irq % 32))); + wordreg = readl_gicd(GICD_ISACTIVER + (irq / 32) * 4); + active = !!(wordreg & (1u << (irq % 32))); + + printk("IRQ%03d %s%03d: %c%c%c pri:%02x tgt:%02x ", + irq, type, type_nr, + enable ? 'e' : '-', + pend ? 'p' : '-', + active ? 'a' : '-', + priority, target); + + if ( desc->status & IRQ_GUEST ) + { + struct domain *d = desc->action->dev_id; + printk("dom%d %s", d->domain_id, desc->action->name); + } + else + { + printk("Xen"); + } + printk("\n"); + } +} + /* XXX different for level vs edge */ static hw_irq_controller gicv2_host_irq_type = { .typename = "gic-v2", @@ -680,6 +743,7 @@ const static struct gic_hw_operations gicv2_ops = { .save_state = gicv2_save_state, .restore_state = gicv2_restore_state, .dump_state = gicv2_dump_state, + .dump_state_guest = gicv2_dump_state_guest, .gicv_setup = gicv2v_setup, .gic_host_irq_type = &gicv2_host_irq_type, .gic_guest_irq_type = &gicv2_guest_irq_type, diff --git a/xen/arch/arm/gic-v3.c b/xen/arch/arm/gic-v3.c index ab80670..4516304 100644 --- a/xen/arch/arm/gic-v3.c +++ b/xen/arch/arm/gic-v3.c @@ -394,7 +394,7 @@ static void gicv3_restore_state(const struct vcpu *v) dsb(sy); } -static void gicv3_dump_state(const struct vcpu *v) +static void gicv3_dump_state_guest(const struct vcpu *v) { int i; @@ -1177,7 +1177,8 @@ static const struct gic_hw_operations gicv3_ops = { .info = &gicv3_info, .save_state = gicv3_save_state, .restore_state = gicv3_restore_state, - .dump_state = gicv3_dump_state, + .dump_state = NULL, + .dump_state_guest = gicv3_dump_state_guest, .gicv_setup = gicv_v3_init, .gic_host_irq_type = &gicv3_host_irq_type, .gic_guest_irq_type = &gicv3_guest_irq_type, diff --git a/xen/arch/arm/gic.c b/xen/arch/arm/gic.c index 390c8b0..6c5581b 100644 --- a/xen/arch/arm/gic.c +++ b/xen/arch/arm/gic.c @@ -27,6 +27,7 @@ #include <xen/softirq.h> #include <xen/list.h> #include <xen/device_tree.h> +#include <xen/keyhandler.h> #include <asm/p2m.h> #include <asm/domain.h> #include <asm/platform.h> @@ -163,6 +164,24 @@ int gic_irq_xlate(const u32 *intspec, unsigned int intsize, return 0; } + +static void do_dump_gic(unsigned char key) +{ + if ( gic_hw_ops->dump_state ) + { + printk("'%c' pressed -> dumping GIC state\n", key); + gic_hw_ops->dump_state(); + } + else + printk("'%c' pressed -> no GIC dump state handler\n", key); +} + +static struct keyhandler dump_gic_keyhandler = { + .irq_callback = 0, + .u.fn = do_dump_gic, + .desc = "dump GIC state" +}; + /* Set up the GIC */ void __init gic_init(void) { @@ -191,6 +210,8 @@ void __init gic_init(void) /* Clear LR mask for cpu0 */ clear_cpu_lr_mask(); + + register_keyhandler('G', &dump_gic_keyhandler); } void send_SGI_mask(const cpumask_t *cpumask, enum gic_sgi sgi) @@ -609,12 +630,12 @@ static void maintenance_interrupt(int irq, void *dev_id, struct cpu_user_regs *r perfc_incr(maintenance_irqs); } -void gic_dump_info(struct vcpu *v) +void gic_dump_info_guest(struct vcpu *v) { struct pending_irq *p; printk("GICH_LRs (vcpu %d) mask=%"PRIx64"\n", v->vcpu_id, v->arch.lr_mask); - gic_hw_ops->dump_state(v); + gic_hw_ops->dump_state_guest(v); list_for_each_entry ( p, &v->arch.vgic.inflight_irqs, inflight ) { diff --git a/xen/include/asm-arm/gic.h b/xen/include/asm-arm/gic.h index 6f5767f..65a379c 100644 --- a/xen/include/asm-arm/gic.h +++ b/xen/include/asm-arm/gic.h @@ -263,7 +263,7 @@ extern void send_SGI_self(enum gic_sgi sgi); extern void send_SGI_allbutself(enum gic_sgi sgi); /* print useful debug info */ -extern void gic_dump_info(struct vcpu *v); +extern void gic_dump_info_guest(struct vcpu *v); /* Number of interrupt lines */ extern unsigned int gic_number_lines(void); @@ -291,8 +291,10 @@ struct gic_hw_operations { void (*save_state)(struct vcpu *); /* Restore GIC registers */ void (*restore_state)(const struct vcpu *); + /* Dump GIC host register information */ + void (*dump_state)(void); /* Dump GIC LR register information */ - void (*dump_state)(const struct vcpu *); + void (*dump_state_guest)(const struct vcpu *); /* Map MMIO region of GIC */ int (*gicv_setup)(struct domain *); -- 2.1.4 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |