1 // SPDX-License-Identifier: (BSD-2-Clause AND BSD-3-Clause) 2 /* 3 * Copyright (c) 2015, Linaro Limited 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright notice, 10 * this list of conditions and the following disclaimer. 11 * 12 * 2. Redistributions in binary form must reproduce the above copyright notice, 13 * this list of conditions and the following disclaimer in the documentation 14 * and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 * POSSIBILITY OF SUCH DAMAGE. 27 */ 28 /* 29 * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved. 30 * 31 * Redistribution and use in source and binary forms, with or without 32 * modification, are permitted provided that the following conditions are met: 33 * 34 * Redistributions of source code must retain the above copyright notice, this 35 * list of conditions and the following disclaimer. 36 * 37 * Redistributions in binary form must reproduce the above copyright notice, 38 * this list of conditions and the following disclaimer in the documentation 39 * and/or other materials provided with the distribution. 40 * 41 * Neither the name of ARM nor the names of its contributors may be used 42 * to endorse or promote products derived from this software without specific 43 * prior written permission. 44 * 45 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 46 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 47 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 48 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 49 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 50 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 51 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 52 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 53 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 54 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 55 * POSSIBILITY OF SUCH DAMAGE. 56 */ 57 58 #include <assert.h> 59 #include <drivers/tzc400.h> 60 #include <io.h> 61 #include <kernel/panic.h> 62 #include <stddef.h> 63 #include <trace.h> 64 #include <util.h> 65 66 /* 67 * Implementation defined values used to validate inputs later. 68 * Filters : max of 4 ; 0 to 3 69 * Regions : max of 9 ; 0 to 8 70 * Address width : Values between 32 to 64 71 */ 72 struct tzc_instance { 73 vaddr_t base; 74 uint8_t addr_width; 75 uint8_t num_filters; 76 uint8_t num_regions; 77 }; 78 79 static struct tzc_instance tzc; 80 81 82 static uint32_t tzc_read_build_config(vaddr_t base) 83 { 84 return io_read32(base + BUILD_CONFIG_OFF); 85 } 86 87 static uint32_t tzc_read_gate_keeper(vaddr_t base) 88 { 89 return io_read32(base + GATE_KEEPER_OFF); 90 } 91 92 static void tzc_write_gate_keeper(vaddr_t base, uint32_t val) 93 { 94 io_write32(base + GATE_KEEPER_OFF, val); 95 } 96 97 static void tzc_write_action(vaddr_t base, enum tzc_action action) 98 { 99 io_write32(base + ACTION_OFF, action); 100 } 101 102 static uint32_t tzc_read_region_base_low(vaddr_t base, uint32_t region) 103 { 104 return io_read32(base + REGION_BASE_LOW_OFF + REGION_NUM_OFF(region)); 105 } 106 107 static void tzc_write_region_base_low(vaddr_t base, uint32_t region, 108 uint32_t val) 109 { 110 io_write32(base + REGION_BASE_LOW_OFF + REGION_NUM_OFF(region), val); 111 } 112 113 static uint32_t tzc_read_region_base_high(vaddr_t base, uint32_t region) 114 { 115 return io_read32(base + REGION_BASE_HIGH_OFF + REGION_NUM_OFF(region)); 116 } 117 118 static void tzc_write_region_base_high(vaddr_t base, uint32_t region, 119 uint32_t val) 120 { 121 io_write32(base + REGION_BASE_HIGH_OFF + REGION_NUM_OFF(region), val); 122 } 123 124 static uint32_t tzc_read_region_top_low(vaddr_t base, uint32_t region) 125 { 126 return io_read32(base + REGION_TOP_LOW_OFF + REGION_NUM_OFF(region)); 127 } 128 129 static void tzc_write_region_top_low(vaddr_t base, uint32_t region, 130 uint32_t val) 131 { 132 io_write32(base + REGION_TOP_LOW_OFF + REGION_NUM_OFF(region), val); 133 } 134 135 static uint32_t tzc_read_region_top_high(vaddr_t base, uint32_t region) 136 { 137 return io_read32(base + REGION_TOP_HIGH_OFF + REGION_NUM_OFF(region)); 138 } 139 140 static void tzc_write_region_top_high(vaddr_t base, uint32_t region, 141 uint32_t val) 142 { 143 io_write32(base + REGION_TOP_HIGH_OFF + REGION_NUM_OFF(region), val); 144 } 145 146 static uint32_t tzc_read_region_attributes(vaddr_t base, uint32_t region) 147 { 148 return io_read32(base + REGION_ATTRIBUTES_OFF + REGION_NUM_OFF(region)); 149 } 150 151 static void tzc_write_region_attributes(vaddr_t base, uint32_t region, 152 uint32_t val) 153 { 154 io_write32(base + REGION_ATTRIBUTES_OFF + REGION_NUM_OFF(region), val); 155 } 156 157 static uint32_t tzc_read_region_id_access(vaddr_t base, uint32_t region) 158 { 159 return io_read32(base + REGION_ID_ACCESS_OFF + REGION_NUM_OFF(region)); 160 } 161 162 static void tzc_write_region_id_access(vaddr_t base, uint32_t region, 163 uint32_t val) 164 { 165 io_write32(base + REGION_ID_ACCESS_OFF + REGION_NUM_OFF(region), val); 166 } 167 168 static uint32_t tzc_read_component_id(vaddr_t base) 169 { 170 uint32_t id; 171 172 id = io_read8(base + CID0_OFF); 173 id |= SHIFT_U32(io_read8(base + CID1_OFF), 8); 174 id |= SHIFT_U32(io_read8(base + CID2_OFF), 16); 175 id |= SHIFT_U32(io_read8(base + CID3_OFF), 24); 176 177 return id; 178 } 179 180 static uint32_t tzc_get_gate_keeper(vaddr_t base, uint8_t filter) 181 { 182 uint32_t tmp; 183 184 tmp = (tzc_read_gate_keeper(base) >> GATE_KEEPER_OS_SHIFT) & 185 GATE_KEEPER_OS_MASK; 186 187 return (tmp >> filter) & GATE_KEEPER_FILTER_MASK; 188 } 189 190 /* This function is not MP safe. */ 191 static void tzc_set_gate_keeper(vaddr_t base, uint8_t filter, uint32_t val) 192 { 193 uint32_t tmp; 194 195 /* Upper half is current state. Lower half is requested state. */ 196 tmp = (tzc_read_gate_keeper(base) >> GATE_KEEPER_OS_SHIFT) & 197 GATE_KEEPER_OS_MASK; 198 199 if (val) 200 tmp |= (1 << filter); 201 else 202 tmp &= ~(1 << filter); 203 204 tzc_write_gate_keeper(base, (tmp & GATE_KEEPER_OR_MASK) << 205 GATE_KEEPER_OR_SHIFT); 206 207 /* Wait here until we see the change reflected in the TZC status. */ 208 while (((tzc_read_gate_keeper(base) >> GATE_KEEPER_OS_SHIFT) & 209 GATE_KEEPER_OS_MASK) != tmp) 210 ; 211 } 212 213 214 void tzc_init(vaddr_t base) 215 { 216 uint32_t tzc_id, tzc_build; 217 218 assert(base); 219 tzc.base = base; 220 221 /* 222 * We expect to see a tzc400. Check component ID. The TZC-400 TRM shows 223 * component ID is expected to be "0xB105F00D". 224 */ 225 tzc_id = tzc_read_component_id(tzc.base); 226 if (tzc_id != TZC400_COMPONENT_ID) { 227 EMSG("TZC : Wrong device ID (0x%" PRIx32 ")", tzc_id); 228 panic(); 229 } 230 231 /* Save values we will use later. */ 232 tzc_build = tzc_read_build_config(tzc.base); 233 tzc.num_filters = ((tzc_build >> BUILD_CONFIG_NF_SHIFT) & 234 BUILD_CONFIG_NF_MASK) + 1; 235 tzc.addr_width = ((tzc_build >> BUILD_CONFIG_AW_SHIFT) & 236 BUILD_CONFIG_AW_MASK) + 1; 237 tzc.num_regions = ((tzc_build >> BUILD_CONFIG_NR_SHIFT) & 238 BUILD_CONFIG_NR_MASK) + 1; 239 } 240 241 static uint32_t addr_low(vaddr_t addr) 242 { 243 return (uint32_t)addr; 244 } 245 246 static uint32_t addr_high(vaddr_t addr __unused) 247 { 248 #if (UINTPTR_MAX == UINT64_MAX) 249 return (addr >> 32); 250 #else 251 return 0; 252 #endif 253 } 254 255 256 /* 257 * `tzc_configure_region` is used to program regions into the TrustZone 258 * controller. A region can be associated with more than one filter. The 259 * associated filters are passed in as a bitmap (bit0 = filter0). 260 * NOTE: 261 * The region 0 covers the whole address space and is enabled on all filters, 262 * this cannot be changed. It is, however, possible to change some region 0 263 * permissions. 264 */ 265 void tzc_configure_region(uint32_t filters, 266 uint8_t region, 267 vaddr_t region_base, 268 vaddr_t region_top, 269 enum tzc_region_attributes sec_attr, 270 uint32_t ns_device_access) 271 { 272 assert(tzc.base); 273 274 /* Do range checks on filters and regions. */ 275 assert(((filters >> tzc.num_filters) == 0) && 276 (region < tzc.num_regions)); 277 278 /* 279 * Do address range check based on TZC configuration. A 64bit address is 280 * the max and expected case. 281 */ 282 #if (UINTPTR_MAX == UINT64_MAX) 283 assert(((region_top <= (UINT64_MAX >> (64 - tzc.addr_width))) && 284 (region_base < region_top))); 285 #endif 286 /* region_base and (region_top + 1) must be 4KB aligned */ 287 assert(((region_base | (region_top + 1)) & (4096 - 1)) == 0); 288 289 assert(sec_attr <= TZC_REGION_S_RDWR); 290 291 /* 292 * Inputs look ok, start programming registers. 293 * All the address registers are 32 bits wide and have a LOW and HIGH 294 * component used to construct a up to a 64bit address. 295 */ 296 tzc_write_region_base_low(tzc.base, region, 297 addr_low(region_base)); 298 tzc_write_region_base_high(tzc.base, region, 299 addr_high(region_base)); 300 301 tzc_write_region_top_low(tzc.base, region, 302 addr_low(region_top)); 303 tzc_write_region_top_high(tzc.base, region, 304 addr_high(region_top)); 305 306 /* Assign the region to a filter and set secure attributes */ 307 tzc_write_region_attributes(tzc.base, region, 308 (sec_attr << REG_ATTR_SEC_SHIFT) | filters); 309 310 /* 311 * Specify which non-secure devices have permission to access this 312 * region. 313 */ 314 tzc_write_region_id_access(tzc.base, region, ns_device_access); 315 } 316 317 TEE_Result tzc_get_region_config(uint8_t region, struct tzc_region_config *cfg) 318 { 319 uint32_t val32 = 0; 320 321 if (region >= tzc.num_regions) 322 return TEE_ERROR_GENERIC; 323 324 cfg->base = reg_pair_to_64(tzc_read_region_base_high(tzc.base, region), 325 tzc_read_region_base_low(tzc.base, region)); 326 cfg->top = reg_pair_to_64(tzc_read_region_top_high(tzc.base, region), 327 tzc_read_region_top_low(tzc.base, region)); 328 329 cfg->ns_device_access = tzc_read_region_id_access(tzc.base, region); 330 331 val32 = tzc_read_region_attributes(tzc.base, region); 332 cfg->sec_attr = val32 >> REG_ATTR_SEC_SHIFT; 333 cfg->filters = val32 & REG_ATTR_F_EN_MASK; 334 335 return TEE_SUCCESS; 336 } 337 338 void tzc_set_action(enum tzc_action action) 339 { 340 assert(tzc.base); 341 342 /* 343 * - Currently no handler is provided to trap an error via interrupt 344 * or exception. 345 * - The interrupt action has not been tested. 346 */ 347 tzc_write_action(tzc.base, action); 348 } 349 350 351 void tzc_enable_filters(void) 352 { 353 uint32_t state; 354 uint32_t filter; 355 356 assert(tzc.base); 357 358 for (filter = 0; filter < tzc.num_filters; filter++) { 359 state = tzc_get_gate_keeper(tzc.base, filter); 360 if (state) { 361 /* 362 * The TZC filter is already configured. Changing the 363 * programmer's view in an active system can cause 364 * unpredictable behavior therefore panic for now rather 365 * than try to determine whether this is safe in this 366 * instance. See: 367 * http://infocenter.arm.com/help/index.jsp?\ 368 * topic=/com.arm.doc.ddi0504c/CJHHECBF.html 369 */ 370 EMSG("TZC : Filter %d Gatekeeper already enabled", 371 filter); 372 panic(); 373 } 374 tzc_set_gate_keeper(tzc.base, filter, 1); 375 } 376 } 377 378 379 void tzc_disable_filters(void) 380 { 381 uint32_t filter; 382 383 assert(tzc.base); 384 385 /* 386 * We don't do the same state check as above as the Gatekeepers are 387 * disabled after reset. 388 */ 389 for (filter = 0; filter < tzc.num_filters; filter++) 390 tzc_set_gate_keeper(tzc.base, filter, 0); 391 } 392 393 static bool __maybe_unused write_not_read(unsigned int filter) 394 { 395 return io_read32(tzc.base + FAIL_CONTROL(filter)) & 396 FAIL_CONTROL_DIRECTION_WRITE; 397 } 398 399 static bool __maybe_unused nonsecure_not_secure(unsigned int filter) 400 { 401 return io_read32(tzc.base + FAIL_CONTROL(filter)) & 402 FAIL_CONTROL_NONSECURE; 403 } 404 405 static bool __maybe_unused priv_not_unpriv(unsigned int filter) 406 { 407 return io_read32(tzc.base + FAIL_CONTROL(filter)) & 408 FAIL_CONTROL_PRIVILEGED; 409 } 410 411 static void dump_fail_filter(unsigned int filter) 412 { 413 uint64_t __maybe_unused addr = 0; 414 uint32_t status = io_read32(tzc.base + INT_STATUS); 415 416 if (!(status & BIT(filter + INT_STATUS_OVERLAP_SHIFT)) && 417 !(status & BIT(filter + INT_STATUS_OVERRUN_SHIFT)) && 418 !(status & BIT(filter + INT_STATUS_STATUS_SHIFT))) 419 return; 420 421 if (status & BIT(filter + INT_STATUS_OVERLAP_SHIFT)) 422 EMSG("Overlap violation on filter %u", filter); 423 424 if (status & BIT(filter + INT_STATUS_OVERRUN_SHIFT)) 425 EMSG("Overrun violation on filter %u", filter); 426 427 if (status & BIT(filter + INT_STATUS_STATUS_SHIFT)) 428 EMSG("Permission violation on filter %u", filter); 429 430 addr = reg_pair_to_64(io_read32(tzc.base + FAIL_ADDRESS_HIGH(filter)), 431 io_read32(tzc.base + FAIL_ADDRESS_LOW(filter))); 432 433 EMSG("Violation @0x%"PRIx64", %ssecure %sprivileged %s, AXI ID %"PRIx32, 434 addr, 435 nonsecure_not_secure(filter) ? "non-" : "", 436 priv_not_unpriv(filter) ? "" : "un", 437 write_not_read(filter) ? "write" : "read", 438 io_read32(tzc.base + FAIL_ID(filter))); 439 } 440 441 /* 442 * Dump info when TZC400 catches an unallowed access with TZC 443 * interrupt enabled. 444 */ 445 void tzc_fail_dump(void) 446 { 447 unsigned int filter = 0; 448 449 for (filter = 0; filter < tzc.num_filters; filter++) 450 dump_fail_filter(filter); 451 } 452 453 void tzc_int_clear(void) 454 { 455 assert(tzc.base); 456 457 io_setbits32(tzc.base + INT_CLEAR, GENMASK_32(tzc.num_filters - 1, 0)); 458 } 459 460 #if TRACE_LEVEL >= TRACE_DEBUG 461 462 #define REGION_MAX 8 463 static const __maybe_unused char * const tzc_attr_msg[] = { 464 "TZC_REGION_S_NONE", 465 "TZC_REGION_S_RD", 466 "TZC_REGION_S_WR", 467 "TZC_REGION_S_RDWR" 468 }; 469 470 void tzc_dump_state(void) 471 { 472 uint32_t n; 473 uint32_t temp_32reg, temp_32reg_h; 474 unsigned int filter = 0; 475 476 for (n = 0; n <= REGION_MAX; n++) { 477 temp_32reg = tzc_read_region_attributes(tzc.base, n); 478 if (!(temp_32reg & REG_ATTR_F_EN_MASK)) 479 continue; 480 481 DMSG("region %d", n); 482 temp_32reg = tzc_read_region_base_low(tzc.base, n); 483 temp_32reg_h = tzc_read_region_base_high(tzc.base, n); 484 DMSG("region_base: 0x%08x%08x", temp_32reg_h, temp_32reg); 485 temp_32reg = tzc_read_region_top_low(tzc.base, n); 486 temp_32reg_h = tzc_read_region_top_high(tzc.base, n); 487 DMSG("region_top: 0x%08x%08x", temp_32reg_h, temp_32reg); 488 temp_32reg = tzc_read_region_attributes(tzc.base, n); 489 DMSG("secure rw: %s", 490 tzc_attr_msg[temp_32reg >> REG_ATTR_SEC_SHIFT]); 491 492 for (filter = 0; filter < tzc.num_filters; filter++) 493 if (temp_32reg & BIT(filter)) 494 DMSG("filter %u enable", filter); 495 } 496 } 497 498 #endif /* CFG_TRACE_LEVEL >= TRACE_DEBUG */ 499