1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * Copyright (c) 2011 The Chromium OS Authors. 4 * (C) Copyright 2010,2011 5 * Graeme Russ, <graeme.russ@gmail.com> 6 */ 7 8#include <common.h> 9#include <init.h> 10#include <asm/e820.h> 11#include <asm/cb_sysinfo.h> 12#include <asm/global_data.h> 13 14DECLARE_GLOBAL_DATA_PTR; 15 16unsigned int install_e820_map(unsigned int max_entries, 17 struct e820_entry *entries) 18{ 19 return cb_install_e820_map(max_entries, entries); 20} 21 22/* 23 * This function looks for the highest region of memory lower than 4GB which 24 * has enough space for U-Boot where U-Boot is aligned on a page boundary. It 25 * overrides the default implementation found elsewhere which simply picks the 26 * end of ram, wherever that may be. The location of the stack, the relocation 27 * address, and how far U-Boot is moved by relocation are set in the global 28 * data structure. 29 */ 30phys_addr_t board_get_usable_ram_top(phys_size_t total_size) 31{ 32 uintptr_t dest_addr = 0; 33 int i; 34 35 for (i = 0; i < lib_sysinfo.n_memranges; i++) { 36 struct memrange *memrange = &lib_sysinfo.memrange[i]; 37 /* Force U-Boot to relocate to a page aligned address. */ 38 uint64_t start = roundup(memrange->base, 1 << 12); 39 uint64_t end = memrange->base + memrange->size; 40 41 /* Ignore non-memory regions. */ 42 if (memrange->type != CB_MEM_RAM) 43 continue; 44 45 /* Filter memory over 4GB. */ 46 if (end > 0xffffffffULL) 47 end = 0x100000000ULL; 48 /* Skip this region if it's too small. */ 49 if (end - start < total_size) 50 continue; 51 52 /* Use this address if it's the largest so far. */ 53 if (end > dest_addr) 54 dest_addr = end; 55 } 56 57 /* If no suitable area was found, return an error. */ 58 if (!dest_addr) 59 panic("No available memory found for relocation"); 60 61 return (ulong)dest_addr; 62} 63 64int dram_init(void) 65{ 66 int i; 67 phys_size_t ram_size = 0; 68 69 for (i = 0; i < lib_sysinfo.n_memranges; i++) { 70 struct memrange *memrange = &lib_sysinfo.memrange[i]; 71 unsigned long long end = memrange->base + memrange->size; 72 73 if (memrange->type == CB_MEM_RAM && end > ram_size) 74 ram_size += memrange->size; 75 } 76 77 gd->ram_size = ram_size; 78 if (ram_size == 0) 79 return -1; 80 81 return 0; 82} 83 84int dram_init_banksize(void) 85{ 86 int i, j; 87 88 if (CONFIG_NR_DRAM_BANKS) { 89 for (i = 0, j = 0; i < lib_sysinfo.n_memranges; i++) { 90 struct memrange *memrange = &lib_sysinfo.memrange[i]; 91 92 if (memrange->type == CB_MEM_RAM) { 93 gd->bd->bi_dram[j].start = memrange->base; 94 gd->bd->bi_dram[j].size = memrange->size; 95 j++; 96 if (j >= CONFIG_NR_DRAM_BANKS) 97 break; 98 } 99 } 100 } 101 102 return 0; 103} 104