[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-arm] [PATCH v7 05/20] hw/arm/smmuv3: Skeleton
From: |
Linu Cherian |
Subject: |
Re: [Qemu-arm] [PATCH v7 05/20] hw/arm/smmuv3: Skeleton |
Date: |
Fri, 8 Sep 2017 16:22:14 +0530 |
User-agent: |
Mutt/1.5.21 (2010-09-15) |
Hi Eric,
On Fri Sep 01, 2017 at 07:21:08PM +0200, Eric Auger wrote:
> From: Prem Mallappa <address@hidden>
>
> This patch implements a skeleton for the smmuv3 device.
> Datatypes and register definitions are introduced. The MMIO
> region, the interrupts and the queue are initialized (PRI is
> not supported).
>
> Only the MMIO read operation is implemented here.
>
> Signed-off-by: Prem Mallappa <address@hidden>
> Signed-off-by: Eric Auger <address@hidden>
>
> ---
> v6 -> v7:
> - split into several patches
>
> v5 -> v6:
> - Use IOMMUMemoryregion
> - regs become uint32_t and fix 64b MMIO access (.impl)
> - trace_smmuv3_write/read_mmio take the size param
>
> v4 -> v5:
> - change smmuv3_translate proto (IOMMUAccessFlags flag)
> - has_stagex replaced by is_ste_stagex
> - smmu_cfg_populate removed
> - added smmuv3_decode_config and reworked error management
> - remwork the naming of IOMMU mrs
> - fix SMMU_CMDQ_CONS offset
>
> v3 -> v4
> - smmu_irq_update
> - fix hash key allocation
> - set smmu_iommu_ops
> - set SMMU_REG_CR0,
> - smmuv3_translate: ret.perm not set in bypass mode
> - use trace events
> - renamed STM2U64 into L1STD_L2PTR and STMSPAN into L1STD_SPAN
> - rework smmu_find_ste
> - fix tg2granule in TT0/0b10 corresponds to 16kB
>
> v2 -> v3:
> - move creation of include/hw/arm/smmuv3.h to this patch to fix compil issue
> - compilation allowed
> - fix sbus allocation in smmu_init_pci_iommu
> - restructure code into headers
> - misc cleanups
> ---
> hw/arm/Makefile.objs | 2 +-
> hw/arm/smmuv3-internal.h | 201 +++++++++++++++++++++++++++++++++++++++
> hw/arm/smmuv3.c | 239
> +++++++++++++++++++++++++++++++++++++++++++++++
> hw/arm/trace-events | 3 +
> include/hw/arm/smmuv3.h | 79 ++++++++++++++++
> 5 files changed, 523 insertions(+), 1 deletion(-)
> create mode 100644 hw/arm/smmuv3-internal.h
> create mode 100644 hw/arm/smmuv3.c
> create mode 100644 include/hw/arm/smmuv3.h
>
> diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
> index 5b2d38d..a7c808b 100644
> --- a/hw/arm/Makefile.objs
> +++ b/hw/arm/Makefile.objs
> @@ -19,4 +19,4 @@ obj-$(CONFIG_FSL_IMX31) += fsl-imx31.o kzm.o
> obj-$(CONFIG_FSL_IMX6) += fsl-imx6.o sabrelite.o
> obj-$(CONFIG_ASPEED_SOC) += aspeed_soc.o aspeed.o
> obj-$(CONFIG_MPS2) += mps2.o
> -obj-$(CONFIG_ARM_SMMUV3) += smmu-common.o
> +obj-$(CONFIG_ARM_SMMUV3) += smmu-common.o smmuv3.o
> diff --git a/hw/arm/smmuv3-internal.h b/hw/arm/smmuv3-internal.h
> new file mode 100644
> index 0000000..488acc8
> --- /dev/null
> +++ b/hw/arm/smmuv3-internal.h
> @@ -0,0 +1,201 @@
> +/*
> + * ARM SMMUv3 support - Internal API
> + *
> + * Copyright (C) 2014-2016 Broadcom Corporation
> + * Copyright (c) 2017 Red Hat, Inc.
> + * Written by Prem Mallappa, Eric Auger
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation, either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License along
> + * with this program; if not, see <http://www.gnu.org/licenses/>.
> + */
> +
> +#ifndef HW_ARM_SMMU_V3_INTERNAL_H
> +#define HW_ARM_SMMU_V3_INTERNAL_H
> +
> +#include "trace.h"
> +#include "qemu/error-report.h"
> +#include "hw/arm/smmu-common.h"
> +
> +/*****************************
> + * MMIO Register
> + *****************************/
> +enum {
> + SMMU_REG_IDR0 = 0x0,
> +
> +/* IDR0 Field Values and supported features */
> +
> +#define SMMU_IDR0_S2P 1 /* stage 2 */
> +#define SMMU_IDR0_S1P 1 /* stage 1 */
> +#define SMMU_IDR0_TTF 2 /* Aarch64 only - not Aarch32 (LPAE) */
> +#define SMMU_IDR0_COHACC 1 /* IO coherent access */
> +#define SMMU_IDR0_HTTU 2 /* Access and Dirty flag update */
> +#define SMMU_IDR0_HYP 0 /* Hypervisor Stage 1 contexts */
> +#define SMMU_IDR0_ATS 0 /* PCIe RC ATS */
> +#define SMMU_IDR0_ASID16 1 /* 16-bit ASID */
> +#define SMMU_IDR0_PRI 0 /* Page Request Interface */
> +#define SMMU_IDR0_VMID16 0 /* 16-bit VMID */
> +#define SMMU_IDR0_CD2L 0 /* 2-level Context Descriptor table */
> +#define SMMU_IDR0_STALL 1 /* Stalling fault model */
> +#define SMMU_IDR0_TERM 1 /* Termination model behaviour */
> +#define SMMU_IDR0_STLEVEL 1 /* Multi-level Stream Table */
> +
> +#define SMMU_IDR0_S2P_SHIFT 0
> +#define SMMU_IDR0_S1P_SHIFT 1
> +#define SMMU_IDR0_TTF_SHIFT 2
> +#define SMMU_IDR0_COHACC_SHIFT 4
> +#define SMMU_IDR0_HTTU_SHIFT 6
> +#define SMMU_IDR0_HYP_SHIFT 9
> +#define SMMU_IDR0_ATS_SHIFT 10
> +#define SMMU_IDR0_ASID16_SHIFT 12
> +#define SMMU_IDR0_PRI_SHIFT 16
> +#define SMMU_IDR0_VMID16_SHIFT 18
> +#define SMMU_IDR0_CD2L_SHIFT 19
> +#define SMMU_IDR0_STALL_SHIFT 24
> +#define SMMU_IDR0_TERM_SHIFT 26
> +#define SMMU_IDR0_STLEVEL_SHIFT 27
> +
> + SMMU_REG_IDR1 = 0x4,
> +#define SMMU_IDR1_SIDSIZE 16
> + SMMU_REG_IDR2 = 0x8,
> + SMMU_REG_IDR3 = 0xc,
> + SMMU_REG_IDR4 = 0x10,
> + SMMU_REG_IDR5 = 0x14,
> +#define SMMU_IDR5_GRAN_SHIFT 4
> +#define SMMU_IDR5_GRAN 0b101 /* GRAN4K, GRAN64K */
> +#define SMMU_IDR5_OAS 4 /* 44 bits */
> + SMMU_REG_IIDR = 0x1c,
> + SMMU_REG_CR0 = 0x20,
> +
> +#define SMMU_CR0_SMMU_ENABLE (1 << 0)
> +#define SMMU_CR0_PRIQ_ENABLE (1 << 1)
> +#define SMMU_CR0_EVTQ_ENABLE (1 << 2)
> +#define SMMU_CR0_CMDQ_ENABLE (1 << 3)
> +#define SMMU_CR0_ATS_CHECK (1 << 4)
> +
> + SMMU_REG_CR0_ACK = 0x24,
> + SMMU_REG_CR1 = 0x28,
> + SMMU_REG_CR2 = 0x2c,
> +
> + SMMU_REG_STATUSR = 0x40,
> +
> + SMMU_REG_IRQ_CTRL = 0x50,
> + SMMU_REG_IRQ_CTRL_ACK = 0x54,
> +
> +#define SMMU_IRQ_CTRL_GERROR_EN (1 << 0)
> +#define SMMU_IRQ_CTRL_EVENT_EN (1 << 1)
> +#define SMMU_IRQ_CTRL_PRI_EN (1 << 2)
> +
> + SMMU_REG_GERROR = 0x60,
> +
> +#define SMMU_GERROR_CMDQ (1 << 0)
> +#define SMMU_GERROR_EVENTQ_ABT (1 << 2)
> +#define SMMU_GERROR_PRIQ_ABT (1 << 3)
> +#define SMMU_GERROR_MSI_CMDQ_ABT (1 << 4)
> +#define SMMU_GERROR_MSI_EVENTQ_ABT (1 << 5)
> +#define SMMU_GERROR_MSI_PRIQ_ABT (1 << 6)
> +#define SMMU_GERROR_MSI_GERROR_ABT (1 << 7)
> +#define SMMU_GERROR_SFM_ERR (1 << 8)
> +
> + SMMU_REG_GERRORN = 0x64,
> + SMMU_REG_GERROR_IRQ_CFG0 = 0x68,
> + SMMU_REG_GERROR_IRQ_CFG1 = 0x70,
> + SMMU_REG_GERROR_IRQ_CFG2 = 0x74,
> +
> + /* SMMU_BASE_RA Applies to STRTAB_BASE, CMDQ_BASE and EVTQ_BASE */
> +#define SMMU_BASE_RA (1ULL << 62)
> + SMMU_REG_STRTAB_BASE = 0x80,
> + SMMU_REG_STRTAB_BASE_CFG = 0x88,
> +
> + SMMU_REG_CMDQ_BASE = 0x90,
> + SMMU_REG_CMDQ_PROD = 0x98,
> + SMMU_REG_CMDQ_CONS = 0x9c,
> + /* CMD Consumer (CONS) */
> +#define SMMU_CMD_CONS_ERR_SHIFT 24
> +#define SMMU_CMD_CONS_ERR_BITS 7
> +
> + SMMU_REG_EVTQ_BASE = 0xa0,
> + SMMU_REG_EVTQ_PROD = 0xa8,
> + SMMU_REG_EVTQ_CONS = 0xac,
> + SMMU_REG_EVTQ_IRQ_CFG0 = 0xb0,
> + SMMU_REG_EVTQ_IRQ_CFG1 = 0xb8,
> + SMMU_REG_EVTQ_IRQ_CFG2 = 0xbc,
> +
> + SMMU_REG_PRIQ_BASE = 0xc0,
> + SMMU_REG_PRIQ_PROD = 0xc8,
> + SMMU_REG_PRIQ_CONS = 0xcc,
> + SMMU_REG_PRIQ_IRQ_CFG0 = 0xd0,
> + SMMU_REG_PRIQ_IRQ_CFG1 = 0xd8,
> + SMMU_REG_PRIQ_IRQ_CFG2 = 0xdc,
> +
> + SMMU_ID_REGS_OFFSET = 0xfd0,
> +
> + /* Secure registers are not used for now */
> + SMMU_SECURE_OFFSET = 0x8000,
> +};
> +
> +/**********************
> + * Data Structures
> + **********************/
> +
> +struct __smmu_data2 {
> + uint32_t word[2];
> +};
> +
> +struct __smmu_data8 {
> + uint32_t word[8];
> +};
> +
> +struct __smmu_data16 {
> + uint32_t word[16];
> +};
> +
> +struct __smmu_data4 {
> + uint32_t word[4];
> +};
> +
> +typedef struct __smmu_data4 Cmd; /* Command Entry */
> +typedef struct __smmu_data8 Evt; /* Event Entry */
> +
> +/*****************************
> + * Register Access Primitives
> + *****************************/
> +
> +static inline void smmu_write32_reg(SMMUV3State *s, uint32_t addr, uint32_t
> val)
> +{
> + s->regs[addr >> 2] = val;
> +}
> +
> +static inline void smmu_write64_reg(SMMUV3State *s, uint32_t addr, uint64_t
> val)
> +{
> + addr >>= 2;
> + s->regs[addr] = extract64(val, 0, 32);
> + s->regs[addr + 1] = extract64(val, 32, 32);
> +}
> +
> +static inline uint32_t smmu_read32_reg(SMMUV3State *s, uint32_t addr)
> +{
> + return s->regs[addr >> 2];
> +}
> +
> +static inline uint64_t smmu_read64_reg(SMMUV3State *s, uint32_t addr)
> +{
> + addr >>= 2;
> + return s->regs[addr] | ((uint64_t)(s->regs[addr + 1]) << 32);
> +}
> +
> +static inline int smmu_enabled(SMMUV3State *s)
> +{
> + return smmu_read32_reg(s, SMMU_REG_CR0) & SMMU_CR0_SMMU_ENABLE;
> +}
> +
> +#endif
> diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
> new file mode 100644
> index 0000000..0a7cd1c
> --- /dev/null
> +++ b/hw/arm/smmuv3.c
> @@ -0,0 +1,239 @@
> +/*
> + * Copyright (C) 2014-2016 Broadcom Corporation
> + * Copyright (c) 2017 Red Hat, Inc.
> + * Written by Prem Mallappa, Eric Auger
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation, either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License along
> + * with this program; if not, see <http://www.gnu.org/licenses/>.
> + */
> +
> +#include "qemu/osdep.h"
> +#include "hw/boards.h"
> +#include "sysemu/sysemu.h"
> +#include "hw/sysbus.h"
> +#include "hw/pci/pci.h"
> +#include "exec/address-spaces.h"
> +#include "trace.h"
> +#include "qemu/error-report.h"
> +
> +#include "hw/arm/smmuv3.h"
> +#include "smmuv3-internal.h"
> +
> +static void smmuv3_init_regs(SMMUV3State *s)
> +{
> + uint32_t data =
> + SMMU_IDR0_STLEVEL << SMMU_IDR0_STLEVEL_SHIFT |
> + SMMU_IDR0_TERM << SMMU_IDR0_TERM_SHIFT |
> + SMMU_IDR0_STALL << SMMU_IDR0_STALL_SHIFT |
> + SMMU_IDR0_VMID16 << SMMU_IDR0_VMID16_SHIFT |
> + SMMU_IDR0_PRI << SMMU_IDR0_PRI_SHIFT |
> + SMMU_IDR0_ASID16 << SMMU_IDR0_ASID16_SHIFT |
> + SMMU_IDR0_ATS << SMMU_IDR0_ATS_SHIFT |
> + SMMU_IDR0_HYP << SMMU_IDR0_HYP_SHIFT |
> + SMMU_IDR0_HTTU << SMMU_IDR0_HTTU_SHIFT |
> + SMMU_IDR0_COHACC << SMMU_IDR0_COHACC_SHIFT |
> + SMMU_IDR0_TTF << SMMU_IDR0_TTF_SHIFT |
> + SMMU_IDR0_S1P << SMMU_IDR0_S1P_SHIFT |
> + SMMU_IDR0_S2P << SMMU_IDR0_S2P_SHIFT;
> +
> + smmu_write32_reg(s, SMMU_REG_IDR0, data);
> +
> +#define SMMU_QUEUE_SIZE_LOG2 19
> + data =
> + 1 << 27 | /* Attr Types override */
> + SMMU_QUEUE_SIZE_LOG2 << 21 | /* Cmd Q size */
> + SMMU_QUEUE_SIZE_LOG2 << 16 | /* Event Q size */
> + SMMU_QUEUE_SIZE_LOG2 << 11 | /* PRI Q size */
> + 0 << 6 | /* SSID not supported */
> + SMMU_IDR1_SIDSIZE;
> +
> + smmu_write32_reg(s, SMMU_REG_IDR1, data);
> +
> + s->sid_size = SMMU_IDR1_SIDSIZE;
> +
> + data = SMMU_IDR5_GRAN << SMMU_IDR5_GRAN_SHIFT | SMMU_IDR5_OAS;
For VFIO case, should we not set the granule size based on underlying
pagesize bitmap derived from VFIO_IOMMU_GET_INFO. Else if guest kernel
is build with 4k page size and the host kernel is 64k we would start
getting map errors.
> +
> + smmu_write32_reg(s, SMMU_REG_IDR5, data);
> +}
> +
> +static void smmuv3_init_queues(SMMUV3State *s)
> +{
> + s->cmdq.prod = 0;
> + s->cmdq.cons = 0;
> + s->cmdq.wrap.prod = 0;
> + s->cmdq.wrap.cons = 0;
> +
> + s->evtq.prod = 0;
> + s->evtq.cons = 0;
> + s->evtq.wrap.prod = 0;
> + s->evtq.wrap.cons = 0;
> +
> + s->cmdq.entries = SMMU_QUEUE_SIZE_LOG2;
> + s->cmdq.ent_size = sizeof(Cmd);
> + s->evtq.entries = SMMU_QUEUE_SIZE_LOG2;
> + s->evtq.ent_size = sizeof(Evt);
> +}
> +
> +static void smmuv3_init(SMMUV3State *s)
> +{
> + smmuv3_init_regs(s);
> + smmuv3_init_queues(s);
> +}
> +
> +static inline void smmu_update_base_reg(SMMUV3State *s, uint64_t *base,
> + uint64_t val)
> +{
> + *base = val & ~(SMMU_BASE_RA | 0x3fULL);
> +}
> +
> +static void smmu_write_mmio_fixup(SMMUV3State *s, hwaddr *addr)
> +{
> + switch (*addr) {
> + case 0x100a8: case 0x100ac: /* Aliasing => page0 registers */
> + case 0x100c8: case 0x100cc:
> + *addr ^= (hwaddr)0x10000;
> + }
> +}
> +
> +static void smmu_write_mmio(void *opaque, hwaddr addr,
> + uint64_t val, unsigned size)
> +{
> +}
> +
> +static uint64_t smmu_read_mmio(void *opaque, hwaddr addr, unsigned size)
> +{
> + SMMUState *sys = opaque;
> + SMMUV3State *s = SMMU_V3_DEV(sys);
> + uint64_t val;
> +
> + smmu_write_mmio_fixup(s, &addr);
> +
> + /* Primecell/Corelink ID registers */
> + switch (addr) {
> + case 0xFF0 ... 0xFFC:
> + case 0xFDC ... 0xFE4:
> + val = 0;
> + error_report("addr:0x%"PRIx64" val:0x%"PRIx64, addr, val);
> + break;
> + case SMMU_REG_STRTAB_BASE ... SMMU_REG_CMDQ_BASE:
> + case SMMU_REG_EVTQ_BASE:
> + case SMMU_REG_PRIQ_BASE ... SMMU_REG_PRIQ_IRQ_CFG1:
> + val = smmu_read64_reg(s, addr);
> + break;
> + default:
> + val = (uint64_t)smmu_read32_reg(s, addr);
> + break;
> + }
> +
> + trace_smmuv3_read_mmio(addr, val, size);
> + return val;
> +}
> +
> +static const MemoryRegionOps smmu_mem_ops = {
> + .read = smmu_read_mmio,
> + .write = smmu_write_mmio,
> + .endianness = DEVICE_LITTLE_ENDIAN,
> + .valid = {
> + .min_access_size = 4,
> + .max_access_size = 8,
> + },
> + .impl = {
> + .min_access_size = 4,
> + .max_access_size = 8,
> + },
> +};
> +
> +static void smmu_init_irq(SMMUV3State *s, SysBusDevice *dev)
> +{
> + int i;
> +
> + for (i = 0; i < ARRAY_SIZE(s->irq); i++) {
> + sysbus_init_irq(dev, &s->irq[i]);
> + }
> +}
> +
> +static void smmu_reset(DeviceState *dev)
> +{
> + SMMUV3State *s = SMMU_V3_DEV(dev);
> + smmuv3_init(s);
> +}
> +
> +static void smmu_realize(DeviceState *d, Error **errp)
> +{
> + SMMUState *sys = SMMU_SYS_DEV(d);
> + SMMUV3State *s = SMMU_V3_DEV(sys);
> + SysBusDevice *dev = SYS_BUS_DEVICE(d);
> +
> + memory_region_init_io(&sys->iomem, OBJECT(s),
> + &smmu_mem_ops, sys, TYPE_SMMU_V3_DEV, 0x20000);
> +
> + sys->mrtypename = g_strdup(TYPE_SMMUV3_IOMMU_MEMORY_REGION);
> +
> + sysbus_init_mmio(dev, &sys->iomem);
> +
> + smmu_init_irq(s, dev);
> +}
> +
> +static const VMStateDescription vmstate_smmuv3 = {
> + .name = "smmuv3",
> + .version_id = 1,
> + .minimum_version_id = 1,
> + .fields = (VMStateField[]) {
> + VMSTATE_UINT32_ARRAY(regs, SMMUV3State, SMMU_NREGS),
> + VMSTATE_END_OF_LIST(),
> + },
> +};
> +
> +static void smmuv3_instance_init(Object *obj)
> +{
> + /* Nothing much to do here as of now */
> +}
> +
> +static void smmuv3_class_init(ObjectClass *klass, void *data)
> +{
> + DeviceClass *dc = DEVICE_CLASS(klass);
> +
> + dc->reset = smmu_reset;
> + dc->vmsd = &vmstate_smmuv3;
> + dc->realize = smmu_realize;
> +}
> +
> +static void smmuv3_iommu_memory_region_class_init(ObjectClass *klass,
> + void *data)
> +{
> +}
> +
> +static const TypeInfo smmuv3_type_info = {
> + .name = TYPE_SMMU_V3_DEV,
> + .parent = TYPE_SMMU_DEV_BASE,
> + .instance_size = sizeof(SMMUV3State),
> + .instance_init = smmuv3_instance_init,
> + .class_data = NULL,
> + .class_size = sizeof(SMMUV3Class),
> + .class_init = smmuv3_class_init,
> +};
> +
> +static const TypeInfo smmuv3_iommu_memory_region_info = {
> + .parent = TYPE_IOMMU_MEMORY_REGION,
> + .name = TYPE_SMMUV3_IOMMU_MEMORY_REGION,
> + .class_init = smmuv3_iommu_memory_region_class_init,
> +};
> +
> +static void smmuv3_register_types(void)
> +{
> + type_register(&smmuv3_type_info);
> + type_register(&smmuv3_iommu_memory_region_info);
> +}
> +
> +type_init(smmuv3_register_types)
> +
> diff --git a/hw/arm/trace-events b/hw/arm/trace-events
> index c67cd39..8affbf7 100644
> --- a/hw/arm/trace-events
> +++ b/hw/arm/trace-events
> @@ -14,3 +14,6 @@ smmu_page_walk_level_block_pte(int stage, int level,
> uint64_t baseaddr, uint64_t
> smmu_page_walk_level_table_pte(int stage, int level, uint64_t baseaddr,
> uint64_t pteaddr, uint64_t pte, uint64_t address) "stage=%d, level=%d
> address@hidden"PRIx64" address@hidden"PRIx64" pte=0x%"PRIx64" next table
> address = 0x%"PRIx64
> smmu_get_pte(uint64_t baseaddr, int index, uint64_t pteaddr, uint64_t pte)
> "baseaddr=0x%"PRIx64" index=0x%x, pteaddr=0x%"PRIx64", pte=0x%"PRIx64
> smmu_set_translated_address(hwaddr iova, hwaddr pa) "iova = 0x%"PRIx64" ->
> pa = 0x%"PRIx64
> +
> +#hw/arm/smmuv3.c
> +smmuv3_read_mmio(hwaddr addr, uint64_t val, unsigned size) "addr:
> 0x%"PRIx64" val:0x%"PRIx64" size: 0x%x"
> diff --git a/include/hw/arm/smmuv3.h b/include/hw/arm/smmuv3.h
> new file mode 100644
> index 0000000..0c8973d
> --- /dev/null
> +++ b/include/hw/arm/smmuv3.h
> @@ -0,0 +1,79 @@
> +/*
> + * Copyright (C) 2014-2016 Broadcom Corporation
> + * Copyright (c) 2017 Red Hat, Inc.
> + * Written by Prem Mallappa, Eric Auger
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation, either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License along
> + * with this program; if not, see <http://www.gnu.org/licenses/>.
> + */
> +
> +#ifndef HW_ARM_SMMUV3_H
> +#define HW_ARM_SMMUV3_H
> +
> +#include "hw/arm/smmu-common.h"
> +
> +#define TYPE_SMMUV3_IOMMU_MEMORY_REGION "smmuv3-iommu-memory-region"
> +
> +#define SMMU_NREGS 0x200
> +
> +typedef struct SMMUQueue {
> + hwaddr base;
> + uint32_t prod;
> + uint32_t cons;
> + union {
> + struct {
> + uint8_t prod:1;
> + uint8_t cons:1;
> + };
> + uint8_t unused;
> + } wrap;
> +
> + uint16_t entries; /* Number of entries */
> + uint8_t ent_size; /* Size of entry in bytes */
> + uint8_t shift; /* Size in log2 */
> +} SMMUQueue;
> +
> +typedef struct SMMUV3State {
> + SMMUState smmu_state;
> +
> + /* Local cache of most-frequently used registers */
> +#define SMMU_FEATURE_2LVL_STE (1 << 0)
> + uint32_t features;
> + uint16_t sid_size;
> + uint16_t sid_split;
> + uint64_t strtab_base;
> +
> + uint32_t regs[SMMU_NREGS];
> +
> + qemu_irq irq[4];
> + SMMUQueue cmdq, evtq;
> +
> +} SMMUV3State;
> +
> +typedef enum {
> + SMMU_IRQ_EVTQ,
> + SMMU_IRQ_PRIQ,
> + SMMU_IRQ_CMD_SYNC,
> + SMMU_IRQ_GERROR,
> +} SMMUIrq;
> +
> +typedef struct {
> + SMMUBaseClass smmu_base_class;
> +} SMMUV3Class;
> +
> +#define TYPE_SMMU_V3_DEV "smmuv3"
> +#define SMMU_V3_DEV(obj) OBJECT_CHECK(SMMUV3State, (obj), TYPE_SMMU_V3_DEV)
> +#define SMMU_V3_DEVICE_GET_CLASS(obj) \
> + OBJECT_GET_CLASS(SMMUBaseClass, (obj), TYPE_SMMU_V3_DEV)
> +
> +#endif
> --
> 2.5.5
>
>
--
Linu cherian
- [Qemu-arm] [PATCH v7 00/20] ARM SMMUv3 Emulation Support, Eric Auger, 2017/09/01
- [Qemu-arm] [PATCH v7 01/20] hw/arm/smmu-common: smmu base device and datatypes, Eric Auger, 2017/09/01
- [Qemu-arm] [PATCH v7 02/20] hw/arm/smmu-common: IOMMU memory region and address space setup, Eric Auger, 2017/09/01
- [Qemu-arm] [PATCH v7 03/20] hw/arm/smmu-common: smmu_read/write_sysmem, Eric Auger, 2017/09/01
- [Qemu-arm] [PATCH v7 04/20] hw/arm/smmu-common: VMSAv8-64 page table walk, Eric Auger, 2017/09/01
- [Qemu-arm] [PATCH v7 06/20] hw/arm/smmuv3: Wired IRQ and GERROR helpers, Eric Auger, 2017/09/01
- [Qemu-arm] [PATCH v7 05/20] hw/arm/smmuv3: Skeleton, Eric Auger, 2017/09/01
- Re: [Qemu-arm] [PATCH v7 05/20] hw/arm/smmuv3: Skeleton,
Linu Cherian <=
- [Qemu-arm] [PATCH v7 07/20] hw/arm/smmuv3: Queue helpers, Eric Auger, 2017/09/01
- [Qemu-arm] [PATCH v7 08/20] hw/arm/smmuv3: Implement MMIO write operations, Eric Auger, 2017/09/01
- [Qemu-arm] [PATCH v7 09/20] hw/arm/smmuv3: Event queue recording helper, Eric Auger, 2017/09/01
- [Qemu-arm] [PATCH v7 10/20] hw/arm/smmuv3: Implement translate callback, Eric Auger, 2017/09/01
- [Qemu-arm] [PATCH v7 11/20] target/arm/kvm: Translate the MSI doorbell in kvm_arch_fixup_msi_route, Eric Auger, 2017/09/01
- [Qemu-arm] [PATCH v7 12/20] hw/arm/smmuv3: Implement data structure and TLB invalidation notifications, Eric Auger, 2017/09/01
- [Qemu-arm] [PATCH v7 13/20] hw/arm/smmuv3: Implement IOMMU memory region replay callback, Eric Auger, 2017/09/01