2 * ARM TrustZone master security 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-msc.h"
22 #include "hw/qdev-properties.h"
24 static void tz_msc_update_irq(TZMSC
*s
)
26 bool level
= s
->irq_status
;
28 trace_tz_msc_update_irq(level
);
29 qemu_set_irq(s
->irq
, level
);
32 static void tz_msc_cfg_nonsec(void *opaque
, int n
, int level
)
34 TZMSC
*s
= TZ_MSC(opaque
);
36 trace_tz_msc_cfg_nonsec(level
);
37 s
->cfg_nonsec
= level
;
40 static void tz_msc_cfg_sec_resp(void *opaque
, int n
, int level
)
42 TZMSC
*s
= TZ_MSC(opaque
);
44 trace_tz_msc_cfg_sec_resp(level
);
45 s
->cfg_sec_resp
= level
;
48 static void tz_msc_irq_clear(void *opaque
, int n
, int level
)
50 TZMSC
*s
= TZ_MSC(opaque
);
52 trace_tz_msc_irq_clear(level
);
56 s
->irq_status
= false;
61 /* The MSC may either block a transaction by aborting it, block a
62 * transaction by making it RAZ/WI, allow it through with
63 * MemTxAttrs indicating a secure transaction, or allow it with
64 * MemTxAttrs indicating a non-secure transaction.
66 typedef enum MSCAction
{
73 static MSCAction
tz_msc_check(TZMSC
*s
, hwaddr addr
)
76 * Check whether to allow an access from the bus master, returning
77 * an MSCAction indicating the required behaviour. If the transaction
78 * is blocked, the caller must check cfg_sec_resp to determine
79 * whether to abort or RAZ/WI the transaction.
81 IDAUInterfaceClass
*iic
= IDAU_INTERFACE_GET_CLASS(s
->idau
);
82 IDAUInterface
*ii
= IDAU_INTERFACE(s
->idau
);
83 bool idau_exempt
= false, idau_ns
= true, idau_nsc
= true;
84 int idau_region
= IREGION_NOTVALID
;
86 iic
->check(ii
, addr
, &idau_region
, &idau_exempt
, &idau_ns
, &idau_nsc
);
90 * Uncheck region -- OK, transaction type depends on
91 * whether bus master is configured as Secure or NonSecure
93 return s
->cfg_nonsec
? MSCAllowNonSecure
: MSCAllowSecure
;
97 /* NonSecure region -- always forward as NS transaction */
98 return MSCAllowNonSecure
;
101 if (!s
->cfg_nonsec
) {
102 /* Access to Secure region by Secure bus master: OK */
103 return MSCAllowSecure
;
106 /* Attempted access to Secure region by NS bus master: block */
107 trace_tz_msc_access_blocked(addr
);
108 if (!s
->cfg_sec_resp
) {
109 return MSCBlockRAZWI
;
113 * The TRM isn't clear on behaviour if irq_clear is high when a
114 * transaction is blocked. We assume that the MSC behaves like the
115 * PPC, where holding irq_clear high suppresses the interrupt.
118 s
->irq_status
= true;
119 tz_msc_update_irq(s
);
121 return MSCBlockAbort
;
124 static MemTxResult
tz_msc_read(void *opaque
, hwaddr addr
, uint64_t *pdata
,
125 unsigned size
, MemTxAttrs attrs
)
128 AddressSpace
*as
= &s
->downstream_as
;
132 switch (tz_msc_check(s
, addr
)) {
140 attrs
.unspecified
= 0;
142 case MSCAllowNonSecure
:
144 attrs
.unspecified
= 0;
150 data
= address_space_ldub(as
, addr
, attrs
, &res
);
153 data
= address_space_lduw_le(as
, addr
, attrs
, &res
);
156 data
= address_space_ldl_le(as
, addr
, attrs
, &res
);
159 data
= address_space_ldq_le(as
, addr
, attrs
, &res
);
162 g_assert_not_reached();
168 static MemTxResult
tz_msc_write(void *opaque
, hwaddr addr
, uint64_t val
,
169 unsigned size
, MemTxAttrs attrs
)
172 AddressSpace
*as
= &s
->downstream_as
;
175 switch (tz_msc_check(s
, addr
)) {
182 attrs
.unspecified
= 0;
184 case MSCAllowNonSecure
:
186 attrs
.unspecified
= 0;
192 address_space_stb(as
, addr
, val
, attrs
, &res
);
195 address_space_stw_le(as
, addr
, val
, attrs
, &res
);
198 address_space_stl_le(as
, addr
, val
, attrs
, &res
);
201 address_space_stq_le(as
, addr
, val
, attrs
, &res
);
204 g_assert_not_reached();
209 static const MemoryRegionOps tz_msc_ops
= {
210 .read_with_attrs
= tz_msc_read
,
211 .write_with_attrs
= tz_msc_write
,
212 .endianness
= DEVICE_LITTLE_ENDIAN
,
215 static void tz_msc_reset(DeviceState
*dev
)
217 TZMSC
*s
= TZ_MSC(dev
);
219 trace_tz_msc_reset();
220 s
->cfg_sec_resp
= false;
221 s
->cfg_nonsec
= false;
226 static void tz_msc_init(Object
*obj
)
228 DeviceState
*dev
= DEVICE(obj
);
229 TZMSC
*s
= TZ_MSC(obj
);
231 qdev_init_gpio_in_named(dev
, tz_msc_cfg_nonsec
, "cfg_nonsec", 1);
232 qdev_init_gpio_in_named(dev
, tz_msc_cfg_sec_resp
, "cfg_sec_resp", 1);
233 qdev_init_gpio_in_named(dev
, tz_msc_irq_clear
, "irq_clear", 1);
234 qdev_init_gpio_out_named(dev
, &s
->irq
, "irq", 1);
237 static void tz_msc_realize(DeviceState
*dev
, Error
**errp
)
239 Object
*obj
= OBJECT(dev
);
240 SysBusDevice
*sbd
= SYS_BUS_DEVICE(dev
);
241 TZMSC
*s
= TZ_MSC(dev
);
242 const char *name
= "tz-msc-downstream";
246 * We can't create the upstream end of the port until realize,
247 * as we don't know the size of the MR used as the downstream until then.
248 * We insist on having a downstream, to avoid complicating the
249 * code with handling the "don't know how big this is" case. It's easy
250 * enough for the user to create an unimplemented_device as downstream
251 * if they have nothing else to plug into this.
253 if (!s
->downstream
) {
254 error_setg(errp
, "MSC 'downstream' link not set");
258 error_setg(errp
, "MSC 'idau' link not set");
262 size
= memory_region_size(s
->downstream
);
263 address_space_init(&s
->downstream_as
, s
->downstream
, name
);
264 memory_region_init_io(&s
->upstream
, obj
, &tz_msc_ops
, s
, name
, size
);
265 sysbus_init_mmio(sbd
, &s
->upstream
);
268 static const VMStateDescription tz_msc_vmstate
= {
271 .minimum_version_id
= 1,
272 .fields
= (VMStateField
[]) {
273 VMSTATE_BOOL(cfg_nonsec
, TZMSC
),
274 VMSTATE_BOOL(cfg_sec_resp
, TZMSC
),
275 VMSTATE_BOOL(irq_clear
, TZMSC
),
276 VMSTATE_BOOL(irq_status
, TZMSC
),
277 VMSTATE_END_OF_LIST()
281 static Property tz_msc_properties
[] = {
282 DEFINE_PROP_LINK("downstream", TZMSC
, downstream
,
283 TYPE_MEMORY_REGION
, MemoryRegion
*),
284 DEFINE_PROP_LINK("idau", TZMSC
, idau
,
285 TYPE_IDAU_INTERFACE
, IDAUInterface
*),
286 DEFINE_PROP_END_OF_LIST(),
289 static void tz_msc_class_init(ObjectClass
*klass
, void *data
)
291 DeviceClass
*dc
= DEVICE_CLASS(klass
);
293 dc
->realize
= tz_msc_realize
;
294 dc
->vmsd
= &tz_msc_vmstate
;
295 dc
->reset
= tz_msc_reset
;
296 dc
->props
= tz_msc_properties
;
299 static const TypeInfo tz_msc_info
= {
301 .parent
= TYPE_SYS_BUS_DEVICE
,
302 .instance_size
= sizeof(TZMSC
),
303 .instance_init
= tz_msc_init
,
304 .class_init
= tz_msc_class_init
,
307 static void tz_msc_register_types(void)
309 type_register_static(&tz_msc_info
);
312 type_init(tz_msc_register_types
);