diff options
Diffstat (limited to 'hw/intc')
| -rw-r--r-- | hw/intc/apic.c | 42 | ||||
| -rw-r--r-- | hw/intc/arm_gic.c | 2 | ||||
| -rw-r--r-- | hw/intc/arm_gicv3_its_kvm.c | 2 | ||||
| -rw-r--r-- | hw/intc/armv7m_nvic.c | 19 | ||||
| -rw-r--r-- | hw/intc/trace-events | 1 |
5 files changed, 40 insertions, 26 deletions
diff --git a/hw/intc/apic.c b/hw/intc/apic.c index 6fda52b86c..97ffdd820f 100644 --- a/hw/intc/apic.c +++ b/hw/intc/apic.c @@ -650,31 +650,17 @@ static void apic_timer(void *opaque) apic_timer_update(s, s->next_time); } -static uint32_t apic_mem_readb(void *opaque, hwaddr addr) -{ - return 0; -} - -static uint32_t apic_mem_readw(void *opaque, hwaddr addr) -{ - return 0; -} - -static void apic_mem_writeb(void *opaque, hwaddr addr, uint32_t val) -{ -} - -static void apic_mem_writew(void *opaque, hwaddr addr, uint32_t val) -{ -} - -static uint32_t apic_mem_readl(void *opaque, hwaddr addr) +static uint64_t apic_mem_read(void *opaque, hwaddr addr, unsigned size) { DeviceState *dev; APICCommonState *s; uint32_t val; int index; + if (size < 4) { + return 0; + } + dev = cpu_get_current_apic(); if (!dev) { return 0; @@ -765,11 +751,17 @@ static void apic_send_msi(MSIMessage *msi) apic_deliver_irq(dest, dest_mode, delivery, vector, trigger_mode); } -static void apic_mem_writel(void *opaque, hwaddr addr, uint32_t val) +static void apic_mem_write(void *opaque, hwaddr addr, uint64_t val, + unsigned size) { DeviceState *dev; APICCommonState *s; int index = (addr >> 4) & 0xff; + + if (size < 4) { + return; + } + if (addr > 0xfff || !index) { /* MSI and MMIO APIC are at the same memory location, * but actually not on the global bus: MSI is on PCI bus @@ -880,10 +872,12 @@ static void apic_post_load(APICCommonState *s) } static const MemoryRegionOps apic_io_ops = { - .old_mmio = { - .read = { apic_mem_readb, apic_mem_readw, apic_mem_readl, }, - .write = { apic_mem_writeb, apic_mem_writew, apic_mem_writel, }, - }, + .read = apic_mem_read, + .write = apic_mem_write, + .impl.min_access_size = 1, + .impl.max_access_size = 4, + .valid.min_access_size = 1, + .valid.max_access_size = 4, .endianness = DEVICE_NATIVE_ENDIAN, }; diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c index c1b35fc1ee..542b4b93ea 100644 --- a/hw/intc/arm_gic.c +++ b/hw/intc/arm_gic.c @@ -2084,7 +2084,7 @@ static void arm_gic_realize(DeviceState *dev, Error **errp) for (i = 0; i < s->num_cpu; i++) { memory_region_init_io(&s->vifaceiomem[i + 1], OBJECT(s), &gic_viface_ops, &s->backref[i], - "gic_viface", 0x1000); + "gic_viface", 0x200); sysbus_init_mmio(sbd, &s->vifaceiomem[i + 1]); } } diff --git a/hw/intc/arm_gicv3_its_kvm.c b/hw/intc/arm_gicv3_its_kvm.c index 271ebe461c..01573abb48 100644 --- a/hw/intc/arm_gicv3_its_kvm.c +++ b/hw/intc/arm_gicv3_its_kvm.c @@ -211,7 +211,7 @@ static void kvm_arm_its_reset(DeviceState *dev) return; } - error_report("ITS KVM: full reset is not supported by the host kernel"); + warn_report("ITS KVM: full reset is not supported by the host kernel"); if (!kvm_device_check_attr(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_ITS_REGS, GITS_CTLR)) { diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c index 351b69ab40..0d816fdd2c 100644 --- a/hw/intc/armv7m_nvic.c +++ b/hw/intc/armv7m_nvic.c @@ -774,6 +774,24 @@ static void set_irq_level(void *opaque, int n, int level) } } +/* callback when external NMI line is changed */ +static void nvic_nmi_trigger(void *opaque, int n, int level) +{ + NVICState *s = opaque; + + trace_nvic_set_nmi_level(level); + + /* + * The architecture doesn't specify whether NMI should share + * the normal-interrupt behaviour of being resampled on + * exception handler return. We choose not to, so just + * set NMI pending here and don't track the current level. + */ + if (level) { + armv7m_nvic_set_pending(s, ARMV7M_EXCP_NMI, false); + } +} + static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs) { ARMCPU *cpu = s->cpu; @@ -2382,6 +2400,7 @@ static void armv7m_nvic_instance_init(Object *obj) qdev_init_gpio_out_named(dev, &nvic->sysresetreq, "SYSRESETREQ", 1); qdev_init_gpio_in_named(dev, nvic_systick_trigger, "systick-trigger", M_REG_NUM_BANKS); + qdev_init_gpio_in_named(dev, nvic_nmi_trigger, "NMI", 1); } static void armv7m_nvic_class_init(ObjectClass *klass, void *data) diff --git a/hw/intc/trace-events b/hw/intc/trace-events index 81c7c399f7..7769869a13 100644 --- a/hw/intc/trace-events +++ b/hw/intc/trace-events @@ -192,6 +192,7 @@ nvic_acknowledge_irq(int irq, int prio) "NVIC acknowledge IRQ: %d now active (pr nvic_get_pending_irq_info(int irq, bool secure) "NVIC next IRQ %d: targets_secure: %d" nvic_complete_irq(int irq, bool secure) "NVIC complete IRQ %d (secure %d)" nvic_set_irq_level(int irq, int level) "NVIC external irq %d level set to %d" +nvic_set_nmi_level(int level) "NVIC external NMI level set to %d" nvic_sysreg_read(uint64_t addr, uint32_t value, unsigned size) "NVIC sysreg read addr 0x%" PRIx64 " data 0x%" PRIx32 " size %u" nvic_sysreg_write(uint64_t addr, uint32_t value, unsigned size) "NVIC sysreg write addr 0x%" PRIx64 " data 0x%" PRIx32 " size %u" |