blob: 66df1287871796fcd84ff3c36e939d2ab58d02fa [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Simon Glassd2269f22015-08-04 12:34:01 -06002/*
3 * Copyright (c) 2015 Google, Inc
4 * Written by Simon Glass <sjg@chromium.org>
Simon Glassd2269f22015-08-04 12:34:01 -06005 */
6
7#include <common.h>
Simon Glass1fa70f82019-11-14 12:57:34 -07008#include <cpu_func.h>
Simon Glassd2269f22015-08-04 12:34:01 -06009#include <efi.h>
10#include <errno.h>
Simon Glass6980b6b2019-11-14 12:57:45 -070011#include <init.h>
Bin Mengdb59dd32018-06-17 05:57:53 -070012#include <usb.h>
Bin Meng106dcfc2018-08-23 08:24:10 -070013#include <asm/bootparam.h>
Bin Meng2f65c072018-08-23 08:24:08 -070014#include <asm/e820.h>
Bin Meng6bd41092018-06-12 08:36:17 -070015#include <asm/post.h>
Simon Glassd2269f22015-08-04 12:34:01 -060016
17DECLARE_GLOBAL_DATA_PTR;
18
19/*
20 * This function looks for the highest region of memory lower than 4GB which
21 * has enough space for U-Boot where U-Boot is aligned on a page boundary.
22 * It overrides the default implementation found elsewhere which simply
23 * picks the end of ram, wherever that may be. The location of the stack,
24 * the relocation address, and how far U-Boot is moved by relocation are
25 * set in the global data structure.
26 */
27ulong board_get_usable_ram_top(ulong total_size)
28{
29 struct efi_mem_desc *desc, *end;
30 struct efi_entry_memmap *map;
31 int ret, size;
32 uintptr_t dest_addr = 0;
33 struct efi_mem_desc *largest = NULL;
34
35 /*
36 * Find largest area of memory below 4GB. We could
37 * call efi_build_mem_table() for a more accurate picture since it
38 * merges areas together where possible. But that function uses more
39 * pre-relocation memory, and it's not critical that we find the
40 * absolute largest region.
41 */
42 ret = efi_info_get(EFIET_MEMORY_MAP, (void **)&map, &size);
43 if (ret) {
44 /* We should have stopped in dram_init(), something is wrong */
45 debug("%s: Missing memory map\n", __func__);
46 goto err;
47 }
48
49 end = (struct efi_mem_desc *)((ulong)map + size);
50 desc = map->desc;
51 for (; desc < end; desc = efi_get_next_mem_desc(map, desc)) {
52 if (desc->type != EFI_CONVENTIONAL_MEMORY ||
53 desc->physical_start >= 1ULL << 32)
54 continue;
55 if (!largest || desc->num_pages > largest->num_pages)
56 largest = desc;
57 }
58
59 /* If no suitable area was found, return an error. */
60 assert(largest);
61 if (!largest || (largest->num_pages << EFI_PAGE_SHIFT) < (2 << 20))
62 goto err;
63
64 dest_addr = largest->physical_start + (largest->num_pages <<
65 EFI_PAGE_SHIFT);
66
67 return (ulong)dest_addr;
68err:
69 panic("No available memory found for relocation");
70 return 0;
71}
72
73int dram_init(void)
74{
75 struct efi_mem_desc *desc, *end;
76 struct efi_entry_memmap *map;
77 int size, ret;
78
79 ret = efi_info_get(EFIET_MEMORY_MAP, (void **)&map, &size);
80 if (ret) {
81 printf("Cannot find EFI memory map tables, ret=%d\n", ret);
82
83 return -ENODEV;
84 }
85
86 end = (struct efi_mem_desc *)((ulong)map + size);
87 gd->ram_size = 0;
88 desc = map->desc;
89 for (; desc < end; desc = efi_get_next_mem_desc(map, desc)) {
90 if (desc->type < EFI_MMAP_IO)
91 gd->ram_size += desc->num_pages << EFI_PAGE_SHIFT;
92 }
93
94 return 0;
95}
96
Simon Glass2f949c32017-03-31 08:40:32 -060097int dram_init_banksize(void)
Simon Glassd2269f22015-08-04 12:34:01 -060098{
99 struct efi_mem_desc *desc, *end;
100 struct efi_entry_memmap *map;
101 int ret, size;
102 int num_banks;
103
104 ret = efi_info_get(EFIET_MEMORY_MAP, (void **)&map, &size);
105 if (ret) {
106 /* We should have stopped in dram_init(), something is wrong */
107 debug("%s: Missing memory map\n", __func__);
Simon Glass2f949c32017-03-31 08:40:32 -0600108 return -ENXIO;
Simon Glassd2269f22015-08-04 12:34:01 -0600109 }
110 end = (struct efi_mem_desc *)((ulong)map + size);
111 desc = map->desc;
112 for (num_banks = 0;
113 desc < end && num_banks < CONFIG_NR_DRAM_BANKS;
114 desc = efi_get_next_mem_desc(map, desc)) {
115 /*
Bin Meng7eb28a52018-06-22 01:38:30 -0700116 * We only use conventional memory and ignore
Simon Glassd2269f22015-08-04 12:34:01 -0600117 * anything less than 1MB.
118 */
119 if (desc->type != EFI_CONVENTIONAL_MEMORY ||
Simon Glassd2269f22015-08-04 12:34:01 -0600120 (desc->num_pages << EFI_PAGE_SHIFT) < 1 << 20)
121 continue;
122 gd->bd->bi_dram[num_banks].start = desc->physical_start;
123 gd->bd->bi_dram[num_banks].size = desc->num_pages <<
124 EFI_PAGE_SHIFT;
125 num_banks++;
126 }
Simon Glass2f949c32017-03-31 08:40:32 -0600127
128 return 0;
Simon Glassd2269f22015-08-04 12:34:01 -0600129}
130
Bin Meng6bd41092018-06-12 08:36:17 -0700131int arch_cpu_init(void)
132{
133 post_code(POST_CPU_INIT);
134
135 return x86_cpu_init_f();
136}
137
Simon Glassee7c36f2017-03-28 10:27:30 -0600138int checkcpu(void)
139{
140 return 0;
141}
142
Simon Glassd2269f22015-08-04 12:34:01 -0600143int print_cpuinfo(void)
144{
145 return default_print_cpuinfo();
146}
147
148/* Find any available tables and copy them to a safe place */
149int reserve_arch(void)
150{
151 struct efi_info_hdr *hdr;
152
153 debug("table=%lx\n", gd->arch.table);
154 if (!gd->arch.table)
155 return 0;
156
157 hdr = (struct efi_info_hdr *)gd->arch.table;
158
159 gd->start_addr_sp -= hdr->total_size;
160 memcpy((void *)gd->start_addr_sp, hdr, hdr->total_size);
161 debug("Stashing EFI table at %lx to %lx, size %x\n",
162 gd->arch.table, gd->start_addr_sp, hdr->total_size);
163 gd->arch.table = gd->start_addr_sp;
164
165 return 0;
166}
Bin Mengdb59dd32018-06-17 05:57:53 -0700167
168int last_stage_init(void)
169{
170 /* start usb so that usb keyboard can be used as input device */
Bin Menga7bb8ef2018-11-29 20:07:13 -0800171 if (CONFIG_IS_ENABLED(USB_KEYBOARD))
172 usb_init();
Bin Mengdb59dd32018-06-17 05:57:53 -0700173
174 return 0;
175}
Bin Meng2f65c072018-08-23 08:24:08 -0700176
177unsigned int install_e820_map(unsigned int max_entries,
178 struct e820_entry *entries)
179{
180 struct efi_mem_desc *desc, *end;
181 struct efi_entry_memmap *map;
182 int size, ret;
183 efi_physical_addr_t last_end_addr = 0;
184 struct e820_entry *last_entry = NULL;
185 __u32 e820_type;
186 unsigned int num_entries = 0;
187
188 ret = efi_info_get(EFIET_MEMORY_MAP, (void **)&map, &size);
189 if (ret) {
190 printf("Cannot find EFI memory map tables, ret=%d\n", ret);
191
192 return -ENODEV;
193 }
194
195 end = (struct efi_mem_desc *)((ulong)map + size);
196 for (desc = map->desc; desc < end;
197 desc = efi_get_next_mem_desc(map, desc)) {
198 if (desc->num_pages == 0)
199 continue;
200
201 switch (desc->type) {
202 case EFI_LOADER_CODE:
203 case EFI_LOADER_DATA:
204 case EFI_BOOT_SERVICES_CODE:
205 case EFI_BOOT_SERVICES_DATA:
206 case EFI_CONVENTIONAL_MEMORY:
207 e820_type = E820_RAM;
208 break;
209
210 case EFI_RESERVED_MEMORY_TYPE:
211 case EFI_RUNTIME_SERVICES_CODE:
212 case EFI_RUNTIME_SERVICES_DATA:
213 case EFI_MMAP_IO:
214 case EFI_MMAP_IO_PORT:
215 case EFI_PAL_CODE:
216 e820_type = E820_RESERVED;
217 break;
218
219 case EFI_ACPI_RECLAIM_MEMORY:
220 e820_type = E820_ACPI;
221 break;
222
223 case EFI_ACPI_MEMORY_NVS:
224 e820_type = E820_NVS;
225 break;
226
227 case EFI_UNUSABLE_MEMORY:
228 e820_type = E820_UNUSABLE;
229 break;
230
231 default:
232 printf("Invalid EFI memory descriptor type (0x%x)!\n",
233 desc->type);
234 continue;
235 }
236
237 if (last_entry != NULL && last_entry->type == e820_type &&
238 desc->physical_start == last_end_addr) {
239 last_entry->size += (desc->num_pages << EFI_PAGE_SHIFT);
240 last_end_addr += (desc->num_pages << EFI_PAGE_SHIFT);
241 } else {
242 if (num_entries >= E820MAX)
243 break;
244
245 entries[num_entries].addr = desc->physical_start;
246 entries[num_entries].size = desc->num_pages;
247 entries[num_entries].size <<= EFI_PAGE_SHIFT;
248 entries[num_entries].type = e820_type;
249 last_entry = &entries[num_entries];
250 last_end_addr = last_entry->addr + last_entry->size;
251 num_entries++;
252 }
253 }
254
255 return num_entries;
256}
Bin Meng106dcfc2018-08-23 08:24:10 -0700257
258void setup_efi_info(struct efi_info *efi_info)
259{
260 struct efi_entry_systable *table;
261 struct efi_entry_memmap *map;
262 char *signature;
263 int size, ret;
264
265 memset(efi_info, 0, sizeof(struct efi_info));
266
267 ret = efi_info_get(EFIET_SYS_TABLE, (void **)&table, &size);
268 if (ret) {
269 printf("Cannot find EFI system table, ret=%d\n", ret);
270 return;
271 }
272 efi_info->efi_systab = (u32)(table->sys_table);
273
274 ret = efi_info_get(EFIET_MEMORY_MAP, (void **)&map, &size);
275 if (ret) {
276 printf("Cannot find EFI memory map tables, ret=%d\n", ret);
277 return;
278 }
279 efi_info->efi_memdesc_size = map->desc_size;
280 efi_info->efi_memdesc_version = map->version;
281 efi_info->efi_memmap = (u32)(map->desc);
282 efi_info->efi_memmap_size = size - sizeof(struct efi_entry_memmap);
283
284#ifdef CONFIG_EFI_STUB_64BIT
285 efi_info->efi_systab_hi = table->sys_table >> 32;
286 efi_info->efi_memmap_hi = (u64)(u32)(map->desc) >> 32;
287 signature = EFI64_LOADER_SIGNATURE;
288#else
289 signature = EFI32_LOADER_SIGNATURE;
290#endif
291 memcpy(&efi_info->efi_loader_signature, signature, 4);
292}