17b02bf3cSSimon Glass /* 27b02bf3cSSimon Glass * Copyright (C) 2014, Bin Meng <bmeng.cn@gmail.com> 37b02bf3cSSimon Glass * 47b02bf3cSSimon Glass * SPDX-License-Identifier: GPL-2.0+ 57b02bf3cSSimon Glass */ 67b02bf3cSSimon Glass 77b02bf3cSSimon Glass #include <common.h> 87b02bf3cSSimon Glass #include <asm/fsp/fsp_support.h> 97b02bf3cSSimon Glass #include <asm/e820.h> 10ff1e18afSBin Meng #include <asm/mrccache.h> 117b02bf3cSSimon Glass #include <asm/post.h> 127b02bf3cSSimon Glass 137b02bf3cSSimon Glass DECLARE_GLOBAL_DATA_PTR; 147b02bf3cSSimon Glass dram_init(void)157b02bf3cSSimon Glassint dram_init(void) 167b02bf3cSSimon Glass { 177b02bf3cSSimon Glass phys_size_t ram_size = 0; 187b02bf3cSSimon Glass const struct hob_header *hdr; 197b02bf3cSSimon Glass struct hob_res_desc *res_desc; 207b02bf3cSSimon Glass 217b02bf3cSSimon Glass hdr = gd->arch.hob_list; 227b02bf3cSSimon Glass while (!end_of_hob(hdr)) { 237b02bf3cSSimon Glass if (hdr->type == HOB_TYPE_RES_DESC) { 247b02bf3cSSimon Glass res_desc = (struct hob_res_desc *)hdr; 257b02bf3cSSimon Glass if (res_desc->type == RES_SYS_MEM || 267b02bf3cSSimon Glass res_desc->type == RES_MEM_RESERVED) { 277b02bf3cSSimon Glass ram_size += res_desc->len; 287b02bf3cSSimon Glass } 297b02bf3cSSimon Glass } 307b02bf3cSSimon Glass hdr = get_next_hob(hdr); 317b02bf3cSSimon Glass } 327b02bf3cSSimon Glass 337b02bf3cSSimon Glass gd->ram_size = ram_size; 347b02bf3cSSimon Glass post_code(POST_DRAM); 357b02bf3cSSimon Glass 36ff1e18afSBin Meng #ifdef CONFIG_ENABLE_MRC_CACHE 37ff1e18afSBin Meng gd->arch.mrc_output = fsp_get_nvs_data(gd->arch.hob_list, 38ff1e18afSBin Meng &gd->arch.mrc_output_len); 39ff1e18afSBin Meng #endif 40ff1e18afSBin Meng 417b02bf3cSSimon Glass return 0; 427b02bf3cSSimon Glass } 437b02bf3cSSimon Glass dram_init_banksize(void)4476b00acaSSimon Glassint dram_init_banksize(void) 457b02bf3cSSimon Glass { 467b02bf3cSSimon Glass gd->bd->bi_dram[0].start = 0; 477b02bf3cSSimon Glass gd->bd->bi_dram[0].size = gd->ram_size; 4876b00acaSSimon Glass 4976b00acaSSimon Glass return 0; 507b02bf3cSSimon Glass } 517b02bf3cSSimon Glass 527b02bf3cSSimon Glass /* 537b02bf3cSSimon Glass * This function looks for the highest region of memory lower than 4GB which 547b02bf3cSSimon Glass * has enough space for U-Boot where U-Boot is aligned on a page boundary. 557b02bf3cSSimon Glass * It overrides the default implementation found elsewhere which simply 567b02bf3cSSimon Glass * picks the end of ram, wherever that may be. The location of the stack, 577b02bf3cSSimon Glass * the relocation address, and how far U-Boot is moved by relocation are 587b02bf3cSSimon Glass * set in the global data structure. 597b02bf3cSSimon Glass */ board_get_usable_ram_top(ulong total_size)607b02bf3cSSimon Glassulong board_get_usable_ram_top(ulong total_size) 617b02bf3cSSimon Glass { 627b02bf3cSSimon Glass return fsp_get_usable_lowmem_top(gd->arch.hob_list); 637b02bf3cSSimon Glass } 647b02bf3cSSimon Glass install_e820_map(unsigned max_entries,struct e820entry * entries)657b02bf3cSSimon Glassunsigned install_e820_map(unsigned max_entries, struct e820entry *entries) 667b02bf3cSSimon Glass { 677b02bf3cSSimon Glass unsigned num_entries = 0; 687b02bf3cSSimon Glass const struct hob_header *hdr; 697b02bf3cSSimon Glass struct hob_res_desc *res_desc; 707b02bf3cSSimon Glass 717b02bf3cSSimon Glass hdr = gd->arch.hob_list; 727b02bf3cSSimon Glass 737b02bf3cSSimon Glass while (!end_of_hob(hdr)) { 747b02bf3cSSimon Glass if (hdr->type == HOB_TYPE_RES_DESC) { 757b02bf3cSSimon Glass res_desc = (struct hob_res_desc *)hdr; 767b02bf3cSSimon Glass entries[num_entries].addr = res_desc->phys_start; 777b02bf3cSSimon Glass entries[num_entries].size = res_desc->len; 787b02bf3cSSimon Glass 797b02bf3cSSimon Glass if (res_desc->type == RES_SYS_MEM) 807b02bf3cSSimon Glass entries[num_entries].type = E820_RAM; 817b02bf3cSSimon Glass else if (res_desc->type == RES_MEM_RESERVED) 827b02bf3cSSimon Glass entries[num_entries].type = E820_RESERVED; 83196193a4SBin Meng 84196193a4SBin Meng num_entries++; 857b02bf3cSSimon Glass } 867b02bf3cSSimon Glass hdr = get_next_hob(hdr); 877b02bf3cSSimon Glass } 887b02bf3cSSimon Glass 891ed6648bSBin Meng /* Mark PCIe ECAM address range as reserved */ 901ed6648bSBin Meng entries[num_entries].addr = CONFIG_PCIE_ECAM_BASE; 911ed6648bSBin Meng entries[num_entries].size = CONFIG_PCIE_ECAM_SIZE; 921ed6648bSBin Meng entries[num_entries].type = E820_RESERVED; 931ed6648bSBin Meng num_entries++; 941ed6648bSBin Meng 95*7d0d2efeSBin Meng #ifdef CONFIG_HAVE_ACPI_RESUME 96*7d0d2efeSBin Meng /* 97*7d0d2efeSBin Meng * Everything between U-Boot's stack and ram top needs to be 98*7d0d2efeSBin Meng * reserved in order for ACPI S3 resume to work. 99*7d0d2efeSBin Meng */ 100*7d0d2efeSBin Meng entries[num_entries].addr = gd->start_addr_sp - CONFIG_STACK_SIZE; 101*7d0d2efeSBin Meng entries[num_entries].size = gd->ram_top - gd->start_addr_sp + \ 102*7d0d2efeSBin Meng CONFIG_STACK_SIZE; 103*7d0d2efeSBin Meng entries[num_entries].type = E820_RESERVED; 104*7d0d2efeSBin Meng num_entries++; 105*7d0d2efeSBin Meng #endif 106*7d0d2efeSBin Meng 1077b02bf3cSSimon Glass return num_entries; 1087b02bf3cSSimon Glass } 109