build_mem_map() leaves gaps between DRAM banks unmapped, causing
configure_reserved_memory() to fail when a reserved-memory node
falls within such a gap. Map inter-bank gaps as MT_DEVICE_NGNRNE
regions and reserve space for the additional MMU entries.

Signed-off-by: Aswin Murugan <[email protected]>
---
 arch/arm/mach-snapdragon/board.c | 30 ++++++++++++++++++++++++++++--
 1 file changed, 28 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-snapdragon/board.c b/arch/arm/mach-snapdragon/board.c
index 35735f1551c..6d25d8ea599 100644
--- a/arch/arm/mach-snapdragon/board.c
+++ b/arch/arm/mach-snapdragon/board.c
@@ -39,7 +39,11 @@ DECLARE_GLOBAL_DATA_PTR;
 
 enum qcom_boot_source qcom_boot_source __section(".data") = 0;
 
-static struct mm_region rbx_mem_map[CONFIG_NR_DRAM_BANKS + 2] = { { 0 } };
+/*
+ * Space for one entry per DRAM bank, one entry per inter-bank gap,
+ * plus the peripheral block entry and the terminator.
+ */
+static struct mm_region rbx_mem_map[2 * CONFIG_NR_DRAM_BANKS + 2] = { { 0 } };
 
 struct mm_region *mem_map = rbx_mem_map;
 
@@ -584,6 +588,7 @@ int board_late_init(void)
 static void build_mem_map(void)
 {
        int i, j;
+       phys_addr_t prev_end;
 
        /*
         * Ensure the peripheral block is sized to correctly cover the address 
range
@@ -599,12 +604,33 @@ static void build_mem_map(void)
                         PTE_BLOCK_NON_SHARE |
                         PTE_BLOCK_PXN | PTE_BLOCK_UXN;
 
-       for (i = 1, j = 0; i < ARRAY_SIZE(rbx_mem_map) - 1 && gd->dram[j].size; 
i++, j++) {
+       /*
+        * Map gaps between DRAM banks as device memory. These regions
+        * are not usable RAM but must remain mapped for attribute updates.
+        */
+       i = 1;
+       prev_end = gd->dram[0].start;
+       for (j = 0; i < ARRAY_SIZE(rbx_mem_map) - 1 && gd->dram[j].size; j++) {
+               if (gd->dram[j].start > prev_end) {
+                       mem_map[i].phys = prev_end;
+                       mem_map[i].virt = mem_map[i].phys;
+                       mem_map[i].size = gd->dram[j].start - prev_end;
+                       mem_map[i].attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+                                          PTE_BLOCK_NON_SHARE |
+                                          PTE_BLOCK_PXN | PTE_BLOCK_UXN |
+                                          PTE_BLOCK_RO;
+                       i++;
+                       if (i >= ARRAY_SIZE(rbx_mem_map) - 1)
+                               break;
+               }
+
                mem_map[i].phys = gd->dram[j].start;
                mem_map[i].virt = mem_map[i].phys;
                mem_map[i].size = gd->dram[j].size;
                mem_map[i].attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | \
                                   PTE_BLOCK_INNER_SHARE;
+               prev_end = gd->dram[j].start + gd->dram[j].size;
+               i++;
        }
 
        mem_map[i].phys = UINT64_MAX;
-- 
2.34.1

Reply via email to