soc/qualcomm/common: Add MMU configuration for fragmented DRAM regions
Stating with Qualcomm X1P42100 SoC generation, the DRAM memory map is not expected to be contiguous (unlike previous generations) therefore, the memory map could be something like this. 1. Assume hardware design has 4GB of DRAM then the memory map would look like: - DDR_SPACE (2 GB) : 0x80000000 - 0x100000000 - DDR_SPACE_1 (2 GB) : 0x880000000 - 0x900000000 2. Assume hardware design has 16GB of DRAM then the memory map would look like: - DDR_SPACE (2 GB) : 0x80000000 - 0x100000000 - DDR_SPACE_1 (14 GB) : 0x880000000 - 0x400000000 3. Assume hardware design has 64GB of DRAM then the memory map would look like: - DDR_SPACE (2 GB) : 0x80000000 - 0x100000000 - DDR_SPACE_1 (30 GB) : 0x880000000 - 0x1000000000 - DDR_SPACE_2 (32 GB) : 0x8800000000 - 0x9000000000 This commit introduces logic to handle systems with fragmented DRAM configurations. Previously, the Memory Management Unit (MMU) was configured assuming a single, contiguous block of DRAM. This change extends the MMU setup to properly configure multiple, non-contiguous DRAM regions. The changes include: - Declaring dram_space_1 and dram_space_2 as optional regions, allowing the dynamic allocation for these DRAM ranges based on DRAM capacity of the platform. - Introduce `qc_get_soc_dram_space_config` function that takes care of DRAM based resource splitting as per `_dram`, `_dram_space_1` and `_dram_space_2` region limit. - Modifying qc_mmu_dram_config_post_dram_init() to check for these optional regions and configure them individually. This ensures all available DRAM is correctly mapped and accessible to the system. This approach improves flexibility and allows coreboot to support a wider range of Qualcomm platforms with different memory layouts. TEST=Able to boot google/quenbi to OS. Change-Id: If3788f4c77535f9a5e47ad2034ab9a8e0fe85b51 Signed-off-by: Subrata Banik <subratabanik@google.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/88752 Reviewed-by: Kapil Porwal <kapilporwal@google.com> Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
parent
b4347f11d9
commit
276432faf7
3 changed files with 62 additions and 3 deletions
|
|
@ -12,6 +12,7 @@
|
|||
|
||||
static struct region * const ddr_region = (struct region *)_ddr_information;
|
||||
|
||||
struct region *qc_get_soc_dram_space_config(size_t ddr_size, int *count);
|
||||
void soc_mmu_dram_config_post_dram_init(void);
|
||||
void qc_mmu_dram_config_post_dram_init(size_t ddr_size);
|
||||
bool soc_modem_carve_out(void **start, void **end);
|
||||
|
|
|
|||
|
|
@ -32,4 +32,12 @@ DECLARE_REGION(dram_modem)
|
|||
DECLARE_REGION(dram_tz)
|
||||
DECLARE_REGION(dram_tz_rem)
|
||||
|
||||
/*
|
||||
* DDR_SPACE (2 GB) aka `_dram`: 0x80000000 - 0x100000000
|
||||
* DDR_SPACE_1 (30 GB) aka `_dram_space_1`: 0x880000000 - 0x1000000000
|
||||
* DDR_SPACE_2 (480 GB) aka `dram_space_2`: 0x8800000000 - 0x10000000000
|
||||
*/
|
||||
DECLARE_OPTIONAL_REGION(dram_space_1)
|
||||
DECLARE_OPTIONAL_REGION(dram_space_2)
|
||||
|
||||
#endif // _SOC_QUALCOMM_SYMBOLS_COMMON_H_
|
||||
|
|
|
|||
|
|
@ -1,22 +1,72 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
#include <arch/mmu.h>
|
||||
#include <console/console.h>
|
||||
#include <soc/mmu.h>
|
||||
#include <soc/mmu_common.h>
|
||||
#include <soc/symbols_common.h>
|
||||
|
||||
/* DRAM region: DDR_SPACE, DDR_SPACE_1 and DDR_SPACE_2 */
|
||||
#define MAX_DRAM_SPACE_INDEX 3
|
||||
|
||||
__weak bool soc_modem_carve_out(void **start, void **end) { return false; }
|
||||
|
||||
struct region *qc_get_soc_dram_space_config(size_t ddr_size, int *count)
|
||||
{
|
||||
static struct region config[MAX_DRAM_SPACE_INDEX];
|
||||
static int populated_count = 0;
|
||||
int i;
|
||||
|
||||
if (!populated_count) {
|
||||
void *region_start[MAX_DRAM_SPACE_INDEX] = {
|
||||
_dram,
|
||||
_dram_space_1,
|
||||
_dram_space_2
|
||||
};
|
||||
size_t size[MAX_DRAM_SPACE_INDEX] = {
|
||||
REGION_SIZE(dram),
|
||||
REGION_SIZE(dram_space_1),
|
||||
REGION_SIZE(dram_space_2)
|
||||
};
|
||||
|
||||
/* Handle the case where DDR space is contiguous */
|
||||
if (!_edram)
|
||||
size[0] = ddr_size;
|
||||
|
||||
for (i = 0; i < MAX_DRAM_SPACE_INDEX && ddr_size > 0; i++) {
|
||||
config[i].offset = (size_t)region_start[i];
|
||||
size_t to_map = MIN(ddr_size, size[i]);
|
||||
config[i].size = to_map;
|
||||
ddr_size -= to_map;
|
||||
}
|
||||
|
||||
populated_count = i;
|
||||
|
||||
if (ddr_size)
|
||||
printk(BIOS_CRIT, "Too much DRAM for available windows (%zu bytes left over)!\n",
|
||||
ddr_size);
|
||||
}
|
||||
|
||||
*count = populated_count;
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
void qc_mmu_dram_config_post_dram_init(size_t ddr_size)
|
||||
{
|
||||
void *start = NULL;
|
||||
void *end = NULL;
|
||||
|
||||
if (!soc_modem_carve_out(&start, &end)) {
|
||||
mmu_config_range((void *)_dram, ddr_size, CACHED_RAM);
|
||||
} else {
|
||||
if (soc_modem_carve_out(&start, &end)) {
|
||||
if (_dram_space_1)
|
||||
die("Using carve out together with DRAM windows not supported");
|
||||
mmu_config_range((void *)_dram, start - (void *)_dram, CACHED_RAM);
|
||||
mmu_config_range(end, (void *)_dram + ddr_size - end, CACHED_RAM);
|
||||
} else {
|
||||
int count;
|
||||
struct region *config = qc_get_soc_dram_space_config(ddr_size, &count);
|
||||
for (int i = 0; i < count; i++)
|
||||
mmu_config_range((void *)config[i].offset, config[i].size, CACHED_RAM);
|
||||
}
|
||||
|
||||
mmu_config_range((void *)_aop_code_ram, REGION_SIZE(aop_code_ram),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue