From 1b760645b932d217d99224b5b7854a5c8ca33e4b Mon Sep 17 00:00:00 2001 From: Subrata Banik Date: Fri, 15 Aug 2025 00:51:57 +0530 Subject: [PATCH] soc/qc/x1p42100: Dynamically configure DRAM resources in ramstage This commit updates the x1p42100 platform to support a dynamic memory layout for DRAM. This is a crucial step toward supporting different board variants with varying memory capacities. The changes involve: - ramstage build: The mmu.c source file is now included in the ramstage build, providing the necessary functions to configure the Memory Management Unit (MMU) for fragmented memory regions. - Linker Script (memlayout.ld): The dram_space_1 and dram_space_2 regions are statically defined with their maximum possible sizes. - SoC Initialization (soc.c): The soc_read_resources function is refactored to use a new helper function, qc_get_soc_dram_space_config, to retrieve a list of available DRAM regions. It then iterates through this list to dynamically register each memory region with ram_range. This replaces the previous static ram_range call with a more flexible approach that can handle fragmented memory maps. Reserved regions are also updated to use a dynamic index. This refactoring allows the system to correctly handle memory maps for devices with more than 2GB of DRAM, which was a limitation of the previous static configuration. TEST=Able to build and boot google/quenbi w/ 16GB of DRAM (using DDR_SPACE and DDR_SPACE_1 regions). Change-Id: If94644110272713f77db5a0dd6d23ec0798a15f0 Signed-off-by: Subrata Banik Reviewed-on: https://review.coreboot.org/c/coreboot/+/88753 Reviewed-by: Kapil Porwal Tested-by: build bot (Jenkins) --- src/soc/qualcomm/x1p42100/Makefile.mk | 1 + src/soc/qualcomm/x1p42100/memlayout.ld | 19 +++++++++++++++++++ src/soc/qualcomm/x1p42100/soc.c | 20 ++++++++++++++------ 3 files changed, 34 insertions(+), 6 deletions(-) diff --git a/src/soc/qualcomm/x1p42100/Makefile.mk b/src/soc/qualcomm/x1p42100/Makefile.mk index 62930c9c33..d96dd8d760 100644 --- a/src/soc/qualcomm/x1p42100/Makefile.mk +++ b/src/soc/qualcomm/x1p42100/Makefile.mk @@ -40,6 +40,7 @@ romstage-$(CONFIG_DRIVERS_UART) += ../common/qupv3_uart.c ################################################################################ ramstage-y += soc.c ramstage-y += cbmem.c +ramstage-y += ../common/mmu.c ramstage-$(CONFIG_DRIVERS_UART) += ../common/qupv3_uart.c ramstage-$(CONFIG_PCI) += ../common/pcie_common.c ramstage-$(CONFIG_PCI) += pcie.c diff --git a/src/soc/qualcomm/x1p42100/memlayout.ld b/src/soc/qualcomm/x1p42100/memlayout.ld index 27f4be7e1a..ea21c27331 100644 --- a/src/soc/qualcomm/x1p42100/memlayout.ld +++ b/src/soc/qualcomm/x1p42100/memlayout.ld @@ -65,4 +65,23 @@ SECTIONS REGION(dram_tz, 0xD8000000, 0xD6000, 0x1000) BL31(0xD80D6000, 1M) REGION(dram_tz_rem, 0xD81D6000, 0x72EA000, 0x1000) + DRAM_END(0x100000000) + + /* + * Define the address range limits for fragmented DRAM regions. + * + * These regions, `dram_space_1` and `dram_space_2`, are used to map physical + * memory beyond the initial `_dram` region. The MMU configuration logic in + * `mmu.c` uses `REGION_SIZE()` to dynamically size these ranges based on the + * total system DRAM capacity, which is determined by the QCLib. + * + * Example for a 16GB DRAM system: + * - `_dram` (2GB): 0x80000000 - 0x100000000 + * - `_dram_space_1` (14GB): 0x880000000 - 0x440000000 (0x880000000 + 14GB) + * + * Note: The example memory addresses are for illustration and depend on the + * platform's specific memory map. + */ + REGION(dram_space_1, 0x880000000, 0x780000000, 4K) + REGION(dram_space_2, 0x8800000000, 0x7800000000, 4K) } diff --git a/src/soc/qualcomm/x1p42100/soc.c b/src/soc/qualcomm/x1p42100/soc.c index a30c1b0ba4..fd429cc465 100644 --- a/src/soc/qualcomm/x1p42100/soc.c +++ b/src/soc/qualcomm/x1p42100/soc.c @@ -12,16 +12,24 @@ static struct device_operations pci_domain_ops = { .scan_bus = &pci_host_bridge_scan_bus, .enable = &qcom_setup_pcie_host, }; + static void soc_read_resources(struct device *dev) { - ram_range(dev, 0, (uintptr_t)region_offset(ddr_region), region_sz(ddr_region)); - reserved_ram_range(dev, 1, (uintptr_t)_dram_cpucp_dtbs, REGION_SIZE(dram_cpucp_dtbs)); - reserved_ram_range(dev, 2, (uintptr_t)_dram_cpucp, REGION_SIZE(dram_cpucp)); + int index = 0; + int count; + struct region *config = qc_get_soc_dram_space_config(region_sz(ddr_region), + &count); - reserved_ram_range(dev, 3, (uintptr_t)_dram_tz, REGION_SIZE(dram_tz)); - reserved_ram_range(dev, 4, (uintptr_t)_dram_tz_rem, REGION_SIZE(dram_tz_rem)); + for (int i = 0; i < count; i++) + ram_range(dev, index++, (uintptr_t)config[i].offset, config[i].size); - reserved_ram_range(dev, 5, (uintptr_t)_dram_aop, REGION_SIZE(dram_aop)); + reserved_ram_range(dev, index++, (uintptr_t)_dram_cpucp_dtbs, REGION_SIZE(dram_cpucp_dtbs)); + reserved_ram_range(dev, index++, (uintptr_t)_dram_cpucp, REGION_SIZE(dram_cpucp)); + + reserved_ram_range(dev, index++, (uintptr_t)_dram_tz, REGION_SIZE(dram_tz)); + reserved_ram_range(dev, index++, (uintptr_t)_dram_tz_rem, REGION_SIZE(dram_tz_rem)); + + reserved_ram_range(dev, index++, (uintptr_t)_dram_aop, REGION_SIZE(dram_aop)); } static void soc_init(struct device *dev)