cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

tz-mpc.c (19454B)


      1/*
      2 * ARM AHB5 TrustZone Memory Protection Controller emulation
      3 *
      4 * Copyright (c) 2018 Linaro Limited
      5 * Written by Peter Maydell
      6 *
      7 * This program is free software; you can redistribute it and/or modify
      8 * it under the terms of the GNU General Public License version 2 or
      9 * (at your option) any later version.
     10 */
     11
     12#include "qemu/osdep.h"
     13#include "qemu/log.h"
     14#include "qemu/module.h"
     15#include "qapi/error.h"
     16#include "trace.h"
     17#include "hw/sysbus.h"
     18#include "migration/vmstate.h"
     19#include "hw/registerfields.h"
     20#include "hw/irq.h"
     21#include "hw/misc/tz-mpc.h"
     22#include "hw/qdev-properties.h"
     23
     24/* Our IOMMU has two IOMMU indexes, one for secure transactions and one for
     25 * non-secure transactions.
     26 */
     27enum {
     28    IOMMU_IDX_S,
     29    IOMMU_IDX_NS,
     30    IOMMU_NUM_INDEXES,
     31};
     32
     33/* Config registers */
     34REG32(CTRL, 0x00)
     35    FIELD(CTRL, SEC_RESP, 4, 1)
     36    FIELD(CTRL, AUTOINC, 8, 1)
     37    FIELD(CTRL, LOCKDOWN, 31, 1)
     38REG32(BLK_MAX, 0x10)
     39REG32(BLK_CFG, 0x14)
     40REG32(BLK_IDX, 0x18)
     41REG32(BLK_LUT, 0x1c)
     42REG32(INT_STAT, 0x20)
     43    FIELD(INT_STAT, IRQ, 0, 1)
     44REG32(INT_CLEAR, 0x24)
     45    FIELD(INT_CLEAR, IRQ, 0, 1)
     46REG32(INT_EN, 0x28)
     47    FIELD(INT_EN, IRQ, 0, 1)
     48REG32(INT_INFO1, 0x2c)
     49REG32(INT_INFO2, 0x30)
     50    FIELD(INT_INFO2, HMASTER, 0, 16)
     51    FIELD(INT_INFO2, HNONSEC, 16, 1)
     52    FIELD(INT_INFO2, CFG_NS, 17, 1)
     53REG32(INT_SET, 0x34)
     54    FIELD(INT_SET, IRQ, 0, 1)
     55REG32(PIDR4, 0xfd0)
     56REG32(PIDR5, 0xfd4)
     57REG32(PIDR6, 0xfd8)
     58REG32(PIDR7, 0xfdc)
     59REG32(PIDR0, 0xfe0)
     60REG32(PIDR1, 0xfe4)
     61REG32(PIDR2, 0xfe8)
     62REG32(PIDR3, 0xfec)
     63REG32(CIDR0, 0xff0)
     64REG32(CIDR1, 0xff4)
     65REG32(CIDR2, 0xff8)
     66REG32(CIDR3, 0xffc)
     67
     68static const uint8_t tz_mpc_idregs[] = {
     69    0x04, 0x00, 0x00, 0x00,
     70    0x60, 0xb8, 0x1b, 0x00,
     71    0x0d, 0xf0, 0x05, 0xb1,
     72};
     73
     74static void tz_mpc_irq_update(TZMPC *s)
     75{
     76    qemu_set_irq(s->irq, s->int_stat && s->int_en);
     77}
     78
     79static void tz_mpc_iommu_notify(TZMPC *s, uint32_t lutidx,
     80                                uint32_t oldlut, uint32_t newlut)
     81{
     82    /* Called when the LUT word at lutidx has changed from oldlut to newlut;
     83     * must call the IOMMU notifiers for the changed blocks.
     84     */
     85    IOMMUTLBEvent event = {
     86        .entry = {
     87            .addr_mask = s->blocksize - 1,
     88        }
     89    };
     90    hwaddr addr = lutidx * s->blocksize * 32;
     91    int i;
     92
     93    for (i = 0; i < 32; i++, addr += s->blocksize) {
     94        bool block_is_ns;
     95
     96        if (!((oldlut ^ newlut) & (1 << i))) {
     97            continue;
     98        }
     99        /* This changes the mappings for both the S and the NS space,
    100         * so we need to do four notifies: an UNMAP then a MAP for each.
    101         */
    102        block_is_ns = newlut & (1 << i);
    103
    104        trace_tz_mpc_iommu_notify(addr);
    105        event.entry.iova = addr;
    106        event.entry.translated_addr = addr;
    107
    108        event.type = IOMMU_NOTIFIER_UNMAP;
    109        event.entry.perm = IOMMU_NONE;
    110        memory_region_notify_iommu(&s->upstream, IOMMU_IDX_S, event);
    111        memory_region_notify_iommu(&s->upstream, IOMMU_IDX_NS, event);
    112
    113        event.type = IOMMU_NOTIFIER_MAP;
    114        event.entry.perm = IOMMU_RW;
    115        if (block_is_ns) {
    116            event.entry.target_as = &s->blocked_io_as;
    117        } else {
    118            event.entry.target_as = &s->downstream_as;
    119        }
    120        memory_region_notify_iommu(&s->upstream, IOMMU_IDX_S, event);
    121        if (block_is_ns) {
    122            event.entry.target_as = &s->downstream_as;
    123        } else {
    124            event.entry.target_as = &s->blocked_io_as;
    125        }
    126        memory_region_notify_iommu(&s->upstream, IOMMU_IDX_NS, event);
    127    }
    128}
    129
    130static void tz_mpc_autoinc_idx(TZMPC *s, unsigned access_size)
    131{
    132    /* Auto-increment BLK_IDX if necessary */
    133    if (access_size == 4 && (s->ctrl & R_CTRL_AUTOINC_MASK)) {
    134        s->blk_idx++;
    135        s->blk_idx %= s->blk_max;
    136    }
    137}
    138
    139static MemTxResult tz_mpc_reg_read(void *opaque, hwaddr addr,
    140                                   uint64_t *pdata,
    141                                   unsigned size, MemTxAttrs attrs)
    142{
    143    TZMPC *s = TZ_MPC(opaque);
    144    uint64_t r;
    145    uint32_t offset = addr & ~0x3;
    146
    147    if (!attrs.secure && offset < A_PIDR4) {
    148        /* NS accesses can only see the ID registers */
    149        qemu_log_mask(LOG_GUEST_ERROR,
    150                      "TZ MPC register read: NS access to offset 0x%x\n",
    151                      offset);
    152        r = 0;
    153        goto read_out;
    154    }
    155
    156    switch (offset) {
    157    case A_CTRL:
    158        r = s->ctrl;
    159        break;
    160    case A_BLK_MAX:
    161        r = s->blk_max - 1;
    162        break;
    163    case A_BLK_CFG:
    164        /* We are never in "init in progress state", so this just indicates
    165         * the block size. s->blocksize == (1 << BLK_CFG + 5), so
    166         * BLK_CFG == ctz32(s->blocksize) - 5
    167         */
    168        r = ctz32(s->blocksize) - 5;
    169        break;
    170    case A_BLK_IDX:
    171        r = s->blk_idx;
    172        break;
    173    case A_BLK_LUT:
    174        r = s->blk_lut[s->blk_idx];
    175        tz_mpc_autoinc_idx(s, size);
    176        break;
    177    case A_INT_STAT:
    178        r = s->int_stat;
    179        break;
    180    case A_INT_EN:
    181        r = s->int_en;
    182        break;
    183    case A_INT_INFO1:
    184        r = s->int_info1;
    185        break;
    186    case A_INT_INFO2:
    187        r = s->int_info2;
    188        break;
    189    case A_PIDR4:
    190    case A_PIDR5:
    191    case A_PIDR6:
    192    case A_PIDR7:
    193    case A_PIDR0:
    194    case A_PIDR1:
    195    case A_PIDR2:
    196    case A_PIDR3:
    197    case A_CIDR0:
    198    case A_CIDR1:
    199    case A_CIDR2:
    200    case A_CIDR3:
    201        r = tz_mpc_idregs[(offset - A_PIDR4) / 4];
    202        break;
    203    case A_INT_CLEAR:
    204    case A_INT_SET:
    205        qemu_log_mask(LOG_GUEST_ERROR,
    206                      "TZ MPC register read: write-only offset 0x%x\n",
    207                      offset);
    208        r = 0;
    209        break;
    210    default:
    211        qemu_log_mask(LOG_GUEST_ERROR,
    212                      "TZ MPC register read: bad offset 0x%x\n", offset);
    213        r = 0;
    214        break;
    215    }
    216
    217    if (size != 4) {
    218        /* None of our registers are read-sensitive (except BLK_LUT,
    219         * which can special case the "size not 4" case), so just
    220         * pull the right bytes out of the word read result.
    221         */
    222        r = extract32(r, (addr & 3) * 8, size * 8);
    223    }
    224
    225read_out:
    226    trace_tz_mpc_reg_read(addr, r, size);
    227    *pdata = r;
    228    return MEMTX_OK;
    229}
    230
    231static MemTxResult tz_mpc_reg_write(void *opaque, hwaddr addr,
    232                                    uint64_t value,
    233                                    unsigned size, MemTxAttrs attrs)
    234{
    235    TZMPC *s = TZ_MPC(opaque);
    236    uint32_t offset = addr & ~0x3;
    237
    238    trace_tz_mpc_reg_write(addr, value, size);
    239
    240    if (!attrs.secure && offset < A_PIDR4) {
    241        /* NS accesses can only see the ID registers */
    242        qemu_log_mask(LOG_GUEST_ERROR,
    243                      "TZ MPC register write: NS access to offset 0x%x\n",
    244                      offset);
    245        return MEMTX_OK;
    246    }
    247
    248    if (size != 4) {
    249        /* Expand the byte or halfword write to a full word size.
    250         * In most cases we can do this with zeroes; the exceptions
    251         * are CTRL, BLK_IDX and BLK_LUT.
    252         */
    253        uint32_t oldval;
    254
    255        switch (offset) {
    256        case A_CTRL:
    257            oldval = s->ctrl;
    258            break;
    259        case A_BLK_IDX:
    260            oldval = s->blk_idx;
    261            break;
    262        case A_BLK_LUT:
    263            oldval = s->blk_lut[s->blk_idx];
    264            break;
    265        default:
    266            oldval = 0;
    267            break;
    268        }
    269        value = deposit32(oldval, (addr & 3) * 8, size * 8, value);
    270    }
    271
    272    if ((s->ctrl & R_CTRL_LOCKDOWN_MASK) &&
    273        (offset == A_CTRL || offset == A_BLK_LUT || offset == A_INT_EN)) {
    274        /* Lockdown mode makes these three registers read-only, and
    275         * the only way out of it is to reset the device.
    276         */
    277        qemu_log_mask(LOG_GUEST_ERROR, "TZ MPC register write to offset 0x%x "
    278                      "while MPC is in lockdown mode\n", offset);
    279        return MEMTX_OK;
    280    }
    281
    282    switch (offset) {
    283    case A_CTRL:
    284        /* We don't implement the 'data gating' feature so all other bits
    285         * are reserved and we make them RAZ/WI.
    286         */
    287        s->ctrl = value & (R_CTRL_SEC_RESP_MASK |
    288                           R_CTRL_AUTOINC_MASK |
    289                           R_CTRL_LOCKDOWN_MASK);
    290        break;
    291    case A_BLK_IDX:
    292        s->blk_idx = value % s->blk_max;
    293        break;
    294    case A_BLK_LUT:
    295        tz_mpc_iommu_notify(s, s->blk_idx, s->blk_lut[s->blk_idx], value);
    296        s->blk_lut[s->blk_idx] = value;
    297        tz_mpc_autoinc_idx(s, size);
    298        break;
    299    case A_INT_CLEAR:
    300        if (value & R_INT_CLEAR_IRQ_MASK) {
    301            s->int_stat = 0;
    302            tz_mpc_irq_update(s);
    303        }
    304        break;
    305    case A_INT_EN:
    306        s->int_en = value & R_INT_EN_IRQ_MASK;
    307        tz_mpc_irq_update(s);
    308        break;
    309    case A_INT_SET:
    310        if (value & R_INT_SET_IRQ_MASK) {
    311            s->int_stat = R_INT_STAT_IRQ_MASK;
    312            tz_mpc_irq_update(s);
    313        }
    314        break;
    315    case A_PIDR4:
    316    case A_PIDR5:
    317    case A_PIDR6:
    318    case A_PIDR7:
    319    case A_PIDR0:
    320    case A_PIDR1:
    321    case A_PIDR2:
    322    case A_PIDR3:
    323    case A_CIDR0:
    324    case A_CIDR1:
    325    case A_CIDR2:
    326    case A_CIDR3:
    327        qemu_log_mask(LOG_GUEST_ERROR,
    328                      "TZ MPC register write: read-only offset 0x%x\n", offset);
    329        break;
    330    default:
    331        qemu_log_mask(LOG_GUEST_ERROR,
    332                      "TZ MPC register write: bad offset 0x%x\n", offset);
    333        break;
    334    }
    335
    336    return MEMTX_OK;
    337}
    338
    339static const MemoryRegionOps tz_mpc_reg_ops = {
    340    .read_with_attrs = tz_mpc_reg_read,
    341    .write_with_attrs = tz_mpc_reg_write,
    342    .endianness = DEVICE_LITTLE_ENDIAN,
    343    .valid.min_access_size = 1,
    344    .valid.max_access_size = 4,
    345    .impl.min_access_size = 1,
    346    .impl.max_access_size = 4,
    347};
    348
    349static inline bool tz_mpc_cfg_ns(TZMPC *s, hwaddr addr)
    350{
    351    /* Return the cfg_ns bit from the LUT for the specified address */
    352    hwaddr blknum = addr / s->blocksize;
    353    hwaddr blkword = blknum / 32;
    354    uint32_t blkbit = 1U << (blknum % 32);
    355
    356    /* This would imply the address was larger than the size we
    357     * defined this memory region to be, so it can't happen.
    358     */
    359    assert(blkword < s->blk_max);
    360    return s->blk_lut[blkword] & blkbit;
    361}
    362
    363static MemTxResult tz_mpc_handle_block(TZMPC *s, hwaddr addr, MemTxAttrs attrs)
    364{
    365    /* Handle a blocked transaction: raise IRQ, capture info, etc */
    366    if (!s->int_stat) {
    367        /* First blocked transfer: capture information into INT_INFO1 and
    368         * INT_INFO2. Subsequent transfers are still blocked but don't
    369         * capture information until the guest clears the interrupt.
    370         */
    371
    372        s->int_info1 = addr;
    373        s->int_info2 = 0;
    374        s->int_info2 = FIELD_DP32(s->int_info2, INT_INFO2, HMASTER,
    375                                  attrs.requester_id & 0xffff);
    376        s->int_info2 = FIELD_DP32(s->int_info2, INT_INFO2, HNONSEC,
    377                                  ~attrs.secure);
    378        s->int_info2 = FIELD_DP32(s->int_info2, INT_INFO2, CFG_NS,
    379                                  tz_mpc_cfg_ns(s, addr));
    380        s->int_stat |= R_INT_STAT_IRQ_MASK;
    381        tz_mpc_irq_update(s);
    382    }
    383
    384    /* Generate bus error if desired; otherwise RAZ/WI */
    385    return (s->ctrl & R_CTRL_SEC_RESP_MASK) ? MEMTX_ERROR : MEMTX_OK;
    386}
    387
    388/* Accesses only reach these read and write functions if the MPC is
    389 * blocking them; non-blocked accesses go directly to the downstream
    390 * memory region without passing through this code.
    391 */
    392static MemTxResult tz_mpc_mem_blocked_read(void *opaque, hwaddr addr,
    393                                           uint64_t *pdata,
    394                                           unsigned size, MemTxAttrs attrs)
    395{
    396    TZMPC *s = TZ_MPC(opaque);
    397
    398    trace_tz_mpc_mem_blocked_read(addr, size, attrs.secure);
    399
    400    *pdata = 0;
    401    return tz_mpc_handle_block(s, addr, attrs);
    402}
    403
    404static MemTxResult tz_mpc_mem_blocked_write(void *opaque, hwaddr addr,
    405                                            uint64_t value,
    406                                            unsigned size, MemTxAttrs attrs)
    407{
    408    TZMPC *s = TZ_MPC(opaque);
    409
    410    trace_tz_mpc_mem_blocked_write(addr, value, size, attrs.secure);
    411
    412    return tz_mpc_handle_block(s, addr, attrs);
    413}
    414
    415static const MemoryRegionOps tz_mpc_mem_blocked_ops = {
    416    .read_with_attrs = tz_mpc_mem_blocked_read,
    417    .write_with_attrs = tz_mpc_mem_blocked_write,
    418    .endianness = DEVICE_LITTLE_ENDIAN,
    419    .valid.min_access_size = 1,
    420    .valid.max_access_size = 8,
    421    .impl.min_access_size = 1,
    422    .impl.max_access_size = 8,
    423};
    424
    425static IOMMUTLBEntry tz_mpc_translate(IOMMUMemoryRegion *iommu,
    426                                      hwaddr addr, IOMMUAccessFlags flags,
    427                                      int iommu_idx)
    428{
    429    TZMPC *s = TZ_MPC(container_of(iommu, TZMPC, upstream));
    430    bool ok;
    431
    432    IOMMUTLBEntry ret = {
    433        .iova = addr & ~(s->blocksize - 1),
    434        .translated_addr = addr & ~(s->blocksize - 1),
    435        .addr_mask = s->blocksize - 1,
    436        .perm = IOMMU_RW,
    437    };
    438
    439    /* Look at the per-block configuration for this address, and
    440     * return a TLB entry directing the transaction at either
    441     * downstream_as or blocked_io_as, as appropriate.
    442     * If the LUT cfg_ns bit is 1, only non-secure transactions
    443     * may pass. If the bit is 0, only secure transactions may pass.
    444     */
    445    ok = tz_mpc_cfg_ns(s, addr) == (iommu_idx == IOMMU_IDX_NS);
    446
    447    trace_tz_mpc_translate(addr, flags,
    448                           iommu_idx == IOMMU_IDX_S ? "S" : "NS",
    449                           ok ? "pass" : "block");
    450
    451    ret.target_as = ok ? &s->downstream_as : &s->blocked_io_as;
    452    return ret;
    453}
    454
    455static int tz_mpc_attrs_to_index(IOMMUMemoryRegion *iommu, MemTxAttrs attrs)
    456{
    457    /* We treat unspecified attributes like secure. Transactions with
    458     * unspecified attributes come from places like
    459     * rom_reset() for initial image load, and we want
    460     * those to pass through the from-reset "everything is secure" config.
    461     * All the real during-emulation transactions from the CPU will
    462     * specify attributes.
    463     */
    464    return (attrs.unspecified || attrs.secure) ? IOMMU_IDX_S : IOMMU_IDX_NS;
    465}
    466
    467static int tz_mpc_num_indexes(IOMMUMemoryRegion *iommu)
    468{
    469    return IOMMU_NUM_INDEXES;
    470}
    471
    472static void tz_mpc_reset(DeviceState *dev)
    473{
    474    TZMPC *s = TZ_MPC(dev);
    475
    476    s->ctrl = 0x00000100;
    477    s->blk_idx = 0;
    478    s->int_stat = 0;
    479    s->int_en = 1;
    480    s->int_info1 = 0;
    481    s->int_info2 = 0;
    482
    483    memset(s->blk_lut, 0, s->blk_max * sizeof(uint32_t));
    484}
    485
    486static void tz_mpc_init(Object *obj)
    487{
    488    DeviceState *dev = DEVICE(obj);
    489    TZMPC *s = TZ_MPC(obj);
    490
    491    qdev_init_gpio_out_named(dev, &s->irq, "irq", 1);
    492}
    493
    494static void tz_mpc_realize(DeviceState *dev, Error **errp)
    495{
    496    Object *obj = OBJECT(dev);
    497    SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
    498    TZMPC *s = TZ_MPC(dev);
    499    uint64_t size;
    500
    501    /* We can't create the upstream end of the port until realize,
    502     * as we don't know the size of the MR used as the downstream until then.
    503     * We insist on having a downstream, to avoid complicating the code
    504     * with handling the "don't know how big this is" case. It's easy
    505     * enough for the user to create an unimplemented_device as downstream
    506     * if they have nothing else to plug into this.
    507     */
    508    if (!s->downstream) {
    509        error_setg(errp, "MPC 'downstream' link not set");
    510        return;
    511    }
    512
    513    size = memory_region_size(s->downstream);
    514
    515    memory_region_init_iommu(&s->upstream, sizeof(s->upstream),
    516                             TYPE_TZ_MPC_IOMMU_MEMORY_REGION,
    517                             obj, "tz-mpc-upstream", size);
    518
    519    /* In real hardware the block size is configurable. In QEMU we could
    520     * make it configurable but will need it to be at least as big as the
    521     * target page size so we can execute out of the resulting MRs. Guest
    522     * software is supposed to check the block size using the BLK_CFG
    523     * register, so make it fixed at the page size.
    524     */
    525    s->blocksize = memory_region_iommu_get_min_page_size(&s->upstream);
    526    if (size % s->blocksize != 0) {
    527        error_setg(errp,
    528                   "MPC 'downstream' size %" PRId64
    529                   " is not a multiple of %" HWADDR_PRIx " bytes",
    530                   size, s->blocksize);
    531        object_unref(OBJECT(&s->upstream));
    532        return;
    533    }
    534
    535    /* BLK_MAX is the max value of BLK_IDX, which indexes an array of 32-bit
    536     * words, each bit of which indicates one block.
    537     */
    538    s->blk_max = DIV_ROUND_UP(size / s->blocksize, 32);
    539
    540    memory_region_init_io(&s->regmr, obj, &tz_mpc_reg_ops,
    541                          s, "tz-mpc-regs", 0x1000);
    542    sysbus_init_mmio(sbd, &s->regmr);
    543
    544    sysbus_init_mmio(sbd, MEMORY_REGION(&s->upstream));
    545
    546    /* This memory region is not exposed to users of this device as a
    547     * sysbus MMIO region, but is instead used internally as something
    548     * that our IOMMU translate function might direct accesses to.
    549     */
    550    memory_region_init_io(&s->blocked_io, obj, &tz_mpc_mem_blocked_ops,
    551                          s, "tz-mpc-blocked-io", size);
    552
    553    address_space_init(&s->downstream_as, s->downstream,
    554                       "tz-mpc-downstream");
    555    address_space_init(&s->blocked_io_as, &s->blocked_io,
    556                       "tz-mpc-blocked-io");
    557
    558    s->blk_lut = g_new0(uint32_t, s->blk_max);
    559}
    560
    561static int tz_mpc_post_load(void *opaque, int version_id)
    562{
    563    TZMPC *s = TZ_MPC(opaque);
    564
    565    /* Check the incoming data doesn't point blk_idx off the end of blk_lut. */
    566    if (s->blk_idx >= s->blk_max) {
    567        return -1;
    568    }
    569    return 0;
    570}
    571
    572static const VMStateDescription tz_mpc_vmstate = {
    573    .name = "tz-mpc",
    574    .version_id = 1,
    575    .minimum_version_id = 1,
    576    .post_load = tz_mpc_post_load,
    577    .fields = (VMStateField[]) {
    578        VMSTATE_UINT32(ctrl, TZMPC),
    579        VMSTATE_UINT32(blk_idx, TZMPC),
    580        VMSTATE_UINT32(int_stat, TZMPC),
    581        VMSTATE_UINT32(int_en, TZMPC),
    582        VMSTATE_UINT32(int_info1, TZMPC),
    583        VMSTATE_UINT32(int_info2, TZMPC),
    584        VMSTATE_VARRAY_UINT32(blk_lut, TZMPC, blk_max,
    585                              0, vmstate_info_uint32, uint32_t),
    586        VMSTATE_END_OF_LIST()
    587    }
    588};
    589
    590static Property tz_mpc_properties[] = {
    591    DEFINE_PROP_LINK("downstream", TZMPC, downstream,
    592                     TYPE_MEMORY_REGION, MemoryRegion *),
    593    DEFINE_PROP_END_OF_LIST(),
    594};
    595
    596static void tz_mpc_class_init(ObjectClass *klass, void *data)
    597{
    598    DeviceClass *dc = DEVICE_CLASS(klass);
    599
    600    dc->realize = tz_mpc_realize;
    601    dc->vmsd = &tz_mpc_vmstate;
    602    dc->reset = tz_mpc_reset;
    603    device_class_set_props(dc, tz_mpc_properties);
    604}
    605
    606static const TypeInfo tz_mpc_info = {
    607    .name = TYPE_TZ_MPC,
    608    .parent = TYPE_SYS_BUS_DEVICE,
    609    .instance_size = sizeof(TZMPC),
    610    .instance_init = tz_mpc_init,
    611    .class_init = tz_mpc_class_init,
    612};
    613
    614static void tz_mpc_iommu_memory_region_class_init(ObjectClass *klass,
    615                                                  void *data)
    616{
    617    IOMMUMemoryRegionClass *imrc = IOMMU_MEMORY_REGION_CLASS(klass);
    618
    619    imrc->translate = tz_mpc_translate;
    620    imrc->attrs_to_index = tz_mpc_attrs_to_index;
    621    imrc->num_indexes = tz_mpc_num_indexes;
    622}
    623
    624static const TypeInfo tz_mpc_iommu_memory_region_info = {
    625    .name = TYPE_TZ_MPC_IOMMU_MEMORY_REGION,
    626    .parent = TYPE_IOMMU_MEMORY_REGION,
    627    .class_init = tz_mpc_iommu_memory_region_class_init,
    628};
    629
    630static void tz_mpc_register_types(void)
    631{
    632    type_register_static(&tz_mpc_info);
    633    type_register_static(&tz_mpc_iommu_memory_region_info);
    634}
    635
    636type_init(tz_mpc_register_types);