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 "hw/registerfields.h"
19 #include "hw/misc/tz-msc.h"
21 static void tz_msc_update_irq(TZMSC
*s
)
23 bool level
= s
->irq_status
;
25 trace_tz_msc_update_irq(level
);
26 qemu_set_irq(s
->irq
, level
);
29 static void tz_msc_cfg_nonsec(void *opaque
, int n
, int level
)
31 TZMSC
*s
= TZ_MSC(opaque
);
33 trace_tz_msc_cfg_nonsec(level
);
34 s
->cfg_nonsec
= level
;
37 static void tz_msc_cfg_sec_resp(void *opaque
, int n
, int level
)
39 TZMSC
*s
= TZ_MSC(opaque
);
41 trace_tz_msc_cfg_sec_resp(level
);
42 s
->cfg_sec_resp
= level
;
45 static void tz_msc_irq_clear(void *opaque
, int n
, int level
)
47 TZMSC
*s
= TZ_MSC(opaque
);
49 trace_tz_msc_irq_clear(level
);
53 s
->irq_status
= false;
58 /* The MSC may either block a transaction by aborting it, block a
59 * transaction by making it RAZ/WI, allow it through with
60 * MemTxAttrs indicating a secure transaction, or allow it with
61 * MemTxAttrs indicating a non-secure transaction.
63 typedef enum MSCAction
{
70 static MSCAction
tz_msc_check(TZMSC
*s
, hwaddr addr
)
73 * Check whether to allow an access from the bus master, returning
74 * an MSCAction indicating the required behaviour. If the transaction
75 * is blocked, the caller must check cfg_sec_resp to determine
76 * whether to abort or RAZ/WI the transaction.
78 IDAUInterfaceClass
*iic
= IDAU_INTERFACE_GET_CLASS(s
->idau
);
79 IDAUInterface
*ii
= IDAU_INTERFACE(s
->idau
);
80 bool idau_exempt
= false, idau_ns
= true, idau_nsc
= true;
81 int idau_region
= IREGION_NOTVALID
;
83 iic
->check(ii
, addr
, &idau_region
, &idau_exempt
, &idau_ns
, &idau_nsc
);
87 * Uncheck region -- OK, transaction type depends on
88 * whether bus master is configured as Secure or NonSecure
90 return s
->cfg_nonsec
? MSCAllowNonSecure
: MSCAllowSecure
;
94 /* NonSecure region -- always forward as NS transaction */
95 return MSCAllowNonSecure
;
99 /* Access to Secure region by Secure bus master: OK */
100 return MSCAllowSecure
;
103 /* Attempted access to Secure region by NS bus master: block */
104 trace_tz_msc_access_blocked(addr
);
105 if (!s
->cfg_sec_resp
) {
106 return MSCBlockRAZWI
;
110 * The TRM isn't clear on behaviour if irq_clear is high when a
111 * transaction is blocked. We assume that the MSC behaves like the
112 * PPC, where holding irq_clear high suppresses the interrupt.
115 s
->irq_status
= true;
116 tz_msc_update_irq(s
);
118 return MSCBlockAbort
;
121 static MemTxResult
tz_msc_read(void *opaque
, hwaddr addr
, uint64_t *pdata
,
122 unsigned size
, MemTxAttrs attrs
)
125 AddressSpace
*as
= &s
->downstream_as
;
129 switch (tz_msc_check(s
, addr
)) {
137 attrs
.unspecified
= 0;
139 case MSCAllowNonSecure
:
141 attrs
.unspecified
= 0;
147 data
= address_space_ldub(as
, addr
, attrs
, &res
);
150 data
= address_space_lduw_le(as
, addr
, attrs
, &res
);
153 data
= address_space_ldl_le(as
, addr
, attrs
, &res
);
156 data
= address_space_ldq_le(as
, addr
, attrs
, &res
);
159 g_assert_not_reached();
165 static MemTxResult
tz_msc_write(void *opaque
, hwaddr addr
, uint64_t val
,
166 unsigned size
, MemTxAttrs attrs
)
169 AddressSpace
*as
= &s
->downstream_as
;
172 switch (tz_msc_check(s
, addr
)) {
179 attrs
.unspecified
= 0;
181 case MSCAllowNonSecure
:
183 attrs
.unspecified
= 0;
189 address_space_stb(as
, addr
, val
, attrs
, &res
);
192 address_space_stw_le(as
, addr
, val
, attrs
, &res
);
195 address_space_stl_le(as
, addr
, val
, attrs
, &res
);
198 address_space_stq_le(as
, addr
, val
, attrs
, &res
);
201 g_assert_not_reached();
206 static const MemoryRegionOps tz_msc_ops
= {
207 .read_with_attrs
= tz_msc_read
,
208 .write_with_attrs
= tz_msc_write
,
209 .endianness
= DEVICE_LITTLE_ENDIAN
,
212 static void tz_msc_reset(DeviceState
*dev
)
214 TZMSC
*s
= TZ_MSC(dev
);
216 trace_tz_msc_reset();
217 s
->cfg_sec_resp
= false;
218 s
->cfg_nonsec
= false;
223 static void tz_msc_init(Object
*obj
)
225 DeviceState
*dev
= DEVICE(obj
);
226 TZMSC
*s
= TZ_MSC(obj
);
228 qdev_init_gpio_in_named(dev
, tz_msc_cfg_nonsec
, "cfg_nonsec", 1);
229 qdev_init_gpio_in_named(dev
, tz_msc_cfg_sec_resp
, "cfg_sec_resp", 1);
230 qdev_init_gpio_in_named(dev
, tz_msc_irq_clear
, "irq_clear", 1);
231 qdev_init_gpio_out_named(dev
, &s
->irq
, "irq", 1);
234 static void tz_msc_realize(DeviceState
*dev
, Error
**errp
)
236 Object
*obj
= OBJECT(dev
);
237 SysBusDevice
*sbd
= SYS_BUS_DEVICE(dev
);
238 TZMSC
*s
= TZ_MSC(dev
);
239 const char *name
= "tz-msc-downstream";
243 * We can't create the upstream end of the port until realize,
244 * as we don't know the size of the MR used as the downstream until then.
245 * We insist on having a downstream, to avoid complicating the
246 * code with handling the "don't know how big this is" case. It's easy
247 * enough for the user to create an unimplemented_device as downstream
248 * if they have nothing else to plug into this.
250 if (!s
->downstream
) {
251 error_setg(errp
, "MSC 'downstream' link not set");
255 error_setg(errp
, "MSC 'idau' link not set");
259 size
= memory_region_size(s
->downstream
);
260 address_space_init(&s
->downstream_as
, s
->downstream
, name
);
261 memory_region_init_io(&s
->upstream
, obj
, &tz_msc_ops
, s
, name
, size
);
262 sysbus_init_mmio(sbd
, &s
->upstream
);
265 static const VMStateDescription tz_msc_vmstate
= {
268 .minimum_version_id
= 1,
269 .fields
= (VMStateField
[]) {
270 VMSTATE_BOOL(cfg_nonsec
, TZMSC
),
271 VMSTATE_BOOL(cfg_sec_resp
, TZMSC
),
272 VMSTATE_BOOL(irq_clear
, TZMSC
),
273 VMSTATE_BOOL(irq_status
, TZMSC
),
274 VMSTATE_END_OF_LIST()
278 static Property tz_msc_properties
[] = {
279 DEFINE_PROP_LINK("downstream", TZMSC
, downstream
,
280 TYPE_MEMORY_REGION
, MemoryRegion
*),
281 DEFINE_PROP_LINK("idau", TZMSC
, idau
,
282 TYPE_IDAU_INTERFACE
, IDAUInterface
*),
283 DEFINE_PROP_END_OF_LIST(),
286 static void tz_msc_class_init(ObjectClass
*klass
, void *data
)
288 DeviceClass
*dc
= DEVICE_CLASS(klass
);
290 dc
->realize
= tz_msc_realize
;
291 dc
->vmsd
= &tz_msc_vmstate
;
292 dc
->reset
= tz_msc_reset
;
293 dc
->props
= tz_msc_properties
;
296 static const TypeInfo tz_msc_info
= {
298 .parent
= TYPE_SYS_BUS_DEVICE
,
299 .instance_size
= sizeof(TZMSC
),
300 .instance_init
= tz_msc_init
,
301 .class_init
= tz_msc_class_init
,
304 static void tz_msc_register_types(void)
306 type_register_static(&tz_msc_info
);
309 type_init(tz_msc_register_types
);