1cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler/* Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
2e1a25ab10804338a6a669a256bd320139f850648Louis Yung-Chieh Lo * Use of this source code is governed by a BSD-style license that can be
3e1a25ab10804338a6a669a256bd320139f850648Louis Yung-Chieh Lo * found in the LICENSE file.
4e1a25ab10804338a6a669a256bd320139f850648Louis Yung-Chieh Lo */
5e1a25ab10804338a6a669a256bd320139f850648Louis Yung-Chieh Lo
60c3ba249abb1dc60f5ebabccf84ff13206440b83Bill Richardson#include "sysincludes.h"
70c3ba249abb1dc60f5ebabccf84ff13206440b83Bill Richardson
80dce41c2ece9020d5ac9bb68c9772432fac85e64Louis Yung-Chieh Lo#include "cgptlib.h"
90dce41c2ece9020d5ac9bb68c9772432fac85e64Louis Yung-Chieh Lo#include "cgptlib_internal.h"
1049fa8e51ad4dff55b74d852d270ce5d0b9590034Louis Yung-Chieh Lo#include "crc32.h"
1137f6b55a25f337f555da1dfbe585d32cd004103dLouis Yung-Chieh Lo#include "gpt.h"
1237f6b55a25f337f555da1dfbe585d32cd004103dLouis Yung-Chieh Lo#include "utility.h"
13e49e8af65fce38da7a308305566f8a14f102254aRandall Spangler#include "vboot_api.h"
14e1a25ab10804338a6a669a256bd320139f850648Louis Yung-Chieh Lo
15cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spanglerint GptInit(GptData *gpt)
16cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler{
17cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler	int retval;
18b31ddcec6a826986cd215725bf4defbc6021fe6bLouis Yung-Chieh Lo
19cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler	gpt->modified = 0;
20cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler	gpt->current_kernel = CGPT_KERNEL_ENTRY_NOT_FOUND;
21cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler	gpt->current_priority = 999;
2249fa8e51ad4dff55b74d852d270ce5d0b9590034Louis Yung-Chieh Lo
23cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler	retval = GptSanityCheck(gpt);
24cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler	if (GPT_SUCCESS != retval) {
25cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler		VBDEBUG(("GptInit() failed sanity check\n"));
26cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler		return retval;
27cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler	}
2849fa8e51ad4dff55b74d852d270ce5d0b9590034Louis Yung-Chieh Lo
29cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler	GptRepair(gpt);
30cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler	return GPT_SUCCESS;
3149fa8e51ad4dff55b74d852d270ce5d0b9590034Louis Yung-Chieh Lo}
3249fa8e51ad4dff55b74d852d270ce5d0b9590034Louis Yung-Chieh Lo
33cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spanglerint GptNextKernelEntry(GptData *gpt, uint64_t *start_sector, uint64_t *size)
34cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler{
35cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler	GptHeader *header = (GptHeader *)gpt->primary_header;
36cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler	GptEntry *entries = (GptEntry *)gpt->primary_entries;
37cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler	GptEntry *e;
38cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler	int new_kernel = CGPT_KERNEL_ENTRY_NOT_FOUND;
39cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler	int new_prio = 0;
40cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler	uint32_t i;
41cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler
42cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler	/*
43cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler	 * If we already found a kernel, continue the scan at the current
44cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler	 * kernel's priority, in case there is another kernel with the same
45cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler	 * priority.
46cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler	 */
47cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler	if (gpt->current_kernel != CGPT_KERNEL_ENTRY_NOT_FOUND) {
48cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler		for (i = gpt->current_kernel + 1;
49cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler		     i < header->number_of_entries; i++) {
50cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler			e = entries + i;
51cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler			if (!IsKernelEntry(e))
52cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler				continue;
53cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler			VBDEBUG(("GptNextKernelEntry looking at same prio "
54cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler				 "partition %d\n", i+1));
55cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler			VBDEBUG(("GptNextKernelEntry s%d t%d p%d\n",
56cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler				 GetEntrySuccessful(e), GetEntryTries(e),
57cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler				 GetEntryPriority(e)));
58cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler			if (!(GetEntrySuccessful(e) || GetEntryTries(e)))
59cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler				continue;
60cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler			if (GetEntryPriority(e) == gpt->current_priority) {
61cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler				gpt->current_kernel = i;
62cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler				*start_sector = e->starting_lba;
63cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler				*size = e->ending_lba - e->starting_lba + 1;
64cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler				VBDEBUG(("GptNextKernelEntry likes it\n"));
65cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler				return GPT_SUCCESS;
66cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler			}
67cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler		}
68cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler	}
69cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler
70cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler	/*
71cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler	 * We're still here, so scan for the remaining kernel with the highest
72cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler	 * priority less than the previous attempt.
73cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler	 */
74cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler	for (i = 0, e = entries; i < header->number_of_entries; i++, e++) {
75cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler		int current_prio = GetEntryPriority(e);
76cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler		if (!IsKernelEntry(e))
77cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler			continue;
78cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler		VBDEBUG(("GptNextKernelEntry looking at new prio "
79cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler			 "partition %d\n", i+1));
80cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler		VBDEBUG(("GptNextKernelEntry s%d t%d p%d\n",
81cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler			 GetEntrySuccessful(e), GetEntryTries(e),
82cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler			 GetEntryPriority(e)));
83cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler		if (!(GetEntrySuccessful(e) || GetEntryTries(e)))
84cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler			continue;
85cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler		if (current_prio >= gpt->current_priority) {
86cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler			/* Already returned this kernel in a previous call */
87cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler			continue;
88cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler		}
89cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler		if (current_prio > new_prio) {
90cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler			new_kernel = i;
91cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler			new_prio = current_prio;
92cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler		}
93cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler	}
94cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler
95cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler	/*
96cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler	 * Save what we found.  Note that if we didn't find a new kernel,
97cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler	 * new_prio will still be -1, so future calls to this function will
98cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler	 * also fail.
99cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler	 */
100cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler	gpt->current_kernel = new_kernel;
101cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler	gpt->current_priority = new_prio;
102cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler
103cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler	if (CGPT_KERNEL_ENTRY_NOT_FOUND == new_kernel) {
104cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler		VBDEBUG(("GptNextKernelEntry no more kernels\n"));
105cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler		return GPT_ERROR_NO_VALID_KERNEL;
106cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler	}
107cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler
108cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler	VBDEBUG(("GptNextKernelEntry likes partition %d\n", new_kernel + 1));
109cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler	e = entries + new_kernel;
110cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler	*start_sector = e->starting_lba;
111cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler	*size = e->ending_lba - e->starting_lba + 1;
112cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler	return GPT_SUCCESS;
113e1a25ab10804338a6a669a256bd320139f850648Louis Yung-Chieh Lo}
114e1a25ab10804338a6a669a256bd320139f850648Louis Yung-Chieh Lo
115f620c0d6560dcb5c6b6b004bd50f4713f191d381Furquan Shaikh/*
116f620c0d6560dcb5c6b6b004bd50f4713f191d381Furquan Shaikh * Func: GptUpdateKernelWithEntry
117f620c0d6560dcb5c6b6b004bd50f4713f191d381Furquan Shaikh * Desc: This function updates the given kernel entry according to the provided
118f620c0d6560dcb5c6b6b004bd50f4713f191d381Furquan Shaikh * update_type.
119f620c0d6560dcb5c6b6b004bd50f4713f191d381Furquan Shaikh */
120f620c0d6560dcb5c6b6b004bd50f4713f191d381Furquan Shaikhint GptUpdateKernelWithEntry(GptData *gpt, GptEntry *e, uint32_t update_type)
121cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler{
1225c9e4532b9bc45cff22f37d3556da679809a60a7Albert Chaulk	int modified = 0;
123cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler
124cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler	if (!IsKernelEntry(e))
125cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler		return GPT_ERROR_INVALID_UPDATE_TYPE;
126cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler
127cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler	switch (update_type) {
128cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler	case GPT_UPDATE_ENTRY_TRY: {
129cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler		/* Used up a try */
130cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler		int tries;
131cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler		if (GetEntrySuccessful(e)) {
132cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler			/*
133cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler			 * Successfully booted this partition, so tries field
134cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler			 * is ignored.
135cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler			 */
136cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler			return GPT_SUCCESS;
137cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler		}
138cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler		tries = GetEntryTries(e);
139cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler		if (tries > 1) {
140cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler			/* Still have tries left */
1415c9e4532b9bc45cff22f37d3556da679809a60a7Albert Chaulk			modified = 1;
142cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler			SetEntryTries(e, tries - 1);
143cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler			break;
144cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler		}
145cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler		/* Out of tries, so drop through and mark partition bad. */
146cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler	}
147cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler	case GPT_UPDATE_ENTRY_BAD: {
148cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler		/* Giving up on this partition entirely. */
149cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler		if (!GetEntrySuccessful(e)) {
150cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler			/*
151cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler			 * Only clear tries and priority if the successful bit
152cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler			 * is not set.
153cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler			 */
1545c9e4532b9bc45cff22f37d3556da679809a60a7Albert Chaulk			modified = 1;
1555c9e4532b9bc45cff22f37d3556da679809a60a7Albert Chaulk			SetEntryTries(e, 0);
1565c9e4532b9bc45cff22f37d3556da679809a60a7Albert Chaulk			SetEntryPriority(e, 0);
157cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler		}
158cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler		break;
159cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler	}
160f620c0d6560dcb5c6b6b004bd50f4713f191d381Furquan Shaikh	case GPT_UPDATE_ENTRY_RESET: {
161f620c0d6560dcb5c6b6b004bd50f4713f191d381Furquan Shaikh		/*
162f620c0d6560dcb5c6b6b004bd50f4713f191d381Furquan Shaikh		 * Used for fastboot mode. If image is written to kernel
163f620c0d6560dcb5c6b6b004bd50f4713f191d381Furquan Shaikh		 * partition, its GPT entry is marked with S1,P1,T15
164f620c0d6560dcb5c6b6b004bd50f4713f191d381Furquan Shaikh		 */
165f620c0d6560dcb5c6b6b004bd50f4713f191d381Furquan Shaikh		modified = 1;
166f620c0d6560dcb5c6b6b004bd50f4713f191d381Furquan Shaikh		SetEntryTries(e, 15);
167f620c0d6560dcb5c6b6b004bd50f4713f191d381Furquan Shaikh		SetEntryPriority(e, 1);
168f620c0d6560dcb5c6b6b004bd50f4713f191d381Furquan Shaikh		SetEntrySuccessful(e, 1);
169f620c0d6560dcb5c6b6b004bd50f4713f191d381Furquan Shaikh		break;
170f620c0d6560dcb5c6b6b004bd50f4713f191d381Furquan Shaikh	}
171f620c0d6560dcb5c6b6b004bd50f4713f191d381Furquan Shaikh	case GPT_UPDATE_ENTRY_INVALID: {
172f620c0d6560dcb5c6b6b004bd50f4713f191d381Furquan Shaikh		/*
173f620c0d6560dcb5c6b6b004bd50f4713f191d381Furquan Shaikh		 * Used for fastboot mode. If kernel partition is erased, its
174f620c0d6560dcb5c6b6b004bd50f4713f191d381Furquan Shaikh		 * GPT entry is marked with S0,P0,T0
175f620c0d6560dcb5c6b6b004bd50f4713f191d381Furquan Shaikh		 */
176f620c0d6560dcb5c6b6b004bd50f4713f191d381Furquan Shaikh		modified = 1;
177f620c0d6560dcb5c6b6b004bd50f4713f191d381Furquan Shaikh		SetEntryTries(e, 0);
178f620c0d6560dcb5c6b6b004bd50f4713f191d381Furquan Shaikh		SetEntryPriority(e, 0);
179f620c0d6560dcb5c6b6b004bd50f4713f191d381Furquan Shaikh		SetEntrySuccessful(e, 0);
180f620c0d6560dcb5c6b6b004bd50f4713f191d381Furquan Shaikh		break;
181f620c0d6560dcb5c6b6b004bd50f4713f191d381Furquan Shaikh	}
182cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler	default:
183cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler		return GPT_ERROR_INVALID_UPDATE_TYPE;
184cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler	}
185cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler
1865c9e4532b9bc45cff22f37d3556da679809a60a7Albert Chaulk	if (modified) {
1875c9e4532b9bc45cff22f37d3556da679809a60a7Albert Chaulk		GptModified(gpt);
1885c9e4532b9bc45cff22f37d3556da679809a60a7Albert Chaulk	}
189cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler
190cefe12c105a91e6ee9f44bca218bd6e4f89bcb71Randall Spangler	return GPT_SUCCESS;
191e1a25ab10804338a6a669a256bd320139f850648Louis Yung-Chieh Lo}
192f620c0d6560dcb5c6b6b004bd50f4713f191d381Furquan Shaikh
193f620c0d6560dcb5c6b6b004bd50f4713f191d381Furquan Shaikh/*
194f620c0d6560dcb5c6b6b004bd50f4713f191d381Furquan Shaikh * Func: GptUpdateKernelEntry
195f620c0d6560dcb5c6b6b004bd50f4713f191d381Furquan Shaikh * Desc: This function updates current_kernel entry with provided
196f620c0d6560dcb5c6b6b004bd50f4713f191d381Furquan Shaikh * update_type. If current_kernel is not set, then it returns error.
197f620c0d6560dcb5c6b6b004bd50f4713f191d381Furquan Shaikh */
198f620c0d6560dcb5c6b6b004bd50f4713f191d381Furquan Shaikhint GptUpdateKernelEntry(GptData *gpt, uint32_t update_type)
199f620c0d6560dcb5c6b6b004bd50f4713f191d381Furquan Shaikh{
200f620c0d6560dcb5c6b6b004bd50f4713f191d381Furquan Shaikh	GptEntry *entries = (GptEntry *)gpt->primary_entries;
201f620c0d6560dcb5c6b6b004bd50f4713f191d381Furquan Shaikh	GptEntry *e = entries + gpt->current_kernel;
202f620c0d6560dcb5c6b6b004bd50f4713f191d381Furquan Shaikh
203f620c0d6560dcb5c6b6b004bd50f4713f191d381Furquan Shaikh	if (gpt->current_kernel == CGPT_KERNEL_ENTRY_NOT_FOUND)
204f620c0d6560dcb5c6b6b004bd50f4713f191d381Furquan Shaikh		return GPT_ERROR_INVALID_UPDATE_TYPE;
205f620c0d6560dcb5c6b6b004bd50f4713f191d381Furquan Shaikh
206f620c0d6560dcb5c6b6b004bd50f4713f191d381Furquan Shaikh	return GptUpdateKernelWithEntry(gpt, e, update_type);
207f620c0d6560dcb5c6b6b004bd50f4713f191d381Furquan Shaikh}
208f620c0d6560dcb5c6b6b004bd50f4713f191d381Furquan Shaikh
209f620c0d6560dcb5c6b6b004bd50f4713f191d381Furquan Shaikh/*
210f620c0d6560dcb5c6b6b004bd50f4713f191d381Furquan Shaikh * Func: GptFindNthEntry
211f620c0d6560dcb5c6b6b004bd50f4713f191d381Furquan Shaikh * Desc: This function returns the nth instance of parition entry matching the
212f620c0d6560dcb5c6b6b004bd50f4713f191d381Furquan Shaikh * partition type guid from the gpt table. Instance value starts from 0. If the
213f620c0d6560dcb5c6b6b004bd50f4713f191d381Furquan Shaikh * entry is not found it returns NULL.
214f620c0d6560dcb5c6b6b004bd50f4713f191d381Furquan Shaikh */
215f620c0d6560dcb5c6b6b004bd50f4713f191d381Furquan ShaikhGptEntry *GptFindNthEntry(GptData *gpt, const Guid *guid, unsigned int n)
216f620c0d6560dcb5c6b6b004bd50f4713f191d381Furquan Shaikh{
217f620c0d6560dcb5c6b6b004bd50f4713f191d381Furquan Shaikh	GptHeader *header = (GptHeader *)gpt->primary_header;
218f620c0d6560dcb5c6b6b004bd50f4713f191d381Furquan Shaikh	GptEntry *entries = (GptEntry *)gpt->primary_entries;
219f620c0d6560dcb5c6b6b004bd50f4713f191d381Furquan Shaikh	GptEntry *e;
220f620c0d6560dcb5c6b6b004bd50f4713f191d381Furquan Shaikh	int i;
221f620c0d6560dcb5c6b6b004bd50f4713f191d381Furquan Shaikh
222f620c0d6560dcb5c6b6b004bd50f4713f191d381Furquan Shaikh	for (i = 0, e = entries; i < header->number_of_entries; i++, e++) {
223f620c0d6560dcb5c6b6b004bd50f4713f191d381Furquan Shaikh		if (!Memcmp(&e->type, guid, sizeof(*guid))) {
224f620c0d6560dcb5c6b6b004bd50f4713f191d381Furquan Shaikh			if (n == 0)
225f620c0d6560dcb5c6b6b004bd50f4713f191d381Furquan Shaikh				return e;
226f620c0d6560dcb5c6b6b004bd50f4713f191d381Furquan Shaikh			n--;
227f620c0d6560dcb5c6b6b004bd50f4713f191d381Furquan Shaikh		}
228f620c0d6560dcb5c6b6b004bd50f4713f191d381Furquan Shaikh	}
229f620c0d6560dcb5c6b6b004bd50f4713f191d381Furquan Shaikh
230f620c0d6560dcb5c6b6b004bd50f4713f191d381Furquan Shaikh	return NULL;
231f620c0d6560dcb5c6b6b004bd50f4713f191d381Furquan Shaikh}
232