Use Shikra fixed pre-DDR memory map when enabling caches in
SPL. Allocate page tables from the early malloc-F heap and
select the board map through a common Qualcomm hook.

Signed-off-by: Abhilash V <[email protected]>
---
 arch/arm/mach-snapdragon/mem_map.c   |  24 ++++-
 arch/arm/mach-snapdragon/qcom-priv.h |   4 +
 board/qualcomm/shikra/spl-shikra.c   | 140 +++++++++++++++++++++++++++
 3 files changed, 166 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-snapdragon/mem_map.c 
b/arch/arm/mach-snapdragon/mem_map.c
index 17c18e5096a..9df522f7a4e 100644
--- a/arch/arm/mach-snapdragon/mem_map.c
+++ b/arch/arm/mach-snapdragon/mem_map.c
@@ -28,6 +28,19 @@ static struct mm_region rbx_mem_map[CONFIG_NR_DRAM_BANKS + 
2] = { { 0 } };
 
 struct mm_region *mem_map = rbx_mem_map;
 
+#if defined(CONFIG_SPL_BUILD)
+enum qcom_memmap_source qcom_memmap_source __section(".data") = 0;
+#endif
+
+/*
+ * SPL platforms whose pre-DRAM address map differs from the common Qualcomm
+ * map may override this hook.
+ */
+struct mm_region *__weak qcom_spl_mem_map(void)
+{
+       return NULL;
+}
+
 static void build_mem_map(void)
 {
        int i, j;
@@ -65,10 +78,12 @@ static void build_mem_map(void)
 #endif
 }
 
+#if !defined(CONFIG_SPL_BUILD)
 u64 get_page_table_size(void)
 {
        return SZ_1M;
 }
+#endif
 
 struct mem_resource_attrs {
        fdt_addr_t start;
@@ -185,6 +200,7 @@ static void configure_reserved_memory(void)
  */
 void enable_caches(void)
 {
+       struct mm_region *spl_mem_map;
        u64 tlb_addr = gd->arch.tlb_addr;
        u64 tlb_size = gd->arch.tlb_size;
        u64 pt_size;
@@ -192,7 +208,11 @@ void enable_caches(void)
 
        gd->arch.tlb_fillptr = tlb_addr;
 
-       build_mem_map();
+       spl_mem_map = qcom_spl_mem_map();
+       if (spl_mem_map)
+               mem_map = spl_mem_map;
+       else
+               build_mem_map();
 
        icache_enable();
 
@@ -223,4 +243,4 @@ void enable_caches(void)
                debug("carveout time: %lums\n", get_timer(carveout_start));
        }
        dcache_enable();
-}
\ No newline at end of file
+}
diff --git a/arch/arm/mach-snapdragon/qcom-priv.h 
b/arch/arm/mach-snapdragon/qcom-priv.h
index 27e5c54e512..c267c0d9aec 100644
--- a/arch/arm/mach-snapdragon/qcom-priv.h
+++ b/arch/arm/mach-snapdragon/qcom-priv.h
@@ -5,6 +5,8 @@
 
 #include <stdbool.h>
 
+struct mm_region;
+
 /**
  * enum qcom_boot_source - Track where we got loaded from.
  * Used for capsule update logic.
@@ -40,4 +42,6 @@ static inline void qcom_configure_capsule_updates(void) {}
 
 int qcom_parse_memory(const void *fdt, bool fdt_is_internal);
 
+struct mm_region *qcom_spl_mem_map(void);
+
 #endif /* __QCOM_PRIV_H__ */
diff --git a/board/qualcomm/shikra/spl-shikra.c 
b/board/qualcomm/shikra/spl-shikra.c
index b967b0137b1..9bab677cce5 100644
--- a/board/qualcomm/shikra/spl-shikra.c
+++ b/board/qualcomm/shikra/spl-shikra.c
@@ -3,15 +3,107 @@
  * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
  */
 #include <blk.h>
+#include <cpu_func.h>
 #include <asm/io.h>
+#include <asm/sections.h>
+#include <asm/system.h>
+#include <asm/armv8/mmu.h>
 #include <dm/uclass.h>
+#include <init.h>
 #include <linux/err.h>
+#include <linux/sizes.h>
 #include <linux/string.h>
+#include <malloc.h>
 #include <mach/qclib.h>
 #include <mach/spl.h>
 #include <part.h>
 #include <spl.h>
 
+DECLARE_GLOBAL_DATA_PTR;
+
+#if defined(CONFIG_SPL_BUILD)
+/*
+ * The SPL device tree does not describe the complete early physical layout,
+ * so use Shikra's fixed map when enabling the MMU.
+ */
+#define SHIKRA_SPL_DEVICE_REG_LOW_BASE         0x00000000UL
+#define SHIKRA_SPL_SYSTEM_IMEM_BASE            0x0c100000UL
+#define SHIKRA_SPL_SYSTEM_IMEM_SIZE            0x00020000UL
+#define SHIKRA_SPL_BOOTIMEM_BASE               0x0c200000UL
+#define SHIKRA_SPL_BOOTIMEM_SIZE               0x001c0000UL
+#define SHIKRA_SPL_DEVICE_REG_HIGH_BASE        (SHIKRA_SPL_BOOTIMEM_BASE + \
+                                                SHIKRA_SPL_BOOTIMEM_SIZE)
+#define SHIKRA_SPL_DDR_BASE                    0x80000000UL
+#define SHIKRA_SPL_DDR_SIZE                    0x80000000UL
+#define SHIKRA_SPL_DDR2_BASE                   0x880000000ULL
+#define SHIKRA_SPL_DDR2_SIZE                   (SZ_32G - SZ_2G)
+#define SHIKRA_SPL_DEVICE_REG_LOW_SIZE         (SHIKRA_SPL_SYSTEM_IMEM_BASE - \
+                                                SHIKRA_SPL_DEVICE_REG_LOW_BASE)
+#define SHIKRA_SPL_DEVICE_REG_HIGH_SIZE        (SHIKRA_SPL_DDR_BASE - \
+                                                
SHIKRA_SPL_DEVICE_REG_HIGH_BASE)
+
+static struct mm_region shikra_spl_mem_map[] = {
+       {
+               .virt = SHIKRA_SPL_DEVICE_REG_LOW_BASE,
+               .phys = SHIKRA_SPL_DEVICE_REG_LOW_BASE,
+               .size = SHIKRA_SPL_DEVICE_REG_LOW_SIZE,
+               .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+                        PTE_BLOCK_NON_SHARE,
+       }, {
+               .virt = SHIKRA_SPL_SYSTEM_IMEM_BASE,
+               .phys = SHIKRA_SPL_SYSTEM_IMEM_BASE,
+               .size = SHIKRA_SPL_SYSTEM_IMEM_SIZE,
+               .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+                        PTE_BLOCK_INNER_SHARE,
+       }, {
+               /* SPL and QCLIB execute directly from BOOT_IMEM. */
+               .virt = SHIKRA_SPL_BOOTIMEM_BASE,
+               .phys = SHIKRA_SPL_BOOTIMEM_BASE,
+               .size = SHIKRA_SPL_BOOTIMEM_SIZE,
+               .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+                        PTE_BLOCK_INNER_SHARE,
+       }, {
+               .virt = SHIKRA_SPL_DEVICE_REG_HIGH_BASE,
+               .phys = SHIKRA_SPL_DEVICE_REG_HIGH_BASE,
+               .size = SHIKRA_SPL_DEVICE_REG_HIGH_SIZE,
+               .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+                        PTE_BLOCK_NON_SHARE,
+       }, {
+               .virt = SHIKRA_SPL_DDR_BASE,
+               .phys = SHIKRA_SPL_DDR_BASE,
+               .size = SHIKRA_SPL_DDR_SIZE,
+               .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL_NC) |
+                        PTE_BLOCK_INNER_SHARE,
+       }, {
+               .virt = SHIKRA_SPL_DDR2_BASE,
+               .phys = SHIKRA_SPL_DDR2_BASE,
+               .size = SHIKRA_SPL_DDR2_SIZE,
+               .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL_NC) |
+                        PTE_BLOCK_INNER_SHARE,
+       }, {
+               0,
+       }
+};
+
+struct mm_region *qcom_spl_mem_map(void)
+{
+       return shikra_spl_mem_map;
+}
+
+int arm_reserve_mmu(void)
+{
+#if !(CONFIG_IS_ENABLED(SYS_ICACHE_OFF) && CONFIG_IS_ENABLED(SYS_DCACHE_OFF))
+       mem_map = qcom_spl_mem_map();
+       gd->arch.tlb_size = PGTABLE_SIZE;
+       gd->arch.tlb_addr = (unsigned long)memalign(SZ_64K, gd->arch.tlb_size);
+       if (!gd->arch.tlb_addr)
+               return -ENOMEM;
+#endif
+
+       return 0;
+}
+#endif
+
 #define IPQ_SPL_BOOTCFG_REG_ADDR       0x1B46070
 #define IPQ_SPL_BOOTCFG_DEV_MASK       GENMASK(5, 1)
 #define IPQ_SPL_BOOTCFG_DEV_SHFT       0x1
@@ -55,6 +147,54 @@ enum {
        IPQ_SPL_BOOTCFG_DEV_MAX
 };
 
+#if defined(CONFIG_SPL_BUILD)
+void board_init_f(ulong dummy)
+{
+       int ret = 0;
+
+       memset(__bss_start, 0, __bss_end - __bss_start);
+
+       qcom_spl_malloc_init_f();
+
+       ret = spl_early_init();
+       if (ret) {
+               pr_debug("spl_early_init() failed (%d)\n", ret);
+               goto fail;
+       }
+
+       event_notify_null(EVT_LAST_STAGE_INIT);
+
+       preloader_console_init();
+
+#if !(CONFIG_IS_ENABLED(SYS_ICACHE_OFF) && CONFIG_IS_ENABLED(SYS_DCACHE_OFF))
+       ret = arm_reserve_mmu();
+       if (ret) {
+               pr_debug("arm_reserve_mmu() failed (%d)\n", ret);
+               goto fail;
+       }
+
+       enable_caches();
+#endif
+
+       ret = qcom_spl_loader_pre_ddr(spl_boot_device());
+       if (ret) {
+               pr_debug("qcom_spl_loader_pre_ddr() failed (%d)\n", ret);
+               goto fail;
+       }
+
+       ret = qcom_spl_invoke_qclib();
+       if (ret) {
+               pr_debug("qcom_spl_invoke_qclib() failed (%d)\n", ret);
+               goto fail;
+       }
+
+       board_init_r(NULL, 0);
+
+fail:
+       if (ret)
+               reset_cpu();
+}
+#endif
 int qcom_spl_soc_qclib_override(struct interface_table *table,
                                const void *fit, int images_node)
 {
-- 
2.34.1

Reply via email to