Hi York, > -----Original Message----- > From: York Sun [mailto:york...@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 <york...@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, > + 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 }, @@ -179,7 > +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 }, > + PMD_SECT_NON_SHARE | PMD_SECT_PXN | PMD_SECT_UXN | PMD_SECT_NS }, > { 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, @@ - > 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; > + gd->secure_ram |= MEM_RESERVE_SECURE_MAINTAINED; #endif > } else { > 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 > } > > #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; > + gd->secure_ram |= MEM_RESERVE_SECURE_MAINTAINED; #endif > } else { > 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 > } > > #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; > + gd->secure_ram |= MEM_RESERVE_SECURE_MAINTAINED; #endif > } else { > 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 > } > > #ifdef CONFIG_SYS_DP_DDR_BASE_PHY > -- > 1.7.9.5 Thanks, Zhiqiang _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot