[PATCH v2 13/15] mach-snapdragon: support parsing memory map from SMEM

Casey Connolly casey.connolly at linaro.org
Mon May 4 20:57:41 CEST 2026


It is possible to derive the memory map for a Qualcomm platform from the
SMEM shared memory region. The memory map is populated by the preloader.

Introduce support for parsing this data and using it to populate
U-Boot's memory map. Since we aren't yet sure if this will work for
every platform, it is not yet used in all cases, if U-Boot is booted
with an internal FDT which has the memory map defined, this will
be used instead.

If the FDT is internal FDT with no memory map defined, then U-Boot will
try to use SMEM. This should remove the need to define the memory map
statically in a U-Boot overlay for boards that don't chainload.

Signed-off-by: Casey Connolly <casey.connolly at linaro.org>
---
 arch/arm/Kconfig                     |   1 +
 arch/arm/mach-snapdragon/board.c     |  45 +++++---
 arch/arm/mach-snapdragon/dram.c      | 172 +++++++++++++++++++++++++------
 arch/arm/mach-snapdragon/qcom-priv.h |  17 ++-
 arch/arm/mach-snapdragon/rampart.h   | 194 +++++++++++++++++++++++++++++++++++
 5 files changed, 386 insertions(+), 43 deletions(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index a8fcfe76296c..1da0677d85b3 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1140,8 +1140,9 @@ config ARCH_SNAPDRAGON
 	select DM_RESET
 	select POWER_DOMAIN
 	select GPIO_EXTRA_HEADER
 	select OF_CONTROL
+	select QCOM_SMEM
 	select SPMI
 	select BOARD_LATE_INIT
 	select OF_BOARD
 	select SAVE_PREV_BL_FDT_ADDR if !ENABLE_ARM_SOC_BOOT0_HOOK
diff --git a/arch/arm/mach-snapdragon/board.c b/arch/arm/mach-snapdragon/board.c
index a2d97ad77910..7610891191fd 100644
--- a/arch/arm/mach-snapdragon/board.c
+++ b/arch/arm/mach-snapdragon/board.c
@@ -29,16 +29,18 @@
 #include <lmb.h>
 #include <malloc.h>
 #include <fdt_support.h>
 #include <usb.h>
+#include <soc/qcom/smem.h>
 #include <sort.h>
 #include <time.h>
 
 #include "qcom-priv.h"
 
 DECLARE_GLOBAL_DATA_PTR;
 
 enum qcom_boot_source qcom_boot_source __section(".data") = 0;
+enum qcom_memmap_source qcom_memmap_source __section(".data") = 0;
 
 static struct mm_region rbx_mem_map[CONFIG_NR_DRAM_BANKS + 2] = { { 0 } };
 
 struct mm_region *mem_map = rbx_mem_map;
@@ -109,18 +111,18 @@ int board_fdt_blob_setup(void **fdtp)
 		      (phys_addr_t)external_fdt);
 
 	/* Prefer memory information from internal DT if it's present */
 	if (internal_valid)
-		ret = qcom_parse_memory(internal_fdt);
+		ret = qcom_parse_memory(internal_fdt, true);
 
 	if (ret < 0 && external_valid) {
 		/* No internal FDT or it lacks a proper /memory node.
 		 * The previous bootloader handed us something, let's try that.
 		 */
 		if (internal_valid)
 			debug("No memory info in internal FDT, falling back to external\n");
 
-		ret = qcom_parse_memory(external_fdt);
+		ret = qcom_parse_memory(external_fdt, false);
 	}
 
 	if (ret < 0)
 		panic("No valid memory ranges found!\n");
@@ -373,23 +375,39 @@ static void configure_env(void)
 
 	qcom_set_serialno();
 }
 
-void qcom_show_boot_source(void)
+static void qcom_show_boot_context(void)
 {
-	const char *name = "UNKNOWN";
+	const char *boot_source = "UNKNOWN";
+	const char *memmap_source = "UNKNOWN";
 
 	switch (qcom_boot_source) {
 	case QCOM_BOOT_SOURCE_ANDROID:
-		name = "ABL";
+		boot_source = "ABL";
 		break;
 	case QCOM_BOOT_SOURCE_XBL:
-		name = "XBL";
+		boot_source = "XBL";
 		break;
 	}
 
-	log_info("U-Boot loaded from %s\n", name);
-	env_set("boot_source", name);
+	log_info("U-Boot loaded from %s\n", boot_source);
+	env_set("boot_source", boot_source);
+
+	switch (qcom_memmap_source) {
+	case QCOM_MEMMAP_SOURCE_INTERNAL_FDT:
+		memmap_source = "INTERNAL_FDT";
+		break;
+	case QCOM_MEMMAP_SOURCE_EXTERNAL_FDT:
+		memmap_source = "EXTERNAL_FDT";
+		break;
+	case QCOM_MEMMAP_SOURCE_SMEM:
+		memmap_source = "SMEM";
+		break;
+	}
+
+	log_info("Memory map loaded from %s\n", memmap_source);
+	env_set("memmap_source", memmap_source);
 }
 
 void __weak qcom_late_init(void)
 {
@@ -458,9 +476,9 @@ int board_late_init(void)
 
 	configure_env();
 	qcom_late_init();
 
-	qcom_show_boot_source();
+	qcom_show_boot_context();
 	/* Configure the dfu_string for capsule updates */
 	qcom_configure_capsule_updates();
 
 	return 0;
@@ -648,11 +666,14 @@ void enable_caches(void)
 	gd->arch.tlb_emerg = gd->arch.tlb_addr;
 	gd->arch.tlb_addr = tlb_addr;
 	gd->arch.tlb_size = tlb_size;
 
-	/* On some boards speculative access may trigger a NOC or XPU violation so explicitly mark reserved
-	 * regions as inacessible (PTE_TYPE_FAULT) */
-	if (fdt_node_check_compatible(gd->fdt_blob, 0, "qcom,qcs404") == 0) {
+	/*
+	 * On some boards speculative access may trigger a NOC or XPU violation so explicitly mark
+	 * reserved regions as inacessible (PTE_TYPE_FAULT)
+	 */
+	if (qcom_memmap_source == QCOM_MEMMAP_SOURCE_SMEM ||
+	    fdt_node_check_compatible(gd->fdt_blob, 0, "qcom,qcs404") == 0) {
 		carveout_start = get_timer(0);
 		/* Takes ~20-50ms on SDM845 */
 		configure_reserved_memory();
 		debug("carveout time: %lums\n", get_timer(carveout_start));
diff --git a/arch/arm/mach-snapdragon/dram.c b/arch/arm/mach-snapdragon/dram.c
index ad73b685a935..af5f3c84882c 100644
--- a/arch/arm/mach-snapdragon/dram.c
+++ b/arch/arm/mach-snapdragon/dram.c
@@ -9,8 +9,12 @@
 #include <asm-generic/unaligned.h>
 #include <dm.h>
 #include <log.h>
 #include <sort.h>
+#include <soc/qcom/smem.h>
+
+#include "qcom-priv.h"
+#include "rampart.h"
 
 static struct {
 	phys_addr_t start;
 	phys_size_t size;
@@ -47,8 +51,12 @@ static void qcom_configure_bi_dram(void)
 
 	for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
 		gd->bd->bi_dram[i].start = prevbl_ddr_banks[i].start;
 		gd->bd->bi_dram[i].size = prevbl_ddr_banks[i].size;
+		debug("Bank[%d]: start = %#011llx, size = %#011llx\n",
+		      i, gd->bd->bi_dram[i].start, gd->bd->bi_dram[i].size);
+		if (!prevbl_ddr_banks[i].size)
+			break;
 	}
 }
 
 int dram_init_banksize(void)
@@ -57,8 +65,124 @@ int dram_init_banksize(void)
 
 	return 0;
 }
 
+#define entry_field(v, e, field) (v == 0 ? ((struct ram_partition_entry_v0 *)(e))->field : \
+				 (v == 1 ? ((struct ram_partition_entry_v1 *)(e))->field : \
+				  ((struct ram_partition_entry_v3 *)(e))->field))
+#define entry_start(v, e) entry_field(v, e, start_address)
+#define entry_length(v, e) entry_field(v, e, length)
+#define entry_category(v, e) entry_field(v, e, partition_category)
+#define entry_domain(v, e) entry_field(v, e, partition_domain)
+#define entry_type(v, e) entry_field(v, e, partition_type)
+
+/* Parse memory map from SMEM, return the number of entries */
+static int qcom_parse_memory_smem(phys_addr_t *ram_end)
+{
+	size_t size;
+	int i, j = 0, ret;
+	struct usable_ram_partition_table_header *header;
+	u32 ver;
+	void *entry;
+	u32 entry_size; // Size of each RAM partition entry (version dependent)
+
+	ret = qcom_smem_init();
+	if (ret) {
+		debug("Failed to initialize SMEM: %d.\n", ret);
+		return ret;
+	}
+
+	header = qcom_smem_get(QCOM_SMEM_HOST_ANY, SMEM_USABLE_RAM_PARTITION_TABLE, &size);
+	if (!header) {
+		debug("Failed to find SMEM partition.\n");
+		return -ENODEV;
+	}
+
+	ver = header->version;
+	debug("SMEM RAM partition table version %u. %u entries\n", ver, header->num_partitions);
+
+	switch (ver) {
+	case 0:
+		entry_size = sizeof(struct ram_partition_entry_v0);
+		entry = ((struct usable_ram_partition_table_v0 *)header)->entries;
+		break;
+	case 1:
+		entry_size = sizeof(struct ram_partition_entry_v1);
+		entry = ((struct usable_ram_partition_table_v1 *)header)->entries;
+		break;
+	default:
+		pr_warn("Unknown SMEM ram partition table version!\n");
+	case 2:
+	case 3:
+		entry_size = sizeof(struct ram_partition_entry_v3);
+		entry = ((struct usable_ram_partition_table_v3 *)header)->entries;
+		break;
+	}
+
+	debug("SMEM RAM partition entry size: %u bytes\n", entry_size);
+
+	/* Check validy of RAM */
+	for (i = 0; i < header->num_partitions && j < CONFIG_NR_DRAM_BANKS; i++, entry += entry_size) {
+		debug("Entry %d: [%#010llx - %#010llx]\n", i, entry_start(ver, entry),
+		      (u64)entry_start(ver, entry) + entry_length(ver, entry));
+		debug("          cat: %#04x type: %#04x domain: %#04x\n", entry_category(ver, entry),
+		      entry_type(ver, entry), entry_domain(ver, entry));
+
+
+		if (entry_category(ver, entry) != RAM_PARTITION_SDRAM ||
+		    entry_type(ver, entry) != RAM_PARTITION_SYS_MEMORY)
+			continue;
+		if (!entry_length(ver, entry) && !entry_start(ver, entry))
+			break;
+
+		prevbl_ddr_banks[j].start = entry_start(ver, entry);
+		prevbl_ddr_banks[j].size = entry_length(ver, entry);
+		*ram_end = max(*ram_end, prevbl_ddr_banks[j].start + prevbl_ddr_banks[j].size);
+		j++;
+	}
+
+	if (j == CONFIG_NR_DRAM_BANKS)
+		pr_err("SMEM: More than CONFIG_NR_DRAM_BANKS (%u) entries!", CONFIG_NR_DRAM_BANKS);
+
+	return j;
+}
+
+static void qcom_parse_memory_dt(const fdt64_t *fdt, int *banks, phys_addr_t *ram_end)
+{
+	int offset;
+	const fdt64_t *memory;
+	int memsize;
+	int i, j;
+
+	*ram_end = 0;
+
+	offset = fdt_path_offset(fdt, "/memory");
+	if (offset < 0)
+		return;
+
+	memory = fdt_getprop(fdt, offset, "reg", &memsize);
+	if (!memory)
+		return;
+
+	*banks = min(memsize / (2 * sizeof(u64)), (ulong)CONFIG_NR_DRAM_BANKS);
+
+	if (memsize / sizeof(u64) > CONFIG_NR_DRAM_BANKS * 2)
+		log_err("Provided more than the max of %d memory banks\n", CONFIG_NR_DRAM_BANKS);
+
+	if (*banks > CONFIG_NR_DRAM_BANKS)
+		log_err("Provided more memory banks than we can handle\n");
+
+	for (i = 0, j = 0; i < *banks * 2; i += 2, j++) {
+		prevbl_ddr_banks[j].start = get_unaligned_be64(&memory[i]);
+		prevbl_ddr_banks[j].size = get_unaligned_be64(&memory[i + 1]);
+		if (!prevbl_ddr_banks[j].size) {
+			j--;
+			continue;
+		}
+		*ram_end = max(*ram_end, prevbl_ddr_banks[j].start + prevbl_ddr_banks[j].size);
+	}
+}
+
 /**
  * The generic memory parsing code in U-Boot lacks a few things that we
  * need on Qualcomm:
  *
@@ -76,48 +200,36 @@ int dram_init_banksize(void)
  * We can't use fdtdec_setup_memory_banksize() since it stores the result in
  * gd->bd, which is not yet allocated.
  *
  * @fdt: FDT blob to parse /memory node from
+ * @fdt_is_internal: is the FDT one embedded into U-Boot or was it provided by a prior
+ *		     bootloader stage? This determined if we should try to rely on SMEM
+ *		     (internal FDT) or error. We currently assume that if we are passed
+ *		     an external FDT then it already has the memory map populated.
  *
  * Return: 0 on success or -ENODATA if /memory node is missing or incomplete
  */
-int qcom_parse_memory(const void *fdt)
+int qcom_parse_memory(const void *fdt, bool fdt_is_internal)
 {
-	int offset;
-	const fdt64_t *memory;
-	int memsize;
 	phys_addr_t ram_end = 0;
-	int i, j, banks;
+	int banks;
 
-	offset = fdt_path_offset(fdt, "/memory");
-	if (offset < 0)
-		return -ENODATA;
+	qcom_memmap_source = fdt_is_internal ? QCOM_MEMMAP_SOURCE_INTERNAL_FDT
+					     : QCOM_MEMMAP_SOURCE_EXTERNAL_FDT;
 
-	memory = fdt_getprop(fdt, offset, "reg", &memsize);
-	if (!memory)
-		return -ENODATA;
+	qcom_parse_memory_dt(fdt, &banks, &ram_end);
 
-	banks = min(memsize / (2 * sizeof(u64)), (ulong)CONFIG_NR_DRAM_BANKS);
-
-	if (memsize / sizeof(u64) > CONFIG_NR_DRAM_BANKS * 2)
-		log_err("Provided more than the max of %d memory banks\n", CONFIG_NR_DRAM_BANKS);
-
-	if (banks > CONFIG_NR_DRAM_BANKS)
-		log_err("Provided more memory banks than we can handle\n");
-
-	for (i = 0, j = 0; i < banks * 2; i += 2, j++) {
-		prevbl_ddr_banks[j].start = get_unaligned_be64(&memory[i]);
-		prevbl_ddr_banks[j].size = get_unaligned_be64(&memory[i + 1]);
-		if (!prevbl_ddr_banks[j].size) {
-			j--;
-			continue;
-		}
-		ram_end = max(ram_end, prevbl_ddr_banks[j].start + prevbl_ddr_banks[j].size);
+	/*
+	 * If using an internal FDT but the memory node is empty
+	 * then fall back to SMEM.
+	 */
+	if (!prevbl_ddr_banks[0].size && fdt_is_internal) {
+		banks = qcom_parse_memory_smem(&ram_end);
+		if (banks < 0)
+			panic("Couldn't find a valid memory map!\n");
+		qcom_memmap_source = QCOM_MEMMAP_SOURCE_SMEM;
 	}
 
-	if (!banks || !prevbl_ddr_banks[0].size)
-		return -ENODATA;
-
 	/* Sort our RAM banks -_- */
 	qsort(prevbl_ddr_banks, banks, sizeof(prevbl_ddr_banks[0]), ddr_bank_cmp);
 
 	gd->ram_base = prevbl_ddr_banks[0].start;
diff --git a/arch/arm/mach-snapdragon/qcom-priv.h b/arch/arm/mach-snapdragon/qcom-priv.h
index ce409314a98b..39dc8fcc76ad 100644
--- a/arch/arm/mach-snapdragon/qcom-priv.h
+++ b/arch/arm/mach-snapdragon/qcom-priv.h
@@ -2,8 +2,10 @@
 
 #ifndef __QCOM_PRIV_H__
 #define __QCOM_PRIV_H__
 
+#include <stdbool.h>
+
 /**
  * enum qcom_boot_source - Track where we got loaded from.
  * Used for capsule update logic.
  *
@@ -16,13 +18,26 @@ enum qcom_boot_source {
 };
 
 extern enum qcom_boot_source qcom_boot_source;
 
+/*
+ * enum qcom_memmap_source - Track where we got the memory map from.
+ * used for debugging and validation.
+ */
+enum qcom_memmap_source {
+	QCOM_MEMMAP_SOURCE_INTERNAL_FDT = 1,
+	QCOM_MEMMAP_SOURCE_EXTERNAL_FDT,
+	QCOM_MEMMAP_SOURCE_SMEM,
+};
+
+/* Set by qcom_parse_memory() */
+extern enum qcom_memmap_source qcom_memmap_source;
+
 #if IS_ENABLED(CONFIG_EFI_HAVE_CAPSULE_SUPPORT)
 void qcom_configure_capsule_updates(void);
 #else
 void qcom_configure_capsule_updates(void) {}
 #endif /* EFI_HAVE_CAPSULE_SUPPORT */
 
-int qcom_parse_memory(const void *fdt);
+int qcom_parse_memory(const void *fdt, bool fdt_is_internal);
 
 #endif /* __QCOM_PRIV_H__ */
diff --git a/arch/arm/mach-snapdragon/rampart.h b/arch/arm/mach-snapdragon/rampart.h
new file mode 100644
index 000000000000..57f3dbb7eec0
--- /dev/null
+++ b/arch/arm/mach-snapdragon/rampart.h
@@ -0,0 +1,194 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * RAM partition table definitions
+ *
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ *
+ */
+
+#ifndef __QCOM_SMEM_RAMPART_H__
+#define __QCOM_SMEM_RAMPART_H__
+
+#include <linux/types.h>
+
+#define SMEM_USABLE_RAM_PARTITION_TABLE		402
+
+#define RAM_PARTITION_H_MAJOR  03
+#define RAM_PARTITION_H_MINOR  00
+
+/**
+ * Total length of zero filled name string. This is not a C
+ * string, as it can occupy the total number of bytes, and if
+ * it does, it does not require a zero terminator. It cannot
+ * be manipulated with standard string handling library functions.
+ */
+#define RAM_PART_NAME_LENGTH 16
+
+/**
+ * Number of RAM partition entries which are usable by APPS.
+ */
+#define RAM_NUM_PART_ENTRIES 32
+
+/**
+ * @name: Magic numbers
+ * Used in identifying valid RAM partition table.
+ */
+#define RAM_PART_MAGIC1     0x9da5e0a8
+#define RAM_PART_MAGIC2     0xaf9ec4e2
+
+/**
+ * RAM partition attributes.
+ */
+enum ram_partition_attribute_t {
+	RAM_PARTITION_READ_ONLY = 0,       /* Read-only RAM partition */
+	RAM_PARTITION_READWRITE,           /* Read/write RAM partition */
+};
+
+/**
+ * RAM partition categories.
+ */
+enum ram_partition_category_t {
+	RAM_PARTITION_IRAM = 4,                   /* IRAM RAM partition */
+	RAM_PARTITION_IMEM = 5,                   /* IMEM RAM partition */
+	RAM_PARTITION_SDRAM = 14,                  /* SDRAM type without specific bus information**/
+};
+
+/**
+ * RAM Partition domains.
+ * @note: For shared RAM partition, domain value would be 0b11:\n
+ * RAM_PARTITION_APPS_DOMAIN | RAM_PARTITION_MODEM_DOMAIN.
+ */
+enum ram_partition_domain_t {
+	RAM_PARTITION_DEFAULT_DOMAIN = 0,  /* 0b00: No specific domain definition */
+	RAM_PARTITION_APPS_DOMAIN = 1,     /* 0b01: APPS RAM partition */
+	RAM_PARTITION_MODEM_DOMAIN = 2,    /* 0b10: MODEM RAM partition */
+};
+
+/**
+ * RAM Partition types.
+ * @note: The RAM_PARTITION_SYS_MEMORY type represents DDR rams that are attached
+ * to the current system.
+ */
+enum ram_partition_type_t {
+	RAM_PARTITION_SYS_MEMORY = 1,        /* system memory */
+	RAM_PARTITION_BOOT_REGION_MEMORY1,   /* boot loader memory 1 */
+	RAM_PARTITION_BOOT_REGION_MEMORY2,   /* boot loader memory 2, reserved */
+	RAM_PARTITION_APPSBL_MEMORY,         /* apps boot loader memory */
+	RAM_PARTITION_APPS_MEMORY,           /* apps usage memory */
+	RAM_PARTITION_TOOLS_FV_MEMORY,       /* tools usage memory */
+	RAM_PARTITION_QUANTUM_FV_MEMORY,     /* quantum usage memory */
+	RAM_PARTITION_QUEST_FV_MEMORY,       /* quest usage memory */
+};
+
+/* Common table header between versions */
+struct usable_ram_partition_table_header {
+	u32 magic1;          /* Magic number to identify valid RAM partition table */
+	u32 magic2;          /* Magic number to identify valid RAM partition table */
+	u32 version;         /* Version number to track structure definition changes */
+	u32 reserved1;       /* Reserved for future use */
+
+	u32 num_partitions;  /* Number of RAM partition table entries */
+};
+
+/* Holds information for an entry in the RAM partition table */
+struct ram_partition_entry_v3 {
+	char name[RAM_PART_NAME_LENGTH];  /* Partition name, unused for now */
+	u64 start_address;                /* Partition start address in RAM */
+	u64 length;                       /* Partition length in RAM in Bytes */
+	u32 partition_attribute;          /* Partition attribute */
+	u32 partition_category;           /* Partition category */
+	u32 partition_domain;             /* Partition domain */
+	u32 partition_type;               /* Partition type */
+	u32 num_partitions;               /* Number of partitions on device */
+	u32 hw_info;                      /* hw information such as type and frequency */
+	u8 highest_bank_bit;              /* Highest bit corresponding to a bank */
+	u8 reserve0;                      /* Reserved for future use */
+	u8 reserve1;                      /* Reserved for future use */
+	u8 reserve2;                      /* Reserved for future use */
+	u32 min_pasr_size;                /* Minimum PASR size in MB */
+	u64 available_length;             /* Available Partition length in RAM in Bytes */
+};
+
+/*
+ * Defines the RAM partition table structure
+ *
+ * Do not change the placement of the first four elements so that future
+ * compatibility will always be guaranteed at least for the identifiers.
+ *
+ * The other portion of the structure may be changed as necessary to accommodate
+ * new features. Be sure to increment version number if you change it.
+ */
+struct usable_ram_partition_table_v3 {
+	struct usable_ram_partition_table_header header;
+
+	u32 reserved2;       /* Added for 8 bytes alignment of header */
+
+	/* RAM partition table entries */
+	struct ram_partition_entry_v3 entries[RAM_NUM_PART_ENTRIES];
+};
+
+/* Version 1 structure 32 Bit - Holds information for an entry in the RAM partition table */
+struct ram_partition_entry_v1 {
+	char name[RAM_PART_NAME_LENGTH];  /* Partition name, unused for now */
+	u64 start_address;                /* Partition start address in RAM */
+	u64 length;                       /* Partition length in RAM in Bytes */
+	u32 partition_attribute;          /* Partition attribute */
+	u32 partition_category;           /* Partition category */
+	u32 partition_domain;             /* Partition domain */
+	u32 partition_type;               /* Partition type */
+	u32 num_partitions;               /* Number of partitions on device */
+	u32 hw_info;                      /* hw information such as type and frequency */
+	u32 reserved4;                    /* Reserved for future use */
+	u32 reserved5;                    /* Reserved for future use */
+};
+
+/*
+ * Defines the RAM partition table structure (Version 1)
+ *
+ * Do not change the placement of the first four elements so that future
+ * compatibility will always be guaranteed at least for the identifiers.
+ *
+ * The other portion of the structure may be changed as necessary to accommodate
+ * new features. Be sure to increment version number if you change it.
+ */
+struct usable_ram_partition_table_v1 {
+	struct usable_ram_partition_table_header header;
+
+	u32 reserved2;       /* Added for 8 bytes alignment of header */
+
+	/* RAM partition table entries */
+	struct ram_partition_entry_v1 entries[RAM_NUM_PART_ENTRIES];
+};
+
+/* Version 0 structure 32 Bit - Holds information for an entry in the RAM partition table */
+struct ram_partition_entry_v0 {
+	char name[RAM_PART_NAME_LENGTH];  /* Partition name, unused for now */
+	u32 start_address;                /* Partition start address in RAM */
+	u32 length;                       /* Partition length in RAM in Bytes */
+	u32 partition_attribute;          /* Partition attribute */
+	u32 partition_category;           /* Partition category */
+	u32 partition_domain;             /* Partition domain */
+	u32 partition_type;               /* Partition type */
+	u32 num_partitions;               /* Number of partitions on device */
+	u32 reserved3;                    /* Reserved for future use */
+	u32 reserved4;                    /* Reserved for future use */
+	u32 reserved5;                    /* Reserved for future use */
+};
+
+/*
+ * Defines the RAM partition table structure (Version 0)
+ *
+ * Do not change the placement of the first four elements so that future
+ * compatibility will always be guaranteed at least for the identifiers.
+ *
+ * The other portion of the structure may be changed as necessary to accommodate
+ * new features. Be sure to increment version number if you change it.
+ */
+struct usable_ram_partition_table_v0 {
+	struct usable_ram_partition_table_header header;
+
+	/* RAM partition table entries */
+	struct ram_partition_entry_v0 entries[RAM_NUM_PART_ENTRIES];
+};
+
+#endif // __QCOM_SMEM_RAMPART_H__

-- 
2.53.0



More information about the U-Boot mailing list