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 "qapi/error.h"
16 #include "hw/sysbus.h"
17 #include "hw/registerfields.h"
18 #include "hw/misc/tz-msc.h"
20 static void tz_msc_update_irq(TZMSC
*s
)
22 bool level
= s
->irq_status
;
24 trace_tz_msc_update_irq(level
);
25 qemu_set_irq(s
->irq
, level
);
28 static void tz_msc_cfg_nonsec(void *opaque
, int n
, int level
)
30 TZMSC
*s
= TZ_MSC(opaque
);
32 trace_tz_msc_cfg_nonsec(level
);
33 s
->cfg_nonsec
= level
;
36 static void tz_msc_cfg_sec_resp(void *opaque
, int n
, int level
)
38 TZMSC
*s
= TZ_MSC(opaque
);
40 trace_tz_msc_cfg_sec_resp(level
);
41 s
->cfg_sec_resp
= level
;
44 static void tz_msc_irq_clear(void *opaque
, int n
, int level
)
46 TZMSC
*s
= TZ_MSC(opaque
);
48 trace_tz_msc_irq_clear(level
);
52 s
->irq_status
= false;
57 /* The MSC may either block a transaction by aborting it, block a
58 * transaction by making it RAZ/WI, allow it through with
59 * MemTxAttrs indicating a secure transaction, or allow it with
60 * MemTxAttrs indicating a non-secure transaction.
62 typedef enum MSCAction
{
69 static MSCAction
tz_msc_check(TZMSC
*s
, hwaddr addr
)
72 * Check whether to allow an access from the bus master, returning
73 * an MSCAction indicating the required behaviour. If the transaction
74 * is blocked, the caller must check cfg_sec_resp to determine
75 * whether to abort or RAZ/WI the transaction.
77 IDAUInterfaceClass
*iic
= IDAU_INTERFACE_GET_CLASS(s
->idau
);
78 IDAUInterface
*ii
= IDAU_INTERFACE(s
->idau
);
79 bool idau_exempt
= false, idau_ns
= true, idau_nsc
= true;
80 int idau_region
= IREGION_NOTVALID
;
82 iic
->check(ii
, addr
, &idau_region
, &idau_exempt
, &idau_ns
, &idau_nsc
);
86 * Uncheck region -- OK, transaction type depends on
87 * whether bus master is configured as Secure or NonSecure
89 return s
->cfg_nonsec
? MSCAllowNonSecure
: MSCAllowSecure
;
93 /* NonSecure region -- always forward as NS transaction */
94 return MSCAllowNonSecure
;
98 /* Access to Secure region by Secure bus master: OK */
99 return MSCAllowSecure
;
102 /* Attempted access to Secure region by NS bus master: block */
103 trace_tz_msc_access_blocked(addr
);
104 if (!s
->cfg_sec_resp
) {
105 return MSCBlockRAZWI
;
109 * The TRM isn't clear on behaviour if irq_clear is high when a
110 * transaction is blocked. We assume that the MSC behaves like the
111 * PPC, where holding irq_clear high suppresses the interrupt.
114 s
->irq_status
= true;
115 tz_msc_update_irq(s
);
117 return MSCBlockAbort
;
120 static MemTxResult
tz_msc_read(void *opaque
, hwaddr addr
, uint64_t *pdata
,
121 unsigned size
, MemTxAttrs attrs
)
124 AddressSpace
*as
= &s
->downstream_as
;
128 switch (tz_msc_check(s
, addr
)) {
136 attrs
.unspecified
= 0;
138 case MSCAllowNonSecure
:
140 attrs
.unspecified
= 0;
146 data
= address_space_ldub(as
, addr
, attrs
, &res
);
149 data
= address_space_lduw_le(as
, addr
, attrs
, &res
);
152 data
= address_space_ldl_le(as
, addr
, attrs
, &res
);
155 data
= address_space_ldq_le(as
, addr
, attrs
, &res
);
158 g_assert_not_reached();
164 static MemTxResult
tz_msc_write(void *opaque
, hwaddr addr
, uint64_t val
,
165 unsigned size
, MemTxAttrs attrs
)
168 AddressSpace
*as
= &s
->downstream_as
;
171 switch (tz_msc_check(s
, addr
)) {
178 attrs
.unspecified
= 0;
180 case MSCAllowNonSecure
:
182 attrs
.unspecified
= 0;
188 address_space_stb(as
, addr
, val
, attrs
, &res
);
191 address_space_stw_le(as
, addr
, val
, attrs
, &res
);
194 address_space_stl_le(as
, addr
, val
, attrs
, &res
);
197 address_space_stq_le(as
, addr
, val
, attrs
, &res
);
200 g_assert_not_reached();
205 static const MemoryRegionOps tz_msc_ops
= {
206 .read_with_attrs
= tz_msc_read
,
207 .write_with_attrs
= tz_msc_write
,
208 .endianness
= DEVICE_LITTLE_ENDIAN
,
211 static void tz_msc_reset(DeviceState
*dev
)
213 TZMSC
*s
= TZ_MSC(dev
);
215 trace_tz_msc_reset();
216 s
->cfg_sec_resp
= false;
217 s
->cfg_nonsec
= false;
222 static void tz_msc_init(Object
*obj
)
224 DeviceState
*dev
= DEVICE(obj
);
225 TZMSC
*s
= TZ_MSC(obj
);
227 qdev_init_gpio_in_named(dev
, tz_msc_cfg_nonsec
, "cfg_nonsec", 1);
228 qdev_init_gpio_in_named(dev
, tz_msc_cfg_sec_resp
, "cfg_sec_resp", 1);
229 qdev_init_gpio_in_named(dev
, tz_msc_irq_clear
, "irq_clear", 1);
230 qdev_init_gpio_out_named(dev
, &s
->irq
, "irq", 1);
233 static void tz_msc_realize(DeviceState
*dev
, Error
**errp
)
235 Object
*obj
= OBJECT(dev
);
236 SysBusDevice
*sbd
= SYS_BUS_DEVICE(dev
);
237 TZMSC
*s
= TZ_MSC(dev
);
238 const char *name
= "tz-msc-downstream";
242 * We can't create the upstream end of the port until realize,
243 * as we don't know the size of the MR used as the downstream until then.
244 * We insist on having a downstream, to avoid complicating the
245 * code with handling the "don't know how big this is" case. It's easy
246 * enough for the user to create an unimplemented_device as downstream
247 * if they have nothing else to plug into this.
249 if (!s
->downstream
) {
250 error_setg(errp
, "MSC 'downstream' link not set");
254 error_setg(errp
, "MSC 'idau' link not set");
258 size
= memory_region_size(s
->downstream
);
259 address_space_init(&s
->downstream_as
, s
->downstream
, name
);
260 memory_region_init_io(&s
->upstream
, obj
, &tz_msc_ops
, s
, name
, size
);
261 sysbus_init_mmio(sbd
, &s
->upstream
);
264 static const VMStateDescription tz_msc_vmstate
= {
267 .minimum_version_id
= 1,
268 .fields
= (VMStateField
[]) {
269 VMSTATE_BOOL(cfg_nonsec
, TZMSC
),
270 VMSTATE_BOOL(cfg_sec_resp
, TZMSC
),
271 VMSTATE_BOOL(irq_clear
, TZMSC
),
272 VMSTATE_BOOL(irq_status
, TZMSC
),
273 VMSTATE_END_OF_LIST()
277 static Property tz_msc_properties
[] = {
278 DEFINE_PROP_LINK("downstream", TZMSC
, downstream
,
279 TYPE_MEMORY_REGION
, MemoryRegion
*),
280 DEFINE_PROP_LINK("idau", TZMSC
, idau
,
281 TYPE_IDAU_INTERFACE
, IDAUInterface
*),
282 DEFINE_PROP_END_OF_LIST(),
285 static void tz_msc_class_init(ObjectClass
*klass
, void *data
)
287 DeviceClass
*dc
= DEVICE_CLASS(klass
);
289 dc
->realize
= tz_msc_realize
;
290 dc
->vmsd
= &tz_msc_vmstate
;
291 dc
->reset
= tz_msc_reset
;
292 dc
->props
= tz_msc_properties
;
295 static const TypeInfo tz_msc_info
= {
297 .parent
= TYPE_SYS_BUS_DEVICE
,
298 .instance_size
= sizeof(TZMSC
),
299 .instance_init
= tz_msc_init
,
300 .class_init
= tz_msc_class_init
,
303 static void tz_msc_register_types(void)
305 type_register_static(&tz_msc_info
);
308 type_init(tz_msc_register_types
);