armv8/fsl-lsch3: Update early MMU table
authorYork Sun <yorksun@freescale.com>
Sat, 21 Mar 2015 02:28:11 +0000 (19:28 -0700)
committerYork Sun <yorksun@freescale.com>
Thu, 23 Apr 2015 15:55:56 +0000 (08:55 -0700)
During booting, IFC is mapped to low region. After booting up, IFC is
remapped to high region for larger space. The environmental variables are
also stored at high region. In order to read the variables during booting,
a virtual mapping is required.

Cache was enabled for entire IFC space before. Actually the first two
entries are big enough (4MB) to cover the boot code and environmental
variables. Remove extra entries. Move OCRAM entry out of ifdef.

Signed-off-by: York Sun <yorksun@freescale.com>
arch/arm/cpu/armv8/fsl-lsch3/cpu.c
common/board_r.c

index 0e5aa5ca9506f0a6b7bb762701ec7f12bef435e0..595dbd1d63d0659225cd0e8e214be75fedaf888e 100644 (file)
@@ -25,8 +25,9 @@ DECLARE_GLOBAL_DATA_PTR;
  * 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[31:30], table address @01000, 0x2000
- * Level 2 IA[29:21], table address @0x3000
+ * Level 1 IA[31:30], table address @0x1000, 0x2000
+ * Level 2 IA[29:21], table address @0x3000, 0x4000
+ * Address above 0x5000 is free for other purpose.
  */
 
 #define SECTION_SHIFT_L0       39UL
@@ -61,12 +62,12 @@ static inline void early_mmu_setup(void)
 {
        int el;
        u64 i;
-       u64 section_l1t0, section_l1t1, section_l2;
+       u64 section_l1t0, section_l1t1, section_l2t0, section_l2t1;
        u64 *level0_table = (u64 *)CONFIG_SYS_FSL_OCRAM_BASE;
        u64 *level1_table_0 = (u64 *)(CONFIG_SYS_FSL_OCRAM_BASE + 0x1000);
        u64 *level1_table_1 = (u64 *)(CONFIG_SYS_FSL_OCRAM_BASE + 0x2000);
-       u64 *level2_table = (u64 *)(CONFIG_SYS_FSL_OCRAM_BASE + 0x3000);
-
+       u64 *level2_table_0 = (u64 *)(CONFIG_SYS_FSL_OCRAM_BASE + 0x3000);
+       u64 *level2_table_1 = (u64 *)(CONFIG_SYS_FSL_OCRAM_BASE + 0x4000);
 
        level0_table[0] =
                (u64)level1_table_0 | PMD_TYPE_TABLE;
@@ -80,21 +81,25 @@ static inline void early_mmu_setup(void)
         */
        section_l1t0 = 0;
        section_l1t1 = BLOCK_SIZE_L0;
-       section_l2 = 0;
+       section_l2t0 = 0;
+       section_l2t1 = CONFIG_SYS_FLASH_BASE;
        for (i = 0; i < 512; i++) {
                set_pgtable_section(level1_table_0, i, section_l1t0,
                                    MT_DEVICE_NGNRNE);
                set_pgtable_section(level1_table_1, i, section_l1t1,
                                    MT_NORMAL);
-               set_pgtable_section(level2_table, i, section_l2,
+               set_pgtable_section(level2_table_0, i, section_l2t0,
+                                   MT_DEVICE_NGNRNE);
+               set_pgtable_section(level2_table_1, i, section_l2t1,
                                    MT_DEVICE_NGNRNE);
                section_l1t0 += BLOCK_SIZE_L1;
                section_l1t1 += BLOCK_SIZE_L1;
-               section_l2 += BLOCK_SIZE_L2;
+               section_l2t0 += BLOCK_SIZE_L2;
+               section_l2t1 += BLOCK_SIZE_L2;
        }
 
        level1_table_0[0] =
-               (u64)level2_table | PMD_TYPE_TABLE;
+               (u64)level2_table_0 | PMD_TYPE_TABLE;
        level1_table_0[1] =
                0x40000000 | PMD_SECT_AF | PMD_TYPE_SECT |
                PMD_ATTRINDX(MT_DEVICE_NGNRNE);
@@ -105,17 +110,34 @@ static inline void early_mmu_setup(void)
                0xc0000000 | PMD_SECT_AF | PMD_TYPE_SECT |
                PMD_ATTRINDX(MT_NORMAL);
 
-       /* Rewrite table to enable cache */
-       set_pgtable_section(level2_table,
+       /* Rewerite table to enable cache for OCRAM */
+       set_pgtable_section(level2_table_0,
                            CONFIG_SYS_FSL_OCRAM_BASE >> SECTION_SHIFT_L2,
                            CONFIG_SYS_FSL_OCRAM_BASE,
                            MT_NORMAL);
-       for (i = CONFIG_SYS_IFC_BASE >> SECTION_SHIFT_L2;
-            i < (CONFIG_SYS_IFC_BASE + CONFIG_SYS_IFC_SIZE)
-            >> SECTION_SHIFT_L2; i++) {
-               section_l2 = i << SECTION_SHIFT_L2;
-               set_pgtable_section(level2_table, i,
-                                   section_l2, MT_NORMAL);
+
+#if defined(CONFIG_SYS_NOR0_CSPR_EARLY) && defined(CONFIG_SYS_NOR_AMASK_EARLY)
+       /* Rewrite table to enable cache for two entries (4MB) */
+       section_l2t1 = CONFIG_SYS_IFC_BASE;
+       set_pgtable_section(level2_table_0,
+                           section_l2t1 >> SECTION_SHIFT_L2,
+                           section_l2t1,
+                           MT_NORMAL);
+       section_l2t1 += BLOCK_SIZE_L2;
+       set_pgtable_section(level2_table_0,
+                           section_l2t1 >> SECTION_SHIFT_L2,
+                           section_l2t1,
+                           MT_NORMAL);
+#endif
+
+       /* Create a mapping for 256MB IFC region to final flash location */
+       level1_table_0[CONFIG_SYS_FLASH_BASE >> SECTION_SHIFT_L1] =
+               (u64)level2_table_1 | PMD_TYPE_TABLE;
+       section_l2t1 = CONFIG_SYS_IFC_BASE;
+       for (i = 0; i < 0x10000000 >> SECTION_SHIFT_L2; i++) {
+               set_pgtable_section(level2_table_1, i,
+                                   section_l2t1, MT_DEVICE_NGNRNE);
+               section_l2t1 += BLOCK_SIZE_L2;
        }
 
        el = current_el();
index 42ff18c219030d8478d0e921f5d576d2ddac746b..307124ed8049a0c574042b8b34548e8551373e88 100644 (file)
@@ -702,6 +702,12 @@ init_fnc_t init_sequence_r[] = {
        /* TODO: could x86/PPC have this also perhaps? */
 #ifdef CONFIG_ARM
        initr_caches,
+       /* Note: For Freescale LS2 SoCs, new MMU table is created in DDR.
+        *       A temporary mapping of IFC high region is since removed,
+        *       so environmental variables in NOR flash is not availble
+        *       until board_init() is called below to remap IFC to high
+        *       region.
+        */
 #endif
        initr_reloc_global_data,
 #if defined(CONFIG_SYS_INIT_RAM_LOCK) && defined(CONFIG_E500)