qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

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  */
     27 enum {
     28     IOMMU_IDX_S,
     29     IOMMU_IDX_NS,
     30     IOMMU_NUM_INDEXES,
     31 };
     32 
     33 /* Config registers */
     34 REG32(CTRL, 0x00)
     35     FIELD(CTRL, SEC_RESP, 4, 1)
     36     FIELD(CTRL, AUTOINC, 8, 1)
     37     FIELD(CTRL, LOCKDOWN, 31, 1)
     38 REG32(BLK_MAX, 0x10)
     39 REG32(BLK_CFG, 0x14)
     40 REG32(BLK_IDX, 0x18)
     41 REG32(BLK_LUT, 0x1c)
     42 REG32(INT_STAT, 0x20)
     43     FIELD(INT_STAT, IRQ, 0, 1)
     44 REG32(INT_CLEAR, 0x24)
     45     FIELD(INT_CLEAR, IRQ, 0, 1)
     46 REG32(INT_EN, 0x28)
     47     FIELD(INT_EN, IRQ, 0, 1)
     48 REG32(INT_INFO1, 0x2c)
     49 REG32(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)
     53 REG32(INT_SET, 0x34)
     54     FIELD(INT_SET, IRQ, 0, 1)
     55 REG32(PIDR4, 0xfd0)
     56 REG32(PIDR5, 0xfd4)
     57 REG32(PIDR6, 0xfd8)
     58 REG32(PIDR7, 0xfdc)
     59 REG32(PIDR0, 0xfe0)
     60 REG32(PIDR1, 0xfe4)
     61 REG32(PIDR2, 0xfe8)
     62 REG32(PIDR3, 0xfec)
     63 REG32(CIDR0, 0xff0)
     64 REG32(CIDR1, 0xff4)
     65 REG32(CIDR2, 0xff8)
     66 REG32(CIDR3, 0xffc)
     67 
     68 static const uint8_t tz_mpc_idregs[] = {
     69     0x04, 0x00, 0x00, 0x00,
     70     0x60, 0xb8, 0x1b, 0x00,
     71     0x0d, 0xf0, 0x05, 0xb1,
     72 };
     73 
     74 static void tz_mpc_irq_update(TZMPC *s)
     75 {
     76     qemu_set_irq(s->irq, s->int_stat && s->int_en);
     77 }
     78 
     79 static 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 
    130 static 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 
    139 static 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 
    225 read_out:
    226     trace_tz_mpc_reg_read(addr, r, size);
    227     *pdata = r;
    228     return MEMTX_OK;
    229 }
    230 
    231 static 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 
    339 static 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 
    349 static 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 
    363 static 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  */
    392 static 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 
    404 static 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 
    415 static 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 
    425 static 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 
    455 static 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 
    467 static int tz_mpc_num_indexes(IOMMUMemoryRegion *iommu)
    468 {
    469     return IOMMU_NUM_INDEXES;
    470 }
    471 
    472 static 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 
    486 static 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 
    494 static 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 
    561 static 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 
    572 static 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 
    590 static Property tz_mpc_properties[] = {
    591     DEFINE_PROP_LINK("downstream", TZMPC, downstream,
    592                      TYPE_MEMORY_REGION, MemoryRegion *),
    593     DEFINE_PROP_END_OF_LIST(),
    594 };
    595 
    596 static 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 
    606 static 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 
    614 static 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 
    624 static 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 
    630 static 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 
    636 type_init(tz_mpc_register_types);