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