From e61a7534e33063a76e105d895e5c6317f2d0cd76 Mon Sep 17 00:00:00 2001 From: York Sun Date: Fri, 24 Jun 2016 16:46:18 -0700 Subject: armv8: Move secure_ram variable out of generic global data Secure_ram variable was put in generic global data. But only ARMv8 uses this variable. Move it to ARM specific data structure. Signed-off-by: York Sun diff --git a/README b/README index 26d5ad2..af37d41 100644 --- a/README +++ b/README @@ -3766,10 +3766,11 @@ Configuration Settings: You only need to set this if address zero isn't writeable - CONFIG_SYS_MEM_RESERVE_SECURE + Only implemented for ARMv8 for now. If defined, the size of CONFIG_SYS_MEM_RESERVE_SECURE memory is substracted from total RAM and won't be reported to OS. This memory can be used as secure memory. A variable - gd->secure_ram is used to track the location. In systems + gd->arch.secure_ram is used to track the location. In systems the RAM base is not zero, or RAM is divided into banks, this variable needs to be recalcuated to get the address. diff --git a/arch/arm/cpu/armv8/fsl-layerscape/cpu.c b/arch/arm/cpu/armv8/fsl-layerscape/cpu.c index 8062106..a397f5d 100644 --- a/arch/arm/cpu/armv8/fsl-layerscape/cpu.c +++ b/arch/arm/cpu/armv8/fsl-layerscape/cpu.c @@ -289,8 +289,8 @@ static inline int final_secure_ddr(u64 *level0_table, * 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. + * Put the MMU table in secure memory if gd->arch.secure_ram is valid. + * 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. @@ -321,13 +321,13 @@ static inline void final_mmu_setup(void) if (el == 3) { /* - * Only use gd->secure_ram if the address is recalculated + * Only use gd->arch.secure_ram if the address is recalculated * Align to 4KB for MMU table */ - if (gd->secure_ram & MEM_RESERVE_SECURE_MAINTAINED) - level0_table = (u64 *)(gd->secure_ram & ~0xfff); + if (gd->arch.secure_ram & MEM_RESERVE_SECURE_MAINTAINED) + level0_table = (u64 *)(gd->arch.secure_ram & ~0xfff); else - printf("MMU warning: gd->secure_ram is not maintained, disabled.\n"); + printf("MMU warning: gd->arch.secure_ram is not maintained, disabled.\n"); } #endif level1_table0 = level0_table + 512; @@ -374,7 +374,7 @@ static inline void final_mmu_setup(void) } /* Set the secure memory to secure in MMU */ #ifdef CONFIG_SYS_MEM_RESERVE_SECURE - if (el == 3 && gd->secure_ram & MEM_RESERVE_SECURE_MAINTAINED) { + if (el == 3 && gd->arch.secure_ram & MEM_RESERVE_SECURE_MAINTAINED) { #ifdef CONFIG_FSL_LSCH3 level2_table_secure = level2_table1 + 512; #elif defined(CONFIG_FSL_LSCH2) @@ -382,10 +382,10 @@ static inline void final_mmu_setup(void) #endif if (!final_secure_ddr(level0_table, level2_table_secure, - gd->secure_ram & ~0x3)) { - gd->secure_ram |= MEM_RESERVE_SECURE_SECURED; + gd->arch.secure_ram & ~0x3)) { + gd->arch.secure_ram |= MEM_RESERVE_SECURE_SECURED; debug("Now MMU table is in secured memory at 0x%llx\n", - gd->secure_ram & ~0x3); + gd->arch.secure_ram & ~0x3); } else { printf("MMU warning: Failed to secure DDR\n"); } diff --git a/arch/arm/include/asm/global_data.h b/arch/arm/include/asm/global_data.h index 77d2653..2d76cd4 100644 --- a/arch/arm/include/asm/global_data.h +++ b/arch/arm/include/asm/global_data.h @@ -44,6 +44,20 @@ struct arch_global_data { unsigned long tlb_emerg; #endif #endif +#ifdef CONFIG_SYS_MEM_RESERVE_SECURE +#define MEM_RESERVE_SECURE_SECURED 0x1 +#define MEM_RESERVE_SECURE_MAINTAINED 0x2 +#define MEM_RESERVE_SECURE_ADDR_MASK (~0x3) + /* + * Secure memory addr + * This variable needs maintenance if the RAM base is not zero, + * or if RAM splits into non-consecutive banks. It also has a + * flag indicating the secure memory is marked as secure by MMU. + * Flags used: 0x1 secured + * 0x2 maintained + */ + phys_addr_t secure_ram; +#endif #ifdef CONFIG_OMAP_COMMON u32 omap_boot_device; diff --git a/board/freescale/ls1043aqds/ddr.c b/board/freescale/ls1043aqds/ddr.c index 0fd835d..d4540d0 100644 --- a/board/freescale/ls1043aqds/ddr.c +++ b/board/freescale/ls1043aqds/ddr.c @@ -128,7 +128,7 @@ phys_size_t initdram(int board_type) void dram_init_banksize(void) { /* - * gd->secure_ram tracks the location of secure memory. + * gd->arch.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. */ @@ -139,16 +139,17 @@ void dram_init_banksize(void) gd->bd->bi_dram[1].size = gd->ram_size - CONFIG_SYS_DDR_BLOCK1_SIZE; #ifdef CONFIG_SYS_MEM_RESERVE_SECURE - gd->secure_ram = gd->bd->bi_dram[1].start + - gd->secure_ram - - CONFIG_SYS_DDR_BLOCK1_SIZE; - gd->secure_ram |= MEM_RESERVE_SECURE_MAINTAINED; + gd->arch.secure_ram = gd->bd->bi_dram[1].start + + gd->arch.secure_ram - + CONFIG_SYS_DDR_BLOCK1_SIZE; + gd->arch.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; + gd->arch.secure_ram = gd->bd->bi_dram[0].start + + gd->arch.secure_ram; + gd->arch.secure_ram |= MEM_RESERVE_SECURE_MAINTAINED; #endif } } diff --git a/board/freescale/ls1043ardb/ddr.c b/board/freescale/ls1043ardb/ddr.c index 1e2fd2e..61b1cc4 100644 --- a/board/freescale/ls1043ardb/ddr.c +++ b/board/freescale/ls1043ardb/ddr.c @@ -189,7 +189,7 @@ phys_size_t initdram(int board_type) void dram_init_banksize(void) { /* - * gd->secure_ram tracks the location of secure memory. + * gd->arch.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. */ @@ -200,16 +200,17 @@ void dram_init_banksize(void) gd->bd->bi_dram[1].size = gd->ram_size - CONFIG_SYS_DDR_BLOCK1_SIZE; #ifdef CONFIG_SYS_MEM_RESERVE_SECURE - gd->secure_ram = gd->bd->bi_dram[1].start + - gd->secure_ram - - CONFIG_SYS_DDR_BLOCK1_SIZE; - gd->secure_ram |= MEM_RESERVE_SECURE_MAINTAINED; + gd->arch.secure_ram = gd->bd->bi_dram[1].start + + gd->arch.secure_ram - + CONFIG_SYS_DDR_BLOCK1_SIZE; + gd->arch.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; + gd->arch.secure_ram = gd->bd->bi_dram[0].start + + gd->arch.secure_ram; + gd->arch.secure_ram |= MEM_RESERVE_SECURE_MAINTAINED; #endif } } diff --git a/board/freescale/ls2080a/ddr.c b/board/freescale/ls2080a/ddr.c index 1827ddc..e6130ec 100644 --- a/board/freescale/ls2080a/ddr.c +++ b/board/freescale/ls2080a/ddr.c @@ -177,7 +177,7 @@ void dram_init_banksize(void) #endif /* - * gd->secure_ram tracks the location of secure memory. + * gd->arch.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. */ @@ -188,16 +188,17 @@ void dram_init_banksize(void) 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; + gd->arch.secure_ram = gd->bd->bi_dram[1].start + + gd->arch.secure_ram - + CONFIG_SYS_LS2_DDR_BLOCK1_SIZE; + gd->arch.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; + gd->arch.secure_ram = gd->bd->bi_dram[0].start + + gd->arch.secure_ram; + gd->arch.secure_ram |= MEM_RESERVE_SECURE_MAINTAINED; #endif } diff --git a/board/freescale/ls2080aqds/ddr.c b/board/freescale/ls2080aqds/ddr.c index fcb0366..9c6f477 100644 --- a/board/freescale/ls2080aqds/ddr.c +++ b/board/freescale/ls2080aqds/ddr.c @@ -177,7 +177,7 @@ void dram_init_banksize(void) #endif /* - * gd->secure_ram tracks the location of secure memory. + * gd->arch.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. */ @@ -188,16 +188,17 @@ void dram_init_banksize(void) 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; + gd->arch.secure_ram = gd->bd->bi_dram[1].start + + gd->arch.secure_ram - + CONFIG_SYS_LS2_DDR_BLOCK1_SIZE; + gd->arch.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; + gd->arch.secure_ram = gd->bd->bi_dram[0].start + + gd->arch.secure_ram; + gd->arch.secure_ram |= MEM_RESERVE_SECURE_MAINTAINED; #endif } diff --git a/board/freescale/ls2080ardb/ddr.c b/board/freescale/ls2080ardb/ddr.c index a04d21b..ecd1e71 100644 --- a/board/freescale/ls2080ardb/ddr.c +++ b/board/freescale/ls2080ardb/ddr.c @@ -177,7 +177,7 @@ void dram_init_banksize(void) #endif /* - * gd->secure_ram tracks the location of secure memory. + * gd->arch.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. */ @@ -188,16 +188,17 @@ void dram_init_banksize(void) 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; + gd->arch.secure_ram = gd->bd->bi_dram[1].start + + gd->arch.secure_ram - + CONFIG_SYS_LS2_DDR_BLOCK1_SIZE; + gd->arch.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; + gd->arch.secure_ram = gd->bd->bi_dram[0].start + + gd->arch.secure_ram; + gd->arch.secure_ram |= MEM_RESERVE_SECURE_MAINTAINED; #endif } diff --git a/cmd/bdinfo.c b/cmd/bdinfo.c index 1c4bed9..f2435ab 100644 --- a/cmd/bdinfo.c +++ b/cmd/bdinfo.c @@ -385,9 +385,9 @@ static int do_bdinfo(cmd_tbl_t *cmdtp, int flag, int argc, } #ifdef CONFIG_SYS_MEM_RESERVE_SECURE - if (gd->secure_ram & MEM_RESERVE_SECURE_SECURED) { + if (gd->arch.secure_ram & MEM_RESERVE_SECURE_SECURED) { print_num("Secure ram", - gd->secure_ram & MEM_RESERVE_SECURE_ADDR_MASK); + gd->arch.secure_ram & MEM_RESERVE_SECURE_ADDR_MASK); } #endif #if defined(CONFIG_CMD_NET) && !defined(CONFIG_DM_ETH) diff --git a/common/board_f.c b/common/board_f.c index d405b5b..0fc96bd 100644 --- a/common/board_f.c +++ b/common/board_f.c @@ -339,7 +339,7 @@ static int setup_dest_addr(void) * Record secure memory location. Need recalcuate if memory splits * into banks, or the ram base is not zero. */ - gd->secure_ram = gd->ram_size; + gd->arch.secure_ram = gd->ram_size; #endif /* * Subtract specified amount of memory to hide so that it won't diff --git a/include/asm-generic/global_data.h b/include/asm-generic/global_data.h index 0abcbe4..a6d1d2a 100644 --- a/include/asm-generic/global_data.h +++ b/include/asm-generic/global_data.h @@ -55,20 +55,6 @@ typedef struct global_data { unsigned long relocaddr; /* Start address of U-Boot in RAM */ phys_size_t ram_size; /* RAM size */ -#ifdef CONFIG_SYS_MEM_RESERVE_SECURE -#define MEM_RESERVE_SECURE_SECURED 0x1 -#define MEM_RESERVE_SECURE_MAINTAINED 0x2 -#define MEM_RESERVE_SECURE_ADDR_MASK (~0x3) - /* - * Secure memory addr - * This variable needs maintenance if the RAM base is not zero, - * or if RAM splits into non-consecutive banks. It also has a - * flag indicating the secure memory is marked as secure by MMU. - * Flags used: 0x1 secured - * 0x2 maintained - */ - phys_addr_t secure_ram; -#endif unsigned long mon_len; /* monitor len */ unsigned long irq_sp; /* irq stack pointer */ unsigned long start_addr_sp; /* start_addr_stackpointer */ -- cgit v0.10.2 From 50e93b95653da44b9743357dfa3701e8482fd167 Mon Sep 17 00:00:00 2001 From: York Sun Date: Fri, 24 Jun 2016 16:46:19 -0700 Subject: armv8: Add tlb_allocated to arch global data When secure ram is used, MMU tables have to be put into secure ram. To use common MMU code, gd->arch.tlb_addr will be used to host TLB entry pointer. To save allocated memory for later use, tlb_allocated variable is added to global data structure. Signed-off-by: York Sun diff --git a/arch/arm/include/asm/global_data.h b/arch/arm/include/asm/global_data.h index 2d76cd4..1055017 100644 --- a/arch/arm/include/asm/global_data.h +++ b/arch/arm/include/asm/global_data.h @@ -57,6 +57,7 @@ struct arch_global_data { * 0x2 maintained */ phys_addr_t secure_ram; + unsigned long tlb_allocated; #endif #ifdef CONFIG_OMAP_COMMON diff --git a/common/board_f.c b/common/board_f.c index 0fc96bd..a1138b0 100644 --- a/common/board_f.c +++ b/common/board_f.c @@ -432,6 +432,15 @@ static int reserve_mmu(void) gd->arch.tlb_addr = gd->relocaddr; debug("TLB table from %08lx to %08lx\n", gd->arch.tlb_addr, gd->arch.tlb_addr + gd->arch.tlb_size); + +#ifdef CONFIG_SYS_MEM_RESERVE_SECURE + /* + * Record allocated tlb_addr in case gd->tlb_addr to be overwritten + * with location within secure ram. + */ + gd->arch.tlb_allocated = gd->arch.tlb_addr; +#endif + return 0; } #endif -- cgit v0.10.2 From 252cdb46ee33ff876823d0ce0a0190c3878c76ff Mon Sep 17 00:00:00 2001 From: York Sun Date: Fri, 24 Jun 2016 16:46:20 -0700 Subject: armv8: mmu: house cleaning Make setup_pgtages() and get_tcr() available for platform code to customize MMU tables. Remove unintentional call of create_table(). Signed-off-by: York Sun diff --git a/arch/arm/cpu/armv8/cache_v8.c b/arch/arm/cpu/armv8/cache_v8.c index 1615542..b8867a7 100644 --- a/arch/arm/cpu/armv8/cache_v8.c +++ b/arch/arm/cpu/armv8/cache_v8.c @@ -35,7 +35,7 @@ DECLARE_GLOBAL_DATA_PTR; * off: FFF */ -static u64 get_tcr(int el, u64 *pips, u64 *pva_bits) +u64 get_tcr(int el, u64 *pips, u64 *pva_bits) { u64 max_addr = 0; u64 ips, va_bits; @@ -349,10 +349,13 @@ __weak u64 get_page_table_size(void) return size; } -static void setup_pgtables(void) +void setup_pgtables(void) { int i; + if (!gd->arch.tlb_fillptr || !gd->arch.tlb_addr) + panic("Page table pointer not setup."); + /* * Allocate the first level we're on with invalidate entries. * If the starting level is 0 (va_bits >= 39), then this is our @@ -363,9 +366,6 @@ static void setup_pgtables(void) /* Now add all MMU table entries one after another to the table */ for (i = 0; mem_map[i].size || mem_map[i].attrs; i++) add_map(&mem_map[i]); - - /* Create the same thing once more for our emergency page table */ - create_table(); } static void setup_all_pgtables(void) @@ -527,6 +527,9 @@ void mmu_set_region_dcache_behaviour(phys_addr_t start, size_t size, debug("start=%lx size=%lx\n", (ulong)start, (ulong)size); + if (!gd->arch.tlb_emerg) + panic("Emergency page table not setup."); + /* * We can not modify page tables that we're currently running on, * so we first need to switch to the "emergency" page tables where diff --git a/arch/arm/include/asm/armv8/mmu.h b/arch/arm/include/asm/armv8/mmu.h index 0d08ed3..b7b4706 100644 --- a/arch/arm/include/asm/armv8/mmu.h +++ b/arch/arm/include/asm/armv8/mmu.h @@ -141,6 +141,8 @@ struct mm_region { }; extern struct mm_region *mem_map; +void setup_pgtables(void); +u64 get_tcr(int el, u64 *pips, u64 *pva_bits); #endif #endif /* _ASM_ARMV8_MMU_H_ */ -- cgit v0.10.2 From f733d46620d0efb93091f147f81a4bf9588fad3f Mon Sep 17 00:00:00 2001 From: York Sun Date: Fri, 24 Jun 2016 16:46:21 -0700 Subject: armv8: mmu: split block if necessary When page tables are created, allow later table to be created on previous block entry. Splitting block feature is already working with current code. This patch only rearranges the code order and adds one condition to call split_block(). Signed-off-by: York Sun diff --git a/arch/arm/cpu/armv8/cache_v8.c b/arch/arm/cpu/armv8/cache_v8.c index b8867a7..8604035 100644 --- a/arch/arm/cpu/armv8/cache_v8.c +++ b/arch/arm/cpu/armv8/cache_v8.c @@ -167,6 +167,37 @@ static void set_pte_table(u64 *pte, u64 *table) *pte = PTE_TYPE_TABLE | (ulong)table; } +/* Splits a block PTE into table with subpages spanning the old block */ +static void split_block(u64 *pte, int level) +{ + u64 old_pte = *pte; + u64 *new_table; + u64 i = 0; + /* level describes the parent level, we need the child ones */ + int levelshift = level2shift(level + 1); + + if (pte_type(pte) != PTE_TYPE_BLOCK) + panic("PTE %p (%llx) is not a block. Some driver code wants to " + "modify dcache settings for an range not covered in " + "mem_map.", pte, old_pte); + + new_table = create_table(); + debug("Splitting pte %p (%llx) into %p\n", pte, old_pte, new_table); + + for (i = 0; i < MAX_PTE_ENTRIES; i++) { + new_table[i] = old_pte | (i << levelshift); + + /* Level 3 block PTEs have the table type */ + if ((level + 1) == 3) + new_table[i] |= PTE_TYPE_TABLE; + + debug("Setting new_table[%lld] = %llx\n", i, new_table[i]); + } + + /* Set the new table into effect */ + set_pte_table(pte, new_table); +} + /* Add one mm_region map entry to the page tables */ static void add_map(struct mm_region *map) { @@ -188,6 +219,8 @@ static void add_map(struct mm_region *map) for (level = 1; level < 4; level++) { pte = find_pte(addr, level); + if (!pte) + panic("pte not found\n"); blocksize = 1ULL << level2shift(level); debug("Checking if pte fits for addr=%llx size=%llx " "blocksize=%llx\n", addr, size, blocksize); @@ -199,48 +232,21 @@ static void add_map(struct mm_region *map) addr += blocksize; size -= blocksize; break; - } else if ((pte_type(pte) == PTE_TYPE_FAULT)) { + } else if (pte_type(pte) == PTE_TYPE_FAULT) { /* Page doesn't fit, create subpages */ debug("Creating subtable for addr 0x%llx " "blksize=%llx\n", addr, blocksize); new_table = create_table(); set_pte_table(pte, new_table); + } else if (pte_type(pte) == PTE_TYPE_BLOCK) { + debug("Split block into subtable for addr 0x%llx blksize=0x%llx\n", + addr, blocksize); + split_block(pte, level); } } } } -/* Splits a block PTE into table with subpages spanning the old block */ -static void split_block(u64 *pte, int level) -{ - u64 old_pte = *pte; - u64 *new_table; - u64 i = 0; - /* level describes the parent level, we need the child ones */ - int levelshift = level2shift(level + 1); - - if (pte_type(pte) != PTE_TYPE_BLOCK) - panic("PTE %p (%llx) is not a block. Some driver code wants to " - "modify dcache settings for an range not covered in " - "mem_map.", pte, old_pte); - - new_table = create_table(); - debug("Splitting pte %p (%llx) into %p\n", pte, old_pte, new_table); - - for (i = 0; i < MAX_PTE_ENTRIES; i++) { - new_table[i] = old_pte | (i << levelshift); - - /* Level 3 block PTEs have the table type */ - if ((level + 1) == 3) - new_table[i] |= PTE_TYPE_TABLE; - - debug("Setting new_table[%lld] = %llx\n", i, new_table[i]); - } - - /* Set the new table into effect */ - set_pte_table(pte, new_table); -} - enum pte_type { PTE_INVAL, PTE_BLOCK, -- cgit v0.10.2 From cd4b0c5feaaa524b44889cde8f58d4b121df8fed Mon Sep 17 00:00:00 2001 From: York Sun Date: Fri, 24 Jun 2016 16:46:22 -0700 Subject: armv8: mmu: Add support of non-identical mapping Introduce virtual and physical addresses in the mapping table. This change have no impact on existing boards because they all use idential mapping. Signed-off-by: York Sun diff --git a/arch/arm/cpu/armv8/cache_v8.c b/arch/arm/cpu/armv8/cache_v8.c index 8604035..ac909a1 100644 --- a/arch/arm/cpu/armv8/cache_v8.c +++ b/arch/arm/cpu/armv8/cache_v8.c @@ -44,7 +44,7 @@ u64 get_tcr(int el, u64 *pips, u64 *pva_bits) /* Find the largest address we need to support */ for (i = 0; mem_map[i].size || mem_map[i].attrs; i++) - max_addr = max(max_addr, mem_map[i].base + mem_map[i].size); + max_addr = max(max_addr, mem_map[i].virt + mem_map[i].size); /* Calculate the maximum physical (and thus virtual) address */ if (max_addr > (1ULL << 44)) { @@ -202,7 +202,8 @@ static void split_block(u64 *pte, int level) static void add_map(struct mm_region *map) { u64 *pte; - u64 addr = map->base; + u64 virt = map->virt; + u64 phys = map->phys; u64 size = map->size; u64 attrs = map->attrs | PTE_TYPE_BLOCK | PTE_BLOCK_AF; u64 blocksize; @@ -210,37 +211,39 @@ static void add_map(struct mm_region *map) u64 *new_table; while (size) { - pte = find_pte(addr, 0); + pte = find_pte(virt, 0); if (pte && (pte_type(pte) == PTE_TYPE_FAULT)) { - debug("Creating table for addr 0x%llx\n", addr); + debug("Creating table for virt 0x%llx\n", virt); new_table = create_table(); set_pte_table(pte, new_table); } for (level = 1; level < 4; level++) { - pte = find_pte(addr, level); + pte = find_pte(virt, level); if (!pte) panic("pte not found\n"); + blocksize = 1ULL << level2shift(level); - debug("Checking if pte fits for addr=%llx size=%llx " - "blocksize=%llx\n", addr, size, blocksize); - if (size >= blocksize && !(addr & (blocksize - 1))) { + debug("Checking if pte fits for virt=%llx size=%llx blocksize=%llx\n", + virt, size, blocksize); + if (size >= blocksize && !(virt & (blocksize - 1))) { /* Page fits, create block PTE */ - debug("Setting PTE %p to block addr=%llx\n", - pte, addr); - *pte = addr | attrs; - addr += blocksize; + debug("Setting PTE %p to block virt=%llx\n", + pte, virt); + *pte = phys | attrs; + virt += blocksize; + phys += blocksize; size -= blocksize; break; } else if (pte_type(pte) == PTE_TYPE_FAULT) { /* Page doesn't fit, create subpages */ - debug("Creating subtable for addr 0x%llx " - "blksize=%llx\n", addr, blocksize); + debug("Creating subtable for virt 0x%llx blksize=%llx\n", + virt, blocksize); new_table = create_table(); set_pte_table(pte, new_table); } else if (pte_type(pte) == PTE_TYPE_BLOCK) { - debug("Split block into subtable for addr 0x%llx blksize=0x%llx\n", - addr, blocksize); + debug("Split block into subtable for virt 0x%llx blksize=0x%llx\n", + virt, blocksize); split_block(pte, level); } } @@ -271,7 +274,7 @@ static int count_required_pts(u64 addr, int level, u64 maxaddr) for (i = 0; mem_map[i].size || mem_map[i].attrs; i++) { struct mm_region *map = &mem_map[i]; - u64 start = map->base; + u64 start = map->virt; u64 end = start + map->size; /* Check if the PTE would overlap with the map */ diff --git a/arch/arm/cpu/armv8/s32v234/cpu.c b/arch/arm/cpu/armv8/s32v234/cpu.c index dac12a2..5c97e0e 100644 --- a/arch/arm/cpu/armv8/s32v234/cpu.c +++ b/arch/arm/cpu/armv8/s32v234/cpu.c @@ -32,24 +32,28 @@ u32 cpu_mask(void) static struct mm_region s32v234_mem_map[] = { { - .base = S32V234_IRAM_BASE, + .virt = S32V234_IRAM_BASE, + .phys = S32V234_IRAM_BASE, .size = S32V234_IRAM_SIZE, .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_OUTER_SHARE }, { - .base = S32V234_DRAM_BASE1, + .virt = S32V234_DRAM_BASE1, + .phys = S32V234_DRAM_BASE1, .size = S32V234_DRAM_SIZE1, .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_OUTER_SHARE }, { - .base = S32V234_PERIPH_BASE, + .virt = S32V234_PERIPH_BASE, + .phys = S32V234_PERIPH_BASE, .size = S32V234_PERIPH_SIZE, .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | PTE_BLOCK_NON_SHARE /* TODO: Do we need these? */ /* | PTE_BLOCK_PXN | PTE_BLOCK_UXN */ }, { - .base = S32V234_DRAM_BASE2, + .virt = S32V234_DRAM_BASE2, + .phys = S32V234_DRAM_BASE2, .size = S32V234_DRAM_SIZE2, .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL_NC) | PTE_BLOCK_OUTER_SHARE diff --git a/arch/arm/cpu/armv8/zynqmp/cpu.c b/arch/arm/cpu/armv8/zynqmp/cpu.c index 509f0aa..b0f1295 100644 --- a/arch/arm/cpu/armv8/zynqmp/cpu.c +++ b/arch/arm/cpu/armv8/zynqmp/cpu.c @@ -18,40 +18,47 @@ DECLARE_GLOBAL_DATA_PTR; static struct mm_region zynqmp_mem_map[] = { { - .base = 0x0UL, + .virt = 0x0UL, + .phys = 0x0UL, .size = 0x80000000UL, .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_INNER_SHARE }, { - .base = 0x80000000UL, + .virt = 0x80000000UL, + .phys = 0x80000000UL, .size = 0x70000000UL, .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN }, { - .base = 0xf8000000UL, + .virt = 0xf8000000UL, + .phys = 0xf8000000UL, .size = 0x07e00000UL, .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN }, { - .base = 0xffe00000UL, + .virt = 0xffe00000UL, + .phys = 0xffe00000UL, .size = 0x00200000UL, .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_INNER_SHARE }, { - .base = 0x400000000UL, + .virt = 0x400000000UL, + .phys = 0x400000000UL, .size = 0x200000000UL, .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN }, { - .base = 0x600000000UL, + .virt = 0x600000000UL, + .phys = 0x600000000UL, .size = 0x800000000UL, .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_INNER_SHARE }, { - .base = 0xe00000000UL, + .virt = 0xe00000000UL, + .phys = 0xe00000000UL, .size = 0xf200000000UL, .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | PTE_BLOCK_NON_SHARE | diff --git a/arch/arm/include/asm/armv8/mmu.h b/arch/arm/include/asm/armv8/mmu.h index b7b4706..aa0f3c4 100644 --- a/arch/arm/include/asm/armv8/mmu.h +++ b/arch/arm/include/asm/armv8/mmu.h @@ -135,7 +135,8 @@ static inline void set_ttbr_tcr_mair(int el, u64 table, u64 tcr, u64 attr) } struct mm_region { - u64 base; + u64 virt; + u64 phys; u64 size; u64 attrs; }; diff --git a/arch/arm/mach-exynos/mmu-arm64.c b/arch/arm/mach-exynos/mmu-arm64.c index ba6d99d..2381422 100644 --- a/arch/arm/mach-exynos/mmu-arm64.c +++ b/arch/arm/mach-exynos/mmu-arm64.c @@ -13,21 +13,20 @@ DECLARE_GLOBAL_DATA_PTR; #ifdef CONFIG_EXYNOS7420 static struct mm_region exynos7420_mem_map[] = { { - .base = 0x10000000UL, + .virt = 0x10000000UL, + .phys = 0x10000000UL, .size = 0x10000000UL, .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN, }, { - .base = 0x40000000UL, + .virt = 0x40000000UL, + .phys = 0x40000000UL, .size = 0x80000000UL, .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_INNER_SHARE, }, { /* List terminator */ - .base = 0, - .size = 0, - .attrs = 0, }, }; diff --git a/arch/arm/mach-meson/board.c b/arch/arm/mach-meson/board.c index 64fa3c1..1dd53e2 100644 --- a/arch/arm/mach-meson/board.c +++ b/arch/arm/mach-meson/board.c @@ -48,12 +48,14 @@ void reset_cpu(ulong addr) static struct mm_region gxbb_mem_map[] = { { - .base = 0x0UL, + .virt = 0x0UL, + .phys = 0x0UL, .size = 0x80000000UL, .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_INNER_SHARE }, { - .base = 0x80000000UL, + .virt = 0x80000000UL, + .phys = 0x80000000UL, .size = 0x80000000UL, .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | PTE_BLOCK_NON_SHARE | diff --git a/arch/arm/mach-snapdragon/sysmap-apq8016.c b/arch/arm/mach-snapdragon/sysmap-apq8016.c index ef0db2a..580b9c7 100644 --- a/arch/arm/mach-snapdragon/sysmap-apq8016.c +++ b/arch/arm/mach-snapdragon/sysmap-apq8016.c @@ -11,13 +11,15 @@ static struct mm_region apq8016_mem_map[] = { { - .base = 0x0UL, /* Peripheral block */ + .virt = 0x0UL, /* Peripheral block */ + .phys = 0x0UL, /* Peripheral block */ .size = 0x8000000UL, .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN }, { - .base = 0x80000000UL, /* DDR */ + .virt = 0x80000000UL, /* DDR */ + .phys = 0x80000000UL, /* DDR */ .size = 0x80000000UL, .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_INNER_SHARE diff --git a/arch/arm/mach-sunxi/board.c b/arch/arm/mach-sunxi/board.c index 66e028e..01bfc93 100644 --- a/arch/arm/mach-sunxi/board.c +++ b/arch/arm/mach-sunxi/board.c @@ -46,13 +46,15 @@ struct fel_stash fel_stash __attribute__((section(".data"))); static struct mm_region sunxi_mem_map[] = { { /* SRAM, MMIO regions */ - .base = 0x0UL, + .virt = 0x0UL, + .phys = 0x0UL, .size = 0x40000000UL, .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | PTE_BLOCK_NON_SHARE }, { /* RAM */ - .base = 0x40000000UL, + .virt = 0x40000000UL, + .phys = 0x40000000UL, .size = 0x80000000UL, .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_INNER_SHARE diff --git a/arch/arm/mach-tegra/arm64-mmu.c b/arch/arm/mach-tegra/arm64-mmu.c index 501c4f0..7b1d258 100644 --- a/arch/arm/mach-tegra/arm64-mmu.c +++ b/arch/arm/mach-tegra/arm64-mmu.c @@ -14,13 +14,15 @@ static struct mm_region tegra_mem_map[] = { { - .base = 0x0UL, + .virt = 0x0UL, + .phys = 0x0UL, .size = 0x80000000UL, .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN }, { - .base = 0x80000000UL, + .virt = 0x80000000UL, + .phys = 0x80000000UL, .size = 0xff80000000UL, .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_INNER_SHARE diff --git a/arch/arm/mach-uniphier/arm64/mem_map.c b/arch/arm/mach-uniphier/arm64/mem_map.c index 74ef919..67bc4f1 100644 --- a/arch/arm/mach-uniphier/arm64/mem_map.c +++ b/arch/arm/mach-uniphier/arm64/mem_map.c @@ -10,14 +10,16 @@ static struct mm_region uniphier_mem_map[] = { { - .base = 0x00000000, + .virt = 0x00000000, + .phys = 0x00000000, .size = 0x80000000, .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN }, { - .base = 0x80000000, + .virt = 0x80000000, + .phys = 0x80000000, .size = 0xc0000000, .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_INNER_SHARE diff --git a/board/armltd/vexpress64/vexpress64.c b/board/armltd/vexpress64/vexpress64.c index 973b579..e34af6c 100644 --- a/board/armltd/vexpress64/vexpress64.c +++ b/board/armltd/vexpress64/vexpress64.c @@ -31,13 +31,15 @@ U_BOOT_DEVICE(vexpress_serials) = { static struct mm_region vexpress64_mem_map[] = { { - .base = 0x0UL, + .virt = 0x0UL, + .phys = 0x0UL, .size = 0x80000000UL, .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN }, { - .base = 0x80000000UL, + .virt = 0x80000000UL, + .phys = 0x80000000UL, .size = 0xff80000000UL, .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_INNER_SHARE diff --git a/board/cavium/thunderx/thunderx.c b/board/cavium/thunderx/thunderx.c index 9131a38..960ca53 100644 --- a/board/cavium/thunderx/thunderx.c +++ b/board/cavium/thunderx/thunderx.c @@ -45,16 +45,19 @@ DECLARE_GLOBAL_DATA_PTR; static struct mm_region thunderx_mem_map[] = { { - .base = 0x000000000000UL, + .virt = 0x000000000000UL, + .phys = 0x000000000000UL, .size = 0x40000000000UL, .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_NON_SHARE, }, { - .base = 0x800000000000UL, + .virt = 0x800000000000UL, + .phys = 0x800000000000UL, .size = 0x40000000000UL, .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | PTE_BLOCK_NON_SHARE, }, { - .base = 0x840000000000UL, + .virt = 0x840000000000UL, + .phys = 0x840000000000UL, .size = 0x40000000000UL, .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | PTE_BLOCK_NON_SHARE, diff --git a/board/hisilicon/hikey/hikey.c b/board/hisilicon/hikey/hikey.c index 7abc678..72d6334 100644 --- a/board/hisilicon/hikey/hikey.c +++ b/board/hisilicon/hikey/hikey.c @@ -93,12 +93,14 @@ U_BOOT_DEVICE(hikey_seriala) = { static struct mm_region hikey_mem_map[] = { { - .base = 0x0UL, + .virt = 0x0UL, + .phys = 0x0UL, .size = 0x80000000UL, .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_INNER_SHARE }, { - .base = 0x80000000UL, + .virt = 0x80000000UL, + .phys = 0x80000000UL, .size = 0x80000000UL, .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | PTE_BLOCK_NON_SHARE | diff --git a/board/raspberrypi/rpi/rpi.c b/board/raspberrypi/rpi/rpi.c index c45ddb1..fbfbf6c 100644 --- a/board/raspberrypi/rpi/rpi.c +++ b/board/raspberrypi/rpi/rpi.c @@ -234,12 +234,14 @@ static const struct rpi_model *model; #ifdef CONFIG_ARM64 static struct mm_region bcm2837_mem_map[] = { { - .base = 0x00000000UL, + .virt = 0x00000000UL, + .phys = 0x00000000UL, .size = 0x3f000000UL, .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_INNER_SHARE }, { - .base = 0x3f000000UL, + .virt = 0x3f000000UL, + .phys = 0x3f000000UL, .size = 0x01000000UL, .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | PTE_BLOCK_NON_SHARE | -- cgit v0.10.2 From 5ad5823d0c71a45f886d0016a74d62a5216abe10 Mon Sep 17 00:00:00 2001 From: York Sun Date: Fri, 24 Jun 2016 16:46:23 -0700 Subject: armv8: layerscape: Convert to use common MMU framework Drop platform code to create static MMU tables. Use common framework to create MMU tables on the run. Tested on LS2080ARDB with secure and non-secure ram scenarios. Signed-off-by: York Sun diff --git a/arch/arm/cpu/armv8/fsl-layerscape/cpu.c b/arch/arm/cpu/armv8/fsl-layerscape/cpu.c index a397f5d..b6ebedc 100644 --- a/arch/arm/cpu/armv8/fsl-layerscape/cpu.c +++ b/arch/arm/cpu/armv8/fsl-layerscape/cpu.c @@ -26,13 +26,7 @@ DECLARE_GLOBAL_DATA_PTR; -static struct mm_region layerscape_mem_map[] = { - { - /* List terminator */ - 0, - } -}; -struct mm_region *mem_map = layerscape_mem_map; +struct mm_region *mem_map = early_map; void cpu_name(char *name) { @@ -56,233 +50,35 @@ void cpu_name(char *name) } #ifndef CONFIG_SYS_DCACHE_OFF -static void set_pgtable_section(u64 *page_table, u64 index, u64 section, - u64 memory_type, u64 attribute) -{ - u64 value; - - value = section | PTE_TYPE_BLOCK | PTE_BLOCK_AF; - value |= PMD_ATTRINDX(memory_type); - value |= attribute; - page_table[index] = value; -} - -static void set_pgtable_table(u64 *page_table, u64 index, u64 *table_addr) -{ - u64 value; - - value = (u64)table_addr | PTE_TYPE_TABLE; - page_table[index] = value; -} - -/* - * Set the block entries according to the information of the table. - */ -static int set_block_entry(const struct sys_mmu_table *list, - struct table_info *table) -{ - u64 block_size = 0, block_shift = 0; - u64 block_addr, index; - int j; - - if (table->entry_size == BLOCK_SIZE_L1) { - block_size = BLOCK_SIZE_L1; - block_shift = SECTION_SHIFT_L1; - } else if (table->entry_size == BLOCK_SIZE_L2) { - block_size = BLOCK_SIZE_L2; - block_shift = SECTION_SHIFT_L2; - } else { - return -EINVAL; - } - - block_addr = list->phys_addr; - index = (list->virt_addr - table->table_base) >> block_shift; - - for (j = 0; j < (list->size >> block_shift); j++) { - set_pgtable_section(table->ptr, - index, - block_addr, - list->memory_type, - list->attribute); - block_addr += block_size; - index++; - } - - return 0; -} - -/* - * Find the corresponding table entry for the list. - */ -static int find_table(const struct sys_mmu_table *list, - struct table_info *table, u64 *level0_table) -{ - u64 index = 0, level = 0; - u64 *level_table = level0_table; - u64 temp_base = 0, block_size = 0, block_shift = 0; - - while (level < 3) { - if (level == 0) { - block_size = BLOCK_SIZE_L0; - block_shift = SECTION_SHIFT_L0; - } else if (level == 1) { - block_size = BLOCK_SIZE_L1; - block_shift = SECTION_SHIFT_L1; - } else if (level == 2) { - block_size = BLOCK_SIZE_L2; - block_shift = SECTION_SHIFT_L2; - } - - index = 0; - while (list->virt_addr >= temp_base) { - index++; - temp_base += block_size; - } - - temp_base -= block_size; - - if ((level_table[index - 1] & PTE_TYPE_MASK) == - PTE_TYPE_TABLE) { - level_table = (u64 *)(level_table[index - 1] & - ~PTE_TYPE_MASK); - level++; - continue; - } else { - if (level == 0) - return -EINVAL; - - if ((list->phys_addr + list->size) > - (temp_base + block_size * NUM_OF_ENTRY)) - return -EINVAL; - - /* - * Check the address and size of the list member is - * aligned with the block size. - */ - if (((list->phys_addr & (block_size - 1)) != 0) || - ((list->size & (block_size - 1)) != 0)) - return -EINVAL; - - table->ptr = level_table; - table->table_base = temp_base - - ((index - 1) << block_shift); - table->entry_size = block_size; - - return 0; - } - } - return -EINVAL; -} - /* * To start MMU before DDR is available, we create MMU table in SRAM. * The base address of SRAM is CONFIG_SYS_FSL_OCRAM_BASE. We use three * levels of translation tables here to cover 40-bit address space. * We use 4KB granule size, with 40 bits physical address, T0SZ=24 - * Level 0 IA[39], table address @0 - * Level 1 IA[38:30], table address @0x1000, 0x2000 - * Level 2 IA[29:21], table address @0x3000, 0x4000 - * Address above 0x5000 is free for other purpose. + * Address above EARLY_PGTABLE_SIZE (0x5000) is free for other purpose. + * Note, the debug print in cache_v8.c is not usable for debugging + * these early MMU tables because UART is not yet available. */ static inline void early_mmu_setup(void) { - unsigned int el, i; - u64 *level0_table = (u64 *)CONFIG_SYS_FSL_OCRAM_BASE; - u64 *level1_table0 = (u64 *)(CONFIG_SYS_FSL_OCRAM_BASE + 0x1000); - u64 *level1_table1 = (u64 *)(CONFIG_SYS_FSL_OCRAM_BASE + 0x2000); - u64 *level2_table0 = (u64 *)(CONFIG_SYS_FSL_OCRAM_BASE + 0x3000); - u64 *level2_table1 = (u64 *)(CONFIG_SYS_FSL_OCRAM_BASE + 0x4000); - - struct table_info table = {level0_table, 0, BLOCK_SIZE_L0}; + unsigned int el = current_el(); - /* Invalidate all table entries */ - memset(level0_table, 0, 0x5000); + /* global data is already setup, no allocation yet */ + gd->arch.tlb_addr = CONFIG_SYS_FSL_OCRAM_BASE; + gd->arch.tlb_fillptr = gd->arch.tlb_addr; + gd->arch.tlb_size = EARLY_PGTABLE_SIZE; - /* Fill in the table entries */ - set_pgtable_table(level0_table, 0, level1_table0); - set_pgtable_table(level0_table, 1, level1_table1); - set_pgtable_table(level1_table0, 0, level2_table0); + /* Create early page tables */ + setup_pgtables(); -#ifdef CONFIG_FSL_LSCH3 - set_pgtable_table(level1_table0, - CONFIG_SYS_FLASH_BASE >> SECTION_SHIFT_L1, - level2_table1); -#elif defined(CONFIG_FSL_LSCH2) - set_pgtable_table(level1_table0, 1, level2_table1); -#endif - /* Find the table and fill in the block entries */ - for (i = 0; i < ARRAY_SIZE(early_mmu_table); i++) { - if (find_table(&early_mmu_table[i], - &table, level0_table) == 0) { - /* - * If find_table() returns error, it cannot be dealt - * with here. Breakpoint can be added for debugging. - */ - set_block_entry(&early_mmu_table[i], &table); - /* - * If set_block_entry() returns error, it cannot be - * dealt with here too. - */ - } - } - - el = current_el(); - - set_ttbr_tcr_mair(el, (u64)level0_table, LAYERSCAPE_TCR, + /* point TTBR to the new table */ + set_ttbr_tcr_mair(el, gd->arch.tlb_addr, + get_tcr(el, NULL, NULL) & + ~(TCR_ORGN_MASK | TCR_IRGN_MASK), MEMORY_ATTRIBUTES); - 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, - PTE_BLOCK_OUTER_SHARE | PTE_BLOCK_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 = PTE_BLOCK_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; + set_sctlr(get_sctlr() | CR_M); } -#endif /* * The final tables look similar to early tables, but different in detail. @@ -291,113 +87,59 @@ static inline int final_secure_ddr(u64 *level0_table, * * Put the MMU table in secure memory if gd->arch.secure_ram is valid. * 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. - * - * For LSCH3: - * Level 2 table 1 contains 512 entries for each 2MB from 32GB to 33GB. - * For LSCH2: - * Level 2 table 1 contains 512 entries for each 2MB from 1GB to 2GB. - * Level 2 table 2 contains 512 entries for each 2MB from 20GB to 21GB. */ static inline void final_mmu_setup(void) { + u64 tlb_addr_save = gd->arch.tlb_addr; unsigned int el = current_el(); - unsigned int i; - u64 *level0_table = (u64 *)gd->arch.tlb_addr; - u64 *level1_table0; - u64 *level1_table1; - u64 *level2_table0; - u64 *level2_table1; -#ifdef CONFIG_FSL_LSCH2 - u64 *level2_table2; -#endif - struct table_info table = {NULL, 0, BLOCK_SIZE_L0}; - #ifdef CONFIG_SYS_MEM_RESERVE_SECURE - u64 *level2_table_secure; - - if (el == 3) { - /* - * Only use gd->arch.secure_ram if the address is recalculated - * Align to 4KB for MMU table - */ - if (gd->arch.secure_ram & MEM_RESERVE_SECURE_MAINTAINED) - level0_table = (u64 *)(gd->arch.secure_ram & ~0xfff); - else - printf("MMU warning: gd->arch.secure_ram is not maintained, disabled.\n"); - } -#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; + int index; #endif - table.ptr = level0_table; - /* Invalidate all table entries */ - memset(level0_table, 0, PGTABLE_SIZE); - - /* Fill in the table entries */ - set_pgtable_table(level0_table, 0, level1_table0); - set_pgtable_table(level0_table, 1, level1_table1); - set_pgtable_table(level1_table0, 0, level2_table0); -#ifdef CONFIG_FSL_LSCH3 - set_pgtable_table(level1_table0, - CONFIG_SYS_FSL_QBMAN_BASE >> SECTION_SHIFT_L1, - level2_table1); -#elif defined(CONFIG_FSL_LSCH2) - set_pgtable_table(level1_table0, 1, level2_table1); - set_pgtable_table(level1_table0, - CONFIG_SYS_FSL_QBMAN_BASE >> SECTION_SHIFT_L1, - level2_table2); -#endif - - /* Find the table and fill in the block entries */ - for (i = 0; i < ARRAY_SIZE(final_mmu_table); i++) { - if (find_table(&final_mmu_table[i], - &table, level0_table) == 0) { - if (set_block_entry(&final_mmu_table[i], - &table) != 0) { - printf("MMU error: could not set block entry for %p\n", - &final_mmu_table[i]); - } + mem_map = final_map; - } else { - printf("MMU error: could not find the table for %p\n", - &final_mmu_table[i]); - } - } - /* Set the secure memory to secure in MMU */ #ifdef CONFIG_SYS_MEM_RESERVE_SECURE - if (el == 3 && gd->arch.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 - if (!final_secure_ddr(level0_table, - level2_table_secure, - gd->arch.secure_ram & ~0x3)) { + if (gd->arch.secure_ram & MEM_RESERVE_SECURE_MAINTAINED) { + if (el == 3) { + /* + * Only use gd->arch.secure_ram if the address is + * recalculated. Align to 4KB for MMU table. + */ + /* put page tables in secure ram */ + index = ARRAY_SIZE(final_map) - 2; + gd->arch.tlb_addr = gd->arch.secure_ram & ~0xfff; + final_map[index].virt = gd->arch.secure_ram & ~0x3; + final_map[index].phys = final_map[index].virt; + final_map[index].size = CONFIG_SYS_MEM_RESERVE_SECURE; + final_map[index].attrs = PTE_BLOCK_OUTER_SHARE; gd->arch.secure_ram |= MEM_RESERVE_SECURE_SECURED; - debug("Now MMU table is in secured memory at 0x%llx\n", - gd->arch.secure_ram & ~0x3); + tlb_addr_save = gd->arch.tlb_addr; } else { - printf("MMU warning: Failed to secure DDR\n"); + /* Use allocated (board_f.c) memory for TLB */ + tlb_addr_save = gd->arch.tlb_allocated; + gd->arch.tlb_addr = tlb_addr_save; } } #endif + /* Reset the fill ptr */ + gd->arch.tlb_fillptr = tlb_addr_save; + + /* Create normal system page tables */ + setup_pgtables(); + + /* Create emergency page tables */ + gd->arch.tlb_addr = gd->arch.tlb_fillptr; + gd->arch.tlb_emerg = gd->arch.tlb_addr; + setup_pgtables(); + gd->arch.tlb_addr = tlb_addr_save; + /* flush new MMU table */ - flush_dcache_range((ulong)level0_table, - (ulong)level0_table + gd->arch.tlb_size); + flush_dcache_range(gd->arch.tlb_addr, + gd->arch.tlb_addr + gd->arch.tlb_size); /* point TTBR to the new table */ - set_ttbr_tcr_mair(el, (u64)level0_table, LAYERSCAPE_TCR_FINAL, + set_ttbr_tcr_mair(el, gd->arch.tlb_addr, get_tcr(el, NULL, NULL), MEMORY_ATTRIBUTES); /* * MMU is already enabled, just need to invalidate TLB to load the diff --git a/arch/arm/include/asm/arch-fsl-layerscape/cpu.h b/arch/arm/include/asm/arch-fsl-layerscape/cpu.h index 197b0eb..5fd5e87 100644 --- a/arch/arm/include/asm/arch-fsl-layerscape/cpu.h +++ b/arch/arm/include/asm/arch-fsl-layerscape/cpu.h @@ -19,29 +19,6 @@ static struct cpu_type cpu_type_list[] = { #ifndef CONFIG_SYS_DCACHE_OFF -#define SECTION_SHIFT_L0 39UL -#define SECTION_SHIFT_L1 30UL -#define SECTION_SHIFT_L2 21UL -#define BLOCK_SIZE_L0 0x8000000000 -#define BLOCK_SIZE_L1 0x40000000 -#define BLOCK_SIZE_L2 0x200000 -#define NUM_OF_ENTRY 512 -#define TCR_EL2_PS_40BIT (2 << 16) - -#define LAYERSCAPE_VA_BITS (40) -#define LAYERSCAPE_TCR (TCR_TG0_4K | \ - TCR_EL2_PS_40BIT | \ - TCR_SHARED_NON | \ - TCR_ORGN_NC | \ - TCR_IRGN_NC | \ - TCR_T0SZ(LAYERSCAPE_VA_BITS)) -#define LAYERSCAPE_TCR_FINAL (TCR_TG0_4K | \ - TCR_EL2_PS_40BIT | \ - TCR_SHARED_OUTER | \ - TCR_ORGN_WBWA | \ - TCR_IRGN_WBWA | \ - TCR_T0SZ(LAYERSCAPE_VA_BITS)) - #ifdef CONFIG_FSL_LSCH3 #define CONFIG_SYS_FSL_CCSR_BASE 0x00000000 #define CONFIG_SYS_FSL_CCSR_SIZE 0x10000000 @@ -101,174 +78,261 @@ static struct cpu_type cpu_type_list[] = { #define CONFIG_SYS_FSL_DRAM_SIZE3 0x7800000000 /* 480GB */ #endif -struct sys_mmu_table { - u64 virt_addr; - u64 phys_addr; - u64 size; - u64 memory_type; - u64 attribute; -}; - -struct table_info { - u64 *ptr; - u64 table_base; - u64 entry_size; -}; - -static const struct sys_mmu_table early_mmu_table[] = { +#define EARLY_PGTABLE_SIZE 0x5000 +static struct mm_region early_map[] = { #ifdef CONFIG_FSL_LSCH3 { CONFIG_SYS_FSL_CCSR_BASE, CONFIG_SYS_FSL_CCSR_BASE, - CONFIG_SYS_FSL_CCSR_SIZE, MT_DEVICE_NGNRNE, - PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN }, + CONFIG_SYS_FSL_CCSR_SIZE, + PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | + PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN + }, { CONFIG_SYS_FSL_OCRAM_BASE, CONFIG_SYS_FSL_OCRAM_BASE, - CONFIG_SYS_FSL_OCRAM_SIZE, MT_NORMAL, PTE_BLOCK_NON_SHARE }, + CONFIG_SYS_FSL_OCRAM_SIZE, + PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_NON_SHARE + }, { CONFIG_SYS_FSL_QSPI_BASE1, CONFIG_SYS_FSL_QSPI_BASE1, - CONFIG_SYS_FSL_QSPI_SIZE1, MT_NORMAL, PTE_BLOCK_NON_SHARE}, + CONFIG_SYS_FSL_QSPI_SIZE1, + PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_NON_SHARE}, /* For IFC Region #1, only the first 4MB is cache-enabled */ { CONFIG_SYS_FSL_IFC_BASE1, CONFIG_SYS_FSL_IFC_BASE1, - CONFIG_SYS_FSL_IFC_SIZE1_1, MT_NORMAL, PTE_BLOCK_NON_SHARE }, + CONFIG_SYS_FSL_IFC_SIZE1_1, + PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_NON_SHARE + }, { CONFIG_SYS_FSL_IFC_BASE1 + CONFIG_SYS_FSL_IFC_SIZE1_1, CONFIG_SYS_FSL_IFC_BASE1 + CONFIG_SYS_FSL_IFC_SIZE1_1, CONFIG_SYS_FSL_IFC_SIZE1 - CONFIG_SYS_FSL_IFC_SIZE1_1, - MT_DEVICE_NGNRNE, PTE_BLOCK_NON_SHARE }, + PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | PTE_BLOCK_NON_SHARE + }, { CONFIG_SYS_FLASH_BASE, CONFIG_SYS_FSL_IFC_BASE1, - CONFIG_SYS_FSL_IFC_SIZE1, MT_DEVICE_NGNRNE, PTE_BLOCK_NON_SHARE }, + CONFIG_SYS_FSL_IFC_SIZE1, + PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | PTE_BLOCK_NON_SHARE + }, { CONFIG_SYS_FSL_DRAM_BASE1, CONFIG_SYS_FSL_DRAM_BASE1, - CONFIG_SYS_FSL_DRAM_SIZE1, MT_NORMAL, - PTE_BLOCK_OUTER_SHARE | PTE_BLOCK_NS }, + CONFIG_SYS_FSL_DRAM_SIZE1, + PTE_BLOCK_MEMTYPE(MT_NORMAL) | + PTE_BLOCK_OUTER_SHARE | PTE_BLOCK_NS + }, /* Map IFC region #2 up to CONFIG_SYS_FLASH_BASE for NAND boot */ { CONFIG_SYS_FSL_IFC_BASE2, CONFIG_SYS_FSL_IFC_BASE2, CONFIG_SYS_FLASH_BASE - CONFIG_SYS_FSL_IFC_BASE2, - MT_DEVICE_NGNRNE, PTE_BLOCK_NON_SHARE }, + PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | PTE_BLOCK_NON_SHARE + }, { CONFIG_SYS_FSL_DCSR_BASE, CONFIG_SYS_FSL_DCSR_BASE, - CONFIG_SYS_FSL_DCSR_SIZE, MT_DEVICE_NGNRNE, - PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN }, + CONFIG_SYS_FSL_DCSR_SIZE, + PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | + PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN + }, { CONFIG_SYS_FSL_DRAM_BASE2, CONFIG_SYS_FSL_DRAM_BASE2, - CONFIG_SYS_FSL_DRAM_SIZE2, MT_NORMAL, - PTE_BLOCK_OUTER_SHARE | PTE_BLOCK_NS }, + CONFIG_SYS_FSL_DRAM_SIZE2, + PTE_BLOCK_MEMTYPE(MT_NORMAL) | + PTE_BLOCK_OUTER_SHARE | PTE_BLOCK_NS + }, #elif defined(CONFIG_FSL_LSCH2) { CONFIG_SYS_FSL_CCSR_BASE, CONFIG_SYS_FSL_CCSR_BASE, - CONFIG_SYS_FSL_CCSR_SIZE, MT_DEVICE_NGNRNE, - PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN }, + CONFIG_SYS_FSL_CCSR_SIZE, + PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | + PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN + }, { CONFIG_SYS_FSL_OCRAM_BASE, CONFIG_SYS_FSL_OCRAM_BASE, - CONFIG_SYS_FSL_OCRAM_SIZE, MT_NORMAL, PTE_BLOCK_NON_SHARE }, + CONFIG_SYS_FSL_OCRAM_SIZE, + PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_NON_SHARE + }, { CONFIG_SYS_FSL_DCSR_BASE, CONFIG_SYS_FSL_DCSR_BASE, - CONFIG_SYS_FSL_DCSR_SIZE, MT_DEVICE_NGNRNE, - PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN }, + CONFIG_SYS_FSL_DCSR_SIZE, + PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | + PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN + }, { CONFIG_SYS_FSL_QSPI_BASE, CONFIG_SYS_FSL_QSPI_BASE, - CONFIG_SYS_FSL_QSPI_SIZE, MT_DEVICE_NGNRNE, PTE_BLOCK_NON_SHARE }, + CONFIG_SYS_FSL_QSPI_SIZE, + PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | PTE_BLOCK_NON_SHARE + }, { CONFIG_SYS_FSL_IFC_BASE, CONFIG_SYS_FSL_IFC_BASE, - CONFIG_SYS_FSL_IFC_SIZE, MT_DEVICE_NGNRNE, PTE_BLOCK_NON_SHARE }, + CONFIG_SYS_FSL_IFC_SIZE, + PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | PTE_BLOCK_NON_SHARE + }, { CONFIG_SYS_FSL_DRAM_BASE1, CONFIG_SYS_FSL_DRAM_BASE1, - CONFIG_SYS_FSL_DRAM_SIZE1, MT_NORMAL, - PTE_BLOCK_OUTER_SHARE | PTE_BLOCK_NS }, + CONFIG_SYS_FSL_DRAM_SIZE1, + PTE_BLOCK_MEMTYPE(MT_NORMAL) | + PTE_BLOCK_OUTER_SHARE | PTE_BLOCK_NS + }, { CONFIG_SYS_FSL_DRAM_BASE2, CONFIG_SYS_FSL_DRAM_BASE2, - CONFIG_SYS_FSL_DRAM_SIZE2, MT_NORMAL, - PTE_BLOCK_OUTER_SHARE | PTE_BLOCK_NS }, + CONFIG_SYS_FSL_DRAM_SIZE2, + PTE_BLOCK_MEMTYPE(MT_NORMAL) | + PTE_BLOCK_OUTER_SHARE | PTE_BLOCK_NS + }, #endif + {}, /* list terminator */ }; -static const struct sys_mmu_table final_mmu_table[] = { +static struct mm_region final_map[] = { #ifdef CONFIG_FSL_LSCH3 { CONFIG_SYS_FSL_CCSR_BASE, CONFIG_SYS_FSL_CCSR_BASE, - CONFIG_SYS_FSL_CCSR_SIZE, MT_DEVICE_NGNRNE, - PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN }, + CONFIG_SYS_FSL_CCSR_SIZE, + PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | + PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN + }, { CONFIG_SYS_FSL_OCRAM_BASE, CONFIG_SYS_FSL_OCRAM_BASE, - CONFIG_SYS_FSL_OCRAM_SIZE, MT_NORMAL, PTE_BLOCK_NON_SHARE }, + CONFIG_SYS_FSL_OCRAM_SIZE, + PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_NON_SHARE + }, { CONFIG_SYS_FSL_DRAM_BASE1, CONFIG_SYS_FSL_DRAM_BASE1, - CONFIG_SYS_FSL_DRAM_SIZE1, MT_NORMAL, - PTE_BLOCK_OUTER_SHARE | PTE_BLOCK_NS }, + CONFIG_SYS_FSL_DRAM_SIZE1, + PTE_BLOCK_MEMTYPE(MT_NORMAL) | + PTE_BLOCK_OUTER_SHARE | PTE_BLOCK_NS + }, { CONFIG_SYS_FSL_QSPI_BASE1, CONFIG_SYS_FSL_QSPI_BASE1, - CONFIG_SYS_FSL_QSPI_SIZE1, MT_NORMAL, PTE_BLOCK_NON_SHARE}, + CONFIG_SYS_FSL_QSPI_SIZE1, + PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_NON_SHARE + }, { CONFIG_SYS_FSL_QSPI_BASE2, CONFIG_SYS_FSL_QSPI_BASE2, - CONFIG_SYS_FSL_QSPI_SIZE2, MT_DEVICE_NGNRNE, - PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN }, + CONFIG_SYS_FSL_QSPI_SIZE2, + PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | + PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN + }, { CONFIG_SYS_FSL_IFC_BASE2, CONFIG_SYS_FSL_IFC_BASE2, - CONFIG_SYS_FSL_IFC_SIZE2, MT_DEVICE_NGNRNE, PTE_BLOCK_NON_SHARE }, + CONFIG_SYS_FSL_IFC_SIZE2, + PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | PTE_BLOCK_NON_SHARE + }, { CONFIG_SYS_FSL_DCSR_BASE, CONFIG_SYS_FSL_DCSR_BASE, - CONFIG_SYS_FSL_DCSR_SIZE, MT_DEVICE_NGNRNE, - PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN }, + CONFIG_SYS_FSL_DCSR_SIZE, + PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | + PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN + }, { CONFIG_SYS_FSL_MC_BASE, CONFIG_SYS_FSL_MC_BASE, - CONFIG_SYS_FSL_MC_SIZE, MT_DEVICE_NGNRNE, - PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN }, + CONFIG_SYS_FSL_MC_SIZE, + PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | + PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN + }, { CONFIG_SYS_FSL_NI_BASE, CONFIG_SYS_FSL_NI_BASE, - CONFIG_SYS_FSL_NI_SIZE, MT_DEVICE_NGNRNE, - PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN }, + CONFIG_SYS_FSL_NI_SIZE, + PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | + PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN + }, /* 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, - PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN | PTE_BLOCK_NS }, + CONFIG_SYS_FSL_QBMAN_SIZE_1, + PTE_BLOCK_MEMTYPE(MT_NORMAL) | + PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN | PTE_BLOCK_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, - MT_DEVICE_NGNRNE, PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN }, + PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | + PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN + }, { CONFIG_SYS_PCIE1_PHYS_ADDR, CONFIG_SYS_PCIE1_PHYS_ADDR, - CONFIG_SYS_PCIE1_PHYS_SIZE, MT_DEVICE_NGNRNE, - PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN }, + CONFIG_SYS_PCIE1_PHYS_SIZE, + PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | + PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN + }, { CONFIG_SYS_PCIE2_PHYS_ADDR, CONFIG_SYS_PCIE2_PHYS_ADDR, - CONFIG_SYS_PCIE2_PHYS_SIZE, MT_DEVICE_NGNRNE, - PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN }, + CONFIG_SYS_PCIE2_PHYS_SIZE, + PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | + PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN + }, { CONFIG_SYS_PCIE3_PHYS_ADDR, CONFIG_SYS_PCIE3_PHYS_ADDR, - CONFIG_SYS_PCIE3_PHYS_SIZE, MT_DEVICE_NGNRNE, - PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN }, + CONFIG_SYS_PCIE3_PHYS_SIZE, + PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | + PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN + }, #ifdef CONFIG_LS2080A { CONFIG_SYS_PCIE4_PHYS_ADDR, CONFIG_SYS_PCIE4_PHYS_ADDR, - CONFIG_SYS_PCIE4_PHYS_SIZE, MT_DEVICE_NGNRNE, - PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN }, + CONFIG_SYS_PCIE4_PHYS_SIZE, + PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | + PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN + }, #endif { CONFIG_SYS_FSL_WRIOP1_BASE, CONFIG_SYS_FSL_WRIOP1_BASE, - CONFIG_SYS_FSL_WRIOP1_SIZE, MT_DEVICE_NGNRNE, - PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN }, + CONFIG_SYS_FSL_WRIOP1_SIZE, + PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | + PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN + }, { CONFIG_SYS_FSL_AIOP1_BASE, CONFIG_SYS_FSL_AIOP1_BASE, - CONFIG_SYS_FSL_AIOP1_SIZE, MT_DEVICE_NGNRNE, - PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN }, + CONFIG_SYS_FSL_AIOP1_SIZE, + PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | + PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN + }, { CONFIG_SYS_FSL_PEBUF_BASE, CONFIG_SYS_FSL_PEBUF_BASE, - CONFIG_SYS_FSL_PEBUF_SIZE, MT_DEVICE_NGNRNE, - PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN }, + CONFIG_SYS_FSL_PEBUF_SIZE, + PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | + PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN + }, { CONFIG_SYS_FSL_DRAM_BASE2, CONFIG_SYS_FSL_DRAM_BASE2, - CONFIG_SYS_FSL_DRAM_SIZE2, MT_NORMAL, - PTE_BLOCK_OUTER_SHARE | PTE_BLOCK_NS }, + CONFIG_SYS_FSL_DRAM_SIZE2, + PTE_BLOCK_MEMTYPE(MT_NORMAL) | + PTE_BLOCK_OUTER_SHARE | PTE_BLOCK_NS + }, #elif defined(CONFIG_FSL_LSCH2) { CONFIG_SYS_FSL_BOOTROM_BASE, CONFIG_SYS_FSL_BOOTROM_BASE, - CONFIG_SYS_FSL_BOOTROM_SIZE, MT_DEVICE_NGNRNE, - PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN }, + CONFIG_SYS_FSL_BOOTROM_SIZE, + PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | + PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN + }, { CONFIG_SYS_FSL_CCSR_BASE, CONFIG_SYS_FSL_CCSR_BASE, - CONFIG_SYS_FSL_CCSR_SIZE, MT_DEVICE_NGNRNE, - PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN }, + CONFIG_SYS_FSL_CCSR_SIZE, + PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | + PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN + }, { CONFIG_SYS_FSL_OCRAM_BASE, CONFIG_SYS_FSL_OCRAM_BASE, - CONFIG_SYS_FSL_OCRAM_SIZE, MT_NORMAL, PTE_BLOCK_NON_SHARE }, + CONFIG_SYS_FSL_OCRAM_SIZE, + PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_NON_SHARE + }, { CONFIG_SYS_FSL_DCSR_BASE, CONFIG_SYS_FSL_DCSR_BASE, - CONFIG_SYS_FSL_DCSR_SIZE, MT_DEVICE_NGNRNE, - PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN }, + CONFIG_SYS_FSL_DCSR_SIZE, + PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | + PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN + }, { CONFIG_SYS_FSL_QSPI_BASE, CONFIG_SYS_FSL_QSPI_BASE, - CONFIG_SYS_FSL_QSPI_SIZE, MT_DEVICE_NGNRNE, - PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN }, + CONFIG_SYS_FSL_QSPI_SIZE, + PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | + PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN + }, { CONFIG_SYS_FSL_IFC_BASE, CONFIG_SYS_FSL_IFC_BASE, - CONFIG_SYS_FSL_IFC_SIZE, MT_DEVICE_NGNRNE, PTE_BLOCK_NON_SHARE }, + CONFIG_SYS_FSL_IFC_SIZE, + PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | PTE_BLOCK_NON_SHARE + }, { CONFIG_SYS_FSL_DRAM_BASE1, CONFIG_SYS_FSL_DRAM_BASE1, - CONFIG_SYS_FSL_DRAM_SIZE1, MT_NORMAL, - PTE_BLOCK_OUTER_SHARE | PTE_BLOCK_NS }, + CONFIG_SYS_FSL_DRAM_SIZE1, + PTE_BLOCK_MEMTYPE(MT_NORMAL) | + PTE_BLOCK_OUTER_SHARE | PTE_BLOCK_NS + }, { CONFIG_SYS_FSL_QBMAN_BASE, CONFIG_SYS_FSL_QBMAN_BASE, - CONFIG_SYS_FSL_QBMAN_SIZE, MT_DEVICE_NGNRNE, - PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN }, + CONFIG_SYS_FSL_QBMAN_SIZE, + PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | + PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN + }, { CONFIG_SYS_FSL_DRAM_BASE2, CONFIG_SYS_FSL_DRAM_BASE2, - CONFIG_SYS_FSL_DRAM_SIZE2, MT_NORMAL, - PTE_BLOCK_OUTER_SHARE | PTE_BLOCK_NS }, + CONFIG_SYS_FSL_DRAM_SIZE2, + PTE_BLOCK_MEMTYPE(MT_NORMAL) | + PTE_BLOCK_OUTER_SHARE | PTE_BLOCK_NS + }, { CONFIG_SYS_PCIE1_PHYS_ADDR, CONFIG_SYS_PCIE1_PHYS_ADDR, - CONFIG_SYS_PCIE1_PHYS_SIZE, MT_DEVICE_NGNRNE, - PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN }, + CONFIG_SYS_PCIE1_PHYS_SIZE, + PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | + PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN + }, { CONFIG_SYS_PCIE2_PHYS_ADDR, CONFIG_SYS_PCIE2_PHYS_ADDR, - CONFIG_SYS_PCIE2_PHYS_SIZE, MT_DEVICE_NGNRNE, - PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN }, + CONFIG_SYS_PCIE2_PHYS_SIZE, + PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | + PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN + }, { CONFIG_SYS_PCIE3_PHYS_ADDR, CONFIG_SYS_PCIE3_PHYS_ADDR, - CONFIG_SYS_PCIE3_PHYS_SIZE, MT_DEVICE_NGNRNE, - PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN }, + CONFIG_SYS_PCIE3_PHYS_SIZE, + PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | + PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN + }, { CONFIG_SYS_FSL_DRAM_BASE3, CONFIG_SYS_FSL_DRAM_BASE3, - CONFIG_SYS_FSL_DRAM_SIZE3, MT_NORMAL, - PTE_BLOCK_OUTER_SHARE | PTE_BLOCK_NS }, + CONFIG_SYS_FSL_DRAM_SIZE3, + PTE_BLOCK_MEMTYPE(MT_NORMAL) | + PTE_BLOCK_OUTER_SHARE | PTE_BLOCK_NS + }, #endif -}; +#ifdef CONFIG_SYS_MEM_RESERVE_SECURE + {}, /* space holder for secure mem */ #endif + {}, +}; +#endif /* !CONFIG_SYS_DCACHE_OFF */ int fsl_qoriq_core_to_cluster(unsigned int core); u32 cpu_mask(void); -- cgit v0.10.2 From 85cdf38e69bbf3b2bb67c8218c8e4cbf28f8759b Mon Sep 17 00:00:00 2001 From: Hou Zhiqiang Date: Tue, 28 Jun 2016 20:18:12 +0800 Subject: armv8: fsl-layerscape: add i/d-cache enable function to enable_caches This function assume that the d-cache and MMU has been enabled earlier, so it just created MMU table in main memory. But the assumption is not always correct, for example, the early setup is done in EL3, while enable_caches() is called when the PE has turned into another EL. Define the function mmu_setup() for fsl-layerscape to cover the weak one. Signed-off-by: Hou Zhiqiang Reviewed-by: York Sun diff --git a/arch/arm/cpu/armv8/fsl-layerscape/cpu.c b/arch/arm/cpu/armv8/fsl-layerscape/cpu.c index b6ebedc..bcedf2c 100644 --- a/arch/arm/cpu/armv8/fsl-layerscape/cpu.c +++ b/arch/arm/cpu/armv8/fsl-layerscape/cpu.c @@ -164,15 +164,21 @@ int arch_cpu_init(void) return 0; } +void mmu_setup(void) +{ + final_mmu_setup(); +} + /* - * This function is called from lib/board.c. - * It recreates MMU table in main memory. MMU and d-cache are enabled earlier. - * There is no need to disable d-cache for this operation. + * This function is called from common/board_r.c. + * It recreates MMU table in main memory. */ void enable_caches(void) { - final_mmu_setup(); + mmu_setup(); __asm_invalidate_tlb_all(); + icache_enable(); + dcache_enable(); } #endif -- cgit v0.10.2 From b45db3b59035735a0479d8df260d2349cdc3c21c Mon Sep 17 00:00:00 2001 From: Hou Zhiqiang Date: Tue, 28 Jun 2016 20:18:13 +0800 Subject: ARMv8: add the secure monitor firmware framework This framework is introduced for ARMv8 secure monitor mode firmware. The main functions of the framework are, on EL3, verify the firmware, load it to the secure memory and jump into it, and while it returned to U-Boot, do some necessary setups at the 'target exception level' that is determined by the respective secure firmware. So far, the framework support only FIT format image, and need to define the name of which config node should be used in 'configurations' and the name of property for the raw secure firmware image in that config. The FIT image should be stored in Byte accessing memory, such as NOR Flash, or else it should be copied to main memory to use this framework. Signed-off-by: Hou Zhiqiang Reviewed-by: York Sun diff --git a/arch/arm/cpu/armv8/Makefile b/arch/arm/cpu/armv8/Makefile index bf8644c..ee9e009 100644 --- a/arch/arm/cpu/armv8/Makefile +++ b/arch/arm/cpu/armv8/Makefile @@ -15,6 +15,7 @@ obj-y += cache.o obj-y += tlb.o obj-y += transition.o obj-y += fwcall.o +obj-$(CONFIG_ARMV8_SEC_FIRMWARE_SUPPORT) += sec_firmware.o sec_firmware_asm.o obj-$(CONFIG_FSL_LAYERSCAPE) += fsl-layerscape/ obj-$(CONFIG_S32V234) += s32v234/ diff --git a/arch/arm/cpu/armv8/sec_firmware.c b/arch/arm/cpu/armv8/sec_firmware.c new file mode 100644 index 0000000..e21e199 --- /dev/null +++ b/arch/arm/cpu/armv8/sec_firmware.c @@ -0,0 +1,270 @@ +/* + * Copyright 2016 NXP Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; +extern void c_runtime_cpu_setup(void); + +#define SEC_FIRMWARE_LOADED 0x1 +#define SEC_FIRMWARE_RUNNING 0x2 +#define SEC_FIRMWARE_ADDR_MASK (~0x3) + /* + * Secure firmware load addr + * Flags used: 0x1 secure firmware has been loaded to secure memory + * 0x2 secure firmware is running + */ + phys_addr_t sec_firmware_addr; + +static int sec_firmware_get_data(const void *sec_firmware_img, + const void **data, size_t *size) +{ + int conf_node_off, fw_node_off; + char *conf_node_name = NULL; + char *desc; + int ret; + + conf_node_name = SEC_FIRMEWARE_FIT_CNF_NAME; + + conf_node_off = fit_conf_get_node(sec_firmware_img, conf_node_name); + if (conf_node_off < 0) { + printf("SEC Firmware: %s: no such config\n", conf_node_name); + return -ENOENT; + } + + fw_node_off = fit_conf_get_prop_node(sec_firmware_img, conf_node_off, + SEC_FIRMWARE_FIT_IMAGE); + if (fw_node_off < 0) { + printf("SEC Firmware: No '%s' in config\n", + SEC_FIRMWARE_FIT_IMAGE); + return -ENOLINK; + } + + /* Verify secure firmware image */ + if (!(fit_image_verify(sec_firmware_img, fw_node_off))) { + printf("SEC Firmware: Bad firmware image (bad CRC)\n"); + return -EINVAL; + } + + if (fit_image_get_data(sec_firmware_img, fw_node_off, data, size)) { + printf("SEC Firmware: Can't get %s subimage data/size", + SEC_FIRMWARE_FIT_IMAGE); + return -ENOENT; + } + + ret = fit_get_desc(sec_firmware_img, fw_node_off, &desc); + if (ret) + printf("SEC Firmware: Can't get description\n"); + else + printf("%s\n", desc); + + return ret; +} + +/* + * SEC Firmware FIT image parser checks if the image is in FIT + * format, verifies integrity of the image and calculates raw + * image address and size values. + * + * Returns 0 on success and a negative errno on error task fail. + */ +static int sec_firmware_parse_image(const void *sec_firmware_img, + const void **raw_image_addr, + size_t *raw_image_size) +{ + int ret; + + ret = sec_firmware_get_data(sec_firmware_img, raw_image_addr, + raw_image_size); + if (ret) + return ret; + + debug("SEC Firmware: raw_image_addr = 0x%p, raw_image_size = 0x%lx\n", + *raw_image_addr, *raw_image_size); + + return 0; +} + +static int sec_firmware_copy_image(const char *title, + u64 image_addr, u32 image_size, u64 sec_firmware) +{ + debug("%s copied to address 0x%p\n", title, (void *)sec_firmware); + memcpy((void *)sec_firmware, (void *)image_addr, image_size); + flush_dcache_range(sec_firmware, sec_firmware + image_size); + + return 0; +} + +/* + * This function will parse the SEC Firmware image, and then load it + * to secure memory. + */ +static int sec_firmware_load_image(const void *sec_firmware_img) +{ + const void *raw_image_addr; + size_t raw_image_size = 0; + int ret; + + /* + * The Excetpion Level must be EL3 to load and initialize + * the SEC Firmware. + */ + if (current_el() != 3) { + ret = -EACCES; + goto out; + } + +#ifdef CONFIG_SYS_MEM_RESERVE_SECURE + /* + * The SEC Firmware must be stored in secure memory. + * Append SEC Firmware to secure mmu table. + */ + if (!(gd->arch.secure_ram & MEM_RESERVE_SECURE_MAINTAINED)) { + ret = -ENXIO; + goto out; + } + + sec_firmware_addr = (gd->arch.secure_ram & MEM_RESERVE_SECURE_ADDR_MASK) + + gd->arch.tlb_size; +#else +#error "The CONFIG_SYS_MEM_RESERVE_SECURE must be defined when enabled SEC Firmware support" +#endif + + /* Align SEC Firmware base address to 4K */ + sec_firmware_addr = (sec_firmware_addr + 0xfff) & ~0xfff; + debug("SEC Firmware: Load address: 0x%llx\n", + sec_firmware_addr & SEC_FIRMWARE_ADDR_MASK); + + ret = sec_firmware_parse_image(sec_firmware_img, &raw_image_addr, + &raw_image_size); + if (ret) + goto out; + + /* TODO: + * Check if the end addr of SEC Firmware has been extend the secure + * memory. + */ + + /* Copy the secure firmware to secure memory */ + ret = sec_firmware_copy_image("SEC Firmware", (u64)raw_image_addr, + raw_image_size, sec_firmware_addr & + SEC_FIRMWARE_ADDR_MASK); + if (ret) + goto out; + + sec_firmware_addr |= SEC_FIRMWARE_LOADED; + debug("SEC Firmware: Entry point: 0x%llx\n", + sec_firmware_addr & SEC_FIRMWARE_ADDR_MASK); + + return 0; + +out: + printf("SEC Firmware: error (%d)\n", ret); + sec_firmware_addr = 0; + + return ret; +} + +static int sec_firmware_entry(u32 *eret_hold_l, u32 *eret_hold_h) +{ + const void *entry = (void *)(sec_firmware_addr & + SEC_FIRMWARE_ADDR_MASK); + + return _sec_firmware_entry(entry, eret_hold_l, eret_hold_h); +} + +/* Check the secure firmware FIT image */ +__weak bool sec_firmware_is_valid(const void *sec_firmware_img) +{ + if (fdt_check_header(sec_firmware_img)) { + printf("SEC Firmware: Bad firmware image (not a FIT image)\n"); + return false; + } + + if (!fit_check_format(sec_firmware_img)) { + printf("SEC Firmware: Bad firmware image (bad FIT header)\n"); + return false; + } + + return true; +} + +#ifdef CONFIG_ARMV8_PSCI +/* + * The PSCI_VERSION function is added from PSCI v0.2. When the PSCI + * v0.1 received this function, the NOT_SUPPORTED (0xffff_ffff) error + * number will be returned according to SMC Calling Conventions. But + * when getting the NOT_SUPPORTED error number, we cannot ensure if + * the PSCI version is v0.1 or other error occurred. So, PSCI v0.1 + * won't be supported by this framework. + * And if the secure firmware isn't running, return NOT_SUPPORTED. + * + * The return value on success is PSCI version in format + * major[31:16]:minor[15:0]. + */ +unsigned int sec_firmware_support_psci_version(void) +{ + if (sec_firmware_addr & SEC_FIRMWARE_RUNNING) + return _sec_firmware_support_psci_version(); + + return 0xffffffff; +} +#endif + +/* + * sec_firmware_init - Initialize the SEC Firmware + * @sec_firmware_img: the SEC Firmware image address + * @eret_hold_l: the address to hold exception return address low + * @eret_hold_h: the address to hold exception return address high + */ +int sec_firmware_init(const void *sec_firmware_img, + u32 *eret_hold_l, + u32 *eret_hold_h) +{ + int ret; + + if (!sec_firmware_is_valid(sec_firmware_img)) + return -EINVAL; + + ret = sec_firmware_load_image(sec_firmware_img); + if (ret) { + printf("SEC Firmware: Failed to load image\n"); + return ret; + } else if (sec_firmware_addr & SEC_FIRMWARE_LOADED) { + ret = sec_firmware_entry(eret_hold_l, eret_hold_h); + if (ret) { + printf("SEC Firmware: Failed to initialize\n"); + return ret; + } + } + + debug("SEC Firmware: Return from SEC Firmware: current_el = %d\n", + current_el()); + + /* + * The PE will be turned into target EL when returned from + * SEC Firmware. + */ + if (current_el() != SEC_FIRMWARE_TARGET_EL) + return -EACCES; + + sec_firmware_addr |= SEC_FIRMWARE_RUNNING; + + /* Set exception table and enable caches if it isn't EL3 */ + if (current_el() != 3) { + c_runtime_cpu_setup(); + enable_caches(); + } + + return 0; +} diff --git a/arch/arm/cpu/armv8/sec_firmware_asm.S b/arch/arm/cpu/armv8/sec_firmware_asm.S new file mode 100644 index 0000000..0c6a462 --- /dev/null +++ b/arch/arm/cpu/armv8/sec_firmware_asm.S @@ -0,0 +1,53 @@ +/* + * Copyright 2016 NXP Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include + +WEAK(_sec_firmware_entry) + /* + * x0: Secure Firmware entry point + * x1: Exception return address Low + * x2: Exception return address High + */ + + /* Save stack pointer for EL2 */ + mov x3, sp + msr sp_el2, x3 + + /* Set exception return address hold pointer */ + adr x4, 1f + mov x3, x4 +#ifdef SEC_FIRMWARE_ERET_ADDR_REVERT + rev w3, w3 +#endif + str w3, [x1] + lsr x3, x4, #32 +#ifdef SEC_FIRMWARE_ERET_ADDR_REVERT + rev w3, w3 +#endif + str w3, [x2] + + /* Call SEC monitor */ + br x0 + +1: + mov x0, #0 + ret +ENDPROC(_sec_firmware_entry) + +#ifdef CONFIG_ARMV8_PSCI +ENTRY(_sec_firmware_support_psci_version) + mov x0, 0x84000000 + mov x1, 0x0 + mov x2, 0x0 + mov x3, 0x0 + smc #0 + ret +ENDPROC(_sec_firmware_support_psci_version) +#endif diff --git a/arch/arm/include/asm/armv8/sec_firmware.h b/arch/arm/include/asm/armv8/sec_firmware.h new file mode 100644 index 0000000..39a1333 --- /dev/null +++ b/arch/arm/include/asm/armv8/sec_firmware.h @@ -0,0 +1,18 @@ +/* + * Copyright 2016 NXP Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __SEC_FIRMWARE_H_ +#define __SEC_FIRMWARE_H_ + +int sec_firmware_init(const void *, u32 *, u32 *); +int _sec_firmware_entry(const void *, u32 *, u32 *); +bool sec_firmware_is_valid(const void *); +#ifdef CONFIG_ARMV8_PSCI +unsigned int sec_firmware_support_psci_version(void); +unsigned int _sec_firmware_support_psci_version(void); +#endif + +#endif /* __SEC_FIRMWARE_H_ */ -- cgit v0.10.2 From f1dd4cadd20c3b6b2454b7f293265caa66f27fee Mon Sep 17 00:00:00 2001 From: Hou Zhiqiang Date: Tue, 28 Jun 2016 20:18:14 +0800 Subject: ARMv8/layerscape: Add FSL PPA support The FSL Primary Protected Application (PPA) is a software component loaded during boot which runs in TrustZone and remains resident after boot. Use the secure firmware framework to integrate FSL PPA into U-Boot. Signed-off-by: Hou Zhiqiang Reviewed-by: York Sun diff --git a/arch/arm/cpu/armv8/fsl-layerscape/Makefile b/arch/arm/cpu/armv8/fsl-layerscape/Makefile index eb2cbc3..bcf6b48 100644 --- a/arch/arm/cpu/armv8/fsl-layerscape/Makefile +++ b/arch/arm/cpu/armv8/fsl-layerscape/Makefile @@ -10,6 +10,7 @@ obj-y += soc.o obj-$(CONFIG_MP) += mp.o obj-$(CONFIG_OF_LIBFDT) += fdt.o obj-$(CONFIG_SPL) += spl.o +obj-$(CONFIG_FSL_LS_PPA) += ppa.o ifneq ($(CONFIG_FSL_LSCH3),) obj-y += fsl_lsch3_speed.o diff --git a/arch/arm/cpu/armv8/fsl-layerscape/ppa.c b/arch/arm/cpu/armv8/fsl-layerscape/ppa.c new file mode 100644 index 0000000..541b251 --- /dev/null +++ b/arch/arm/cpu/armv8/fsl-layerscape/ppa.c @@ -0,0 +1,48 @@ +/* + * Copyright 2016 NXP Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_FSL_LSCH3 +#include +#elif defined(CONFIG_FSL_LSCH2) +#include +#endif +#ifdef CONFIG_ARMV8_SEC_FIRMWARE_SUPPORT +#include +#endif + +int ppa_init(void) +{ + const void *ppa_fit_addr; + u32 *boot_loc_ptr_l, *boot_loc_ptr_h; + int ret; + +#ifdef CONFIG_SYS_LS_PPA_FW_IN_NOR + ppa_fit_addr = (void *)CONFIG_SYS_LS_PPA_FW_ADDR; +#else +#error "No CONFIG_SYS_LS_PPA_FW_IN_xxx defined" +#endif + +#ifdef CONFIG_FSL_LSCH3 + struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR); + boot_loc_ptr_l = &gur->bootlocptrl; + boot_loc_ptr_h = &gur->bootlocptrh; +#elif defined(CONFIG_FSL_LSCH2) + struct ccsr_scfg __iomem *scfg = (void *)(CONFIG_SYS_FSL_SCFG_ADDR); + boot_loc_ptr_l = &scfg->scratchrw[1]; + boot_loc_ptr_h = &scfg->scratchrw[0]; +#endif + + debug("fsl-ppa: boot_loc_ptr_l = 0x%p, boot_loc_ptr_h =0x%p\n", + boot_loc_ptr_l, boot_loc_ptr_h); + ret = sec_firmware_init(ppa_fit_addr, boot_loc_ptr_l, boot_loc_ptr_h); + + return ret; +} diff --git a/arch/arm/include/asm/arch-fsl-layerscape/ppa.h b/arch/arm/include/asm/arch-fsl-layerscape/ppa.h new file mode 100644 index 0000000..1f1442b --- /dev/null +++ b/arch/arm/include/asm/arch-fsl-layerscape/ppa.h @@ -0,0 +1,16 @@ +/* + * Copyright 2016 NXP Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __FSL_PPA_H_ +#define __FSL_PPA_H_ + +#define SEC_FIRMWARE_FIT_IMAGE "firmware" +#define SEC_FIRMEWARE_FIT_CNF_NAME "config@1" +#define SEC_FIRMWARE_TARGET_EL 2 + +int ppa_init(void); + +#endif diff --git a/arch/arm/include/asm/armv8/sec_firmware.h b/arch/arm/include/asm/armv8/sec_firmware.h index 39a1333..eb68185 100644 --- a/arch/arm/include/asm/armv8/sec_firmware.h +++ b/arch/arm/include/asm/armv8/sec_firmware.h @@ -7,6 +7,10 @@ #ifndef __SEC_FIRMWARE_H_ #define __SEC_FIRMWARE_H_ +#ifdef CONFIG_FSL_LS_PPA +#include +#endif + int sec_firmware_init(const void *, u32 *, u32 *); int _sec_firmware_entry(const void *, u32 *, u32 *); bool sec_firmware_is_valid(const void *); -- cgit v0.10.2 From 032d5bb4aed40f1d0de0698501fcacee594caabc Mon Sep 17 00:00:00 2001 From: Hou Zhiqiang Date: Tue, 28 Jun 2016 20:18:15 +0800 Subject: ARMv8/Layerscape: switch SMP method accordingly If the PSCI and PPA is ready, skip the fixup for spin-table and waking secondary cores. Otherwise, change SMP method to spin-table, and the device node of PSCI will be removed. Signed-off-by: Hou Zhiqiang Reviewed-by: York Sun diff --git a/arch/arm/cpu/armv8/fsl-layerscape/cpu.c b/arch/arm/cpu/armv8/fsl-layerscape/cpu.c index bcedf2c..7a2ec6b 100644 --- a/arch/arm/cpu/armv8/fsl-layerscape/cpu.c +++ b/arch/arm/cpu/armv8/fsl-layerscape/cpu.c @@ -23,6 +23,9 @@ #ifdef CONFIG_FSL_ESDHC #include #endif +#ifdef CONFIG_ARMV8_SEC_FIRMWARE_SUPPORT +#include +#endif DECLARE_GLOBAL_DATA_PTR; @@ -364,6 +367,7 @@ int arch_early_init_r(void) { #ifdef CONFIG_MP int rv = 1; + u32 psci_ver = 0xffffffff; #endif #ifdef CONFIG_SYS_FSL_ERRATUM_A009635 @@ -371,9 +375,15 @@ int arch_early_init_r(void) #endif #ifdef CONFIG_MP - rv = fsl_layerscape_wake_seconday_cores(); - if (rv) - printf("Did not wake secondary cores\n"); +#if defined(CONFIG_ARMV8_SEC_FIRMWARE_SUPPORT) && defined(CONFIG_ARMV8_PSCI) + /* Check the psci version to determine if the psci is supported */ + psci_ver = sec_firmware_support_psci_version(); +#endif + if (psci_ver == 0xffffffff) { + rv = fsl_layerscape_wake_seconday_cores(); + if (rv) + printf("Did not wake secondary cores\n"); + } #endif #ifdef CONFIG_SYS_HAS_SERDES diff --git a/arch/arm/cpu/armv8/fsl-layerscape/fdt.c b/arch/arm/cpu/armv8/fsl-layerscape/fdt.c index d17227a..40d6a76 100644 --- a/arch/arm/cpu/armv8/fsl-layerscape/fdt.c +++ b/arch/arm/cpu/armv8/fsl-layerscape/fdt.c @@ -22,6 +22,9 @@ #endif #include #include +#ifdef CONFIG_ARMV8_SEC_FIRMWARE_SUPPORT +#include +#endif int fdt_fixup_phy_connection(void *blob, int offset, phy_interface_t phyc) { @@ -38,7 +41,37 @@ void ft_fixup_cpu(void *blob) int addr_cells; u64 val, core_id; size_t *boot_code_size = &(__secondary_boot_code_size); +#if defined(CONFIG_ARMV8_SEC_FIRMWARE_SUPPORT) && defined(CONFIG_ARMV8_PSCI) + int node; + u32 psci_ver; + + /* Check the psci version to determine if the psci is supported */ + psci_ver = sec_firmware_support_psci_version(); + if (psci_ver == 0xffffffff) { + /* remove psci DT node */ + node = fdt_path_offset(blob, "/psci"); + if (node >= 0) + goto remove_psci_node; + + node = fdt_node_offset_by_compatible(blob, -1, "arm,psci"); + if (node >= 0) + goto remove_psci_node; + + node = fdt_node_offset_by_compatible(blob, -1, "arm,psci-0.2"); + if (node >= 0) + goto remove_psci_node; + node = fdt_node_offset_by_compatible(blob, -1, "arm,psci-1.0"); + if (node >= 0) + goto remove_psci_node; + +remove_psci_node: + if (node >= 0) + fdt_del_node(blob, node); + } else { + return; + } +#endif off = fdt_path_offset(blob, "/cpus"); if (off < 0) { puts("couldn't find /cpus node\n"); -- cgit v0.10.2 From 45684ae37bf96b455a1d4a957b80551dc2c85959 Mon Sep 17 00:00:00 2001 From: Hou Zhiqiang Date: Tue, 28 Jun 2016 20:18:16 +0800 Subject: ARMv8/PSCI: Fixup the device tree for PSCI Set the enable-method in the cpu node to PSCI, and create device node for PSCI, when PSCI was enabled. Signed-off-by: Hou Zhiqiang Reviewed-by: York Sun diff --git a/arch/arm/cpu/armv7/virt-dt.c b/arch/arm/cpu/armv7/virt-dt.c index 32c368f..707dad4 100644 --- a/arch/arm/cpu/armv7/virt-dt.c +++ b/arch/arm/cpu/armv7/virt-dt.c @@ -26,69 +26,6 @@ #include #include -static int fdt_psci(void *fdt) -{ -#ifdef CONFIG_ARMV7_PSCI - int nodeoff; - int tmp; - - nodeoff = fdt_path_offset(fdt, "/cpus"); - if (nodeoff < 0) { - printf("couldn't find /cpus\n"); - return nodeoff; - } - - /* add 'enable-method = "psci"' to each cpu node */ - for (tmp = fdt_first_subnode(fdt, nodeoff); - tmp >= 0; - tmp = fdt_next_subnode(fdt, tmp)) { - const struct fdt_property *prop; - int len; - - prop = fdt_get_property(fdt, tmp, "device_type", &len); - if (!prop) - continue; - if (len < 4) - continue; - if (strcmp(prop->data, "cpu")) - continue; - - fdt_setprop_string(fdt, tmp, "enable-method", "psci"); - } - - nodeoff = fdt_path_offset(fdt, "/psci"); - if (nodeoff < 0) { - nodeoff = fdt_path_offset(fdt, "/"); - if (nodeoff < 0) - return nodeoff; - - nodeoff = fdt_add_subnode(fdt, nodeoff, "psci"); - if (nodeoff < 0) - return nodeoff; - } - - tmp = fdt_setprop_string(fdt, nodeoff, "compatible", "arm,psci"); - if (tmp) - return tmp; - tmp = fdt_setprop_string(fdt, nodeoff, "method", "smc"); - if (tmp) - return tmp; - tmp = fdt_setprop_u32(fdt, nodeoff, "cpu_suspend", ARM_PSCI_FN_CPU_SUSPEND); - if (tmp) - return tmp; - tmp = fdt_setprop_u32(fdt, nodeoff, "cpu_off", ARM_PSCI_FN_CPU_OFF); - if (tmp) - return tmp; - tmp = fdt_setprop_u32(fdt, nodeoff, "cpu_on", ARM_PSCI_FN_CPU_ON); - if (tmp) - return tmp; - tmp = fdt_setprop_u32(fdt, nodeoff, "migrate", ARM_PSCI_FN_MIGRATE); - if (tmp) - return tmp; -#endif - return 0; -} - int armv7_apply_memory_carveout(u64 *start, u64 *size) { #ifdef CONFIG_ARMV7_SECURE_RESERVE_SIZE diff --git a/arch/arm/cpu/armv8/Makefile b/arch/arm/cpu/armv8/Makefile index ee9e009..33e6db0 100644 --- a/arch/arm/cpu/armv8/Makefile +++ b/arch/arm/cpu/armv8/Makefile @@ -15,6 +15,7 @@ obj-y += cache.o obj-y += tlb.o obj-y += transition.o obj-y += fwcall.o +obj-y += cpu-dt.o obj-$(CONFIG_ARMV8_SEC_FIRMWARE_SUPPORT) += sec_firmware.o sec_firmware_asm.o obj-$(CONFIG_FSL_LAYERSCAPE) += fsl-layerscape/ diff --git a/arch/arm/cpu/armv8/cpu-dt.c b/arch/arm/cpu/armv8/cpu-dt.c new file mode 100644 index 0000000..9ffb49c --- /dev/null +++ b/arch/arm/cpu/armv8/cpu-dt.c @@ -0,0 +1,31 @@ +/* + * Copyright 2016 NXP Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#ifdef CONFIG_ARMV8_SEC_FIRMWARE_SUPPORT +#include +#endif + +int psci_update_dt(void *fdt) +{ +#ifdef CONFIG_MP +#if defined(CONFIG_ARMV8_PSCI) +#ifdef CONFIG_ARMV8_SEC_FIRMWARE_SUPPORT + /* + * If the PSCI in SEC Firmware didn't work, avoid to update the + * device node of PSCI. But still return 0 instead of an error + * number to support detecting PSCI dynamically and then switching + * the SMP boot method between PSCI and spin-table. + */ + if (sec_firmware_support_psci_version() == 0xffffffff) + return 0; +#endif + fdt_psci(fdt); +#endif +#endif + return 0; +} diff --git a/arch/arm/include/asm/psci.h b/arch/arm/include/asm/psci.h index bc5edda..f92633b 100644 --- a/arch/arm/include/asm/psci.h +++ b/arch/arm/include/asm/psci.h @@ -57,6 +57,7 @@ void psci_cpu_off_common(void); int psci_update_dt(void *fdt); void psci_board_init(void); +int fdt_psci(void *fdt); #endif /* ! __ASSEMBLY__ */ #endif /* __ARM_PSCI_H__ */ diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile index 0e05e87..f406419 100644 --- a/arch/arm/lib/Makefile +++ b/arch/arm/lib/Makefile @@ -55,6 +55,8 @@ ifndef CONFIG_ARM64 obj-y += cache-cp15.o endif +obj-y += psci-dt.o + obj-$(CONFIG_DEBUG_LL) += debug.o # For EABI conformant tool chains, provide eabi_compat() diff --git a/arch/arm/lib/bootm-fdt.c b/arch/arm/lib/bootm-fdt.c index 76b75d8..fe5b488 100644 --- a/arch/arm/lib/bootm-fdt.c +++ b/arch/arm/lib/bootm-fdt.c @@ -45,7 +45,7 @@ int arch_fixup_fdt(void *blob) if (ret) return ret; -#ifdef CONFIG_ARMV7_NONSEC +#if defined(CONFIG_ARMV7_NONSEC) || defined(CONFIG_ARMV8_PSCI) ret = psci_update_dt(blob); if (ret) return ret; diff --git a/arch/arm/lib/psci-dt.c b/arch/arm/lib/psci-dt.c new file mode 100644 index 0000000..8dc31d4 --- /dev/null +++ b/arch/arm/lib/psci-dt.c @@ -0,0 +1,123 @@ +/* + * Copyright 2016 NXP Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_ARMV8_SEC_FIRMWARE_SUPPORT +#include +#endif + +int fdt_psci(void *fdt) +{ +#if defined(CONFIG_ARMV8_PSCI) || defined(CONFIG_ARMV7_PSCI) + int nodeoff; + unsigned int psci_ver = 0; + char *psci_compt; + int tmp; + + nodeoff = fdt_path_offset(fdt, "/cpus"); + if (nodeoff < 0) { + printf("couldn't find /cpus\n"); + return nodeoff; + } + + /* add 'enable-method = "psci"' to each cpu node */ + for (tmp = fdt_first_subnode(fdt, nodeoff); + tmp >= 0; + tmp = fdt_next_subnode(fdt, tmp)) { + const struct fdt_property *prop; + int len; + + prop = fdt_get_property(fdt, tmp, "device_type", &len); + if (!prop) + continue; + if (len < 4) + continue; + if (strcmp(prop->data, "cpu")) + continue; + + /* + * Not checking rv here, our approach is to skip over errors in + * individual cpu nodes, hopefully some of the nodes are + * processed correctly and those will boot + */ + fdt_setprop_string(fdt, tmp, "enable-method", "psci"); + } + + /* + * The PSCI node might be called "/psci" or might be called something + * else but contain either of the compatible strings + * "arm,psci"/"arm,psci-0.2" + */ + nodeoff = fdt_path_offset(fdt, "/psci"); + if (nodeoff >= 0) + goto init_psci_node; + + nodeoff = fdt_node_offset_by_compatible(fdt, -1, "arm,psci"); + if (nodeoff >= 0) + goto init_psci_node; + + nodeoff = fdt_node_offset_by_compatible(fdt, -1, "arm,psci-0.2"); + if (nodeoff >= 0) + goto init_psci_node; + + nodeoff = fdt_node_offset_by_compatible(fdt, -1, "arm,psci-1.0"); + if (nodeoff >= 0) + goto init_psci_node; + + nodeoff = fdt_path_offset(fdt, "/"); + if (nodeoff < 0) + return nodeoff; + + nodeoff = fdt_add_subnode(fdt, nodeoff, "psci"); + if (nodeoff < 0) + return nodeoff; + +init_psci_node: +#ifdef CONFIG_ARMV8_SEC_FIRMWARE_SUPPORT + psci_ver = sec_firmware_support_psci_version(); +#endif + switch (psci_ver) { + case 0x00010000: + psci_compt = "arm,psci-1.0"; + break; + case 0x00000002: + psci_compt = "arm,psci-0.2"; + break; + default: + psci_compt = "arm,psci"; + break; + } + + tmp = fdt_setprop_string(fdt, nodeoff, "compatible", psci_compt); + if (tmp) + return tmp; + tmp = fdt_setprop_string(fdt, nodeoff, "method", "smc"); + if (tmp) + return tmp; + +#ifdef CONFIG_ARMV7_PSCI + tmp = fdt_setprop_u32(fdt, nodeoff, "cpu_suspend", + ARM_PSCI_FN_CPU_SUSPEND); + if (tmp) + return tmp; + tmp = fdt_setprop_u32(fdt, nodeoff, "cpu_off", ARM_PSCI_FN_CPU_OFF); + if (tmp) + return tmp; + tmp = fdt_setprop_u32(fdt, nodeoff, "cpu_on", ARM_PSCI_FN_CPU_ON); + if (tmp) + return tmp; + tmp = fdt_setprop_u32(fdt, nodeoff, "migrate", ARM_PSCI_FN_MIGRATE); + if (tmp) + return tmp; +#endif +#endif + return 0; +} -- cgit v0.10.2 From 0e68a3694d1f33c69be7d1cec5a4261aa1d3d01d Mon Sep 17 00:00:00 2001 From: Hou Zhiqiang Date: Tue, 28 Jun 2016 20:18:17 +0800 Subject: ARMv8/ls1043ardb: Integrate FSL PPA The PPA use PSCI to make secondary cores bootup. So when PPA was enabled, add the CONFIG_ARMV8_PSCI to identify the SMP boot-method between PSCI and spin-table. Signed-off-by: Hou Zhiqiang Reviewed-by: York Sun diff --git a/board/freescale/ls1043ardb/ls1043ardb.c b/board/freescale/ls1043ardb/ls1043ardb.c index 1436520..d3e37b4 100644 --- a/board/freescale/ls1043ardb/ls1043ardb.c +++ b/board/freescale/ls1043ardb/ls1043ardb.c @@ -24,7 +24,9 @@ #ifdef CONFIG_U_QE #include #endif - +#ifdef CONFIG_FSL_LS_PPA +#include +#endif DECLARE_GLOBAL_DATA_PTR; @@ -92,6 +94,10 @@ int board_init(void) enable_layerscape_ns_access(); #endif +#ifdef CONFIG_FSL_LS_PPA + ppa_init(); +#endif + #ifdef CONFIG_U_QE u_qe_init(); #endif diff --git a/include/configs/ls1043ardb.h b/include/configs/ls1043ardb.h index 94ddfb1..44f86fa 100644 --- a/include/configs/ls1043ardb.h +++ b/include/configs/ls1043ardb.h @@ -9,6 +9,17 @@ #include "ls1043a_common.h" +#if defined(CONFIG_FSL_LS_PPA) +#define CONFIG_ARMV8_SEC_FIRMWARE_SUPPORT +#define SEC_FIRMWARE_ERET_ADDR_REVERT +#define CONFIG_ARMV8_PSCI + +#define CONFIG_SYS_LS_PPA_FW_IN_NOR +#ifdef CONFIG_SYS_LS_PPA_FW_IN_NOR +#define CONFIG_SYS_LS_PPA_FW_ADDR 0x60500000 +#endif +#endif + #define CONFIG_DISPLAY_CPUINFO #define CONFIG_DISPLAY_BOARDINFO -- cgit v0.10.2