1 // SPDX-License-Identifier: GPL-2.0+
3 * Copyright (C) 2019 Intel Corporation <www.intel.com>
8 #include <asm/global_data.h>
9 #include <linux/sizes.h>
11 #include <asm/arch/slimbootloader.h>
13 DECLARE_GLOBAL_DATA_PTR;
16 * This returns a data pointer of memory map info from the guid hob.
18 * @return: A data pointer of memory map info hob
20 static struct sbl_memory_map_info *get_memory_map_info(void)
22 struct sbl_memory_map_info *data;
23 const efi_guid_t guid = SBL_MEMORY_MAP_INFO_GUID;
25 if (!gd->arch.hob_list)
28 data = hob_get_guid_hob_data(gd->arch.hob_list, NULL, &guid);
30 panic("memory map info hob not found\n");
32 panic("invalid number of memory map entries\n");
37 #define for_each_if(condition) if (!(condition)) {} else
39 #define for_each_memory_map_entry_reversed(iter, entries) \
40 for (iter = entries->count - 1; iter >= 0; iter--) \
41 for_each_if(entries->entry[iter].type == E820_RAM)
44 * This is to give usable memory region information for u-boot relocation.
45 * so search usable memory region lower than 4GB.
46 * The memory map entries from Slim Bootloader hob are already sorted.
48 * @total_size: The memory size that u-boot occupies
49 * @return : The top available memory address lower than 4GB
51 ulong board_get_usable_ram_top(ulong total_size)
53 struct sbl_memory_map_info *data;
59 data = get_memory_map_info();
62 * sorted memory map entries from Slim Bootloader based on physical
63 * start memory address, from low to high. So do reversed search to
64 * get highest usable, suitable size, 4KB aligned available memory
68 for_each_memory_map_entry_reversed(i, data) {
69 addr_start = data->entry[i].addr;
70 addr_end = addr_start + data->entry[i].size;
72 if (addr_start > SZ_4G)
78 if (addr_end < total_size)
81 /* to relocate u-boot at 4K aligned memory */
82 addr_end = rounddown(addr_end - total_size, SZ_4K);
83 if (addr_end >= addr_start) {
84 ram_top = (ulong)addr_end + total_size;
90 panic("failed to find available memory for relocation!");
96 * The memory initialization has already been done in previous Slim Bootloader
97 * stage thru FSP-M. Instead, this sets the ram_size from the memory map info
102 struct sbl_memory_map_info *data;
106 data = get_memory_map_info();
109 * sorted memory map entries from Slim Bootloader based on physical
110 * start memory address, from low to high. So do reversed search to
111 * simply get highest usable memory address as RAM size
114 for_each_memory_map_entry_reversed(i, data) {
115 /* simply use the highest usable memory address as RAM size */
116 ram_size = data->entry[i].addr + data->entry[i].size;
121 panic("failed to detect memory size");
123 gd->ram_size = ram_size;
127 int dram_init_banksize(void)
129 if (!CONFIG_NR_DRAM_BANKS)
132 /* simply use a single bank to have whole size for now */
133 gd->bd->bi_dram[0].start = 0;
134 gd->bd->bi_dram[0].size = gd->ram_size;
138 unsigned int install_e820_map(unsigned int max_entries,
139 struct e820_entry *entries)
141 struct sbl_memory_map_info *data;
144 data = get_memory_map_info();
146 for (i = 0; i < data->count; i++) {
147 entries[i].addr = data->entry[i].addr;
148 entries[i].size = data->entry[i].size;
149 entries[i].type = data->entry[i].type;