DDR has been set as secure in MMU tables. Non-secure master such
as SDHC DMA cannot access data correctly. Mixing secure and non-
secure MMU entries requirs the MMU tables themselves in secure
memory. This patch moves MMU tables into a secure DDR area reserved
for TrustZone with size CONFIG_FSL_PPA_RESERVED_DRAM_SIZE.

Early MMU tables are changed to set DDR as non-secure. Before
setting final MMU tables in secure DDR, existing MMU needs to be
updated with a secure DDR entry. A new table is added into final
MMU tables so secure memory can have 2MB granuality.

A new global data variable secure_ram is introduced to host the
address of secure memory. "bdinfo" command shows its value.

Signed-off-by: York Sun <york...@freescale.com>

---

Changes in v1: None

 arch/arm/cpu/armv8/fsl-layerscape/cpu.c        |  126 ++++++++++++++++++++++--
 arch/arm/include/asm/arch-fsl-layerscape/cpu.h |   12 ++-
 arch/arm/include/asm/global_data.h             |    3 +
 board/freescale/ls2085a/ddr.c                  |   10 ++
 board/freescale/ls2085aqds/ddr.c               |   10 ++
 board/freescale/ls2085ardb/ddr.c               |   10 ++
 common/cmd_bdinfo.c                            |    4 +
 7 files changed, 162 insertions(+), 13 deletions(-)

diff --git a/arch/arm/cpu/armv8/fsl-layerscape/cpu.c 
b/arch/arm/cpu/armv8/fsl-layerscape/cpu.c
index 690c263..5ce6f8f 100644
--- a/arch/arm/cpu/armv8/fsl-layerscape/cpu.c
+++ b/arch/arm/cpu/armv8/fsl-layerscape/cpu.c
@@ -207,10 +207,86 @@ static inline void early_mmu_setup(void)
 }
 
 /*
+ * Called from early mmu setup. The phys_addr needs to be in
+ * the table and aligned. This function sets the block to secure.
+ */
+static inline int fixup_early_secure_ddr(u64 *level0_table,
+                                        phys_addr_t phys_addr)
+{
+       int ret = 0;
+#ifdef CONFIG_FSL_PPA_RESERVED_DRAM_SIZE
+       struct table_info table = {};
+       struct sys_mmu_table ddr_entry = {
+               0, 0, BLOCK_SIZE_L1, MT_NORMAL, PMD_SECT_OUTER_SHARE
+       };
+
+       ddr_entry.virt_addr = phys_addr;
+       ddr_entry.phys_addr = phys_addr;
+       ret = find_table(&ddr_entry, &table, level0_table);
+       if (!ret)
+               ret = set_block_entry(&ddr_entry, &table);
+#endif
+
+       return ret;
+}
+/*
+ * Called from final mmu setup. The phys_addr is new, non-existing
+ * address. A new sub table is created @level2_table_secure.
+ */
+static inline int final_secure_ddr(u64 *level0_table,
+                                  u64 *level2_table_secure,
+                                  phys_addr_t phys_addr)
+{
+       int ret = 0;
+#ifdef CONFIG_FSL_PPA_RESERVED_DRAM_SIZE
+       struct table_info table = {};
+       struct sys_mmu_table ddr_entry = {
+               0, 0, BLOCK_SIZE_L1, MT_NORMAL,
+               PMD_SECT_OUTER_SHARE | PMD_SECT_NS
+       };
+       u64 index;
+
+       /* Need to create a new table */
+       ddr_entry.virt_addr = phys_addr & ~(BLOCK_SIZE_L1 - 1);
+       ddr_entry.phys_addr = phys_addr & ~(BLOCK_SIZE_L1 - 1);
+       ret = find_table(&ddr_entry, &table, level0_table);
+       if (ret)
+               return ret;
+       index = (ddr_entry.virt_addr - table.table_base) >> SECTION_SHIFT_L1;
+       set_pgtable_table(table.ptr, index, level2_table_secure);
+       table.ptr = level2_table_secure;
+       table.table_base = ddr_entry.virt_addr;
+       table.entry_size = BLOCK_SIZE_L2;
+       ret = set_block_entry(&ddr_entry, &table);
+       if (ret) {
+               printf("MMU error: could not fill non-secure ddr block 
entries\n");
+               return ret;
+       }
+       ddr_entry.virt_addr = phys_addr;
+       ddr_entry.phys_addr = phys_addr;
+       ddr_entry.size = CONFIG_FSL_PPA_RESERVED_DRAM_SIZE;
+       ddr_entry.attribute = PMD_SECT_OUTER_SHARE;
+       ret = find_table(&ddr_entry, &table, level0_table);
+       if (ret) {
+               printf("MMU error: could not find secure ddr table\n");
+               return ret;
+       }
+       ret = set_block_entry(&ddr_entry, &table);
+       if (ret)
+               printf("MMU error: could not set secure ddr block entry\n");
+#endif
+
+       return ret;
+}
+
+/*
  * The final tables look similar to early tables, but different in detail.
  * These tables are in DRAM. Sub tables are added to enable cache for
  * QBMan and OCRAM.
  *
+ * Put the MMU table in secure memory if gd->arch.secure_ram is set.
+ * OCRAM will be not used for this purpose so gd->arch.secure_ram can't be 0.
+ *
  * Level 1 table 0 contains 512 entries for each 1GB from 0 to 512GB.
  * Level 1 table 1 contains 512 entries for each 1GB from 512GB to 1TB.
  * Level 2 table 0 contains 512 entries for each 2MB from 0 to 1GB.
@@ -224,17 +300,35 @@ static inline void early_mmu_setup(void)
 static inline void final_mmu_setup(void)
 {
        unsigned int el, i;
-       u64 *level0_table = (u64 *)gd->arch.tlb_addr;
-       u64 *level1_table0 = (u64 *)(gd->arch.tlb_addr + 0x1000);
-       u64 *level1_table1 = (u64 *)(gd->arch.tlb_addr + 0x2000);
-       u64 *level2_table0 = (u64 *)(gd->arch.tlb_addr + 0x3000);
-#ifdef CONFIG_FSL_LSCH3
-       u64 *level2_table1 = (u64 *)(gd->arch.tlb_addr + 0x4000);
-#elif defined(CONFIG_FSL_LSCH2)
-       u64 *level2_table1 = (u64 *)(gd->arch.tlb_addr + 0x4000);
-       u64 *level2_table2 = (u64 *)(gd->arch.tlb_addr + 0x5000);
+       u64 *level0_table = gd->arch.secure_ram ? (u64 *)gd->arch.secure_ram
+                                               : (u64 *)gd->arch.tlb_addr;
+       u64 *level1_table0 = level0_table + 512;
+       u64 *level1_table1 = level1_table0 + 512;
+       u64 *level2_table0 = level1_table1 + 512;
+       u64 *level2_table1 = level2_table0 + 512;
+#ifdef CONFIG_FSL_LSCH2
+       u64 *level2_table2 = level2_table1 + 512;
 #endif
+       u64 *level2_table_secure;
        struct table_info table = {level0_table, 0, BLOCK_SIZE_L0};
+       u64 secure_ram = gd->arch.secure_ram & ~(BLOCK_SIZE_L1 - 1);
+
+       /*
+        * Modify the early MMU table to create a secure memory
+        * to host the table
+        */
+       if (!fixup_early_secure_ddr((u64 *)CONFIG_SYS_FSL_OCRAM_BASE,
+                                   secure_ram)) {
+               flush_dcache_range(CONFIG_SYS_FSL_OCRAM_BASE,
+                                  CONFIG_SYS_FSL_OCRAM_BASE + 0x5000);
+               asm volatile(
+                       "tlbi vae3, %0\n"
+                       "dsb sy\n"
+                       "isb"
+                       : : "r" (secure_ram) : "memory");
+       } else {
+               printf("MMU error: Failed to create early MMU secure DDR\n");
+       }
 
        /* Invalidate all table entries */
        memset(level0_table, 0, PGTABLE_SIZE);
@@ -269,6 +363,20 @@ static inline void final_mmu_setup(void)
                               &final_mmu_table[i]);
                }
        }
+       /* Set the PPA memory to secure */
+       if (gd->arch.secure_ram) {
+#ifdef CONFIG_FSL_LSCH3
+               level2_table_secure = level2_table1 + 512;
+#elif defined(CONFIG_FSL_LSCH2)
+               level2_table_secure = level2_table2 + 512;
+#endif
+               /* update tlb pointer */
+               gd->arch.tlb_addr = gd->arch.secure_ram;
+               if (!final_secure_ddr(level0_table,
+                                     level2_table_secure,
+                                     gd->arch.secure_ram))
+                       gd->arch.secure_ram |= 1;       /* set the valid flag */
+       }
 
        /* flush new MMU table */
        flush_dcache_range(gd->arch.tlb_addr,
diff --git a/arch/arm/include/asm/arch-fsl-layerscape/cpu.h 
b/arch/arm/include/asm/arch-fsl-layerscape/cpu.h
index b4b85a8..a13a3d3 100644
--- a/arch/arm/include/asm/arch-fsl-layerscape/cpu.h
+++ b/arch/arm/include/asm/arch-fsl-layerscape/cpu.h
@@ -129,12 +129,14 @@ static const struct sys_mmu_table early_mmu_table[] = {
        { CONFIG_SYS_FLASH_BASE, CONFIG_SYS_FSL_IFC_BASE1,
          CONFIG_SYS_FSL_IFC_SIZE1, MT_DEVICE_NGNRNE, PMD_SECT_NON_SHARE },
        { CONFIG_SYS_FSL_DRAM_BASE1, CONFIG_SYS_FSL_DRAM_BASE1,
-         CONFIG_SYS_FSL_DRAM_SIZE1, MT_NORMAL, PMD_SECT_OUTER_SHARE },
+         CONFIG_SYS_FSL_DRAM_SIZE1, MT_NORMAL,
+         PMD_SECT_OUTER_SHARE | PMD_SECT_NS},
        { CONFIG_SYS_FSL_DCSR_BASE, CONFIG_SYS_FSL_DCSR_BASE,
          CONFIG_SYS_FSL_DCSR_SIZE, MT_DEVICE_NGNRNE,
          PMD_SECT_NON_SHARE | PMD_SECT_PXN | PMD_SECT_UXN },
        { CONFIG_SYS_FSL_DRAM_BASE2, CONFIG_SYS_FSL_DRAM_BASE2,
-         CONFIG_SYS_FSL_DRAM_SIZE2, MT_NORMAL, PMD_SECT_OUTER_SHARE },
+         CONFIG_SYS_FSL_DRAM_SIZE2, MT_NORMAL,
+         PMD_SECT_OUTER_SHARE | PMD_SECT_NS },
 #elif defined(CONFIG_FSL_LSCH2)
        { CONFIG_SYS_FSL_CCSR_BASE, CONFIG_SYS_FSL_CCSR_BASE,
          CONFIG_SYS_FSL_CCSR_SIZE, MT_DEVICE_NGNRNE,
@@ -161,7 +163,8 @@ static const struct sys_mmu_table final_mmu_table[] = {
        { CONFIG_SYS_FSL_OCRAM_BASE, CONFIG_SYS_FSL_OCRAM_BASE,
          CONFIG_SYS_FSL_OCRAM_SIZE, MT_NORMAL, PMD_SECT_NON_SHARE },
        { CONFIG_SYS_FSL_DRAM_BASE1, CONFIG_SYS_FSL_DRAM_BASE1,
-         CONFIG_SYS_FSL_DRAM_SIZE1, MT_NORMAL, PMD_SECT_OUTER_SHARE },
+         CONFIG_SYS_FSL_DRAM_SIZE1, MT_NORMAL,
+         PMD_SECT_OUTER_SHARE | PMD_SECT_NS },
        { CONFIG_SYS_FSL_QSPI_BASE2, CONFIG_SYS_FSL_QSPI_BASE2,
          CONFIG_SYS_FSL_QSPI_SIZE2, MT_DEVICE_NGNRNE,
          PMD_SECT_NON_SHARE | PMD_SECT_PXN | PMD_SECT_UXN },
@@ -208,7 +211,8 @@ static const struct sys_mmu_table final_mmu_table[] = {
          CONFIG_SYS_FSL_PEBUF_SIZE, MT_DEVICE_NGNRNE,
          PMD_SECT_NON_SHARE | PMD_SECT_PXN | PMD_SECT_UXN },
        { CONFIG_SYS_FSL_DRAM_BASE2, CONFIG_SYS_FSL_DRAM_BASE2,
-         CONFIG_SYS_FSL_DRAM_SIZE2, MT_NORMAL, PMD_SECT_OUTER_SHARE },
+         CONFIG_SYS_FSL_DRAM_SIZE2, MT_NORMAL,
+         PMD_SECT_OUTER_SHARE | PMD_SECT_NS },
 #elif defined(CONFIG_FSL_LSCH2)
        { CONFIG_SYS_FSL_BOOTROM_BASE, CONFIG_SYS_FSL_BOOTROM_BASE,
          CONFIG_SYS_FSL_BOOTROM_SIZE, MT_DEVICE_NGNRNE,
diff --git a/arch/arm/include/asm/global_data.h 
b/arch/arm/include/asm/global_data.h
index 4e3ea55..d0c7fc4 100644
--- a/arch/arm/include/asm/global_data.h
+++ b/arch/arm/include/asm/global_data.h
@@ -49,6 +49,9 @@ struct arch_global_data {
 #ifdef CONFIG_FSL_LSCH3
        unsigned long mem2_clk;
 #endif
+#ifdef CONFIG_FSL_LAYERSCAPE
+       phys_addr_t secure_ram; /* lsb is a valid flag */
+#endif
 };
 
 #include <asm-generic/global_data.h>
diff --git a/board/freescale/ls2085a/ddr.c b/board/freescale/ls2085a/ddr.c
index 4884fa2..b7c939b 100644
--- a/board/freescale/ls2085a/ddr.c
+++ b/board/freescale/ls2085a/ddr.c
@@ -180,8 +180,18 @@ void dram_init_banksize(void)
                gd->bd->bi_dram[1].start = CONFIG_SYS_DDR_BLOCK2_BASE;
                gd->bd->bi_dram[1].size = gd->ram_size -
                                          CONFIG_SYS_LS2_DDR_BLOCK1_SIZE;
+#ifdef CONFIG_FSL_PPA_RESERVED_DRAM_SIZE
+               gd->arch.secure_ram = gd->bd->bi_dram[1].start +
+                                     gd->bd->bi_dram[1].size -
+                                     CONFIG_FSL_PPA_RESERVED_DRAM_SIZE;
+#endif
        } else {
                gd->bd->bi_dram[0].size = gd->ram_size;
+#ifdef CONFIG_FSL_PPA_RESERVED_DRAM_SIZE
+               gd->arch.secure_ram = gd->bd->bi_dram[0].start +
+                                     gd->bd->bi_dram[0].size -
+                                     CONFIG_FSL_PPA_RESERVED_DRAM_SIZE;
+#endif
        }
 
 #ifdef CONFIG_SYS_DP_DDR_BASE_PHY
diff --git a/board/freescale/ls2085aqds/ddr.c b/board/freescale/ls2085aqds/ddr.c
index 8d71ae1..f24ef12 100644
--- a/board/freescale/ls2085aqds/ddr.c
+++ b/board/freescale/ls2085aqds/ddr.c
@@ -170,8 +170,18 @@ void dram_init_banksize(void)
                gd->bd->bi_dram[1].start = CONFIG_SYS_DDR_BLOCK2_BASE;
                gd->bd->bi_dram[1].size = gd->ram_size -
                                          CONFIG_SYS_LS2_DDR_BLOCK1_SIZE;
+#ifdef CONFIG_FSL_PPA_RESERVED_DRAM_SIZE
+               gd->arch.secure_ram = gd->bd->bi_dram[1].start +
+                                     gd->bd->bi_dram[1].size -
+                                     CONFIG_FSL_PPA_RESERVED_DRAM_SIZE;
+#endif
        } else {
                gd->bd->bi_dram[0].size = gd->ram_size;
+#ifdef CONFIG_FSL_PPA_RESERVED_DRAM_SIZE
+               gd->arch.secure_ram = gd->bd->bi_dram[0].start +
+                                     gd->bd->bi_dram[0].size -
+                                     CONFIG_FSL_PPA_RESERVED_DRAM_SIZE;
+#endif
        }
 
 #ifdef CONFIG_SYS_DP_DDR_BASE_PHY
diff --git a/board/freescale/ls2085ardb/ddr.c b/board/freescale/ls2085ardb/ddr.c
index 8d71ae1..f24ef12 100644
--- a/board/freescale/ls2085ardb/ddr.c
+++ b/board/freescale/ls2085ardb/ddr.c
@@ -170,8 +170,18 @@ void dram_init_banksize(void)
                gd->bd->bi_dram[1].start = CONFIG_SYS_DDR_BLOCK2_BASE;
                gd->bd->bi_dram[1].size = gd->ram_size -
                                          CONFIG_SYS_LS2_DDR_BLOCK1_SIZE;
+#ifdef CONFIG_FSL_PPA_RESERVED_DRAM_SIZE
+               gd->arch.secure_ram = gd->bd->bi_dram[1].start +
+                                     gd->bd->bi_dram[1].size -
+                                     CONFIG_FSL_PPA_RESERVED_DRAM_SIZE;
+#endif
        } else {
                gd->bd->bi_dram[0].size = gd->ram_size;
+#ifdef CONFIG_FSL_PPA_RESERVED_DRAM_SIZE
+               gd->arch.secure_ram = gd->bd->bi_dram[0].start +
+                                     gd->bd->bi_dram[0].size -
+                                     CONFIG_FSL_PPA_RESERVED_DRAM_SIZE;
+#endif
        }
 
 #ifdef CONFIG_SYS_DP_DDR_BASE_PHY
diff --git a/common/cmd_bdinfo.c b/common/cmd_bdinfo.c
index ed3b935..408d020 100644
--- a/common/cmd_bdinfo.c
+++ b/common/cmd_bdinfo.c
@@ -377,6 +377,10 @@ static int do_bdinfo(cmd_tbl_t *cmdtp, int flag, int argc,
                print_num("-> size",    bd->bi_dram[i].size);
        }
 
+#ifdef CONFIG_FSL_LAYERSCAPE
+       if (gd->arch.secure_ram & 0x1)
+               print_num("Secure ram", gd->arch.secure_ram & ~1);
+#endif
 #if defined(CONFIG_CMD_NET) && !defined(CONFIG_DM_ETH)
        print_eths();
 #endif
-- 
1.7.9.5

_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

Reply via email to