xref: /qemu/hw/arm/smmuv3.c (revision 6a736033d343e0e5774849fa0eef88f2582c364a)
110a83cb9SPrem Mallappa /*
210a83cb9SPrem Mallappa  * Copyright (C) 2014-2016 Broadcom Corporation
310a83cb9SPrem Mallappa  * Copyright (c) 2017 Red Hat, Inc.
410a83cb9SPrem Mallappa  * Written by Prem Mallappa, Eric Auger
510a83cb9SPrem Mallappa  *
610a83cb9SPrem Mallappa  * This program is free software; you can redistribute it and/or modify
710a83cb9SPrem Mallappa  * it under the terms of the GNU General Public License version 2 as
810a83cb9SPrem Mallappa  * published by the Free Software Foundation.
910a83cb9SPrem Mallappa  *
1010a83cb9SPrem Mallappa  * This program is distributed in the hope that it will be useful,
1110a83cb9SPrem Mallappa  * but WITHOUT ANY WARRANTY; without even the implied warranty of
1210a83cb9SPrem Mallappa  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1310a83cb9SPrem Mallappa  * GNU General Public License for more details.
1410a83cb9SPrem Mallappa  *
1510a83cb9SPrem Mallappa  * You should have received a copy of the GNU General Public License along
1610a83cb9SPrem Mallappa  * with this program; if not, see <http://www.gnu.org/licenses/>.
1710a83cb9SPrem Mallappa  */
1810a83cb9SPrem Mallappa 
1910a83cb9SPrem Mallappa #include "qemu/osdep.h"
2010a83cb9SPrem Mallappa #include "hw/boards.h"
2110a83cb9SPrem Mallappa #include "sysemu/sysemu.h"
2210a83cb9SPrem Mallappa #include "hw/sysbus.h"
2310a83cb9SPrem Mallappa #include "hw/qdev-core.h"
2410a83cb9SPrem Mallappa #include "hw/pci/pci.h"
2510a83cb9SPrem Mallappa #include "exec/address-spaces.h"
2610a83cb9SPrem Mallappa #include "trace.h"
2710a83cb9SPrem Mallappa #include "qemu/log.h"
2810a83cb9SPrem Mallappa #include "qemu/error-report.h"
2910a83cb9SPrem Mallappa #include "qapi/error.h"
3010a83cb9SPrem Mallappa 
3110a83cb9SPrem Mallappa #include "hw/arm/smmuv3.h"
3210a83cb9SPrem Mallappa #include "smmuv3-internal.h"
3310a83cb9SPrem Mallappa 
34*6a736033SEric Auger /**
35*6a736033SEric Auger  * smmuv3_trigger_irq - pulse @irq if enabled and update
36*6a736033SEric Auger  * GERROR register in case of GERROR interrupt
37*6a736033SEric Auger  *
38*6a736033SEric Auger  * @irq: irq type
39*6a736033SEric Auger  * @gerror_mask: mask of gerrors to toggle (relevant if @irq is GERROR)
40*6a736033SEric Auger  */
41*6a736033SEric Auger void smmuv3_trigger_irq(SMMUv3State *s, SMMUIrq irq, uint32_t gerror_mask)
42*6a736033SEric Auger {
43*6a736033SEric Auger 
44*6a736033SEric Auger     bool pulse = false;
45*6a736033SEric Auger 
46*6a736033SEric Auger     switch (irq) {
47*6a736033SEric Auger     case SMMU_IRQ_EVTQ:
48*6a736033SEric Auger         pulse = smmuv3_eventq_irq_enabled(s);
49*6a736033SEric Auger         break;
50*6a736033SEric Auger     case SMMU_IRQ_PRIQ:
51*6a736033SEric Auger         qemu_log_mask(LOG_UNIMP, "PRI not yet supported\n");
52*6a736033SEric Auger         break;
53*6a736033SEric Auger     case SMMU_IRQ_CMD_SYNC:
54*6a736033SEric Auger         pulse = true;
55*6a736033SEric Auger         break;
56*6a736033SEric Auger     case SMMU_IRQ_GERROR:
57*6a736033SEric Auger     {
58*6a736033SEric Auger         uint32_t pending = s->gerror ^ s->gerrorn;
59*6a736033SEric Auger         uint32_t new_gerrors = ~pending & gerror_mask;
60*6a736033SEric Auger 
61*6a736033SEric Auger         if (!new_gerrors) {
62*6a736033SEric Auger             /* only toggle non pending errors */
63*6a736033SEric Auger             return;
64*6a736033SEric Auger         }
65*6a736033SEric Auger         s->gerror ^= new_gerrors;
66*6a736033SEric Auger         trace_smmuv3_write_gerror(new_gerrors, s->gerror);
67*6a736033SEric Auger 
68*6a736033SEric Auger         pulse = smmuv3_gerror_irq_enabled(s);
69*6a736033SEric Auger         break;
70*6a736033SEric Auger     }
71*6a736033SEric Auger     }
72*6a736033SEric Auger     if (pulse) {
73*6a736033SEric Auger             trace_smmuv3_trigger_irq(irq);
74*6a736033SEric Auger             qemu_irq_pulse(s->irq[irq]);
75*6a736033SEric Auger     }
76*6a736033SEric Auger }
77*6a736033SEric Auger 
78*6a736033SEric Auger void smmuv3_write_gerrorn(SMMUv3State *s, uint32_t new_gerrorn)
79*6a736033SEric Auger {
80*6a736033SEric Auger     uint32_t pending = s->gerror ^ s->gerrorn;
81*6a736033SEric Auger     uint32_t toggled = s->gerrorn ^ new_gerrorn;
82*6a736033SEric Auger 
83*6a736033SEric Auger     if (toggled & ~pending) {
84*6a736033SEric Auger         qemu_log_mask(LOG_GUEST_ERROR,
85*6a736033SEric Auger                       "guest toggles non pending errors = 0x%x\n",
86*6a736033SEric Auger                       toggled & ~pending);
87*6a736033SEric Auger     }
88*6a736033SEric Auger 
89*6a736033SEric Auger     /*
90*6a736033SEric Auger      * We do not raise any error in case guest toggles bits corresponding
91*6a736033SEric Auger      * to not active IRQs (CONSTRAINED UNPREDICTABLE)
92*6a736033SEric Auger      */
93*6a736033SEric Auger     s->gerrorn = new_gerrorn;
94*6a736033SEric Auger 
95*6a736033SEric Auger     trace_smmuv3_write_gerrorn(toggled & pending, s->gerrorn);
96*6a736033SEric Auger }
97*6a736033SEric Auger 
9810a83cb9SPrem Mallappa static void smmuv3_init_regs(SMMUv3State *s)
9910a83cb9SPrem Mallappa {
10010a83cb9SPrem Mallappa     /**
10110a83cb9SPrem Mallappa      * IDR0: stage1 only, AArch64 only, coherent access, 16b ASID,
10210a83cb9SPrem Mallappa      *       multi-level stream table
10310a83cb9SPrem Mallappa      */
10410a83cb9SPrem Mallappa     s->idr[0] = FIELD_DP32(s->idr[0], IDR0, S1P, 1); /* stage 1 supported */
10510a83cb9SPrem Mallappa     s->idr[0] = FIELD_DP32(s->idr[0], IDR0, TTF, 2); /* AArch64 PTW only */
10610a83cb9SPrem Mallappa     s->idr[0] = FIELD_DP32(s->idr[0], IDR0, COHACC, 1); /* IO coherent */
10710a83cb9SPrem Mallappa     s->idr[0] = FIELD_DP32(s->idr[0], IDR0, ASID16, 1); /* 16-bit ASID */
10810a83cb9SPrem Mallappa     s->idr[0] = FIELD_DP32(s->idr[0], IDR0, TTENDIAN, 2); /* little endian */
10910a83cb9SPrem Mallappa     s->idr[0] = FIELD_DP32(s->idr[0], IDR0, STALL_MODEL, 1); /* No stall */
11010a83cb9SPrem Mallappa     /* terminated transaction will always be aborted/error returned */
11110a83cb9SPrem Mallappa     s->idr[0] = FIELD_DP32(s->idr[0], IDR0, TERM_MODEL, 1);
11210a83cb9SPrem Mallappa     /* 2-level stream table supported */
11310a83cb9SPrem Mallappa     s->idr[0] = FIELD_DP32(s->idr[0], IDR0, STLEVEL, 1);
11410a83cb9SPrem Mallappa 
11510a83cb9SPrem Mallappa     s->idr[1] = FIELD_DP32(s->idr[1], IDR1, SIDSIZE, SMMU_IDR1_SIDSIZE);
11610a83cb9SPrem Mallappa     s->idr[1] = FIELD_DP32(s->idr[1], IDR1, EVENTQS, SMMU_EVENTQS);
11710a83cb9SPrem Mallappa     s->idr[1] = FIELD_DP32(s->idr[1], IDR1, CMDQS,   SMMU_CMDQS);
11810a83cb9SPrem Mallappa 
11910a83cb9SPrem Mallappa    /* 4K and 64K granule support */
12010a83cb9SPrem Mallappa     s->idr[5] = FIELD_DP32(s->idr[5], IDR5, GRAN4K, 1);
12110a83cb9SPrem Mallappa     s->idr[5] = FIELD_DP32(s->idr[5], IDR5, GRAN64K, 1);
12210a83cb9SPrem Mallappa     s->idr[5] = FIELD_DP32(s->idr[5], IDR5, OAS, SMMU_IDR5_OAS); /* 44 bits */
12310a83cb9SPrem Mallappa 
12410a83cb9SPrem Mallappa     s->cmdq.base = deposit64(s->cmdq.base, 0, 5, SMMU_CMDQS);
12510a83cb9SPrem Mallappa     s->cmdq.prod = 0;
12610a83cb9SPrem Mallappa     s->cmdq.cons = 0;
12710a83cb9SPrem Mallappa     s->cmdq.entry_size = sizeof(struct Cmd);
12810a83cb9SPrem Mallappa     s->eventq.base = deposit64(s->eventq.base, 0, 5, SMMU_EVENTQS);
12910a83cb9SPrem Mallappa     s->eventq.prod = 0;
13010a83cb9SPrem Mallappa     s->eventq.cons = 0;
13110a83cb9SPrem Mallappa     s->eventq.entry_size = sizeof(struct Evt);
13210a83cb9SPrem Mallappa 
13310a83cb9SPrem Mallappa     s->features = 0;
13410a83cb9SPrem Mallappa     s->sid_split = 0;
13510a83cb9SPrem Mallappa }
13610a83cb9SPrem Mallappa 
13710a83cb9SPrem Mallappa static MemTxResult smmu_write_mmio(void *opaque, hwaddr offset, uint64_t data,
13810a83cb9SPrem Mallappa                                    unsigned size, MemTxAttrs attrs)
13910a83cb9SPrem Mallappa {
14010a83cb9SPrem Mallappa     /* not yet implemented */
14110a83cb9SPrem Mallappa     return MEMTX_ERROR;
14210a83cb9SPrem Mallappa }
14310a83cb9SPrem Mallappa 
14410a83cb9SPrem Mallappa static MemTxResult smmu_readll(SMMUv3State *s, hwaddr offset,
14510a83cb9SPrem Mallappa                                uint64_t *data, MemTxAttrs attrs)
14610a83cb9SPrem Mallappa {
14710a83cb9SPrem Mallappa     switch (offset) {
14810a83cb9SPrem Mallappa     case A_GERROR_IRQ_CFG0:
14910a83cb9SPrem Mallappa         *data = s->gerror_irq_cfg0;
15010a83cb9SPrem Mallappa         return MEMTX_OK;
15110a83cb9SPrem Mallappa     case A_STRTAB_BASE:
15210a83cb9SPrem Mallappa         *data = s->strtab_base;
15310a83cb9SPrem Mallappa         return MEMTX_OK;
15410a83cb9SPrem Mallappa     case A_CMDQ_BASE:
15510a83cb9SPrem Mallappa         *data = s->cmdq.base;
15610a83cb9SPrem Mallappa         return MEMTX_OK;
15710a83cb9SPrem Mallappa     case A_EVENTQ_BASE:
15810a83cb9SPrem Mallappa         *data = s->eventq.base;
15910a83cb9SPrem Mallappa         return MEMTX_OK;
16010a83cb9SPrem Mallappa     default:
16110a83cb9SPrem Mallappa         *data = 0;
16210a83cb9SPrem Mallappa         qemu_log_mask(LOG_UNIMP,
16310a83cb9SPrem Mallappa                       "%s Unexpected 64-bit access to 0x%"PRIx64" (RAZ)\n",
16410a83cb9SPrem Mallappa                       __func__, offset);
16510a83cb9SPrem Mallappa         return MEMTX_OK;
16610a83cb9SPrem Mallappa     }
16710a83cb9SPrem Mallappa }
16810a83cb9SPrem Mallappa 
16910a83cb9SPrem Mallappa static MemTxResult smmu_readl(SMMUv3State *s, hwaddr offset,
17010a83cb9SPrem Mallappa                               uint64_t *data, MemTxAttrs attrs)
17110a83cb9SPrem Mallappa {
17210a83cb9SPrem Mallappa     switch (offset) {
17310a83cb9SPrem Mallappa     case A_IDREGS ... A_IDREGS + 0x1f:
17410a83cb9SPrem Mallappa         *data = smmuv3_idreg(offset - A_IDREGS);
17510a83cb9SPrem Mallappa         return MEMTX_OK;
17610a83cb9SPrem Mallappa     case A_IDR0 ... A_IDR5:
17710a83cb9SPrem Mallappa         *data = s->idr[(offset - A_IDR0) / 4];
17810a83cb9SPrem Mallappa         return MEMTX_OK;
17910a83cb9SPrem Mallappa     case A_IIDR:
18010a83cb9SPrem Mallappa         *data = s->iidr;
18110a83cb9SPrem Mallappa         return MEMTX_OK;
18210a83cb9SPrem Mallappa     case A_CR0:
18310a83cb9SPrem Mallappa         *data = s->cr[0];
18410a83cb9SPrem Mallappa         return MEMTX_OK;
18510a83cb9SPrem Mallappa     case A_CR0ACK:
18610a83cb9SPrem Mallappa         *data = s->cr0ack;
18710a83cb9SPrem Mallappa         return MEMTX_OK;
18810a83cb9SPrem Mallappa     case A_CR1:
18910a83cb9SPrem Mallappa         *data = s->cr[1];
19010a83cb9SPrem Mallappa         return MEMTX_OK;
19110a83cb9SPrem Mallappa     case A_CR2:
19210a83cb9SPrem Mallappa         *data = s->cr[2];
19310a83cb9SPrem Mallappa         return MEMTX_OK;
19410a83cb9SPrem Mallappa     case A_STATUSR:
19510a83cb9SPrem Mallappa         *data = s->statusr;
19610a83cb9SPrem Mallappa         return MEMTX_OK;
19710a83cb9SPrem Mallappa     case A_IRQ_CTRL:
19810a83cb9SPrem Mallappa     case A_IRQ_CTRL_ACK:
19910a83cb9SPrem Mallappa         *data = s->irq_ctrl;
20010a83cb9SPrem Mallappa         return MEMTX_OK;
20110a83cb9SPrem Mallappa     case A_GERROR:
20210a83cb9SPrem Mallappa         *data = s->gerror;
20310a83cb9SPrem Mallappa         return MEMTX_OK;
20410a83cb9SPrem Mallappa     case A_GERRORN:
20510a83cb9SPrem Mallappa         *data = s->gerrorn;
20610a83cb9SPrem Mallappa         return MEMTX_OK;
20710a83cb9SPrem Mallappa     case A_GERROR_IRQ_CFG0: /* 64b */
20810a83cb9SPrem Mallappa         *data = extract64(s->gerror_irq_cfg0, 0, 32);
20910a83cb9SPrem Mallappa         return MEMTX_OK;
21010a83cb9SPrem Mallappa     case A_GERROR_IRQ_CFG0 + 4:
21110a83cb9SPrem Mallappa         *data = extract64(s->gerror_irq_cfg0, 32, 32);
21210a83cb9SPrem Mallappa         return MEMTX_OK;
21310a83cb9SPrem Mallappa     case A_GERROR_IRQ_CFG1:
21410a83cb9SPrem Mallappa         *data = s->gerror_irq_cfg1;
21510a83cb9SPrem Mallappa         return MEMTX_OK;
21610a83cb9SPrem Mallappa     case A_GERROR_IRQ_CFG2:
21710a83cb9SPrem Mallappa         *data = s->gerror_irq_cfg2;
21810a83cb9SPrem Mallappa         return MEMTX_OK;
21910a83cb9SPrem Mallappa     case A_STRTAB_BASE: /* 64b */
22010a83cb9SPrem Mallappa         *data = extract64(s->strtab_base, 0, 32);
22110a83cb9SPrem Mallappa         return MEMTX_OK;
22210a83cb9SPrem Mallappa     case A_STRTAB_BASE + 4: /* 64b */
22310a83cb9SPrem Mallappa         *data = extract64(s->strtab_base, 32, 32);
22410a83cb9SPrem Mallappa         return MEMTX_OK;
22510a83cb9SPrem Mallappa     case A_STRTAB_BASE_CFG:
22610a83cb9SPrem Mallappa         *data = s->strtab_base_cfg;
22710a83cb9SPrem Mallappa         return MEMTX_OK;
22810a83cb9SPrem Mallappa     case A_CMDQ_BASE: /* 64b */
22910a83cb9SPrem Mallappa         *data = extract64(s->cmdq.base, 0, 32);
23010a83cb9SPrem Mallappa         return MEMTX_OK;
23110a83cb9SPrem Mallappa     case A_CMDQ_BASE + 4:
23210a83cb9SPrem Mallappa         *data = extract64(s->cmdq.base, 32, 32);
23310a83cb9SPrem Mallappa         return MEMTX_OK;
23410a83cb9SPrem Mallappa     case A_CMDQ_PROD:
23510a83cb9SPrem Mallappa         *data = s->cmdq.prod;
23610a83cb9SPrem Mallappa         return MEMTX_OK;
23710a83cb9SPrem Mallappa     case A_CMDQ_CONS:
23810a83cb9SPrem Mallappa         *data = s->cmdq.cons;
23910a83cb9SPrem Mallappa         return MEMTX_OK;
24010a83cb9SPrem Mallappa     case A_EVENTQ_BASE: /* 64b */
24110a83cb9SPrem Mallappa         *data = extract64(s->eventq.base, 0, 32);
24210a83cb9SPrem Mallappa         return MEMTX_OK;
24310a83cb9SPrem Mallappa     case A_EVENTQ_BASE + 4: /* 64b */
24410a83cb9SPrem Mallappa         *data = extract64(s->eventq.base, 32, 32);
24510a83cb9SPrem Mallappa         return MEMTX_OK;
24610a83cb9SPrem Mallappa     case A_EVENTQ_PROD:
24710a83cb9SPrem Mallappa         *data = s->eventq.prod;
24810a83cb9SPrem Mallappa         return MEMTX_OK;
24910a83cb9SPrem Mallappa     case A_EVENTQ_CONS:
25010a83cb9SPrem Mallappa         *data = s->eventq.cons;
25110a83cb9SPrem Mallappa         return MEMTX_OK;
25210a83cb9SPrem Mallappa     default:
25310a83cb9SPrem Mallappa         *data = 0;
25410a83cb9SPrem Mallappa         qemu_log_mask(LOG_UNIMP,
25510a83cb9SPrem Mallappa                       "%s unhandled 32-bit access at 0x%"PRIx64" (RAZ)\n",
25610a83cb9SPrem Mallappa                       __func__, offset);
25710a83cb9SPrem Mallappa         return MEMTX_OK;
25810a83cb9SPrem Mallappa     }
25910a83cb9SPrem Mallappa }
26010a83cb9SPrem Mallappa 
26110a83cb9SPrem Mallappa static MemTxResult smmu_read_mmio(void *opaque, hwaddr offset, uint64_t *data,
26210a83cb9SPrem Mallappa                                   unsigned size, MemTxAttrs attrs)
26310a83cb9SPrem Mallappa {
26410a83cb9SPrem Mallappa     SMMUState *sys = opaque;
26510a83cb9SPrem Mallappa     SMMUv3State *s = ARM_SMMUV3(sys);
26610a83cb9SPrem Mallappa     MemTxResult r;
26710a83cb9SPrem Mallappa 
26810a83cb9SPrem Mallappa     /* CONSTRAINED UNPREDICTABLE choice to have page0/1 be exact aliases */
26910a83cb9SPrem Mallappa     offset &= ~0x10000;
27010a83cb9SPrem Mallappa 
27110a83cb9SPrem Mallappa     switch (size) {
27210a83cb9SPrem Mallappa     case 8:
27310a83cb9SPrem Mallappa         r = smmu_readll(s, offset, data, attrs);
27410a83cb9SPrem Mallappa         break;
27510a83cb9SPrem Mallappa     case 4:
27610a83cb9SPrem Mallappa         r = smmu_readl(s, offset, data, attrs);
27710a83cb9SPrem Mallappa         break;
27810a83cb9SPrem Mallappa     default:
27910a83cb9SPrem Mallappa         r = MEMTX_ERROR;
28010a83cb9SPrem Mallappa         break;
28110a83cb9SPrem Mallappa     }
28210a83cb9SPrem Mallappa 
28310a83cb9SPrem Mallappa     trace_smmuv3_read_mmio(offset, *data, size, r);
28410a83cb9SPrem Mallappa     return r;
28510a83cb9SPrem Mallappa }
28610a83cb9SPrem Mallappa 
28710a83cb9SPrem Mallappa static const MemoryRegionOps smmu_mem_ops = {
28810a83cb9SPrem Mallappa     .read_with_attrs = smmu_read_mmio,
28910a83cb9SPrem Mallappa     .write_with_attrs = smmu_write_mmio,
29010a83cb9SPrem Mallappa     .endianness = DEVICE_LITTLE_ENDIAN,
29110a83cb9SPrem Mallappa     .valid = {
29210a83cb9SPrem Mallappa         .min_access_size = 4,
29310a83cb9SPrem Mallappa         .max_access_size = 8,
29410a83cb9SPrem Mallappa     },
29510a83cb9SPrem Mallappa     .impl = {
29610a83cb9SPrem Mallappa         .min_access_size = 4,
29710a83cb9SPrem Mallappa         .max_access_size = 8,
29810a83cb9SPrem Mallappa     },
29910a83cb9SPrem Mallappa };
30010a83cb9SPrem Mallappa 
30110a83cb9SPrem Mallappa static void smmu_init_irq(SMMUv3State *s, SysBusDevice *dev)
30210a83cb9SPrem Mallappa {
30310a83cb9SPrem Mallappa     int i;
30410a83cb9SPrem Mallappa 
30510a83cb9SPrem Mallappa     for (i = 0; i < ARRAY_SIZE(s->irq); i++) {
30610a83cb9SPrem Mallappa         sysbus_init_irq(dev, &s->irq[i]);
30710a83cb9SPrem Mallappa     }
30810a83cb9SPrem Mallappa }
30910a83cb9SPrem Mallappa 
31010a83cb9SPrem Mallappa static void smmu_reset(DeviceState *dev)
31110a83cb9SPrem Mallappa {
31210a83cb9SPrem Mallappa     SMMUv3State *s = ARM_SMMUV3(dev);
31310a83cb9SPrem Mallappa     SMMUv3Class *c = ARM_SMMUV3_GET_CLASS(s);
31410a83cb9SPrem Mallappa 
31510a83cb9SPrem Mallappa     c->parent_reset(dev);
31610a83cb9SPrem Mallappa 
31710a83cb9SPrem Mallappa     smmuv3_init_regs(s);
31810a83cb9SPrem Mallappa }
31910a83cb9SPrem Mallappa 
32010a83cb9SPrem Mallappa static void smmu_realize(DeviceState *d, Error **errp)
32110a83cb9SPrem Mallappa {
32210a83cb9SPrem Mallappa     SMMUState *sys = ARM_SMMU(d);
32310a83cb9SPrem Mallappa     SMMUv3State *s = ARM_SMMUV3(sys);
32410a83cb9SPrem Mallappa     SMMUv3Class *c = ARM_SMMUV3_GET_CLASS(s);
32510a83cb9SPrem Mallappa     SysBusDevice *dev = SYS_BUS_DEVICE(d);
32610a83cb9SPrem Mallappa     Error *local_err = NULL;
32710a83cb9SPrem Mallappa 
32810a83cb9SPrem Mallappa     c->parent_realize(d, &local_err);
32910a83cb9SPrem Mallappa     if (local_err) {
33010a83cb9SPrem Mallappa         error_propagate(errp, local_err);
33110a83cb9SPrem Mallappa         return;
33210a83cb9SPrem Mallappa     }
33310a83cb9SPrem Mallappa 
33410a83cb9SPrem Mallappa     memory_region_init_io(&sys->iomem, OBJECT(s),
33510a83cb9SPrem Mallappa                           &smmu_mem_ops, sys, TYPE_ARM_SMMUV3, 0x20000);
33610a83cb9SPrem Mallappa 
33710a83cb9SPrem Mallappa     sys->mrtypename = TYPE_SMMUV3_IOMMU_MEMORY_REGION;
33810a83cb9SPrem Mallappa 
33910a83cb9SPrem Mallappa     sysbus_init_mmio(dev, &sys->iomem);
34010a83cb9SPrem Mallappa 
34110a83cb9SPrem Mallappa     smmu_init_irq(s, dev);
34210a83cb9SPrem Mallappa }
34310a83cb9SPrem Mallappa 
34410a83cb9SPrem Mallappa static const VMStateDescription vmstate_smmuv3_queue = {
34510a83cb9SPrem Mallappa     .name = "smmuv3_queue",
34610a83cb9SPrem Mallappa     .version_id = 1,
34710a83cb9SPrem Mallappa     .minimum_version_id = 1,
34810a83cb9SPrem Mallappa     .fields = (VMStateField[]) {
34910a83cb9SPrem Mallappa         VMSTATE_UINT64(base, SMMUQueue),
35010a83cb9SPrem Mallappa         VMSTATE_UINT32(prod, SMMUQueue),
35110a83cb9SPrem Mallappa         VMSTATE_UINT32(cons, SMMUQueue),
35210a83cb9SPrem Mallappa         VMSTATE_UINT8(log2size, SMMUQueue),
35310a83cb9SPrem Mallappa     },
35410a83cb9SPrem Mallappa };
35510a83cb9SPrem Mallappa 
35610a83cb9SPrem Mallappa static const VMStateDescription vmstate_smmuv3 = {
35710a83cb9SPrem Mallappa     .name = "smmuv3",
35810a83cb9SPrem Mallappa     .version_id = 1,
35910a83cb9SPrem Mallappa     .minimum_version_id = 1,
36010a83cb9SPrem Mallappa     .fields = (VMStateField[]) {
36110a83cb9SPrem Mallappa         VMSTATE_UINT32(features, SMMUv3State),
36210a83cb9SPrem Mallappa         VMSTATE_UINT8(sid_size, SMMUv3State),
36310a83cb9SPrem Mallappa         VMSTATE_UINT8(sid_split, SMMUv3State),
36410a83cb9SPrem Mallappa 
36510a83cb9SPrem Mallappa         VMSTATE_UINT32_ARRAY(cr, SMMUv3State, 3),
36610a83cb9SPrem Mallappa         VMSTATE_UINT32(cr0ack, SMMUv3State),
36710a83cb9SPrem Mallappa         VMSTATE_UINT32(statusr, SMMUv3State),
36810a83cb9SPrem Mallappa         VMSTATE_UINT32(irq_ctrl, SMMUv3State),
36910a83cb9SPrem Mallappa         VMSTATE_UINT32(gerror, SMMUv3State),
37010a83cb9SPrem Mallappa         VMSTATE_UINT32(gerrorn, SMMUv3State),
37110a83cb9SPrem Mallappa         VMSTATE_UINT64(gerror_irq_cfg0, SMMUv3State),
37210a83cb9SPrem Mallappa         VMSTATE_UINT32(gerror_irq_cfg1, SMMUv3State),
37310a83cb9SPrem Mallappa         VMSTATE_UINT32(gerror_irq_cfg2, SMMUv3State),
37410a83cb9SPrem Mallappa         VMSTATE_UINT64(strtab_base, SMMUv3State),
37510a83cb9SPrem Mallappa         VMSTATE_UINT32(strtab_base_cfg, SMMUv3State),
37610a83cb9SPrem Mallappa         VMSTATE_UINT64(eventq_irq_cfg0, SMMUv3State),
37710a83cb9SPrem Mallappa         VMSTATE_UINT32(eventq_irq_cfg1, SMMUv3State),
37810a83cb9SPrem Mallappa         VMSTATE_UINT32(eventq_irq_cfg2, SMMUv3State),
37910a83cb9SPrem Mallappa 
38010a83cb9SPrem Mallappa         VMSTATE_STRUCT(cmdq, SMMUv3State, 0, vmstate_smmuv3_queue, SMMUQueue),
38110a83cb9SPrem Mallappa         VMSTATE_STRUCT(eventq, SMMUv3State, 0, vmstate_smmuv3_queue, SMMUQueue),
38210a83cb9SPrem Mallappa 
38310a83cb9SPrem Mallappa         VMSTATE_END_OF_LIST(),
38410a83cb9SPrem Mallappa     },
38510a83cb9SPrem Mallappa };
38610a83cb9SPrem Mallappa 
38710a83cb9SPrem Mallappa static void smmuv3_instance_init(Object *obj)
38810a83cb9SPrem Mallappa {
38910a83cb9SPrem Mallappa     /* Nothing much to do here as of now */
39010a83cb9SPrem Mallappa }
39110a83cb9SPrem Mallappa 
39210a83cb9SPrem Mallappa static void smmuv3_class_init(ObjectClass *klass, void *data)
39310a83cb9SPrem Mallappa {
39410a83cb9SPrem Mallappa     DeviceClass *dc = DEVICE_CLASS(klass);
39510a83cb9SPrem Mallappa     SMMUv3Class *c = ARM_SMMUV3_CLASS(klass);
39610a83cb9SPrem Mallappa 
39710a83cb9SPrem Mallappa     dc->vmsd = &vmstate_smmuv3;
39810a83cb9SPrem Mallappa     device_class_set_parent_reset(dc, smmu_reset, &c->parent_reset);
39910a83cb9SPrem Mallappa     c->parent_realize = dc->realize;
40010a83cb9SPrem Mallappa     dc->realize = smmu_realize;
40110a83cb9SPrem Mallappa }
40210a83cb9SPrem Mallappa 
40310a83cb9SPrem Mallappa static void smmuv3_iommu_memory_region_class_init(ObjectClass *klass,
40410a83cb9SPrem Mallappa                                                   void *data)
40510a83cb9SPrem Mallappa {
40610a83cb9SPrem Mallappa }
40710a83cb9SPrem Mallappa 
40810a83cb9SPrem Mallappa static const TypeInfo smmuv3_type_info = {
40910a83cb9SPrem Mallappa     .name          = TYPE_ARM_SMMUV3,
41010a83cb9SPrem Mallappa     .parent        = TYPE_ARM_SMMU,
41110a83cb9SPrem Mallappa     .instance_size = sizeof(SMMUv3State),
41210a83cb9SPrem Mallappa     .instance_init = smmuv3_instance_init,
41310a83cb9SPrem Mallappa     .class_size    = sizeof(SMMUv3Class),
41410a83cb9SPrem Mallappa     .class_init    = smmuv3_class_init,
41510a83cb9SPrem Mallappa };
41610a83cb9SPrem Mallappa 
41710a83cb9SPrem Mallappa static const TypeInfo smmuv3_iommu_memory_region_info = {
41810a83cb9SPrem Mallappa     .parent = TYPE_IOMMU_MEMORY_REGION,
41910a83cb9SPrem Mallappa     .name = TYPE_SMMUV3_IOMMU_MEMORY_REGION,
42010a83cb9SPrem Mallappa     .class_init = smmuv3_iommu_memory_region_class_init,
42110a83cb9SPrem Mallappa };
42210a83cb9SPrem Mallappa 
42310a83cb9SPrem Mallappa static void smmuv3_register_types(void)
42410a83cb9SPrem Mallappa {
42510a83cb9SPrem Mallappa     type_register(&smmuv3_type_info);
42610a83cb9SPrem Mallappa     type_register(&smmuv3_iommu_memory_region_info);
42710a83cb9SPrem Mallappa }
42810a83cb9SPrem Mallappa 
42910a83cb9SPrem Mallappa type_init(smmuv3_register_types)
43010a83cb9SPrem Mallappa 
431