2 * ARM AHB5 TrustZone Memory Protection Controller emulation
4 * Copyright (c) 2018 Linaro Limited
5 * Written by Peter Maydell
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.
12 #include "qemu/osdep.h"
14 #include "qemu/module.h"
15 #include "qapi/error.h"
17 #include "hw/sysbus.h"
18 #include "migration/vmstate.h"
19 #include "hw/registerfields.h"
21 #include "hw/misc/tz-mpc.h"
23 /* Our IOMMU has two IOMMU indexes, one for secure transactions and one for
24 * non-secure transactions.
32 /* Config registers */
34 FIELD(CTRL
, SEC_RESP
, 4, 1)
35 FIELD(CTRL
, AUTOINC
, 8, 1)
36 FIELD(CTRL
, LOCKDOWN
, 31, 1)
42 FIELD(INT_STAT
, IRQ
, 0, 1)
43 REG32(INT_CLEAR
, 0x24)
44 FIELD(INT_CLEAR
, IRQ
, 0, 1)
46 FIELD(INT_EN
, IRQ
, 0, 1)
47 REG32(INT_INFO1
, 0x2c)
48 REG32(INT_INFO2
, 0x30)
49 FIELD(INT_INFO2
, HMASTER
, 0, 16)
50 FIELD(INT_INFO2
, HNONSEC
, 16, 1)
51 FIELD(INT_INFO2
, CFG_NS
, 17, 1)
53 FIELD(INT_SET
, IRQ
, 0, 1)
67 static const uint8_t tz_mpc_idregs
[] = {
68 0x04, 0x00, 0x00, 0x00,
69 0x60, 0xb8, 0x1b, 0x00,
70 0x0d, 0xf0, 0x05, 0xb1,
73 static void tz_mpc_irq_update(TZMPC
*s
)
75 qemu_set_irq(s
->irq
, s
->int_stat
&& s
->int_en
);
78 static void tz_mpc_iommu_notify(TZMPC
*s
, uint32_t lutidx
,
79 uint32_t oldlut
, uint32_t newlut
)
81 /* Called when the LUT word at lutidx has changed from oldlut to newlut;
82 * must call the IOMMU notifiers for the changed blocks.
84 IOMMUTLBEntry entry
= {
85 .addr_mask
= s
->blocksize
- 1,
87 hwaddr addr
= lutidx
* s
->blocksize
* 32;
90 for (i
= 0; i
< 32; i
++, addr
+= s
->blocksize
) {
93 if (!((oldlut
^ newlut
) & (1 << i
))) {
96 /* This changes the mappings for both the S and the NS space,
97 * so we need to do four notifies: an UNMAP then a MAP for each.
99 block_is_ns
= newlut
& (1 << i
);
101 trace_tz_mpc_iommu_notify(addr
);
103 entry
.translated_addr
= addr
;
105 entry
.perm
= IOMMU_NONE
;
106 memory_region_notify_iommu(&s
->upstream
, IOMMU_IDX_S
, entry
);
107 memory_region_notify_iommu(&s
->upstream
, IOMMU_IDX_NS
, entry
);
109 entry
.perm
= IOMMU_RW
;
111 entry
.target_as
= &s
->blocked_io_as
;
113 entry
.target_as
= &s
->downstream_as
;
115 memory_region_notify_iommu(&s
->upstream
, IOMMU_IDX_S
, entry
);
117 entry
.target_as
= &s
->downstream_as
;
119 entry
.target_as
= &s
->blocked_io_as
;
121 memory_region_notify_iommu(&s
->upstream
, IOMMU_IDX_NS
, entry
);
125 static void tz_mpc_autoinc_idx(TZMPC
*s
, unsigned access_size
)
127 /* Auto-increment BLK_IDX if necessary */
128 if (access_size
== 4 && (s
->ctrl
& R_CTRL_AUTOINC_MASK
)) {
130 s
->blk_idx
%= s
->blk_max
;
134 static MemTxResult
tz_mpc_reg_read(void *opaque
, hwaddr addr
,
136 unsigned size
, MemTxAttrs attrs
)
138 TZMPC
*s
= TZ_MPC(opaque
);
140 uint32_t offset
= addr
& ~0x3;
142 if (!attrs
.secure
&& offset
< A_PIDR4
) {
143 /* NS accesses can only see the ID registers */
144 qemu_log_mask(LOG_GUEST_ERROR
,
145 "TZ MPC register read: NS access to offset 0x%x\n",
159 /* We are never in "init in progress state", so this just indicates
160 * the block size. s->blocksize == (1 << BLK_CFG + 5), so
161 * BLK_CFG == ctz32(s->blocksize) - 5
163 r
= ctz32(s
->blocksize
) - 5;
169 r
= s
->blk_lut
[s
->blk_idx
];
170 tz_mpc_autoinc_idx(s
, size
);
196 r
= tz_mpc_idregs
[(offset
- A_PIDR4
) / 4];
200 qemu_log_mask(LOG_GUEST_ERROR
,
201 "TZ MPC register read: write-only offset 0x%x\n",
206 qemu_log_mask(LOG_GUEST_ERROR
,
207 "TZ MPC register read: bad offset 0x%x\n", offset
);
213 /* None of our registers are read-sensitive (except BLK_LUT,
214 * which can special case the "size not 4" case), so just
215 * pull the right bytes out of the word read result.
217 r
= extract32(r
, (addr
& 3) * 8, size
* 8);
221 trace_tz_mpc_reg_read(addr
, r
, size
);
226 static MemTxResult
tz_mpc_reg_write(void *opaque
, hwaddr addr
,
228 unsigned size
, MemTxAttrs attrs
)
230 TZMPC
*s
= TZ_MPC(opaque
);
231 uint32_t offset
= addr
& ~0x3;
233 trace_tz_mpc_reg_write(addr
, value
, size
);
235 if (!attrs
.secure
&& offset
< A_PIDR4
) {
236 /* NS accesses can only see the ID registers */
237 qemu_log_mask(LOG_GUEST_ERROR
,
238 "TZ MPC register write: NS access to offset 0x%x\n",
244 /* Expand the byte or halfword write to a full word size.
245 * In most cases we can do this with zeroes; the exceptions
246 * are CTRL, BLK_IDX and BLK_LUT.
258 oldval
= s
->blk_lut
[s
->blk_idx
];
264 value
= deposit32(oldval
, (addr
& 3) * 8, size
* 8, value
);
267 if ((s
->ctrl
& R_CTRL_LOCKDOWN_MASK
) &&
268 (offset
== A_CTRL
|| offset
== A_BLK_LUT
|| offset
== A_INT_EN
)) {
269 /* Lockdown mode makes these three registers read-only, and
270 * the only way out of it is to reset the device.
272 qemu_log_mask(LOG_GUEST_ERROR
, "TZ MPC register write to offset 0x%x "
273 "while MPC is in lockdown mode\n", offset
);
279 /* We don't implement the 'data gating' feature so all other bits
280 * are reserved and we make them RAZ/WI.
282 s
->ctrl
= value
& (R_CTRL_SEC_RESP_MASK
|
283 R_CTRL_AUTOINC_MASK
|
284 R_CTRL_LOCKDOWN_MASK
);
287 s
->blk_idx
= value
% s
->blk_max
;
290 tz_mpc_iommu_notify(s
, s
->blk_idx
, s
->blk_lut
[s
->blk_idx
], value
);
291 s
->blk_lut
[s
->blk_idx
] = value
;
292 tz_mpc_autoinc_idx(s
, size
);
295 if (value
& R_INT_CLEAR_IRQ_MASK
) {
297 tz_mpc_irq_update(s
);
301 s
->int_en
= value
& R_INT_EN_IRQ_MASK
;
302 tz_mpc_irq_update(s
);
305 if (value
& R_INT_SET_IRQ_MASK
) {
306 s
->int_stat
= R_INT_STAT_IRQ_MASK
;
307 tz_mpc_irq_update(s
);
322 qemu_log_mask(LOG_GUEST_ERROR
,
323 "TZ MPC register write: read-only offset 0x%x\n", offset
);
326 qemu_log_mask(LOG_GUEST_ERROR
,
327 "TZ MPC register write: bad offset 0x%x\n", offset
);
334 static const MemoryRegionOps tz_mpc_reg_ops
= {
335 .read_with_attrs
= tz_mpc_reg_read
,
336 .write_with_attrs
= tz_mpc_reg_write
,
337 .endianness
= DEVICE_LITTLE_ENDIAN
,
338 .valid
.min_access_size
= 1,
339 .valid
.max_access_size
= 4,
340 .impl
.min_access_size
= 1,
341 .impl
.max_access_size
= 4,
344 static inline bool tz_mpc_cfg_ns(TZMPC
*s
, hwaddr addr
)
346 /* Return the cfg_ns bit from the LUT for the specified address */
347 hwaddr blknum
= addr
/ s
->blocksize
;
348 hwaddr blkword
= blknum
/ 32;
349 uint32_t blkbit
= 1U << (blknum
% 32);
351 /* This would imply the address was larger than the size we
352 * defined this memory region to be, so it can't happen.
354 assert(blkword
< s
->blk_max
);
355 return s
->blk_lut
[blkword
] & blkbit
;
358 static MemTxResult
tz_mpc_handle_block(TZMPC
*s
, hwaddr addr
, MemTxAttrs attrs
)
360 /* Handle a blocked transaction: raise IRQ, capture info, etc */
362 /* First blocked transfer: capture information into INT_INFO1 and
363 * INT_INFO2. Subsequent transfers are still blocked but don't
364 * capture information until the guest clears the interrupt.
369 s
->int_info2
= FIELD_DP32(s
->int_info2
, INT_INFO2
, HMASTER
,
370 attrs
.requester_id
& 0xffff);
371 s
->int_info2
= FIELD_DP32(s
->int_info2
, INT_INFO2
, HNONSEC
,
373 s
->int_info2
= FIELD_DP32(s
->int_info2
, INT_INFO2
, CFG_NS
,
374 tz_mpc_cfg_ns(s
, addr
));
375 s
->int_stat
|= R_INT_STAT_IRQ_MASK
;
376 tz_mpc_irq_update(s
);
379 /* Generate bus error if desired; otherwise RAZ/WI */
380 return (s
->ctrl
& R_CTRL_SEC_RESP_MASK
) ? MEMTX_ERROR
: MEMTX_OK
;
383 /* Accesses only reach these read and write functions if the MPC is
384 * blocking them; non-blocked accesses go directly to the downstream
385 * memory region without passing through this code.
387 static MemTxResult
tz_mpc_mem_blocked_read(void *opaque
, hwaddr addr
,
389 unsigned size
, MemTxAttrs attrs
)
391 TZMPC
*s
= TZ_MPC(opaque
);
393 trace_tz_mpc_mem_blocked_read(addr
, size
, attrs
.secure
);
396 return tz_mpc_handle_block(s
, addr
, attrs
);
399 static MemTxResult
tz_mpc_mem_blocked_write(void *opaque
, hwaddr addr
,
401 unsigned size
, MemTxAttrs attrs
)
403 TZMPC
*s
= TZ_MPC(opaque
);
405 trace_tz_mpc_mem_blocked_write(addr
, value
, size
, attrs
.secure
);
407 return tz_mpc_handle_block(s
, addr
, attrs
);
410 static const MemoryRegionOps tz_mpc_mem_blocked_ops
= {
411 .read_with_attrs
= tz_mpc_mem_blocked_read
,
412 .write_with_attrs
= tz_mpc_mem_blocked_write
,
413 .endianness
= DEVICE_LITTLE_ENDIAN
,
414 .valid
.min_access_size
= 1,
415 .valid
.max_access_size
= 8,
416 .impl
.min_access_size
= 1,
417 .impl
.max_access_size
= 8,
420 static IOMMUTLBEntry
tz_mpc_translate(IOMMUMemoryRegion
*iommu
,
421 hwaddr addr
, IOMMUAccessFlags flags
,
424 TZMPC
*s
= TZ_MPC(container_of(iommu
, TZMPC
, upstream
));
427 IOMMUTLBEntry ret
= {
428 .iova
= addr
& ~(s
->blocksize
- 1),
429 .translated_addr
= addr
& ~(s
->blocksize
- 1),
430 .addr_mask
= s
->blocksize
- 1,
434 /* Look at the per-block configuration for this address, and
435 * return a TLB entry directing the transaction at either
436 * downstream_as or blocked_io_as, as appropriate.
437 * If the LUT cfg_ns bit is 1, only non-secure transactions
438 * may pass. If the bit is 0, only secure transactions may pass.
440 ok
= tz_mpc_cfg_ns(s
, addr
) == (iommu_idx
== IOMMU_IDX_NS
);
442 trace_tz_mpc_translate(addr
, flags
,
443 iommu_idx
== IOMMU_IDX_S
? "S" : "NS",
444 ok
? "pass" : "block");
446 ret
.target_as
= ok
? &s
->downstream_as
: &s
->blocked_io_as
;
450 static int tz_mpc_attrs_to_index(IOMMUMemoryRegion
*iommu
, MemTxAttrs attrs
)
452 /* We treat unspecified attributes like secure. Transactions with
453 * unspecified attributes come from places like
454 * rom_reset() for initial image load, and we want
455 * those to pass through the from-reset "everything is secure" config.
456 * All the real during-emulation transactions from the CPU will
457 * specify attributes.
459 return (attrs
.unspecified
|| attrs
.secure
) ? IOMMU_IDX_S
: IOMMU_IDX_NS
;
462 static int tz_mpc_num_indexes(IOMMUMemoryRegion
*iommu
)
464 return IOMMU_NUM_INDEXES
;
467 static void tz_mpc_reset(DeviceState
*dev
)
469 TZMPC
*s
= TZ_MPC(dev
);
471 s
->ctrl
= 0x00000100;
478 memset(s
->blk_lut
, 0, s
->blk_max
* sizeof(uint32_t));
481 static void tz_mpc_init(Object
*obj
)
483 DeviceState
*dev
= DEVICE(obj
);
484 TZMPC
*s
= TZ_MPC(obj
);
486 qdev_init_gpio_out_named(dev
, &s
->irq
, "irq", 1);
489 static void tz_mpc_realize(DeviceState
*dev
, Error
**errp
)
491 Object
*obj
= OBJECT(dev
);
492 SysBusDevice
*sbd
= SYS_BUS_DEVICE(dev
);
493 TZMPC
*s
= TZ_MPC(dev
);
496 /* We can't create the upstream end of the port until realize,
497 * as we don't know the size of the MR used as the downstream until then.
498 * We insist on having a downstream, to avoid complicating the code
499 * with handling the "don't know how big this is" case. It's easy
500 * enough for the user to create an unimplemented_device as downstream
501 * if they have nothing else to plug into this.
503 if (!s
->downstream
) {
504 error_setg(errp
, "MPC 'downstream' link not set");
508 size
= memory_region_size(s
->downstream
);
510 memory_region_init_iommu(&s
->upstream
, sizeof(s
->upstream
),
511 TYPE_TZ_MPC_IOMMU_MEMORY_REGION
,
512 obj
, "tz-mpc-upstream", size
);
514 /* In real hardware the block size is configurable. In QEMU we could
515 * make it configurable but will need it to be at least as big as the
516 * target page size so we can execute out of the resulting MRs. Guest
517 * software is supposed to check the block size using the BLK_CFG
518 * register, so make it fixed at the page size.
520 s
->blocksize
= memory_region_iommu_get_min_page_size(&s
->upstream
);
521 if (size
% s
->blocksize
!= 0) {
523 "MPC 'downstream' size %" PRId64
524 " is not a multiple of %" HWADDR_PRIx
" bytes",
526 object_unref(OBJECT(&s
->upstream
));
530 /* BLK_MAX is the max value of BLK_IDX, which indexes an array of 32-bit
531 * words, each bit of which indicates one block.
533 s
->blk_max
= DIV_ROUND_UP(size
/ s
->blocksize
, 32);
535 memory_region_init_io(&s
->regmr
, obj
, &tz_mpc_reg_ops
,
536 s
, "tz-mpc-regs", 0x1000);
537 sysbus_init_mmio(sbd
, &s
->regmr
);
539 sysbus_init_mmio(sbd
, MEMORY_REGION(&s
->upstream
));
541 /* This memory region is not exposed to users of this device as a
542 * sysbus MMIO region, but is instead used internally as something
543 * that our IOMMU translate function might direct accesses to.
545 memory_region_init_io(&s
->blocked_io
, obj
, &tz_mpc_mem_blocked_ops
,
546 s
, "tz-mpc-blocked-io", size
);
548 address_space_init(&s
->downstream_as
, s
->downstream
,
549 "tz-mpc-downstream");
550 address_space_init(&s
->blocked_io_as
, &s
->blocked_io
,
551 "tz-mpc-blocked-io");
553 s
->blk_lut
= g_new0(uint32_t, s
->blk_max
);
556 static int tz_mpc_post_load(void *opaque
, int version_id
)
558 TZMPC
*s
= TZ_MPC(opaque
);
560 /* Check the incoming data doesn't point blk_idx off the end of blk_lut. */
561 if (s
->blk_idx
>= s
->blk_max
) {
567 static const VMStateDescription tz_mpc_vmstate
= {
570 .minimum_version_id
= 1,
571 .post_load
= tz_mpc_post_load
,
572 .fields
= (VMStateField
[]) {
573 VMSTATE_UINT32(ctrl
, TZMPC
),
574 VMSTATE_UINT32(blk_idx
, TZMPC
),
575 VMSTATE_UINT32(int_stat
, TZMPC
),
576 VMSTATE_UINT32(int_en
, TZMPC
),
577 VMSTATE_UINT32(int_info1
, TZMPC
),
578 VMSTATE_UINT32(int_info2
, TZMPC
),
579 VMSTATE_VARRAY_UINT32(blk_lut
, TZMPC
, blk_max
,
580 0, vmstate_info_uint32
, uint32_t),
581 VMSTATE_END_OF_LIST()
585 static Property tz_mpc_properties
[] = {
586 DEFINE_PROP_LINK("downstream", TZMPC
, downstream
,
587 TYPE_MEMORY_REGION
, MemoryRegion
*),
588 DEFINE_PROP_END_OF_LIST(),
591 static void tz_mpc_class_init(ObjectClass
*klass
, void *data
)
593 DeviceClass
*dc
= DEVICE_CLASS(klass
);
595 dc
->realize
= tz_mpc_realize
;
596 dc
->vmsd
= &tz_mpc_vmstate
;
597 dc
->reset
= tz_mpc_reset
;
598 dc
->props
= tz_mpc_properties
;
601 static const TypeInfo tz_mpc_info
= {
603 .parent
= TYPE_SYS_BUS_DEVICE
,
604 .instance_size
= sizeof(TZMPC
),
605 .instance_init
= tz_mpc_init
,
606 .class_init
= tz_mpc_class_init
,
609 static void tz_mpc_iommu_memory_region_class_init(ObjectClass
*klass
,
612 IOMMUMemoryRegionClass
*imrc
= IOMMU_MEMORY_REGION_CLASS(klass
);
614 imrc
->translate
= tz_mpc_translate
;
615 imrc
->attrs_to_index
= tz_mpc_attrs_to_index
;
616 imrc
->num_indexes
= tz_mpc_num_indexes
;
619 static const TypeInfo tz_mpc_iommu_memory_region_info
= {
620 .name
= TYPE_TZ_MPC_IOMMU_MEMORY_REGION
,
621 .parent
= TYPE_IOMMU_MEMORY_REGION
,
622 .class_init
= tz_mpc_iommu_memory_region_class_init
,
625 static void tz_mpc_register_types(void)
627 type_register_static(&tz_mpc_info
);
628 type_register_static(&tz_mpc_iommu_memory_region_info
);
631 type_init(tz_mpc_register_types
);