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> 107b02bf3cSSimon Glass #include <asm/post.h> 117b02bf3cSSimon Glass 127b02bf3cSSimon Glass DECLARE_GLOBAL_DATA_PTR; 137b02bf3cSSimon Glass 147b02bf3cSSimon Glass int dram_init(void) 157b02bf3cSSimon Glass { 167b02bf3cSSimon Glass phys_size_t ram_size = 0; 177b02bf3cSSimon Glass const struct hob_header *hdr; 187b02bf3cSSimon Glass struct hob_res_desc *res_desc; 197b02bf3cSSimon Glass 207b02bf3cSSimon Glass hdr = gd->arch.hob_list; 217b02bf3cSSimon Glass while (!end_of_hob(hdr)) { 227b02bf3cSSimon Glass if (hdr->type == HOB_TYPE_RES_DESC) { 237b02bf3cSSimon Glass res_desc = (struct hob_res_desc *)hdr; 247b02bf3cSSimon Glass if (res_desc->type == RES_SYS_MEM || 257b02bf3cSSimon Glass res_desc->type == RES_MEM_RESERVED) { 267b02bf3cSSimon Glass ram_size += res_desc->len; 277b02bf3cSSimon Glass } 287b02bf3cSSimon Glass } 297b02bf3cSSimon Glass hdr = get_next_hob(hdr); 307b02bf3cSSimon Glass } 317b02bf3cSSimon Glass 327b02bf3cSSimon Glass gd->ram_size = ram_size; 337b02bf3cSSimon Glass post_code(POST_DRAM); 347b02bf3cSSimon Glass 357b02bf3cSSimon Glass return 0; 367b02bf3cSSimon Glass } 377b02bf3cSSimon Glass 387b02bf3cSSimon Glass void dram_init_banksize(void) 397b02bf3cSSimon Glass { 407b02bf3cSSimon Glass gd->bd->bi_dram[0].start = 0; 417b02bf3cSSimon Glass gd->bd->bi_dram[0].size = gd->ram_size; 427b02bf3cSSimon Glass } 437b02bf3cSSimon Glass 447b02bf3cSSimon Glass /* 457b02bf3cSSimon Glass * This function looks for the highest region of memory lower than 4GB which 467b02bf3cSSimon Glass * has enough space for U-Boot where U-Boot is aligned on a page boundary. 477b02bf3cSSimon Glass * It overrides the default implementation found elsewhere which simply 487b02bf3cSSimon Glass * picks the end of ram, wherever that may be. The location of the stack, 497b02bf3cSSimon Glass * the relocation address, and how far U-Boot is moved by relocation are 507b02bf3cSSimon Glass * set in the global data structure. 517b02bf3cSSimon Glass */ 527b02bf3cSSimon Glass ulong board_get_usable_ram_top(ulong total_size) 537b02bf3cSSimon Glass { 547b02bf3cSSimon Glass return fsp_get_usable_lowmem_top(gd->arch.hob_list); 557b02bf3cSSimon Glass } 567b02bf3cSSimon Glass 577b02bf3cSSimon Glass unsigned install_e820_map(unsigned max_entries, struct e820entry *entries) 587b02bf3cSSimon Glass { 597b02bf3cSSimon Glass unsigned num_entries = 0; 607b02bf3cSSimon Glass const struct hob_header *hdr; 617b02bf3cSSimon Glass struct hob_res_desc *res_desc; 627b02bf3cSSimon Glass 637b02bf3cSSimon Glass hdr = gd->arch.hob_list; 647b02bf3cSSimon Glass 657b02bf3cSSimon Glass while (!end_of_hob(hdr)) { 667b02bf3cSSimon Glass if (hdr->type == HOB_TYPE_RES_DESC) { 677b02bf3cSSimon Glass res_desc = (struct hob_res_desc *)hdr; 687b02bf3cSSimon Glass entries[num_entries].addr = res_desc->phys_start; 697b02bf3cSSimon Glass entries[num_entries].size = res_desc->len; 707b02bf3cSSimon Glass 717b02bf3cSSimon Glass if (res_desc->type == RES_SYS_MEM) 727b02bf3cSSimon Glass entries[num_entries].type = E820_RAM; 737b02bf3cSSimon Glass else if (res_desc->type == RES_MEM_RESERVED) 747b02bf3cSSimon Glass entries[num_entries].type = E820_RESERVED; 75*196193a4SBin Meng 76*196193a4SBin Meng num_entries++; 777b02bf3cSSimon Glass } 787b02bf3cSSimon Glass hdr = get_next_hob(hdr); 797b02bf3cSSimon Glass } 807b02bf3cSSimon Glass 811ed6648bSBin Meng /* Mark PCIe ECAM address range as reserved */ 821ed6648bSBin Meng entries[num_entries].addr = CONFIG_PCIE_ECAM_BASE; 831ed6648bSBin Meng entries[num_entries].size = CONFIG_PCIE_ECAM_SIZE; 841ed6648bSBin Meng entries[num_entries].type = E820_RESERVED; 851ed6648bSBin Meng num_entries++; 861ed6648bSBin Meng 877b02bf3cSSimon Glass return num_entries; 887b02bf3cSSimon Glass } 89