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