[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