When irqchip in kernel is enabled, the register status of extioi irqchip is in KVM kernel. Here add interrupt status display in user side in order to debug extioi irqchip driver.
Signed-off-by: Bibo Mao <[email protected]> --- hw/intc/loongarch_extioi.c | 58 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/hw/intc/loongarch_extioi.c b/hw/intc/loongarch_extioi.c index 2999740269..06f2aa7b14 100644 --- a/hw/intc/loongarch_extioi.c +++ b/hw/intc/loongarch_extioi.c @@ -10,6 +10,7 @@ #include "qemu/log.h" #include "qapi/error.h" #include "hw/core/irq.h" +#include "hw/intc/intc.h" #include "hw/loongarch/virt.h" #include "system/address-spaces.h" #include "system/kvm.h" @@ -420,11 +421,63 @@ static int vmstate_extioi_post_load(void *opaque, int version_id) return 0; } +static void loongarch_extioi_print_info(InterruptStatsProvider *obj, + GString *buf) +{ + LoongArchExtIOICommonState *s = LOONGARCH_EXTIOI_COMMON(obj); + uint64_t *val; + unsigned long irq; + ExtIOICore *core; + int i; + + vmstate_extioi_pre_save(s); + g_string_append_printf(buf, "%s:\n", object_get_typename(OBJECT(obj))); + + val = (uint64_t *)s->isr; + g_string_append_printf(buf, " ISR 0x%016"PRIx64" 0x%016"PRIx64 + " 0x%016"PRIx64" 0x%016"PRIx64"\n", + *val, *(val + 1), *(val + 2), *(val + 3)); + val = (uint64_t *)s->enable; + g_string_append_printf(buf, " ENABLE 0x%016"PRIx64" 0x%016"PRIx64 + " 0x%016"PRIx64" 0x%016"PRIx64"\n", + *val, *(val + 1), *(val + 2), *(val + 3)); + val = (uint64_t *)s->ipmap; + g_string_append_printf(buf, " IPMAP 0x%016"PRIx64"\n", *val); + + val = (uint64_t *)s->coremap; + for (i = 0; i < EXTIOI_IRQS; i += 32) { + g_string_append_printf(buf, " COREMAP 0x%016"PRIx64" 0x%016"PRIx64 + " 0x%016"PRIx64" 0x%016"PRIx64"\n", + *val, *(val + 1), *(val + 2), *(val + 3)); + val += 4; + } + + core = s->cpu; + for (i = 0; i < s->num_cpu; i++, core++) { + if (!core->cpu) { + continue; + } + + irq = find_first_bit((unsigned long *)core->coreisr, EXTIOI_IRQS); + /* No pending IRQ */ + if (irq == EXTIOI_IRQS) { + continue; + } + + val = (uint64_t *)core->coreisr; + g_string_append_printf(buf, " CPU[%d] ISR 0x%016"PRIx64" 0x%016"PRIx64 + " 0x%016"PRIx64" 0x%016"PRIx64"\n", + i, *val, *(val + 1), *(val + 2), + *(val + 3)); + } +} + static void loongarch_extioi_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); LoongArchExtIOIClass *lec = LOONGARCH_EXTIOI_CLASS(klass); LoongArchExtIOICommonClass *lecc = LOONGARCH_EXTIOI_COMMON_CLASS(klass); + InterruptStatsProviderClass *ic = INTERRUPT_STATS_PROVIDER_CLASS(klass); ResettableClass *rc = RESETTABLE_CLASS(klass); device_class_set_parent_realize(dc, loongarch_extioi_realize, @@ -433,6 +486,7 @@ static void loongarch_extioi_class_init(ObjectClass *klass, const void *data) NULL, &lec->parent_phases); lecc->pre_save = vmstate_extioi_pre_save; lecc->post_load = vmstate_extioi_post_load; + ic->print_info = loongarch_extioi_print_info; } static const TypeInfo loongarch_extioi_types[] = { @@ -442,6 +496,10 @@ static const TypeInfo loongarch_extioi_types[] = { .instance_size = sizeof(LoongArchExtIOIState), .class_size = sizeof(LoongArchExtIOIClass), .class_init = loongarch_extioi_class_init, + .interfaces = (const InterfaceInfo[]) { + { TYPE_INTERRUPT_STATS_PROVIDER }, + { } + }, } }; -- 2.54.0
