arm_nor_psci_mem_protect.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. /*
  2. * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
  3. *
  4. * SPDX-License-Identifier: BSD-3-Clause
  5. */
  6. #include <platform_def.h>
  7. #include <common/debug.h>
  8. #include <drivers/cfi/v2m_flash.h>
  9. #include <lib/psci/psci.h>
  10. #include <lib/utils.h>
  11. #include <plat/arm/common/plat_arm.h>
  12. /*
  13. * DRAM1 is used also to load the NS boot loader. For this reason we
  14. * cannot clear the full DRAM1, because in that case we would clear
  15. * the NS images (especially for RESET_TO_BL31 and RESET_TO_SPMIN cases).
  16. * For this reason we reserve 64 MB for the NS images and protect the RAM
  17. * until the end of DRAM1.
  18. * We limit the size of DRAM2 to 1 GB to avoid big delays while booting
  19. */
  20. #define DRAM1_NS_IMAGE_LIMIT (PLAT_ARM_NS_IMAGE_BASE + (32 << TWO_MB_SHIFT))
  21. #define DRAM1_PROTECTED_SIZE (ARM_NS_DRAM1_END+1u - DRAM1_NS_IMAGE_LIMIT)
  22. static mem_region_t arm_ram_ranges[] = {
  23. {DRAM1_NS_IMAGE_LIMIT, DRAM1_PROTECTED_SIZE},
  24. #ifdef __aarch64__
  25. {ARM_DRAM2_BASE, 1u << ONE_GB_SHIFT},
  26. #endif
  27. };
  28. /*******************************************************************************
  29. * Function that reads the content of the memory protect variable that
  30. * enables clearing of non secure memory when system boots. This variable
  31. * should be stored in a secure NVRAM.
  32. ******************************************************************************/
  33. int arm_psci_read_mem_protect(int *enabled)
  34. {
  35. int tmp;
  36. tmp = *(int *) PLAT_ARM_MEM_PROT_ADDR;
  37. *enabled = (tmp == 1) ? 1 : 0;
  38. return 0;
  39. }
  40. /*******************************************************************************
  41. * Function that writes the content of the memory protect variable that
  42. * enables overwritten of non secure memory when system boots.
  43. ******************************************************************************/
  44. int arm_nor_psci_write_mem_protect(int val)
  45. {
  46. unsigned long enable = (val != 0) ? 1UL : 0UL;
  47. if (nor_unlock(PLAT_ARM_MEM_PROT_ADDR) != 0) {
  48. ERROR("unlocking memory protect variable\n");
  49. return -1;
  50. }
  51. if (enable == 1UL) {
  52. /*
  53. * If we want to write a value different than 0
  54. * then we have to erase the full block because
  55. * otherwise we cannot ensure that the value programmed
  56. * into the flash is going to be the same than the value
  57. * requested by the caller
  58. */
  59. if (nor_erase(PLAT_ARM_MEM_PROT_ADDR) != 0) {
  60. ERROR("erasing block containing memory protect variable\n");
  61. return -1;
  62. }
  63. }
  64. if (nor_word_program(PLAT_ARM_MEM_PROT_ADDR, enable) != 0) {
  65. ERROR("programming memory protection variable\n");
  66. return -1;
  67. }
  68. return 0;
  69. }
  70. /*******************************************************************************
  71. * Function used for required psci operations performed when
  72. * system boots
  73. ******************************************************************************/
  74. /*
  75. * PLAT_MEM_PROTECT_VA_FRAME is a address specifically
  76. * selected in a way that is not needed an additional
  77. * translation table for memprotect. It happens because
  78. * we use a chunk of size 2MB and it means that it can
  79. * be mapped in a level 2 table and the level 2 table
  80. * for 0xc0000000 is already used and the entry for
  81. * 0xc0000000 is not used.
  82. */
  83. #if defined(PLAT_XLAT_TABLES_DYNAMIC)
  84. void arm_nor_psci_do_dyn_mem_protect(void)
  85. {
  86. int enable;
  87. arm_psci_read_mem_protect(&enable);
  88. if (enable == 0)
  89. return;
  90. INFO("PSCI: Overwriting non secure memory\n");
  91. clear_map_dyn_mem_regions(arm_ram_ranges,
  92. ARRAY_SIZE(arm_ram_ranges),
  93. PLAT_ARM_MEM_PROTEC_VA_FRAME,
  94. 1 << TWO_MB_SHIFT);
  95. }
  96. #endif
  97. /*******************************************************************************
  98. * Function used for required psci operations performed when
  99. * system boots and dynamic memory is not used.
  100. ******************************************************************************/
  101. void arm_nor_psci_do_static_mem_protect(void)
  102. {
  103. int enable;
  104. (void) arm_psci_read_mem_protect(&enable);
  105. if (enable == 0)
  106. return;
  107. INFO("PSCI: Overwriting non secure memory\n");
  108. clear_mem_regions(arm_ram_ranges,
  109. ARRAY_SIZE(arm_ram_ranges));
  110. (void) arm_nor_psci_write_mem_protect(0);
  111. }
  112. /*******************************************************************************
  113. * Function that checks if a region is protected by the memory protect
  114. * mechanism
  115. ******************************************************************************/
  116. int arm_psci_mem_protect_chk(uintptr_t base, u_register_t length)
  117. {
  118. return mem_region_in_array_chk(arm_ram_ranges,
  119. ARRAY_SIZE(arm_ram_ranges),
  120. base, length);
  121. }