
Hi York,
-----Original Message----- From: York Sun [mailto:yorksun@freescale.com] Sent: 2015年11月19日 2:02 To: U-Boot Mailing List Cc: Sun York-R58495; Pan Lijun-B44306; Hu Mingkai-B21284; Sharma Bhupesh- B45370; Gong Qianyu-B52263; Tom Rini; Li Yang-Leo-R58472; Albert Aribaud; Hou Zhiqiang-B48286; Kushwaha Prabhakar-B32579; Wang Huan-B18965 Subject: [PATCH v6 2/2] armv8: fsl-layerscape: Make DDR non secure in MMU tables
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.
Early MMU tables are changed to set DDR as non-secure. A new table is added into final MMU tables so secure memory can have 2MB granuality.
gd->secure_ram tracks the location of this secure memory. For ARMv8 SoCs, the RAM base is not zero and RAM is divided into several banks. gd->secure_ram needs to be maintained before using. This maintenance is board-specific, depending on the SoC and memory bank of the secure memory falls into.
Signed-off-by: York Sun yorksun@freescale.com
fixup
Changes in v6: Move cmd_bdinfo change to 1st patch in this set Rearrange #ifdef CONFIG_SYS_MEM_RESERVE_SECURE
Changes in v5: Put ifdef where gd->secure_ram is used
Changes in v4: Drop RFC from patch prefix Drop excessive mmu table for secure ram for early MMU Update commit message accordingly Mark QBMan cacheable portal memory non-secure
Changes in v3: Replace CONFIG_FSL_PPA_RESERVED_DRAM_SIZE with CONFIG_SYS_MEM_RESERVE_SECURE Sanity check gd->secure_ram before using Define CONFIG_SYS_MEM_RESERVE_SECURE in SoC header file Include ls1043ardb Modified commit message.
Changes in v2: Move gd->arch.secure_ram to gd->secure_ram. Change the calculation of gd->secure_ram accordingly. Chnage commit message slightly accordingly.
Changes in v1: None
arch/arm/cpu/armv8/fsl-layerscape/cpu.c | 111 +++++++++++++++++++-- arch/arm/include/asm/arch-fsl-layerscape/config.h | 6 ++ arch/arm/include/asm/arch-fsl-layerscape/cpu.h | 14 ++- board/freescale/ls1043ardb/ddr.c | 4 + board/freescale/ls2085a/ddr.c | 15 +++ board/freescale/ls2085aqds/ddr.c | 15 +++ board/freescale/ls2085ardb/ddr.c | 15 +++ 7 files changed, 165 insertions(+), 15 deletions(-)
diff --git a/arch/arm/cpu/armv8/fsl-layerscape/cpu.c b/arch/arm/cpu/armv8/fsl-layerscape/cpu.c index 9d1c70f..501feb3 100644 --- a/arch/arm/cpu/armv8/fsl-layerscape/cpu.c +++ b/arch/arm/cpu/armv8/fsl-layerscape/cpu.c @@ -206,11 +206,65 @@ static inline void early_mmu_setup(void) set_sctlr(get_sctlr() | CR_M); }
+#ifdef CONFIG_SYS_MEM_RESERVE_SECURE +/*
- Called from final mmu setup. The phys_addr is new, non-existing
- address. A new sub table is created @level2_table_secure to cover
- size of CONFIG_SYS_MEM_RESERVE_SECURE memory.
- */
+static inline int final_secure_ddr(u64 *level0_table,
u64 *level2_table_secure,
phys_addr_t phys_addr)
+{
- int ret = -EINVAL;
- 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_SYS_MEM_RESERVE_SECURE;
- 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");
- return ret;
+} +#endif
/*
- 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->secure_ram is valid.
- OCRAM will be not used for this purpose so gd->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 +278,38 @@ 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;
- u64 *level1_table0;
- u64 *level1_table1;
- u64 *level2_table0;
- u64 *level2_table1;
+#ifdef CONFIG_FSL_LSCH2
- u64 *level2_table2;
#endif
- struct table_info table = {level0_table, 0, BLOCK_SIZE_L0};
- struct table_info table = {NULL, 0, BLOCK_SIZE_L0};
+#ifdef CONFIG_SYS_MEM_RESERVE_SECURE
- u64 *level2_table_secure;
- /* Only use gd->secure_ram if the address is recalculated */
- if (gd->secure_ram & MEM_RESERVE_SECURE_MAINTAINED) {
/* Align to 4KB */
level0_table = (u64 *)(gd->secure_ram & ~0xfff);
- } else {
level0_table = (u64 *)gd->arch.tlb_addr;
printf("MMU warning: gd->secure_ram is not maintained,
disabled.\n");
- }
+#else
- level0_table = (u64 *)gd->arch.tlb_addr; #endif
- level1_table0 = level0_table + 512;
- level1_table1 = level1_table0 + 512;
- level2_table0 = level1_table1 + 512;
- level2_table1 = level2_table0 + 512;
+#ifdef CONFIG_FSL_LSCH2
- level2_table2 = level2_table1 + 512;
+#endif
table.ptr = level0_table;
/* Invalidate all table entries */ memset(level0_table, 0, PGTABLE_SIZE); @@ -269,6 +344,22 @@ static
inline void final_mmu_setup(void) &final_mmu_table[i]); } }
- /* Set the secure memory to secure in MMU */ #ifdef
+CONFIG_SYS_MEM_RESERVE_SECURE
- if (gd->secure_ram & MEM_RESERVE_SECURE_MAINTAINED) { #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->secure_ram & ~0x3;
The memory reserved for mmu table was lost? If it's better to record it and use for non-sec mmu table?
If this func is called from non-secure state, for example EL2, the secure memory cannot be accessed and the PMD_SECT_NS bit should be cleared.
if (!final_secure_ddr(level0_table,
level2_table_secure,
gd->secure_ram & ~0x3))
gd->secure_ram |= MEM_RESERVE_SECURE_SECURED;
- }
+#endif
/* flush new MMU table */ flush_dcache_range(gd->arch.tlb_addr, diff --git a/arch/arm/include/asm/arch-fsl-layerscape/config.h b/arch/arm/include/asm/arch-fsl-layerscape/config.h index 87bb937..5cfc9b3 100644 --- a/arch/arm/include/asm/arch-fsl-layerscape/config.h +++ b/arch/arm/include/asm/arch-fsl-layerscape/config.h @@ -17,6 +17,12 @@ #define CONFIG_SYS_FSL_DDR /* Freescale DDR driver */ #define CONFIG_SYS_FSL_DDR_VER FSL_DDR_VER_5_0
+/*
- Reserve secure memory
- To be aligned with MMU block size
- */
+#define CONFIG_SYS_MEM_RESERVE_SECURE (2048 * 1024) /* 2MB */
#if defined(CONFIG_LS2085A) #define CONFIG_MAX_CPUS 16 #define CONFIG_SYS_FSL_IFC_BANK_COUNT 8 diff --git a/arch/arm/include/asm/arch-fsl-layerscape/cpu.h b/arch/arm/include/asm/arch-fsl-layerscape/cpu.h index b4b85a8..a5fcef0 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,
{ 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,PMD_SECT_OUTER_SHARE | PMD_SECT_NS},
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,
{ 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 }, @@ -179,7PMD_SECT_OUTER_SHARE | PMD_SECT_NS },
+182,7 @@ static const struct sys_mmu_table final_mmu_table[] = { /* For QBMAN portal, only the first 64MB is cache-enabled */ { CONFIG_SYS_FSL_QBMAN_BASE, CONFIG_SYS_FSL_QBMAN_BASE, CONFIG_SYS_FSL_QBMAN_SIZE_1, MT_NORMAL,
PMD_SECT_NON_SHARE | PMD_SECT_PXN | PMD_SECT_UXN },
{ CONFIG_SYS_FSL_QBMAN_BASE + CONFIG_SYS_FSL_QBMAN_SIZE_1, CONFIG_SYS_FSL_QBMAN_BASE + CONFIG_SYS_FSL_QBMAN_SIZE_1, CONFIG_SYS_FSL_QBMAN_SIZE - CONFIG_SYS_FSL_QBMAN_SIZE_1, @@ -PMD_SECT_NON_SHARE | PMD_SECT_PXN | PMD_SECT_UXN | PMD_SECT_NS },
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/board/freescale/ls1043ardb/ddr.c b/board/freescale/ls1043ardb/ddr.c index b181579..82be50b 100644 --- a/board/freescale/ls1043ardb/ddr.c +++ b/board/freescale/ls1043ardb/ddr.c @@ -188,4 +188,8 @@ void dram_init_banksize(void) { gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE; gd->bd->bi_dram[0].size = gd->ram_size; +#ifdef CONFIG_SYS_MEM_RESERVE_SECURE
- gd->secure_ram = gd->bd->bi_dram[0].start + gd->secure_ram;
- gd->secure_ram |= MEM_RESERVE_SECURE_MAINTAINED; #endif
} diff --git a/board/freescale/ls2085a/ddr.c b/board/freescale/ls2085a/ddr.c index 4884fa2..bd8a98a 100644 --- a/board/freescale/ls2085a/ddr.c +++ b/board/freescale/ls2085a/ddr.c @@ -174,14 +174,29 @@ void dram_init_banksize(void) phys_size_t dp_ddr_size; #endif
- /*
* gd->secure_ram tracks the location of secure memory.
* It was set as if the memory starts from 0.
* The address needs to add the offset of its bank.
gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE; if (gd->ram_size > CONFIG_SYS_LS2_DDR_BLOCK1_SIZE) { gd->bd->bi_dram[0].size = CONFIG_SYS_LS2_DDR_BLOCK1_SIZE; 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_SYS_MEM_RESERVE_SECURE
gd->secure_ram = gd->bd->bi_dram[1].start +
gd->secure_ram -
CONFIG_SYS_LS2_DDR_BLOCK1_SIZE;
} else { gd->bd->bi_dram[0].size = gd->ram_size;gd->secure_ram |= MEM_RESERVE_SECURE_MAINTAINED; #endif
+#ifdef CONFIG_SYS_MEM_RESERVE_SECURE
gd->secure_ram = gd->bd->bi_dram[0].start + gd->secure_ram;
}gd->secure_ram |= MEM_RESERVE_SECURE_MAINTAINED; #endif
#ifdef CONFIG_SYS_DP_DDR_BASE_PHY diff --git a/board/freescale/ls2085aqds/ddr.c b/board/freescale/ls2085aqds/ddr.c index 8d71ae1..0604230 100644 --- a/board/freescale/ls2085aqds/ddr.c +++ b/board/freescale/ls2085aqds/ddr.c @@ -164,14 +164,29 @@ void dram_init_banksize(void) phys_size_t dp_ddr_size; #endif
- /*
* gd->secure_ram tracks the location of secure memory.
* It was set as if the memory starts from 0.
* The address needs to add the offset of its bank.
gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE; if (gd->ram_size > CONFIG_SYS_LS2_DDR_BLOCK1_SIZE) { gd->bd->bi_dram[0].size = CONFIG_SYS_LS2_DDR_BLOCK1_SIZE; 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_SYS_MEM_RESERVE_SECURE
gd->secure_ram = gd->bd->bi_dram[1].start +
gd->secure_ram -
CONFIG_SYS_LS2_DDR_BLOCK1_SIZE;
} else { gd->bd->bi_dram[0].size = gd->ram_size;gd->secure_ram |= MEM_RESERVE_SECURE_MAINTAINED; #endif
+#ifdef CONFIG_SYS_MEM_RESERVE_SECURE
gd->secure_ram = gd->bd->bi_dram[0].start + gd->secure_ram;
}gd->secure_ram |= MEM_RESERVE_SECURE_MAINTAINED; #endif
#ifdef CONFIG_SYS_DP_DDR_BASE_PHY diff --git a/board/freescale/ls2085ardb/ddr.c b/board/freescale/ls2085ardb/ddr.c index 8d71ae1..0604230 100644 --- a/board/freescale/ls2085ardb/ddr.c +++ b/board/freescale/ls2085ardb/ddr.c @@ -164,14 +164,29 @@ void dram_init_banksize(void) phys_size_t dp_ddr_size; #endif
- /*
* gd->secure_ram tracks the location of secure memory.
* It was set as if the memory starts from 0.
* The address needs to add the offset of its bank.
gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE; if (gd->ram_size > CONFIG_SYS_LS2_DDR_BLOCK1_SIZE) { gd->bd->bi_dram[0].size = CONFIG_SYS_LS2_DDR_BLOCK1_SIZE; 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_SYS_MEM_RESERVE_SECURE
gd->secure_ram = gd->bd->bi_dram[1].start +
gd->secure_ram -
CONFIG_SYS_LS2_DDR_BLOCK1_SIZE;
} else { gd->bd->bi_dram[0].size = gd->ram_size;gd->secure_ram |= MEM_RESERVE_SECURE_MAINTAINED; #endif
+#ifdef CONFIG_SYS_MEM_RESERVE_SECURE
gd->secure_ram = gd->bd->bi_dram[0].start + gd->secure_ram;
}gd->secure_ram |= MEM_RESERVE_SECURE_MAINTAINED; #endif
#ifdef CONFIG_SYS_DP_DDR_BASE_PHY
1.7.9.5
Thanks, Zhiqiang