1 /* 2 * ARM TrustZone master security 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-msc.h" 22 #include "hw/qdev-properties.h" 23 24 static void tz_msc_update_irq(TZMSC *s) 25 { 26 bool level = s->irq_status; 27 28 trace_tz_msc_update_irq(level); 29 qemu_set_irq(s->irq, level); 30 } 31 32 static void tz_msc_cfg_nonsec(void *opaque, int n, int level) 33 { 34 TZMSC *s = TZ_MSC(opaque); 35 36 trace_tz_msc_cfg_nonsec(level); 37 s->cfg_nonsec = level; 38 } 39 40 static void tz_msc_cfg_sec_resp(void *opaque, int n, int level) 41 { 42 TZMSC *s = TZ_MSC(opaque); 43 44 trace_tz_msc_cfg_sec_resp(level); 45 s->cfg_sec_resp = level; 46 } 47 48 static void tz_msc_irq_clear(void *opaque, int n, int level) 49 { 50 TZMSC *s = TZ_MSC(opaque); 51 52 trace_tz_msc_irq_clear(level); 53 54 s->irq_clear = level; 55 if (level) { 56 s->irq_status = false; 57 tz_msc_update_irq(s); 58 } 59 } 60 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. 65 */ 66 typedef enum MSCAction { 67 MSCBlockAbort, 68 MSCBlockRAZWI, 69 MSCAllowSecure, 70 MSCAllowNonSecure, 71 } MSCAction; 72 73 static MSCAction tz_msc_check(TZMSC *s, hwaddr addr) 74 { 75 /* 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. 80 */ 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; 85 86 iic->check(ii, addr, &idau_region, &idau_exempt, &idau_ns, &idau_nsc); 87 88 if (idau_exempt) { 89 /* 90 * Uncheck region -- OK, transaction type depends on 91 * whether bus master is configured as Secure or NonSecure 92 */ 93 return s->cfg_nonsec ? MSCAllowNonSecure : MSCAllowSecure; 94 } 95 96 if (idau_ns) { 97 /* NonSecure region -- always forward as NS transaction */ 98 return MSCAllowNonSecure; 99 } 100 101 if (!s->cfg_nonsec) { 102 /* Access to Secure region by Secure bus master: OK */ 103 return MSCAllowSecure; 104 } 105 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; 110 } 111 112 /* 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. 116 */ 117 if (!s->irq_clear) { 118 s->irq_status = true; 119 tz_msc_update_irq(s); 120 } 121 return MSCBlockAbort; 122 } 123 124 static MemTxResult tz_msc_read(void *opaque, hwaddr addr, uint64_t *pdata, 125 unsigned size, MemTxAttrs attrs) 126 { 127 TZMSC *s = opaque; 128 AddressSpace *as = &s->downstream_as; 129 uint64_t data; 130 MemTxResult res; 131 132 switch (tz_msc_check(s, addr)) { 133 case MSCBlockAbort: 134 return MEMTX_ERROR; 135 case MSCBlockRAZWI: 136 *pdata = 0; 137 return MEMTX_OK; 138 case MSCAllowSecure: 139 attrs.secure = 1; 140 attrs.unspecified = 0; 141 break; 142 case MSCAllowNonSecure: 143 attrs.secure = 0; 144 attrs.unspecified = 0; 145 break; 146 } 147 148 switch (size) { 149 case 1: 150 data = address_space_ldub(as, addr, attrs, &res); 151 break; 152 case 2: 153 data = address_space_lduw_le(as, addr, attrs, &res); 154 break; 155 case 4: 156 data = address_space_ldl_le(as, addr, attrs, &res); 157 break; 158 case 8: 159 data = address_space_ldq_le(as, addr, attrs, &res); 160 break; 161 default: 162 g_assert_not_reached(); 163 } 164 *pdata = data; 165 return res; 166 } 167 168 static MemTxResult tz_msc_write(void *opaque, hwaddr addr, uint64_t val, 169 unsigned size, MemTxAttrs attrs) 170 { 171 TZMSC *s = opaque; 172 AddressSpace *as = &s->downstream_as; 173 MemTxResult res; 174 175 switch (tz_msc_check(s, addr)) { 176 case MSCBlockAbort: 177 return MEMTX_ERROR; 178 case MSCBlockRAZWI: 179 return MEMTX_OK; 180 case MSCAllowSecure: 181 attrs.secure = 1; 182 attrs.unspecified = 0; 183 break; 184 case MSCAllowNonSecure: 185 attrs.secure = 0; 186 attrs.unspecified = 0; 187 break; 188 } 189 190 switch (size) { 191 case 1: 192 address_space_stb(as, addr, val, attrs, &res); 193 break; 194 case 2: 195 address_space_stw_le(as, addr, val, attrs, &res); 196 break; 197 case 4: 198 address_space_stl_le(as, addr, val, attrs, &res); 199 break; 200 case 8: 201 address_space_stq_le(as, addr, val, attrs, &res); 202 break; 203 default: 204 g_assert_not_reached(); 205 } 206 return res; 207 } 208 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, 213 }; 214 215 static void tz_msc_reset(DeviceState *dev) 216 { 217 TZMSC *s = TZ_MSC(dev); 218 219 trace_tz_msc_reset(); 220 s->cfg_sec_resp = false; 221 s->cfg_nonsec = false; 222 s->irq_clear = 0; 223 s->irq_status = 0; 224 } 225 226 static void tz_msc_init(Object *obj) 227 { 228 DeviceState *dev = DEVICE(obj); 229 TZMSC *s = TZ_MSC(obj); 230 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); 235 } 236 237 static void tz_msc_realize(DeviceState *dev, Error **errp) 238 { 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"; 243 uint64_t size; 244 245 /* 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. 252 */ 253 if (!s->downstream) { 254 error_setg(errp, "MSC 'downstream' link not set"); 255 return; 256 } 257 if (!s->idau) { 258 error_setg(errp, "MSC 'idau' link not set"); 259 return; 260 } 261 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); 266 } 267 268 static const VMStateDescription tz_msc_vmstate = { 269 .name = "tz-msc", 270 .version_id = 1, 271 .minimum_version_id = 1, 272 .fields = (const 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() 278 } 279 }; 280 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(), 287 }; 288 289 static void tz_msc_class_init(ObjectClass *klass, void *data) 290 { 291 DeviceClass *dc = DEVICE_CLASS(klass); 292 293 dc->realize = tz_msc_realize; 294 dc->vmsd = &tz_msc_vmstate; 295 dc->reset = tz_msc_reset; 296 device_class_set_props(dc, tz_msc_properties); 297 } 298 299 static const TypeInfo tz_msc_info = { 300 .name = TYPE_TZ_MSC, 301 .parent = TYPE_SYS_BUS_DEVICE, 302 .instance_size = sizeof(TZMSC), 303 .instance_init = tz_msc_init, 304 .class_init = tz_msc_class_init, 305 }; 306 307 static void tz_msc_register_types(void) 308 { 309 type_register_static(&tz_msc_info); 310 } 311 312 type_init(tz_msc_register_types); 313