Implemented platform-specific reserved memory registration for EFI on Qualcomm Snapdragon platforms. This adds SoC-specific memory regions to the EFI memory map.
Added qcom_reserved_memory.c with predefined memory regions for QCS615 and QCM6490/SC7280 SoCs. The implementation detects the SoC type from device tree and registers appropriate memory regions via efi_add_memory_map(). Implemented efi_add_known_memory() in board.c to hook into the EFI memory initialization. Signed-off-by: Balaji Selvanathan <[email protected]> --- arch/arm/mach-snapdragon/Makefile | 1 + arch/arm/mach-snapdragon/board.c | 15 +++ arch/arm/mach-snapdragon/qcom-priv.h | 10 ++ .../mach-snapdragon/qcom_reserved_memory.c | 114 ++++++++++++++++++ 4 files changed, 140 insertions(+) create mode 100644 arch/arm/mach-snapdragon/qcom_reserved_memory.c diff --git a/arch/arm/mach-snapdragon/Makefile b/arch/arm/mach-snapdragon/Makefile index 343e825c6fd..19820a075e8 100644 --- a/arch/arm/mach-snapdragon/Makefile +++ b/arch/arm/mach-snapdragon/Makefile @@ -4,4 +4,5 @@ obj-y += board.o obj-$(CONFIG_EFI_HAVE_CAPSULE_SUPPORT) += capsule_update.o +obj-$(CONFIG_EFI_LOADER) += qcom_reserved_memory.o obj-$(CONFIG_OF_LIVE) += of_fixup.o diff --git a/arch/arm/mach-snapdragon/board.c b/arch/arm/mach-snapdragon/board.c index 5fb3240acc5..0259623d382 100644 --- a/arch/arm/mach-snapdragon/board.c +++ b/arch/arm/mach-snapdragon/board.c @@ -709,6 +709,21 @@ static void carve_out_reserved_memory(void) } } +#ifdef CONFIG_EFI_LOADER +/** + * efi_add_known_memory() - Add platform-specific reserved memory to EFI map + * + * This function is called by the EFI memory initialization code to allow + * platforms to add their reserved memory regions to the EFI memory map. + * For Qualcomm platforms, this delegates to qcom_add_reserved_memory_to_efi() + * which handles SoC-specific reserved memory regions. + */ +void efi_add_known_memory(void) +{ + qcom_add_reserved_memory_to_efi(); +} +#endif /* CONFIG_EFI_LOADER */ + /* This function open-codes setup_all_pgtables() so that we can * insert additional mappings *before* turning on the MMU. */ diff --git a/arch/arm/mach-snapdragon/qcom-priv.h b/arch/arm/mach-snapdragon/qcom-priv.h index b8bf574e8bb..b488516cfdb 100644 --- a/arch/arm/mach-snapdragon/qcom-priv.h +++ b/arch/arm/mach-snapdragon/qcom-priv.h @@ -17,6 +17,16 @@ enum qcom_boot_source { extern enum qcom_boot_source qcom_boot_source; +#if IS_ENABLED(CONFIG_EFI_LOADER) +/** + * qcom_add_reserved_memory_to_efi() - Add Qualcomm SoC reserved memory to EFI + * + * This function detects the SoC type and adds the appropriate reserved + * memory regions to the EFI memory map. Called from efi_add_known_memory(). + */ +void qcom_add_reserved_memory_to_efi(void); +#endif /* CONFIG_EFI_LOADER */ + #if IS_ENABLED(CONFIG_EFI_HAVE_CAPSULE_SUPPORT) void qcom_configure_capsule_updates(void); #else diff --git a/arch/arm/mach-snapdragon/qcom_reserved_memory.c b/arch/arm/mach-snapdragon/qcom_reserved_memory.c new file mode 100644 index 00000000000..e670f74bc1f --- /dev/null +++ b/arch/arm/mach-snapdragon/qcom_reserved_memory.c @@ -0,0 +1,114 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include <efi_loader.h> +#include <fdt_support.h> +#include <log.h> +#include <linux/sizes.h> +#include <asm/global_data.h> +#include "qcom-priv.h" + +DECLARE_GLOBAL_DATA_PTR; + +/** + * struct reserved_mem_region - Reserved memory region descriptor + * @start: Physical start address of the region + * @size: Size of the region in bytes + * @name: Human-readable name for logging + */ +struct reserved_mem_region { + u64 start; + u64 size; + const char *name; +}; + +/* QCS615 reserved memory regions */ +static const struct reserved_mem_region qcs615_reserved[] = { + { 0x80000000, 0x600000, "hyp" }, + { 0x85D00000, 0x200000, "boot" }, + { 0x85F00000, 0x20000, "aop" }, + { 0x85F40000, 0x30000, "xbl_dt" }, + { 0x86200000, 0x100000, "tz_stat" }, + { 0x86300000, 0x1200000, "tags" }, + { 0x87500000, 0x500000, "tz" }, + { 0x87A00000, 0x1C00000, "tzapps" }, + { 0x8AB00000, 0xCC17000, "pil" }, + { 0xA0000000, 0x1600000, "secure_dsp" }, +}; + +/* SC7280/QCM6490 reserved memory regions */ +static const struct reserved_mem_region sc7280_reserved[] = { + { 0x80600000, 0x100000, "axon_dma" }, + { 0x80894000, 0x40000, "xbl_dt" }, + { 0x84300000, 0x16B00000, "pil_reserved" }, + { 0xE1000000, 0x2400000, "display" }, +}; + +/** + * add_soc_reserved_memory() - Add SoC-specific reserved memory to EFI map + * @regions: Array of reserved memory regions + * @count: Number of regions in the array + * @soc_name: SoC name for logging + * + * This function iterates through the provided reserved memory regions and + * adds them to the EFI memory map with type EFI_RESERVED_MEMORY_TYPE. + */ +static void add_soc_reserved_memory(const struct reserved_mem_region *regions, + int count, const char *soc_name) +{ + int i; + + log_debug("Adding %s reserved memory to EFI map (%d regions)\n", + soc_name, count); + + for (i = 0; i < count; i++) { + efi_status_t ret; + + ret = efi_add_memory_map(regions[i].start, + regions[i].size, + EFI_RESERVED_MEMORY_TYPE); + + if (ret != EFI_SUCCESS) { + log_err("%s: Failed to reserve %s (0x%llx-0x%llx): %lu\n", + soc_name, regions[i].name, + regions[i].start, + regions[i].start + regions[i].size, + ret & ~EFI_ERROR_MASK); + } else { + log_debug("%s: Reserved %s: 0x%llx-0x%llx (%llu KB)\n", + soc_name, regions[i].name, + regions[i].start, + regions[i].start + regions[i].size, + regions[i].size / 1024); + } + } +} + +/** + * qcom_add_reserved_memory_to_efi() - Add Qualcomm SoC reserved memory to EFI + * + * This function detects the SoC type from the device tree and adds the + * appropriate reserved memory regions to the EFI memory map. + * + * Supported SoCs: + * - QCS615 (Talos) + * - QCM6490/SC7280 (Kodiak) + */ +void qcom_add_reserved_memory_to_efi(void) +{ + /* Detect SoC and add appropriate reserved memory */ + if (fdt_node_check_compatible(gd->fdt_blob, 0, "qcom,qcs615") == 0) { + add_soc_reserved_memory(qcs615_reserved, + ARRAY_SIZE(qcs615_reserved), + "QCS615"); + } else if (fdt_node_check_compatible(gd->fdt_blob, 0, "qcom,qcm6490") == 0 || + fdt_node_check_compatible(gd->fdt_blob, 0, "qcom,sc7280") == 0) { + add_soc_reserved_memory(sc7280_reserved, + ARRAY_SIZE(sc7280_reserved), + "QCM6490/SC7280"); + } else { + log_debug("No SoC-specific reserved memory to add\n"); + } +} -- 2.34.1

