sdram.c 3.1 KB

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