coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
hand_off_block.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
3 #include <device/mmio.h>
4 #include <cbmem.h>
5 #include <commonlib/helpers.h>
6 #include <console/console.h>
7 #include <fsp/api.h>
8 #include <fsp/util.h>
9 #include <stdint.h>
10 #include <string.h>
11 
12 #define HOB_HEADER_LEN 8
13 
14 /* GUIDs in little-endian, so they can be used with memcmp() */
16  0x56, 0x4f, 0xff, 0x73, 0x8e, 0xaa, 0x51, 0x44,
17  0xb3, 0x16, 0x36, 0x35, 0x36, 0x67, 0xad, 0x44,
18 };
19 
21  0x59, 0x97, 0xa7, 0x69, 0x73, 0x13, 0x67, 0x43,
22  0xa6, 0xc4, 0xc7, 0xf5, 0x9e, 0xfd, 0x98, 0x6e,
23 };
24 
26  0x8f, 0x78, 0x66, 0x48, 0xa8, 0x6b, 0xd8, 0x47,
27  0x83, 0x6, 0xac, 0xf7, 0x7f, 0x55, 0x10, 0x46
28 };
29 
31  0x02, 0xcf, 0x1a, 0x72, 0x77, 0x4d, 0x2a, 0x4c,
32  0xb3, 0xdc, 0x27, 0x0b, 0x7b, 0xa9, 0xe4, 0xb0
33 };
34 
35 static const uint8_t uuid_fv_info[16] = {
36  0x2e, 0x72, 0x8e, 0x79, 0xb2, 0x15, 0x13, 0x4e,
37  0x8a, 0xe9, 0x6b, 0xa3, 0x0f, 0xf7, 0xf1, 0x67
38 };
39 
40 /*
41  * Utilities for walking HOBs
42  */
43 
44 bool fsp_guid_compare(const uint8_t guid1[16], const uint8_t guid2[16])
45 {
46  return !memcmp(guid1, guid2, 16);
47 }
48 
49 const struct hob_header *fsp_next_hob(const struct hob_header *parent)
50 {
51  union {
52  const struct hob_header *hob;
54  } hob_walker;
55 
56  hob_walker.hob = parent;
57  hob_walker.addr += parent->length;
58  return hob_walker.hob;
59 }
60 
61 static const void *hob_header_to_struct(const struct hob_header *hob)
62 {
63  union {
64  const struct hob_header *hob_hdr;
65  const void *hob_descr;
67  } hob_walker;
68 
69  hob_walker.hob_hdr = hob;
70  hob_walker.addr += HOB_HEADER_LEN;
71  return hob_walker.hob_descr;
72 }
73 
74 static const void *hob_header_to_extension_hob(const struct hob_header *hob)
75 {
76  union {
77  const struct hob_header *hob_hdr;
78  const void *hob_descr;
80  } hob_walker;
81 
82  hob_walker.hob_hdr = hob;
83  hob_walker.addr += HOB_HEADER_LEN + 16; /* header and 16-byte GUID */
84  return hob_walker.hob_descr;
85 }
86 
87 const
89 {
90  return hob_header_to_struct(hob);
91 }
92 
93 /*
94  * Utilities for locating and identifying HOBs
95  */
96 
97 static void *fsp_hob_list_ptr;
98 
99 static void save_hob_list(int is_recovery)
100 {
101  uint32_t *cbmem_loc;
102  const void *hob_list;
103  cbmem_loc = cbmem_add(CBMEM_ID_FSP_RUNTIME, sizeof(*cbmem_loc));
104  if (cbmem_loc == NULL)
105  die("Error: Could not add cbmem area for hob list.\n");
106  hob_list = fsp_get_hob_list();
107  if (!hob_list)
108  die("Error: Could not locate hob list pointer.\n");
109  *cbmem_loc = (uintptr_t)hob_list;
110 }
111 
113 
114 const void *fsp_get_hob_list(void)
115 {
116  uint32_t *list_loc;
117 
118  if (ENV_ROMSTAGE)
119  return fsp_hob_list_ptr;
120  list_loc = cbmem_find(CBMEM_ID_FSP_RUNTIME);
121  return (list_loc) ? (void *)(uintptr_t)(*list_loc) : NULL;
122 }
123 
125 {
126  return &fsp_hob_list_ptr;
127 }
128 
129 static const
131  const uint8_t guid[16])
132 {
133  const struct hob_resource *res;
134 
135  for (; hob->type != HOB_TYPE_END_OF_HOB_LIST;
136  hob = fsp_next_hob(hob)) {
137 
139  continue;
140 
141  res = fsp_hob_header_to_resource(hob);
142  if (fsp_guid_compare(res->owner_guid, guid))
143  return res;
144  }
145  return NULL;
146 }
147 
148 void fsp_print_guid(const void *base)
149 {
150  uint32_t big;
151  uint16_t mid[2];
152 
153  const uint8_t *id = base;
154  big = read32(id + 0);
155  mid[0] = read16(id + 4);
156  mid[1] = read16(id + 6);
157 
158  printk(BIOS_SPEW, "%08x-%04x-%04x-%02x%02x%02x%02x%02x%02x%02x%02x",
159  big, mid[0], mid[1],
160  id[8], id[9], id[10], id[11], id[12], id[13], id[14], id[15]);
161 }
162 
163 int fsp_find_range_hob(struct range_entry *re, const uint8_t guid[16])
164 {
165  const struct hob_resource *fsp_mem;
166  const void *hob_list = fsp_get_hob_list();
167 
168  if (!hob_list)
169  return -1;
170 
171  range_entry_init(re, 0, 0, 0);
172 
173  fsp_mem = find_resource_hob_by_guid(hob_list, guid);
174 
175  if (!fsp_mem) {
176  fsp_print_guid(guid);
177  printk(BIOS_SPEW, " not found!\n");
178  return -1;
179  }
180 
181  range_entry_init(re, fsp_mem->addr, fsp_mem->addr + fsp_mem->length, 0);
182  return 0;
183 }
184 
186 {
188  die("9.1: FSP_RESERVED_MEMORY_RESOURCE_HOB missing!\n");
189 }
190 
191 const void *fsp_find_extension_hob_by_guid(const uint8_t *guid, size_t *size)
192 {
193  const uint8_t *hob_guid;
194  const struct hob_header *hob = fsp_get_hob_list();
195 
196  if (!hob)
197  return NULL;
198 
199  for (; hob->type != HOB_TYPE_END_OF_HOB_LIST;
200  hob = fsp_next_hob(hob)) {
201 
202  if (hob->type != HOB_TYPE_GUID_EXTENSION)
203  continue;
204 
205  hob_guid = hob_header_to_struct(hob);
206  if (fsp_guid_compare(hob_guid, guid)) {
207  *size = hob->length - (HOB_HEADER_LEN + 16);
208  return hob_header_to_extension_hob(hob);
209  }
210  }
211 
212  return NULL;
213 }
214 
215 static void display_fsp_version_info_hob(const void *hob)
216 {
217 #if CONFIG(DISPLAY_FSP_VERSION_INFO) || CONFIG(DISPLAY_FSP_VERSION_INFO_2)
218 
219  int index, cnt, tcount;
220  char *str_ptr;
221  uint8_t vs;
222 #if CONFIG(DISPLAY_FSP_VERSION_INFO)
223  const FIRMWARE_VERSION_INFO *fvi;
224  const FIRMWARE_VERSION_INFO_HOB *fvih =
225  (FIRMWARE_VERSION_INFO_HOB *)hob;
226 
227  fvi = (void *)&fvih[1];
228  str_ptr = (char *)((uintptr_t)fvi +
229  (fvih->Count * sizeof(FIRMWARE_VERSION_INFO)));
230  tcount = fvih->Count;
231 #elif CONFIG(DISPLAY_FSP_VERSION_INFO_2)
232 
233  uint8_t *hobstart = (uint8_t *) hob;
234  hobstart += sizeof(EFI_HOB_GUID_TYPE);
235 
236  const SMBIOS_TABLE_TYPE_OEM_INTEL_FVI *stfvi =
237  (SMBIOS_TABLE_TYPE_OEM_INTEL_FVI *)hobstart;
238  const INTEL_FIRMWARE_VERSION_INFO *fvi;
239 
240  str_ptr = ((char *) &(stfvi->Fvi[0])) +
241  (stfvi->Count * sizeof(INTEL_FIRMWARE_VERSION_INFO));
242  tcount = stfvi->Count;
243  fvi = &stfvi->Fvi[0];
244 #endif
245 
246  for (index = 0; index < tcount; index++) {
247  cnt = strlen(str_ptr);
248 
249 #if CONFIG(DISPLAY_FSP_VERSION_INFO)
250  vs = fvi[index].VersionStringIndex;
251 #elif CONFIG(DISPLAY_FSP_VERSION_INFO_2)
252  vs = fvi[index].VersionString;
253 #endif
254  /* Don't show ingredient name and version if its all 0xFF */
255  if (fvi[index].Version.MajorVersion == 0xFF &&
256  fvi[index].Version.MinorVersion == 0xFF &&
257  fvi[index].Version.Revision == 0xFF &&
258  fvi[index].Version.BuildNumber == 0xFF &&
259  vs == 0) {
260  str_ptr = (char *)((uintptr_t)str_ptr + cnt +
261  sizeof(uint8_t));
262  continue;
263  }
264  /*
265  * Firmware Version String consist of 2 pieces of information
266  * 1. Component Name: string type data holds FW type name.
267  * 2. Version Information : Either a string type data or
268  * numeric field holds FW version information.
269  */
270  printk(BIOS_DEBUG, "%s = ", str_ptr);
271 
272  if (!vs)
273  printk(BIOS_DEBUG, "%x.%x.%x.%x\n",
274  fvi[index].Version.MajorVersion,
275  fvi[index].Version.MinorVersion,
276  fvi[index].Version.Revision,
277  fvi[index].Version.BuildNumber);
278  else {
279  str_ptr = (char *)((uintptr_t)str_ptr + cnt +
280  sizeof(uint8_t));
281  cnt = strlen(str_ptr);
282  printk(BIOS_DEBUG, "%s\n", str_ptr);
283  }
284  str_ptr = (char *)((uintptr_t)str_ptr + cnt +
285  sizeof(uint8_t));
286  }
287 #endif
288 }
289 
291 {
292  const uint8_t *hob_uuid;
293  const struct hob_header *hob = fsp_get_hob_list();
294 
295  if (!hob)
296  return;
297 
298  printk(BIOS_DEBUG, "Display FSP Version Info HOB\n");
299  for (; hob->type != HOB_TYPE_END_OF_HOB_LIST;
300  hob = fsp_next_hob(hob)) {
301  if (hob->type != HOB_TYPE_GUID_EXTENSION)
302  continue;
303 
304  hob_uuid = hob_header_to_struct(hob);
305 
306  if (fsp_guid_compare(hob_uuid, uuid_fv_info)) {
308  }
309  }
310 }
311 
312 const void *fsp_find_nv_storage_data(size_t *size)
313 {
314  if (CONFIG(PLATFORM_USES_FSP2_3)) {
315  const struct fsp_nvs_hob2_data_region_header *hob;
316 
317  hob = (const struct fsp_nvs_hob2_data_region_header *)
319  if (hob != NULL) {
320  *size = hob->nvs_data_length;
321  return (void *)(uintptr_t)hob->nvs_data_ptr;
322  }
323  }
325 }
326 
328 {
330  die("9.3: FSP_BOOTLOADER_TOLUM_HOB missing!\n");
331 }
static uint16_t read16(const void *addr)
Definition: mmio.h:17
static uint32_t read32(const void *addr)
Definition: mmio.h:22
void * cbmem_add(u32 id, u64 size)
Definition: imd_cbmem.c:144
void * cbmem_find(u32 id)
Definition: imd_cbmem.c:166
#define CBMEM_ID_FSP_RUNTIME
Definition: cbmem_id.h:26
static u32 addr
Definition: cirrus.c:14
#define printk(level,...)
Definition: stdlib.h:16
void __noreturn die(const char *fmt,...)
Definition: die.c:17
@ HOB_TYPE_RESOURCE_DESCRIPTOR
Definition: util.h:93
@ HOB_TYPE_GUID_EXTENSION
Definition: util.h:94
@ HOB_TYPE_END_OF_HOB_LIST
Definition: util.h:102
@ CONFIG
Definition: dsi_common.h:201
void fsp_find_reserved_memory(struct range_entry *re)
const void * fsp_get_hob_list(void)
const uint8_t fsp_nv_storage_guid_2[16]
void fsp_display_fvi_version_hob(void)
const uint8_t fsp_reserved_memory_guid[16]
const void * fsp_find_extension_hob_by_guid(const uint8_t *guid, size_t *size)
void fsp_print_guid(const void *base)
const void * fsp_find_nv_storage_data(size_t *size)
void * fsp_get_hob_list_ptr(void)
const uint8_t fsp_nv_storage_guid[16]
static const void * hob_header_to_struct(const struct hob_header *hob)
static void save_hob_list(int is_recovery)
const struct hob_resource * fsp_hob_header_to_resource(const struct hob_header *hob)
#define HOB_HEADER_LEN
const uint8_t fsp_bootloader_tolum_guid[16]
int fsp_find_range_hob(struct range_entry *re, const uint8_t guid[16])
static void * fsp_hob_list_ptr
static const struct hob_resource * find_resource_hob_by_guid(const struct hob_header *hob, const uint8_t guid[16])
const struct hob_header * fsp_next_hob(const struct hob_header *parent)
bool fsp_guid_compare(const uint8_t guid1[16], const uint8_t guid2[16])
static const uint8_t uuid_fv_info[16]
void fsp_find_bootloader_tolum(struct range_entry *re)
static const void * hob_header_to_extension_hob(const struct hob_header *hob)
ROMSTAGE_CBMEM_INIT_HOOK(save_hob_list)
static void display_fsp_version_info_hob(const void *hob)
#define BIOS_DEBUG
BIOS_DEBUG - Verbose output.
Definition: loglevel.h:128
#define BIOS_SPEW
BIOS_SPEW - Excessively verbose output.
Definition: loglevel.h:142
static void range_entry_init(struct range_entry *re, resource_t incl_begin, resource_t excl_end, unsigned long tag)
Definition: memrange.h:33
#define ENV_ROMSTAGE
Definition: rules.h:149
uintptr_t base
Definition: uart.c:17
#define NULL
Definition: stddef.h:19
unsigned short uint16_t
Definition: stdint.h:11
unsigned int uint32_t
Definition: stdint.h:14
unsigned long uintptr_t
Definition: stdint.h:21
unsigned char uint8_t
Definition: stdint.h:8
int memcmp(const void *s1, const void *s2, size_t n)
Definition: memcmp.c:3
size_t strlen(const char *src)
Definition: string.c:42
efi_physical_address nvs_data_ptr
Definition: util.h:32
uint16_t length
Definition: util.h:28
uint16_t type
Definition: util.h:27
uint64_t length
Definition: util.h:56
uint8_t owner_guid[16]
Definition: util.h:52
uint64_t addr
Definition: util.h:55
Definition: memrange.h:24