[U-Boot] [PATCH v6 2/2] armv8: fsl-layerscape: Make DDR non secure in MMU tables

Hou Zhiqiang B48286 at freescale.com
Wed Dec 2 07:38:30 CET 2015


Hi York,

> -----Original Message-----
> From: York Sun [mailto:yorksun at 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 at 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


More information about the U-Boot mailing list