// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (C) 2019 Intel Corporation */ #include #include #include #include #include #include DECLARE_GLOBAL_DATA_PTR; /** * This returns a data pointer of memory map info from the guid hob. * * @return: A data pointer of memory map info hob */ static struct sbl_memory_map_info *get_memory_map_info(void) { struct sbl_memory_map_info *data; const efi_guid_t guid = SBL_MEMORY_MAP_INFO_GUID; if (!gd->arch.hob_list) return NULL; data = hob_get_guid_hob_data(gd->arch.hob_list, NULL, &guid); if (!data) panic("memory map info hob not found\n"); if (!data->count) panic("invalid number of memory map entries\n"); return data; } #define for_each_if(condition) if (!(condition)) {} else #define for_each_memory_map_entry_reversed(iter, entries) \ for (iter = entries->count - 1; iter >= 0; iter--) \ for_each_if(entries->entry[iter].type == E820_RAM) /** * This is to give usable memory region information for u-boot relocation. * so search usable memory region lower than 4GB. * The memory map entries from Slim Bootloader hob are already sorted. * * @total_size: The memory size that u-boot occupies * Return: : The top available memory address lower than 4GB */ phys_addr_t board_get_usable_ram_top(phys_size_t total_size) { struct sbl_memory_map_info *data; int i; u64 addr_start; u64 addr_end; ulong ram_top; data = get_memory_map_info(); /** * sorted memory map entries from Slim Bootloader based on physical * start memory address, from low to high. So do reversed search to * get highest usable, suitable size, 4KB aligned available memory * under 4GB. */ ram_top = 0; for_each_memory_map_entry_reversed(i, data) { addr_start = data->entry[i].addr; addr_end = addr_start + data->entry[i].size; if (addr_start > SZ_4G) continue; if (addr_end > SZ_4G) addr_end = SZ_4G; if (addr_end < total_size) continue; /* to relocate u-boot at 4K aligned memory */ addr_end = rounddown(addr_end - total_size, SZ_4K); if (addr_end >= addr_start) { ram_top = (ulong)addr_end + total_size; break; } } if (!ram_top) panic("failed to find available memory for relocation!"); return ram_top; } /** * The memory initialization has already been done in previous Slim Bootloader * stage thru FSP-M. Instead, this sets the ram_size from the memory map info * hob. */ int dram_init(void) { struct sbl_memory_map_info *data; int i; u64 ram_size; data = get_memory_map_info(); /** * sorted memory map entries from Slim Bootloader based on physical * start memory address, from low to high. So do reversed search to * simply get highest usable memory address as RAM size */ ram_size = 0; for_each_memory_map_entry_reversed(i, data) { /* simply use the highest usable memory address as RAM size */ ram_size = data->entry[i].addr + data->entry[i].size; break; } if (!ram_size) panic("failed to detect memory size"); gd->ram_size = ram_size; return 0; } int dram_init_banksize(void) { if (!CONFIG_NR_DRAM_BANKS) return 0; /* simply use a single bank to have whole size for now */ gd->bd->bi_dram[0].start = 0; gd->bd->bi_dram[0].size = gd->ram_size; return 0; } unsigned int install_e820_map(unsigned int max_entries, struct e820_entry *entries) { struct sbl_memory_map_info *data; unsigned int i; data = get_memory_map_info(); for (i = 0; i < data->count; i++) { entries[i].addr = data->entry[i].addr; entries[i].size = data->entry[i].size; entries[i].type = data->entry[i].type; } return i; }