summaryrefslogtreecommitdiffstats
path: root/hw/intc/armv7m_nvic.c
diff options
context:
space:
mode:
Diffstat (limited to 'hw/intc/armv7m_nvic.c')
-rw-r--r--hw/intc/armv7m_nvic.c274
1 files changed, 4 insertions, 270 deletions
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
index 1e7ddcb94c..13df002ce4 100644
--- a/hw/intc/armv7m_nvic.c
+++ b/hw/intc/armv7m_nvic.c
@@ -2470,172 +2470,6 @@ static const MemoryRegionOps nvic_sysreg_ops = {
.endianness = DEVICE_NATIVE_ENDIAN,
};
-static MemTxResult nvic_sysreg_ns_write(void *opaque, hwaddr addr,
- uint64_t value, unsigned size,
- MemTxAttrs attrs)
-{
- MemoryRegion *mr = opaque;
-
- if (attrs.secure) {
- /* S accesses to the alias act like NS accesses to the real region */
- attrs.secure = 0;
- return memory_region_dispatch_write(mr, addr, value,
- size_memop(size) | MO_TE, attrs);
- } else {
- /* NS attrs are RAZ/WI for privileged, and BusFault for user */
- if (attrs.user) {
- return MEMTX_ERROR;
- }
- return MEMTX_OK;
- }
-}
-
-static MemTxResult nvic_sysreg_ns_read(void *opaque, hwaddr addr,
- uint64_t *data, unsigned size,
- MemTxAttrs attrs)
-{
- MemoryRegion *mr = opaque;
-
- if (attrs.secure) {
- /* S accesses to the alias act like NS accesses to the real region */
- attrs.secure = 0;
- return memory_region_dispatch_read(mr, addr, data,
- size_memop(size) | MO_TE, attrs);
- } else {
- /* NS attrs are RAZ/WI for privileged, and BusFault for user */
- if (attrs.user) {
- return MEMTX_ERROR;
- }
- *data = 0;
- return MEMTX_OK;
- }
-}
-
-static const MemoryRegionOps nvic_sysreg_ns_ops = {
- .read_with_attrs = nvic_sysreg_ns_read,
- .write_with_attrs = nvic_sysreg_ns_write,
- .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
-static MemTxResult nvic_systick_write(void *opaque, hwaddr addr,
- uint64_t value, unsigned size,
- MemTxAttrs attrs)
-{
- NVICState *s = opaque;
- MemoryRegion *mr;
-
- /* Direct the access to the correct systick */
- mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->systick[attrs.secure]), 0);
- return memory_region_dispatch_write(mr, addr, value,
- size_memop(size) | MO_TE, attrs);
-}
-
-static MemTxResult nvic_systick_read(void *opaque, hwaddr addr,
- uint64_t *data, unsigned size,
- MemTxAttrs attrs)
-{
- NVICState *s = opaque;
- MemoryRegion *mr;
-
- /* Direct the access to the correct systick */
- mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->systick[attrs.secure]), 0);
- return memory_region_dispatch_read(mr, addr, data, size_memop(size) | MO_TE,
- attrs);
-}
-
-static const MemoryRegionOps nvic_systick_ops = {
- .read_with_attrs = nvic_systick_read,
- .write_with_attrs = nvic_systick_write,
- .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
-
-static MemTxResult ras_read(void *opaque, hwaddr addr,
- uint64_t *data, unsigned size,
- MemTxAttrs attrs)
-{
- if (attrs.user) {
- return MEMTX_ERROR;
- }
-
- switch (addr) {
- case 0xe10: /* ERRIIDR */
- /* architect field = Arm; product/variant/revision 0 */
- *data = 0x43b;
- break;
- case 0xfc8: /* ERRDEVID */
- /* Minimal RAS: we implement 0 error record indexes */
- *data = 0;
- break;
- default:
- qemu_log_mask(LOG_UNIMP, "Read RAS register offset 0x%x\n",
- (uint32_t)addr);
- *data = 0;
- break;
- }
- return MEMTX_OK;
-}
-
-static MemTxResult ras_write(void *opaque, hwaddr addr,
- uint64_t value, unsigned size,
- MemTxAttrs attrs)
-{
- if (attrs.user) {
- return MEMTX_ERROR;
- }
-
- switch (addr) {
- default:
- qemu_log_mask(LOG_UNIMP, "Write to RAS register offset 0x%x\n",
- (uint32_t)addr);
- break;
- }
- return MEMTX_OK;
-}
-
-static const MemoryRegionOps ras_ops = {
- .read_with_attrs = ras_read,
- .write_with_attrs = ras_write,
- .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
-/*
- * Unassigned portions of the PPB space are RAZ/WI for privileged
- * accesses, and fault for non-privileged accesses.
- */
-static MemTxResult ppb_default_read(void *opaque, hwaddr addr,
- uint64_t *data, unsigned size,
- MemTxAttrs attrs)
-{
- qemu_log_mask(LOG_UNIMP, "Read of unassigned area of PPB: offset 0x%x\n",
- (uint32_t)addr);
- if (attrs.user) {
- return MEMTX_ERROR;
- }
- *data = 0;
- return MEMTX_OK;
-}
-
-static MemTxResult ppb_default_write(void *opaque, hwaddr addr,
- uint64_t value, unsigned size,
- MemTxAttrs attrs)
-{
- qemu_log_mask(LOG_UNIMP, "Write of unassigned area of PPB: offset 0x%x\n",
- (uint32_t)addr);
- if (attrs.user) {
- return MEMTX_ERROR;
- }
- return MEMTX_OK;
-}
-
-static const MemoryRegionOps ppb_default_ops = {
- .read_with_attrs = ppb_default_read,
- .write_with_attrs = ppb_default_write,
- .endianness = DEVICE_NATIVE_ENDIAN,
- .valid.min_access_size = 1,
- .valid.max_access_size = 8,
-};
-
static int nvic_post_load(void *opaque, int version_id)
{
NVICState *s = opaque;
@@ -2851,108 +2685,14 @@ static void armv7m_nvic_realize(DeviceState *dev, Error **errp)
s->num_prio_bits = arm_feature(&s->cpu->env, ARM_FEATURE_V7) ? 8 : 2;
- if (!sysbus_realize(SYS_BUS_DEVICE(&s->systick[M_REG_NS]), errp)) {
- return;
- }
- sysbus_connect_irq(SYS_BUS_DEVICE(&s->systick[M_REG_NS]), 0,
- qdev_get_gpio_in_named(dev, "systick-trigger",
- M_REG_NS));
-
- if (arm_feature(&s->cpu->env, ARM_FEATURE_M_SECURITY)) {
- /* We couldn't init the secure systick device in instance_init
- * as we didn't know then if the CPU had the security extensions;
- * so we have to do it here.
- */
- object_initialize_child(OBJECT(dev), "systick-reg-s",
- &s->systick[M_REG_S], TYPE_SYSTICK);
-
- if (!sysbus_realize(SYS_BUS_DEVICE(&s->systick[M_REG_S]), errp)) {
- return;
- }
- sysbus_connect_irq(SYS_BUS_DEVICE(&s->systick[M_REG_S]), 0,
- qdev_get_gpio_in_named(dev, "systick-trigger",
- M_REG_S));
- }
-
/*
- * This device provides a single sysbus memory region which
- * represents the whole of the "System PPB" space. This is the
- * range from 0xe0000000 to 0xe00fffff and includes the NVIC,
- * the System Control Space (system registers), the systick timer,
- * and for CPUs with the Security extension an NS banked version
- * of all of these.
- *
- * The default behaviour for unimplemented registers/ranges
- * (for instance the Data Watchpoint and Trace unit at 0xe0001000)
- * is to RAZ/WI for privileged access and BusFault for non-privileged
- * access.
- *
- * The NVIC and System Control Space (SCS) starts at 0xe000e000
- * and looks like this:
- * 0x004 - ICTR
- * 0x010 - 0xff - systick
- * 0x100..0x7ec - NVIC
- * 0x7f0..0xcff - Reserved
- * 0xd00..0xd3c - SCS registers
- * 0xd40..0xeff - Reserved or Not implemented
- * 0xf00 - STIR
- *
- * Some registers within this space are banked between security states.
- * In v8M there is a second range 0xe002e000..0xe002efff which is the
- * NonSecure alias SCS; secure accesses to this behave like NS accesses
- * to the main SCS range, and non-secure accesses (including when
- * the security extension is not implemented) are RAZ/WI.
- * Note that both the main SCS range and the alias range are defined
- * to be exempt from memory attribution (R_BLJT) and so the memory
- * transaction attribute always matches the current CPU security
- * state (attrs.secure == env->v7m.secure). In the nvic_sysreg_ns_ops
- * wrappers we change attrs.secure to indicate the NS access; so
- * generally code determining which banked register to use should
- * use attrs.secure; code determining actual behaviour of the system
- * should use env->v7m.secure.
- *
- * The container covers the whole PPB space. Within it the priority
- * of overlapping regions is:
- * - default region (for RAZ/WI and BusFault) : -1
- * - system register regions : 0
- * - systick : 1
- * This is because the systick device is a small block of registers
- * in the middle of the other system control registers.
+ * This device provides a single memory region which covers the
+ * sysreg/NVIC registers from 0xE000E000 .. 0xE000EFFF, with the
+ * exception of the systick timer registers 0xE000E010 .. 0xE000E0FF.
*/
- memory_region_init(&s->container, OBJECT(s), "nvic", 0x100000);
- memory_region_init_io(&s->defaultmem, OBJECT(s), &ppb_default_ops, s,
- "nvic-default", 0x100000);
- memory_region_add_subregion_overlap(&s->container, 0, &s->defaultmem, -1);
memory_region_init_io(&s->sysregmem, OBJECT(s), &nvic_sysreg_ops, s,
"nvic_sysregs", 0x1000);
- memory_region_add_subregion(&s->container, 0xe000, &s->sysregmem);
-
- memory_region_init_io(&s->systickmem, OBJECT(s),
- &nvic_systick_ops, s,
- "nvic_systick", 0xe0);
-
- memory_region_add_subregion_overlap(&s->container, 0xe010,
- &s->systickmem, 1);
-
- if (arm_feature(&s->cpu->env, ARM_FEATURE_V8)) {
- memory_region_init_io(&s->sysreg_ns_mem, OBJECT(s),
- &nvic_sysreg_ns_ops, &s->sysregmem,
- "nvic_sysregs_ns", 0x1000);
- memory_region_add_subregion(&s->container, 0x2e000, &s->sysreg_ns_mem);
- memory_region_init_io(&s->systick_ns_mem, OBJECT(s),
- &nvic_sysreg_ns_ops, &s->systickmem,
- "nvic_systick_ns", 0xe0);
- memory_region_add_subregion_overlap(&s->container, 0x2e010,
- &s->systick_ns_mem, 1);
- }
-
- if (cpu_isar_feature(aa32_ras, s->cpu)) {
- memory_region_init_io(&s->ras_mem, OBJECT(s),
- &ras_ops, s, "nvic_ras", 0x1000);
- memory_region_add_subregion(&s->container, 0x5000, &s->ras_mem);
- }
-
- sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->container);
+ sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->sysregmem);
}
static void armv7m_nvic_instance_init(Object *obj)
@@ -2961,12 +2701,6 @@ static void armv7m_nvic_instance_init(Object *obj)
NVICState *nvic = NVIC(obj);
SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
- object_initialize_child(obj, "systick-reg-ns", &nvic->systick[M_REG_NS],
- TYPE_SYSTICK);
- /* We can't initialize the secure systick here, as we don't know
- * yet if we need it.
- */
-
sysbus_init_irq(sbd, &nvic->excpout);
qdev_init_gpio_out_named(dev, &nvic->sysresetreq, "SYSRESETREQ", 1);
qdev_init_gpio_in_named(dev, nvic_systick_trigger, "systick-trigger",