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

Neil Armstrong neil.armstrong at linaro.org
Mon May 18 16:48:56 CEST 2026


On 5/4/26 20:57, Casey Connolly wrote:
> 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)

Re-order the variables since you'll send a v3

> +
> +	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));
> +
> +

Drop empty line

> +		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;
> +}

Undef the entry_* macros after ?

> +
> +static void qcom_parse_memory_dt(const fdt64_t *fdt, int *banks, phys_addr_t *ram_end)
> +{
> +	int offset;
> +	const fdt64_t *memory;

move this one first

> +	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__
> 

Thanks,
Neil


More information about the U-Boot mailing list