1// SPDX-License-Identifier: Intel
2/*
3 * Copyright (C) 2013, Intel Corporation
4 * Copyright (C) 2014, Bin Meng <bmeng.cn@gmail.com>
5 */
6
7#include <common.h>
8#include <asm/hob.h>
9
10/**
11 * Returns the next instance of a HOB type from the starting HOB.
12 *
13 * @type:     HOB type to search
14 * @hob_list: A pointer to the HOB list
15 *
16 * Return: A HOB object with matching type; Otherwise NULL.
17 */
18const struct hob_header *hob_get_next_hob(uint type, const void *hob_list)
19{
20	const struct hob_header *hdr;
21
22	hdr = hob_list;
23
24	/* Parse the HOB list until end of list or matching type is found */
25	while (!end_of_hob(hdr)) {
26		if (hdr->type == type)
27			return hdr;
28
29		hdr = get_next_hob(hdr);
30	}
31
32	return NULL;
33}
34
35/**
36 * Returns the next instance of the matched GUID HOB from the starting HOB.
37 *
38 * @guid:     GUID to search
39 * @hob_list: A pointer to the HOB list
40 *
41 * Return: A HOB object with matching GUID; Otherwise NULL.
42 */
43const struct hob_header *hob_get_next_guid_hob(const efi_guid_t *guid,
44					       const void *hob_list)
45{
46	const struct hob_header *hdr;
47	struct hob_guid *guid_hob;
48
49	hdr = hob_list;
50	while ((hdr = hob_get_next_hob(HOB_TYPE_GUID_EXT, hdr))) {
51		guid_hob = (struct hob_guid *)hdr;
52		if (!guidcmp(guid, &guid_hob->name))
53			break;
54		hdr = get_next_hob(hdr);
55	}
56
57	return hdr;
58}
59
60/**
61 * This function retrieves a GUID HOB data buffer and size.
62 *
63 * @hob_list:      A HOB list pointer.
64 * @len:           A pointer to the GUID HOB data buffer length.
65 *                 If the GUID HOB is located, the length will be updated.
66 * @guid           A pointer to HOB GUID.
67 *
68 * Return: NULL:   Failed to find the GUID HOB.
69 * Return: others: GUID HOB data buffer pointer.
70 */
71void *hob_get_guid_hob_data(const void *hob_list, u32 *len,
72			    const efi_guid_t *guid)
73{
74	const struct hob_header *guid_hob;
75
76	guid_hob = hob_get_next_guid_hob(guid, hob_list);
77	if (!guid_hob)
78		return NULL;
79
80	if (len)
81		*len = get_guid_hob_data_size(guid_hob);
82
83	return get_guid_hob_data(guid_hob);
84}
85