]> git.dujemihanovic.xyz Git - u-boot.git/commitdiff
imx9: cut off OPTEE memory region from U-Boot
authorPeng Fan <peng.fan@nxp.com>
Fri, 28 Apr 2023 04:08:20 +0000 (12:08 +0800)
committerStefano Babic <sbabic@denx.de>
Sun, 21 May 2023 14:54:40 +0000 (16:54 +0200)
OPTEE memory region is set secure access only in ATF with configuration
to TRDC, and need to remove it from U-Boot, otherwise U-Boot and Kernel
may crash when accessing the memory

Signed-off-by: Peng Fan <peng.fan@nxp.com>
arch/arm/mach-imx/imx9/soc.c

index 252663a9eec2e4af264fed151fb2c84254ad1483..f02e9035dd093140726371c48f3b7bb347f0d659 100644 (file)
@@ -180,13 +180,160 @@ static struct mm_region imx93_mem_map[] = {
 
 struct mm_region *mem_map = imx93_mem_map;
 
+static unsigned int imx9_find_dram_entry_in_mem_map(void)
+{
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(imx93_mem_map); i++)
+               if (imx93_mem_map[i].phys == CFG_SYS_SDRAM_BASE)
+                       return i;
+
+       hang(); /* Entry not found, this must never happen. */
+}
+
+void enable_caches(void)
+{
+       /* If OPTEE runs, remove OPTEE memory from MMU table to avoid speculative prefetch
+        * If OPTEE does not run, still update the MMU table according to dram banks structure
+        * to set correct dram size from board_phys_sdram_size
+        */
+       int i = 0;
+       /*
+        * please make sure that entry initial value matches
+        * imx93_mem_map for DRAM1
+        */
+       int entry = imx9_find_dram_entry_in_mem_map();
+       u64 attrs = imx93_mem_map[entry].attrs;
+
+       while (i < CONFIG_NR_DRAM_BANKS &&
+              entry < ARRAY_SIZE(imx93_mem_map)) {
+               if (gd->bd->bi_dram[i].start == 0)
+                       break;
+               imx93_mem_map[entry].phys = gd->bd->bi_dram[i].start;
+               imx93_mem_map[entry].virt = gd->bd->bi_dram[i].start;
+               imx93_mem_map[entry].size = gd->bd->bi_dram[i].size;
+               imx93_mem_map[entry].attrs = attrs;
+               debug("Added memory mapping (%d): %llx %llx\n", entry,
+                     imx93_mem_map[entry].phys, imx93_mem_map[entry].size);
+               i++; entry++;
+       }
+
+       icache_enable();
+       dcache_enable();
+}
+
+__weak int board_phys_sdram_size(phys_size_t *size)
+{
+       if (!size)
+               return -EINVAL;
+
+       *size = PHYS_SDRAM_SIZE;
+
+#ifdef PHYS_SDRAM_2_SIZE
+       *size += PHYS_SDRAM_2_SIZE;
+#endif
+       return 0;
+}
+
 int dram_init(void)
 {
-       gd->ram_size = PHYS_SDRAM_SIZE;
+       phys_size_t sdram_size;
+       int ret;
+
+       ret = board_phys_sdram_size(&sdram_size);
+       if (ret)
+               return ret;
+
+       /* rom_pointer[1] contains the size of TEE occupies */
+       if (rom_pointer[1])
+               gd->ram_size = sdram_size - rom_pointer[1];
+       else
+               gd->ram_size = sdram_size;
+
+       return 0;
+}
+
+int dram_init_banksize(void)
+{
+       int bank = 0;
+       int ret;
+       phys_size_t sdram_size;
+       phys_size_t sdram_b1_size, sdram_b2_size;
+
+       ret = board_phys_sdram_size(&sdram_size);
+       if (ret)
+               return ret;
+
+       /* Bank 1 can't cross over 4GB space */
+       if (sdram_size > 0x80000000) {
+               sdram_b1_size = 0x80000000;
+               sdram_b2_size = sdram_size - 0x80000000;
+       } else {
+               sdram_b1_size = sdram_size;
+               sdram_b2_size = 0;
+       }
+
+       gd->bd->bi_dram[bank].start = PHYS_SDRAM;
+       if (rom_pointer[1]) {
+               phys_addr_t optee_start = (phys_addr_t)rom_pointer[0];
+               phys_size_t optee_size = (size_t)rom_pointer[1];
+
+               gd->bd->bi_dram[bank].size = optee_start - gd->bd->bi_dram[bank].start;
+               if ((optee_start + optee_size) < (PHYS_SDRAM + sdram_b1_size)) {
+                       if (++bank >= CONFIG_NR_DRAM_BANKS) {
+                               puts("CONFIG_NR_DRAM_BANKS is not enough\n");
+                               return -1;
+                       }
+
+                       gd->bd->bi_dram[bank].start = optee_start + optee_size;
+                       gd->bd->bi_dram[bank].size = PHYS_SDRAM +
+                               sdram_b1_size - gd->bd->bi_dram[bank].start;
+               }
+       } else {
+               gd->bd->bi_dram[bank].size = sdram_b1_size;
+       }
+
+       if (sdram_b2_size) {
+               if (++bank >= CONFIG_NR_DRAM_BANKS) {
+                       puts("CONFIG_NR_DRAM_BANKS is not enough for SDRAM_2\n");
+                       return -1;
+               }
+               gd->bd->bi_dram[bank].start = 0x100000000UL;
+               gd->bd->bi_dram[bank].size = sdram_b2_size;
+       }
 
        return 0;
 }
 
+phys_size_t get_effective_memsize(void)
+{
+       int ret;
+       phys_size_t sdram_size;
+       phys_size_t sdram_b1_size;
+
+       ret = board_phys_sdram_size(&sdram_size);
+       if (!ret) {
+               /* Bank 1 can't cross over 4GB space */
+               if (sdram_size > 0x80000000)
+                       sdram_b1_size = 0x80000000;
+               else
+                       sdram_b1_size = sdram_size;
+
+               if (rom_pointer[1]) {
+                       /* We will relocate u-boot to top of dram1. TEE position has two cases:
+                        * 1. At the top of dram1,  Then return the size removed optee size.
+                        * 2. In the middle of dram1, return the size of dram1.
+                        */
+                       if ((rom_pointer[0] + rom_pointer[1]) == (PHYS_SDRAM + sdram_b1_size))
+                               return ((phys_addr_t)rom_pointer[0] - PHYS_SDRAM);
+               }
+
+               return sdram_b1_size;
+       } else {
+               return PHYS_SDRAM_SIZE;
+       }
+}
+
 void imx_get_mac_from_fuse(int dev_id, unsigned char *mac)
 {
        mac[0] = 0x1;