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