tzc380.c 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. /*
  2. * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
  3. *
  4. * SPDX-License-Identifier: BSD-3-Clause
  5. */
  6. #include <assert.h>
  7. #include <stddef.h>
  8. #include <common/debug.h>
  9. #include <drivers/arm/tzc380.h>
  10. #include <lib/mmio.h>
  11. struct tzc380_instance {
  12. uintptr_t base;
  13. uint8_t addr_width;
  14. uint8_t num_regions;
  15. };
  16. struct tzc380_instance tzc380;
  17. static unsigned int tzc380_read_build_config(uintptr_t base)
  18. {
  19. return mmio_read_32(base + TZC380_CONFIGURATION_OFF);
  20. }
  21. static void tzc380_write_action(uintptr_t base, unsigned int action)
  22. {
  23. mmio_write_32(base + ACTION_OFF, action);
  24. }
  25. static void tzc380_write_region_base_low(uintptr_t base, unsigned int region,
  26. unsigned int val)
  27. {
  28. mmio_write_32(base + REGION_SETUP_LOW_OFF(region), val);
  29. }
  30. static void tzc380_write_region_base_high(uintptr_t base, unsigned int region,
  31. unsigned int val)
  32. {
  33. mmio_write_32(base + REGION_SETUP_HIGH_OFF(region), val);
  34. }
  35. static void tzc380_write_region_attributes(uintptr_t base, unsigned int region,
  36. unsigned int val)
  37. {
  38. mmio_write_32(base + REGION_ATTRIBUTES_OFF(region), val);
  39. }
  40. void tzc380_init(uintptr_t base)
  41. {
  42. unsigned int tzc_build;
  43. assert(base != 0U);
  44. tzc380.base = base;
  45. /* Save values we will use later. */
  46. tzc_build = tzc380_read_build_config(tzc380.base);
  47. tzc380.addr_width = ((tzc_build >> BUILD_CONFIG_AW_SHIFT) &
  48. BUILD_CONFIG_AW_MASK) + 1;
  49. tzc380.num_regions = ((tzc_build >> BUILD_CONFIG_NR_SHIFT) &
  50. BUILD_CONFIG_NR_MASK) + 1;
  51. }
  52. static uint32_t addr_low(uintptr_t addr)
  53. {
  54. return (uint32_t)addr;
  55. }
  56. static uint32_t addr_high(uintptr_t addr __unused)
  57. {
  58. #if (UINTPTR_MAX == UINT64_MAX)
  59. return addr >> 32;
  60. #else
  61. return 0;
  62. #endif
  63. }
  64. /*
  65. * `tzc380_configure_region` is used to program regions into the TrustZone
  66. * controller.
  67. */
  68. void tzc380_configure_region(uint8_t region, uintptr_t region_base, unsigned int attr)
  69. {
  70. assert(tzc380.base != 0U);
  71. assert(region < tzc380.num_regions);
  72. tzc380_write_region_base_low(tzc380.base, region, addr_low(region_base));
  73. tzc380_write_region_base_high(tzc380.base, region, addr_high(region_base));
  74. tzc380_write_region_attributes(tzc380.base, region, attr);
  75. }
  76. void tzc380_set_action(unsigned int action)
  77. {
  78. assert(tzc380.base != 0U);
  79. /*
  80. * - Currently no handler is provided to trap an error via interrupt
  81. * or exception.
  82. * - The interrupt action has not been tested.
  83. */
  84. tzc380_write_action(tzc380.base, action);
  85. }