1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Copyright (c) 2015 Google, Inc 4 * Written by Simon Glass <sjg@chromium.org> 5 */ 6 7 #include <common.h> 8 #include <efi.h> 9 #include <errno.h> 10 #include <usb.h> 11 #include <asm/post.h> 12 13 DECLARE_GLOBAL_DATA_PTR; 14 15 /* 16 * This function looks for the highest region of memory lower than 4GB which 17 * has enough space for U-Boot where U-Boot is aligned on a page boundary. 18 * It overrides the default implementation found elsewhere which simply 19 * picks the end of ram, wherever that may be. The location of the stack, 20 * the relocation address, and how far U-Boot is moved by relocation are 21 * set in the global data structure. 22 */ 23 ulong board_get_usable_ram_top(ulong total_size) 24 { 25 struct efi_mem_desc *desc, *end; 26 struct efi_entry_memmap *map; 27 int ret, size; 28 uintptr_t dest_addr = 0; 29 struct efi_mem_desc *largest = NULL; 30 31 /* 32 * Find largest area of memory below 4GB. We could 33 * call efi_build_mem_table() for a more accurate picture since it 34 * merges areas together where possible. But that function uses more 35 * pre-relocation memory, and it's not critical that we find the 36 * absolute largest region. 37 */ 38 ret = efi_info_get(EFIET_MEMORY_MAP, (void **)&map, &size); 39 if (ret) { 40 /* We should have stopped in dram_init(), something is wrong */ 41 debug("%s: Missing memory map\n", __func__); 42 goto err; 43 } 44 45 end = (struct efi_mem_desc *)((ulong)map + size); 46 desc = map->desc; 47 for (; desc < end; desc = efi_get_next_mem_desc(map, desc)) { 48 if (desc->type != EFI_CONVENTIONAL_MEMORY || 49 desc->physical_start >= 1ULL << 32) 50 continue; 51 if (!largest || desc->num_pages > largest->num_pages) 52 largest = desc; 53 } 54 55 /* If no suitable area was found, return an error. */ 56 assert(largest); 57 if (!largest || (largest->num_pages << EFI_PAGE_SHIFT) < (2 << 20)) 58 goto err; 59 60 dest_addr = largest->physical_start + (largest->num_pages << 61 EFI_PAGE_SHIFT); 62 63 return (ulong)dest_addr; 64 err: 65 panic("No available memory found for relocation"); 66 return 0; 67 } 68 69 int dram_init(void) 70 { 71 struct efi_mem_desc *desc, *end; 72 struct efi_entry_memmap *map; 73 int size, ret; 74 75 ret = efi_info_get(EFIET_MEMORY_MAP, (void **)&map, &size); 76 if (ret) { 77 printf("Cannot find EFI memory map tables, ret=%d\n", ret); 78 79 return -ENODEV; 80 } 81 82 end = (struct efi_mem_desc *)((ulong)map + size); 83 gd->ram_size = 0; 84 desc = map->desc; 85 for (; desc < end; desc = efi_get_next_mem_desc(map, desc)) { 86 if (desc->type < EFI_MMAP_IO) 87 gd->ram_size += desc->num_pages << EFI_PAGE_SHIFT; 88 } 89 90 return 0; 91 } 92 93 int dram_init_banksize(void) 94 { 95 struct efi_mem_desc *desc, *end; 96 struct efi_entry_memmap *map; 97 int ret, size; 98 int num_banks; 99 100 ret = efi_info_get(EFIET_MEMORY_MAP, (void **)&map, &size); 101 if (ret) { 102 /* We should have stopped in dram_init(), something is wrong */ 103 debug("%s: Missing memory map\n", __func__); 104 return -ENXIO; 105 } 106 end = (struct efi_mem_desc *)((ulong)map + size); 107 desc = map->desc; 108 for (num_banks = 0; 109 desc < end && num_banks < CONFIG_NR_DRAM_BANKS; 110 desc = efi_get_next_mem_desc(map, desc)) { 111 /* 112 * We only use conventional memory and ignore 113 * anything less than 1MB. 114 */ 115 if (desc->type != EFI_CONVENTIONAL_MEMORY || 116 (desc->num_pages << EFI_PAGE_SHIFT) < 1 << 20) 117 continue; 118 gd->bd->bi_dram[num_banks].start = desc->physical_start; 119 gd->bd->bi_dram[num_banks].size = desc->num_pages << 120 EFI_PAGE_SHIFT; 121 num_banks++; 122 } 123 124 return 0; 125 } 126 127 int arch_cpu_init(void) 128 { 129 post_code(POST_CPU_INIT); 130 131 return x86_cpu_init_f(); 132 } 133 134 int checkcpu(void) 135 { 136 return 0; 137 } 138 139 int print_cpuinfo(void) 140 { 141 return default_print_cpuinfo(); 142 } 143 144 /* Find any available tables and copy them to a safe place */ 145 int reserve_arch(void) 146 { 147 struct efi_info_hdr *hdr; 148 149 debug("table=%lx\n", gd->arch.table); 150 if (!gd->arch.table) 151 return 0; 152 153 hdr = (struct efi_info_hdr *)gd->arch.table; 154 155 gd->start_addr_sp -= hdr->total_size; 156 memcpy((void *)gd->start_addr_sp, hdr, hdr->total_size); 157 debug("Stashing EFI table at %lx to %lx, size %x\n", 158 gd->arch.table, gd->start_addr_sp, hdr->total_size); 159 gd->arch.table = gd->start_addr_sp; 160 161 return 0; 162 } 163 164 int last_stage_init(void) 165 { 166 /* start usb so that usb keyboard can be used as input device */ 167 usb_init(); 168 169 return 0; 170 } 171