blob: 05044cb778ddc939e83538aca8d90cb9404abb19 [file] [log] [blame]
Lee Leahy3dad4892015-05-05 11:14:02 -07001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2013-2014 Sage Electronic Engineering, LLC.
Lee Leahyb5ad8272015-04-20 15:29:16 -07005 * Copyright (C) 2015 Intel Corp.
Lee Leahy3dad4892015-05-05 11:14:02 -07006 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 2 of the License.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
Patrick Georgib890a122015-03-26 15:17:45 +010018 * Foundation, Inc.
Lee Leahy3dad4892015-05-05 11:14:02 -070019 */
20
Lee Leahyb5ad8272015-04-20 15:29:16 -070021#include <arch/early_variables.h>
22#include <arch/hlt.h>
23#include <bootstate.h>
24#include <cbmem.h>
Lee Leahy3dad4892015-05-05 11:14:02 -070025#include <console/console.h>
Lee Leahy3dad4892015-05-05 11:14:02 -070026#include "fsp_util.h"
Lee Leahyb5ad8272015-04-20 15:29:16 -070027#include <ip_checksum.h>
28#include <lib.h> // hexdump
29#include <string.h>
Lee Leahy3dad4892015-05-05 11:14:02 -070030
Alexandru Gagniuc5c9a71e2015-08-28 18:49:40 -040031/* Compares two EFI GUIDs. Returns true of the GUIDs match, false otherwise. */
32static bool compare_guid(const EFI_GUID *guid1, const EFI_GUID *guid2)
Lee Leahy3dad4892015-05-05 11:14:02 -070033{
Alexandru Gagniuc5c9a71e2015-08-28 18:49:40 -040034 return !memcmp(guid1, guid2, sizeof(EFI_GUID));
Lee Leahyb5ad8272015-04-20 15:29:16 -070035}
36
37/* Returns the pointer to the HOB list. */
Alexandru Gagniuc5c9a71e2015-08-28 18:49:40 -040038void *get_hob_list(void)
Lee Leahyb5ad8272015-04-20 15:29:16 -070039{
40 void *hob_list;
41
42 hob_list = fsp_get_hob_list();
43 if (hob_list == NULL)
44 die("Call fsp_set_runtime() before this call!\n");
45 return hob_list;
46}
47
48/* Returns the next instance of a HOB type from the starting HOB. */
Alexandru Gagniuc5c9a71e2015-08-28 18:49:40 -040049void *get_next_hob(uint16_t type, const void *hob_start)
Lee Leahyb5ad8272015-04-20 15:29:16 -070050{
51 EFI_PEI_HOB_POINTERS hob;
52
Alexandru Gagniuc5c9a71e2015-08-28 18:49:40 -040053 if (!hob_start)
54 return NULL;
Lee Leahyb5ad8272015-04-20 15:29:16 -070055
56 hob.Raw = (UINT8 *)hob_start;
57
58 /* Parse the HOB list until end of list or matching type is found. */
59 while (!END_OF_HOB_LIST(hob.Raw)) {
60 if (hob.Header->HobType == type)
61 return hob.Raw;
62 if (GET_HOB_LENGTH(hob.Raw) < sizeof(*hob.Header))
63 break;
64 hob.Raw = GET_NEXT_HOB(hob.Raw);
65 }
66 return NULL;
67}
68
69/* Returns the first instance of a HOB type among the whole HOB list. */
Alexandru Gagniuc5c9a71e2015-08-28 18:49:40 -040070void *get_first_hob(uint16_t type)
Lee Leahyb5ad8272015-04-20 15:29:16 -070071{
Alexandru Gagniuc5c9a71e2015-08-28 18:49:40 -040072 return get_next_hob(type, get_hob_list());
Lee Leahyb5ad8272015-04-20 15:29:16 -070073}
74
75/* Returns the next instance of the matched GUID HOB from the starting HOB. */
Alexandru Gagniuc5c9a71e2015-08-28 18:49:40 -040076void *get_next_guid_hob(const EFI_GUID * guid, const void *hob_start)
Lee Leahyb5ad8272015-04-20 15:29:16 -070077{
78 EFI_PEI_HOB_POINTERS hob;
79
Alexandru Gagniuc5c9a71e2015-08-28 18:49:40 -040080 hob.Raw = (uint8_t *)hob_start;
Lee Leahyb5ad8272015-04-20 15:29:16 -070081 while ((hob.Raw = get_next_hob(EFI_HOB_TYPE_GUID_EXTENSION, hob.Raw))
82 != NULL) {
83 if (compare_guid(guid, &hob.Guid->Name))
84 break;
85 hob.Raw = GET_NEXT_HOB(hob.Raw);
86 }
87 return hob.Raw;
88}
89
90/*
91 * Returns the first instance of the matched GUID HOB among the whole HOB list.
92 */
Alexandru Gagniuc5c9a71e2015-08-28 18:49:40 -040093void *get_first_guid_hob(const EFI_GUID *guid)
Lee Leahyb5ad8272015-04-20 15:29:16 -070094{
95 return get_next_guid_hob(guid, get_hob_list());
96}
97
98/*
99 * Returns the next instance of the matching resource HOB from the starting HOB.
100 */
101void *get_next_resource_hob(const EFI_GUID *guid, const void *hob_start)
102{
103 EFI_PEI_HOB_POINTERS hob;
104
105 hob.Raw = (UINT8 *)hob_start;
106 while ((hob.Raw = get_next_hob(EFI_HOB_TYPE_RESOURCE_DESCRIPTOR,
107 hob.Raw)) != NULL) {
108 if (compare_guid(guid, &hob.ResourceDescriptor->Owner))
109 break;
110 hob.Raw = GET_NEXT_HOB(hob.Raw);
111 }
112 return hob.Raw;
113}
114
115/*
116 * Returns the first instance of the matching resource HOB among the whole HOB
117 * list.
118 */
119void *get_first_resource_hob(const EFI_GUID *guid)
120{
121 return get_next_resource_hob(guid, get_hob_list());
122}
123
124static void print_hob_mem_attributes(void *hob_ptr)
125{
Alexandru Gagniuc5c9a71e2015-08-28 18:49:40 -0400126 EFI_MEMORY_TYPE hob_mem_type;
127 EFI_HOB_MEMORY_ALLOCATION *hob_memory_ptr = hob_ptr;
Lee Leahyb5ad8272015-04-20 15:29:16 -0700128 u64 hob_mem_addr = hob_memory_ptr->AllocDescriptor.MemoryBaseAddress;
129 u64 hob_mem_length = hob_memory_ptr->AllocDescriptor.MemoryLength;
Lee Leahyb5ad8272015-04-20 15:29:16 -0700130
Alexandru Gagniuc5c9a71e2015-08-28 18:49:40 -0400131 hob_mem_type = hob_memory_ptr->AllocDescriptor.MemoryType;
132
133 static const char *hob_mem_type_names[15] = {
134 [EfiReservedMemoryType] = "EfiReservedMemoryType",
135 [EfiLoaderCode] = "EfiLoaderCode",
136 [EfiLoaderData] = "EfiLoaderData",
137 [EfiBootServicesCode] = "EfiBootServicesCode",
138 [EfiBootServicesData] = "EfiBootServicesData",
139 [EfiRuntimeServicesCode] = "EfiRuntimeServicesCode",
140 [EfiRuntimeServicesData] = "EfiRuntimeServicesData",
141 [EfiConventionalMemory] = "EfiConventionalMemory",
142 [EfiUnusableMemory] = "EfiUnusableMemory",
143 [EfiACPIReclaimMemory] = "EfiACPIReclaimMemory",
144 [EfiACPIMemoryNVS] = "EfiACPIMemoryNVS",
145 [EfiMemoryMappedIO] = "EfiMemoryMappedIO",
146 [EfiMemoryMappedIOPortSpace] = "EfiMemoryMappedIOPortSpace",
147 [EfiPalCode] = "EfiPalCode",
148 [EfiMaxMemoryType] = "EfiMaxMemoryType",
149 };
150
151 if (hob_mem_type >= ARRAY_SIZE(hob_mem_type_names))
152 hob_mem_type = EfiReservedMemoryType;
Lee Leahy3dad4892015-05-05 11:14:02 -0700153
154 printk(BIOS_SPEW, " Memory type %s (0x%x)\n",
Alexandru Gagniuc5c9a71e2015-08-28 18:49:40 -0400155 hob_mem_type_names[hob_mem_type],
Lee Leahyb5ad8272015-04-20 15:29:16 -0700156 (u32)hob_mem_type);
Lee Leahy3dad4892015-05-05 11:14:02 -0700157 printk(BIOS_SPEW, " at location 0x%0lx with length 0x%0lx\n",
Lee Leahyb5ad8272015-04-20 15:29:16 -0700158 (unsigned long)hob_mem_addr,
159 (unsigned long)hob_mem_length);
Lee Leahy3dad4892015-05-05 11:14:02 -0700160}
161
Lee Leahyb5ad8272015-04-20 15:29:16 -0700162static void print_hob_resource_attributes(void *hob_ptr)
Lee Leahy3dad4892015-05-05 11:14:02 -0700163{
Lee Leahyb5ad8272015-04-20 15:29:16 -0700164 EFI_HOB_RESOURCE_DESCRIPTOR *hob_resource_ptr =
165 (EFI_HOB_RESOURCE_DESCRIPTOR *)hob_ptr;
166 u32 hob_res_type = hob_resource_ptr->ResourceType;
167 u32 hob_res_attr = hob_resource_ptr->ResourceAttribute;
168 u64 hob_res_addr = hob_resource_ptr->PhysicalStart;
169 u64 hob_res_length = hob_resource_ptr->ResourceLength;
170 const char *hob_res_type_str = NULL;
Lee Leahy3dad4892015-05-05 11:14:02 -0700171
Lee Leahyb5ad8272015-04-20 15:29:16 -0700172 /* HOB Resource Types */
173 switch (hob_res_type) {
Lee Leahy3dad4892015-05-05 11:14:02 -0700174 case EFI_RESOURCE_SYSTEM_MEMORY:
Lee Leahyb5ad8272015-04-20 15:29:16 -0700175 hob_res_type_str = "EFI_RESOURCE_SYSTEM_MEMORY";
176 break;
Lee Leahy3dad4892015-05-05 11:14:02 -0700177 case EFI_RESOURCE_MEMORY_MAPPED_IO:
Lee Leahyb5ad8272015-04-20 15:29:16 -0700178 hob_res_type_str = "EFI_RESOURCE_MEMORY_MAPPED_IO";
179 break;
Lee Leahy3dad4892015-05-05 11:14:02 -0700180 case EFI_RESOURCE_IO:
Lee Leahyb5ad8272015-04-20 15:29:16 -0700181 hob_res_type_str = "EFI_RESOURCE_IO";
182 break;
Lee Leahy3dad4892015-05-05 11:14:02 -0700183 case EFI_RESOURCE_FIRMWARE_DEVICE:
Lee Leahyb5ad8272015-04-20 15:29:16 -0700184 hob_res_type_str = "EFI_RESOURCE_FIRMWARE_DEVICE";
185 break;
Lee Leahy3dad4892015-05-05 11:14:02 -0700186 case EFI_RESOURCE_MEMORY_MAPPED_IO_PORT:
Lee Leahyb5ad8272015-04-20 15:29:16 -0700187 hob_res_type_str = "EFI_RESOURCE_MEMORY_MAPPED_IO_PORT";
188 break;
Lee Leahy3dad4892015-05-05 11:14:02 -0700189 case EFI_RESOURCE_MEMORY_RESERVED:
Lee Leahyb5ad8272015-04-20 15:29:16 -0700190 hob_res_type_str = "EFI_RESOURCE_MEMORY_RESERVED";
191 break;
Lee Leahy3dad4892015-05-05 11:14:02 -0700192 case EFI_RESOURCE_IO_RESERVED:
Lee Leahyb5ad8272015-04-20 15:29:16 -0700193 hob_res_type_str = "EFI_RESOURCE_IO_RESERVED";
194 break;
Lee Leahy3dad4892015-05-05 11:14:02 -0700195 case EFI_RESOURCE_MAX_MEMORY_TYPE:
Lee Leahyb5ad8272015-04-20 15:29:16 -0700196 hob_res_type_str = "EFI_RESOURCE_MAX_MEMORY_TYPE";
197 break;
Lee Leahy3dad4892015-05-05 11:14:02 -0700198 default:
Lee Leahyb5ad8272015-04-20 15:29:16 -0700199 hob_res_type_str = "EFI_RESOURCE_UNKNOWN";
200 break;
Lee Leahy3dad4892015-05-05 11:14:02 -0700201 }
202
203 printk(BIOS_SPEW, " Resource %s (0x%0x) has attributes 0x%0x\n",
Lee Leahyb5ad8272015-04-20 15:29:16 -0700204 hob_res_type_str, hob_res_type, hob_res_attr);
Lee Leahy3dad4892015-05-05 11:14:02 -0700205 printk(BIOS_SPEW, " at location 0x%0lx with length 0x%0lx\n",
Lee Leahyb5ad8272015-04-20 15:29:16 -0700206 (unsigned long)hob_res_addr,
207 (unsigned long)hob_res_length);
Lee Leahy3dad4892015-05-05 11:14:02 -0700208}
209
Lee Leahyb5ad8272015-04-20 15:29:16 -0700210static const char *get_hob_type_string(void *hob_ptr)
Lee Leahy3dad4892015-05-05 11:14:02 -0700211{
Lee Leahyb5ad8272015-04-20 15:29:16 -0700212 EFI_PEI_HOB_POINTERS hob;
Alexandru Gagniuc5c9a71e2015-08-28 18:49:40 -0400213 const char *hob_type_string;
Lee Leahyb5ad8272015-04-20 15:29:16 -0700214 const EFI_GUID fsp_reserved_guid =
215 FSP_RESERVED_MEMORY_RESOURCE_HOB_GUID;
216 const EFI_GUID mrc_guid = FSP_NON_VOLATILE_STORAGE_HOB_GUID;
217 const EFI_GUID bootldr_tmp_mem_guid =
218 FSP_BOOTLOADER_TEMP_MEMORY_HOB_GUID;
219 const EFI_GUID bootldr_tolum_guid = FSP_BOOTLOADER_TOLUM_HOB_GUID;
220 const EFI_GUID graphics_info_guid = EFI_PEI_GRAPHICS_INFO_HOB_GUID;
Lee Leahy4a8c19c2015-06-16 14:33:30 -0700221 const EFI_GUID memory_info_hob_guid = FSP_SMBIOS_MEMORY_INFO_GUID;
Lee Leahy3dad4892015-05-05 11:14:02 -0700222
Lee Leahyb5ad8272015-04-20 15:29:16 -0700223 hob.Header = (EFI_HOB_GENERIC_HEADER *)hob_ptr;
224 switch (hob.Header->HobType) {
Lee Leahy3dad4892015-05-05 11:14:02 -0700225 case EFI_HOB_TYPE_HANDOFF:
Lee Leahyb5ad8272015-04-20 15:29:16 -0700226 hob_type_string = "EFI_HOB_TYPE_HANDOFF";
227 break;
Lee Leahy3dad4892015-05-05 11:14:02 -0700228 case EFI_HOB_TYPE_MEMORY_ALLOCATION:
Lee Leahyb5ad8272015-04-20 15:29:16 -0700229 hob_type_string = "EFI_HOB_TYPE_MEMORY_ALLOCATION";
230 break;
Lee Leahy3dad4892015-05-05 11:14:02 -0700231 case EFI_HOB_TYPE_RESOURCE_DESCRIPTOR:
Lee Leahy4a8c19c2015-06-16 14:33:30 -0700232 if (compare_guid(&fsp_reserved_guid, &hob.Guid->Name))
233 hob_type_string = "FSP_RESERVED_MEMORY_RESOURCE_HOB";
234 else if (compare_guid(&bootldr_tolum_guid, &hob.Guid->Name))
235 hob_type_string = "FSP_BOOTLOADER_TOLUM_HOB_GUID";
Alexandru Gagniuc5c9a71e2015-08-28 18:49:40 -0400236 else
237 hob_type_string = "EFI_HOB_TYPE_RESOURCE_DESCRIPTOR";
Lee Leahyb5ad8272015-04-20 15:29:16 -0700238 break;
Lee Leahy3dad4892015-05-05 11:14:02 -0700239 case EFI_HOB_TYPE_GUID_EXTENSION:
Lee Leahyb5ad8272015-04-20 15:29:16 -0700240 if (compare_guid(&bootldr_tmp_mem_guid, &hob.Guid->Name))
241 hob_type_string = "FSP_BOOTLOADER_TEMP_MEMORY_HOB";
Lee Leahyb5ad8272015-04-20 15:29:16 -0700242 else if (compare_guid(&mrc_guid, &hob.Guid->Name))
243 hob_type_string = "FSP_NON_VOLATILE_STORAGE_HOB";
Lee Leahyb5ad8272015-04-20 15:29:16 -0700244 else if (compare_guid(&graphics_info_guid, &hob.Guid->Name))
245 hob_type_string = "EFI_PEI_GRAPHICS_INFO_HOB_GUID";
Lee Leahy4a8c19c2015-06-16 14:33:30 -0700246 else if (compare_guid(&memory_info_hob_guid, &hob.Guid->Name))
247 hob_type_string = "FSP_SMBIOS_MEMORY_INFO_GUID";
Alexandru Gagniuc5c9a71e2015-08-28 18:49:40 -0400248 else
249 hob_type_string = "EFI_HOB_TYPE_GUID_EXTENSION";
Lee Leahyb5ad8272015-04-20 15:29:16 -0700250 break;
Lee Leahy3dad4892015-05-05 11:14:02 -0700251 case EFI_HOB_TYPE_MEMORY_POOL:
Lee Leahyb5ad8272015-04-20 15:29:16 -0700252 hob_type_string = "EFI_HOB_TYPE_MEMORY_POOL";
253 break;
Lee Leahy3dad4892015-05-05 11:14:02 -0700254 case EFI_HOB_TYPE_UNUSED:
Lee Leahyb5ad8272015-04-20 15:29:16 -0700255 hob_type_string = "EFI_HOB_TYPE_UNUSED";
256 break;
Lee Leahy3dad4892015-05-05 11:14:02 -0700257 case EFI_HOB_TYPE_END_OF_HOB_LIST:
Lee Leahyb5ad8272015-04-20 15:29:16 -0700258 hob_type_string = "EFI_HOB_TYPE_END_OF_HOB_LIST";
259 break;
Lee Leahy3dad4892015-05-05 11:14:02 -0700260 default:
Lee Leahyb5ad8272015-04-20 15:29:16 -0700261 hob_type_string = "EFI_HOB_TYPE_UNRECOGNIZED";
262 break;
Lee Leahy3dad4892015-05-05 11:14:02 -0700263 }
264
Lee Leahyb5ad8272015-04-20 15:29:16 -0700265 return hob_type_string;
Lee Leahy3dad4892015-05-05 11:14:02 -0700266}
267
Lee Leahyb5ad8272015-04-20 15:29:16 -0700268/*
269 * Print out a structure of all the HOBs
Lee Leahy3dad4892015-05-05 11:14:02 -0700270 * that match a certain type:
271 * Print all types (0x0000)
Lee Leahyb5ad8272015-04-20 15:29:16 -0700272 * EFI_HOB_TYPE_HANDOFF (0x0001)
Lee Leahy3dad4892015-05-05 11:14:02 -0700273 * EFI_HOB_TYPE_MEMORY_ALLOCATION (0x0002)
274 * EFI_HOB_TYPE_RESOURCE_DESCRIPTOR (0x0003)
275 * EFI_HOB_TYPE_GUID_EXTENSION (0x0004)
276 * EFI_HOB_TYPE_MEMORY_POOL (0x0007)
277 * EFI_HOB_TYPE_UNUSED (0xFFFE)
278 * EFI_HOB_TYPE_END_OF_HOB_LIST (0xFFFF)
279 */
Lee Leahyb5ad8272015-04-20 15:29:16 -0700280void print_hob_type_structure(u16 hob_type, void *hob_list_ptr)
Lee Leahy3dad4892015-05-05 11:14:02 -0700281{
Lee Leahyb5ad8272015-04-20 15:29:16 -0700282 u32 *current_hob;
283 u32 *next_hob = 0;
284 u8 last_hob = 0;
285 u32 current_type;
286 const char *current_type_str;
Lee Leahy3dad4892015-05-05 11:14:02 -0700287
Lee Leahyb5ad8272015-04-20 15:29:16 -0700288 current_hob = hob_list_ptr;
Lee Leahy3dad4892015-05-05 11:14:02 -0700289
Lee Leahyb5ad8272015-04-20 15:29:16 -0700290 /*
291 * Print out HOBs of our desired type until
Lee Leahy3dad4892015-05-05 11:14:02 -0700292 * the end of the HOB list
293 */
294 printk(BIOS_DEBUG, "\n=== FSP HOB Data Structure ===\n");
Lee Leahyb5ad8272015-04-20 15:29:16 -0700295 printk(BIOS_DEBUG, "0x%p: hob_list_ptr\n", hob_list_ptr);
Lee Leahy3dad4892015-05-05 11:14:02 -0700296 do {
Lee Leahyb5ad8272015-04-20 15:29:16 -0700297 EFI_HOB_GENERIC_HEADER *current_header_ptr =
298 (EFI_HOB_GENERIC_HEADER *)current_hob;
Lee Leahy3dad4892015-05-05 11:14:02 -0700299
Lee Leahyb5ad8272015-04-20 15:29:16 -0700300 /* Get the type of this HOB */
301 current_type = current_header_ptr->HobType;
302 current_type_str = get_hob_type_string(current_hob);
303
304 if (current_type == hob_type || hob_type == 0x0000) {
Alexandru Gagniuc5c9a71e2015-08-28 18:49:40 -0400305 printk(BIOS_DEBUG, "HOB %p is an %s (type 0x%0x)\n",
306 current_hob, current_type_str,
Lee Leahyb5ad8272015-04-20 15:29:16 -0700307 current_type);
308 switch (current_type) {
Lee Leahy3dad4892015-05-05 11:14:02 -0700309 case EFI_HOB_TYPE_MEMORY_ALLOCATION:
Lee Leahyb5ad8272015-04-20 15:29:16 -0700310 print_hob_mem_attributes(current_hob);
311 break;
Lee Leahy3dad4892015-05-05 11:14:02 -0700312 case EFI_HOB_TYPE_RESOURCE_DESCRIPTOR:
Lee Leahyb5ad8272015-04-20 15:29:16 -0700313 print_hob_resource_attributes(current_hob);
314 break;
Lee Leahy3dad4892015-05-05 11:14:02 -0700315 }
316 }
317
Lee Leahyb5ad8272015-04-20 15:29:16 -0700318 /* Check for end of HOB list */
319 last_hob = END_OF_HOB_LIST(current_hob);
320 if (!last_hob) {
321 /* Get next HOB pointer */
322 next_hob = GET_NEXT_HOB(current_hob);
323
324 /* Start on next HOB */
325 current_hob = next_hob;
Lee Leahy3dad4892015-05-05 11:14:02 -0700326 }
Lee Leahyb5ad8272015-04-20 15:29:16 -0700327 } while (!last_hob);
Lee Leahy3dad4892015-05-05 11:14:02 -0700328 printk(BIOS_DEBUG, "=== End of FSP HOB Data Structure ===\n\n");
329}