blob: 4aa364726eae44400c08505a1a46c6494c84ed8f [file] [log] [blame]
richardretanubun07f3d782008-09-26 11:13:22 -04001/*
2 * Copyright (C) 2008 RuggedCom, Inc.
3 * Richard Retanubun <RichardRetanubun@RuggedCom.com>
4 *
5 * See file CREDITS for list of people who contributed to this
6 * project.
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of
11 * the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21 * MA 02111-1307 USA
22 */
23
24/*
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +020025 * Problems with CONFIG_SYS_64BIT_LBA:
richardretanubun07f3d782008-09-26 11:13:22 -040026 *
27 * struct disk_partition.start in include/part.h is sized as ulong.
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +020028 * When CONFIG_SYS_64BIT_LBA is activated, lbaint_t changes from ulong to uint64_t.
richardretanubun07f3d782008-09-26 11:13:22 -040029 * For now, it is cast back to ulong at assignment.
30 *
31 * This limits the maximum size of addressable storage to < 2 Terra Bytes
32 */
33#include <common.h>
34#include <command.h>
35#include <ide.h>
36#include <malloc.h>
Chang Hyun Parkfae2bf22012-12-11 11:09:45 +010037#include <part_efi.h>
Lei Wen6eecc032011-09-07 18:11:19 +000038#include <linux/ctype.h>
richardretanubun07f3d782008-09-26 11:13:22 -040039
Mike Frysinger7bd27222009-01-29 20:02:07 -050040#if defined(CONFIG_CMD_IDE) || \
41 defined(CONFIG_CMD_SATA) || \
42 defined(CONFIG_CMD_SCSI) || \
43 defined(CONFIG_CMD_USB) || \
44 defined(CONFIG_MMC) || \
45 defined(CONFIG_SYSTEMACE)
richardretanubun07f3d782008-09-26 11:13:22 -040046
richardretanubun07f3d782008-09-26 11:13:22 -040047/**
48 * efi_crc32() - EFI version of crc32 function
49 * @buf: buffer to calculate crc32 of
50 * @len - length of buf
51 *
52 * Description: Returns EFI-style CRC32 value for @buf
53 */
Chang Hyun Parkfae2bf22012-12-11 11:09:45 +010054static inline u32 efi_crc32(const void *buf, u32 len)
richardretanubun07f3d782008-09-26 11:13:22 -040055{
56 return crc32(0, buf, len);
57}
58
59/*
60 * Private function prototypes
61 */
62
63static int pmbr_part_valid(struct partition *part);
64static int is_pmbr_valid(legacy_mbr * mbr);
65
66static int is_gpt_valid(block_dev_desc_t * dev_desc, unsigned long long lba,
67 gpt_header * pgpt_head, gpt_entry ** pgpt_pte);
68
69static gpt_entry *alloc_read_gpt_entries(block_dev_desc_t * dev_desc,
70 gpt_header * pgpt_head);
71
72static int is_pte_valid(gpt_entry * pte);
73
Lei Wen6eecc032011-09-07 18:11:19 +000074static char *print_efiname(gpt_entry *pte)
75{
76 static char name[PARTNAME_SZ + 1];
77 int i;
78 for (i = 0; i < PARTNAME_SZ; i++) {
79 u8 c;
80 c = pte->partition_name[i] & 0xff;
81 c = (c && !isprint(c)) ? '.' : c;
82 name[i] = c;
83 }
84 name[PARTNAME_SZ] = 0;
85 return name;
86}
87
Stephen Warren894bfbb2012-09-21 09:50:59 +000088static void uuid_string(unsigned char *uuid, char *str)
89{
90 static const u8 le[16] = {3, 2, 1, 0, 5, 4, 7, 6, 8, 9, 10, 11,
91 12, 13, 14, 15};
92 int i;
93
94 for (i = 0; i < 16; i++) {
95 sprintf(str, "%02x", uuid[le[i]]);
96 str += 2;
97 switch (i) {
98 case 3:
99 case 5:
100 case 7:
101 case 9:
102 *str++ = '-';
103 break;
104 }
105 }
106}
Stephen Warrenf07cd2c2012-10-08 08:14:34 +0000107
Stephen Warrenb4414f42012-10-08 08:14:37 +0000108static efi_guid_t system_guid = PARTITION_SYSTEM_GUID;
109
110static inline int is_bootable(gpt_entry *p)
111{
112 return p->attributes.fields.legacy_bios_bootable ||
113 !memcmp(&(p->partition_type_guid), &system_guid,
114 sizeof(efi_guid_t));
115}
116
Stephen Warrenf07cd2c2012-10-08 08:14:34 +0000117/*
118 * Public Functions (include/part.h)
119 */
120
121void print_part_efi(block_dev_desc_t * dev_desc)
122{
123 ALLOC_CACHE_ALIGN_BUFFER(gpt_header, gpt_head, 1);
124 gpt_entry *gpt_pte = NULL;
125 int i = 0;
126 char uuid[37];
127
128 if (!dev_desc) {
129 printf("%s: Invalid Argument(s)\n", __func__);
130 return;
131 }
132 /* This function validates AND fills in the GPT header and PTE */
133 if (is_gpt_valid(dev_desc, GPT_PRIMARY_PARTITION_TABLE_LBA,
134 gpt_head, &gpt_pte) != 1) {
135 printf("%s: *** ERROR: Invalid GPT ***\n", __func__);
136 return;
137 }
138
139 debug("%s: gpt-entry at %p\n", __func__, gpt_pte);
140
141 printf("Part\tStart LBA\tEnd LBA\t\tName\n");
Stephen Warren13bf2f52012-10-08 08:14:36 +0000142 printf("\tAttributes\n");
Stephen Warrenf07cd2c2012-10-08 08:14:34 +0000143 printf("\tType UUID\n");
144 printf("\tPartition UUID\n");
145
Chang Hyun Parkfae2bf22012-12-11 11:09:45 +0100146 for (i = 0; i < le32_to_cpu(gpt_head->num_partition_entries); i++) {
Stephen Warrenf07cd2c2012-10-08 08:14:34 +0000147 /* Stop at the first non valid PTE */
148 if (!is_pte_valid(&gpt_pte[i]))
149 break;
150
151 printf("%3d\t0x%08llx\t0x%08llx\t\"%s\"\n", (i + 1),
Chang Hyun Parkfae2bf22012-12-11 11:09:45 +0100152 le64_to_cpu(gpt_pte[i].starting_lba),
153 le64_to_cpu(gpt_pte[i].ending_lba),
Stephen Warrenf07cd2c2012-10-08 08:14:34 +0000154 print_efiname(&gpt_pte[i]));
Stephen Warren13bf2f52012-10-08 08:14:36 +0000155 printf("\tattrs:\t0x%016llx\n", gpt_pte[i].attributes.raw);
Stephen Warrenf07cd2c2012-10-08 08:14:34 +0000156 uuid_string(gpt_pte[i].partition_type_guid.b, uuid);
157 printf("\ttype:\t%s\n", uuid);
158 uuid_string(gpt_pte[i].unique_partition_guid.b, uuid);
159 printf("\tuuid:\t%s\n", uuid);
160 }
161
162 /* Remember to free pte */
163 free(gpt_pte);
164 return;
165}
Stephen Warren894bfbb2012-09-21 09:50:59 +0000166
richardretanubun07f3d782008-09-26 11:13:22 -0400167int get_partition_info_efi(block_dev_desc_t * dev_desc, int part,
168 disk_partition_t * info)
169{
Anton staaff75dd582011-10-12 13:56:04 +0000170 ALLOC_CACHE_ALIGN_BUFFER(gpt_header, gpt_head, 1);
Doug Andersondeb5ca82011-10-19 09:47:31 +0000171 gpt_entry *gpt_pte = NULL;
richardretanubun07f3d782008-09-26 11:13:22 -0400172
173 /* "part" argument must be at least 1 */
174 if (!dev_desc || !info || part < 1) {
Doug Andersondf70b1c2011-10-19 08:04:46 +0000175 printf("%s: Invalid Argument(s)\n", __func__);
richardretanubun07f3d782008-09-26 11:13:22 -0400176 return -1;
177 }
178
179 /* This function validates AND fills in the GPT header and PTE */
180 if (is_gpt_valid(dev_desc, GPT_PRIMARY_PARTITION_TABLE_LBA,
Stephen Warren4715a812011-10-28 09:21:46 +0000181 gpt_head, &gpt_pte) != 1) {
Doug Andersondf70b1c2011-10-19 08:04:46 +0000182 printf("%s: *** ERROR: Invalid GPT ***\n", __func__);
richardretanubun07f3d782008-09-26 11:13:22 -0400183 return -1;
184 }
185
Chang Hyun Parkfae2bf22012-12-11 11:09:45 +0100186 if (part > le32_to_cpu(gpt_head->num_partition_entries) ||
Stephen Warrenc04d68c2012-09-21 09:50:58 +0000187 !is_pte_valid(&gpt_pte[part - 1])) {
188 printf("%s: *** ERROR: Invalid partition number %d ***\n",
189 __func__, part);
190 return -1;
191 }
192
richardretanubun07f3d782008-09-26 11:13:22 -0400193 /* The ulong casting limits the maximum disk size to 2 TB */
Chang Hyun Parkfae2bf22012-12-11 11:09:45 +0100194 info->start = (u64)le64_to_cpu(gpt_pte[part - 1].starting_lba);
Richard Retanubun50970832009-01-26 08:45:14 -0500195 /* The ending LBA is inclusive, to calculate size, add 1 to it */
Chang Hyun Parkfae2bf22012-12-11 11:09:45 +0100196 info->size = ((u64)le64_to_cpu(gpt_pte[part - 1].ending_lba) + 1)
Richard Retanubun50970832009-01-26 08:45:14 -0500197 - info->start;
richardretanubun07f3d782008-09-26 11:13:22 -0400198 info->blksz = GPT_BLOCK_SIZE;
199
Lei Wen6eecc032011-09-07 18:11:19 +0000200 sprintf((char *)info->name, "%s",
Doug Andersondeb5ca82011-10-19 09:47:31 +0000201 print_efiname(&gpt_pte[part - 1]));
richardretanubun07f3d782008-09-26 11:13:22 -0400202 sprintf((char *)info->type, "U-Boot");
Stephen Warrenb4414f42012-10-08 08:14:37 +0000203 info->bootable = is_bootable(&gpt_pte[part - 1]);
Stephen Warren894bfbb2012-09-21 09:50:59 +0000204#ifdef CONFIG_PARTITION_UUIDS
205 uuid_string(gpt_pte[part - 1].unique_partition_guid.b, info->uuid);
206#endif
richardretanubun07f3d782008-09-26 11:13:22 -0400207
Doug Andersondf70b1c2011-10-19 08:04:46 +0000208 debug("%s: start 0x%lX, size 0x%lX, name %s", __func__,
richardretanubun07f3d782008-09-26 11:13:22 -0400209 info->start, info->size, info->name);
210
211 /* Remember to free pte */
Doug Andersondeb5ca82011-10-19 09:47:31 +0000212 free(gpt_pte);
richardretanubun07f3d782008-09-26 11:13:22 -0400213 return 0;
214}
215
216int test_part_efi(block_dev_desc_t * dev_desc)
217{
Anton staaff75dd582011-10-12 13:56:04 +0000218 ALLOC_CACHE_ALIGN_BUFFER(legacy_mbr, legacymbr, 1);
richardretanubun07f3d782008-09-26 11:13:22 -0400219
220 /* Read legacy MBR from block 0 and validate it */
Anton staaff75dd582011-10-12 13:56:04 +0000221 if ((dev_desc->block_read(dev_desc->dev, 0, 1, (ulong *)legacymbr) != 1)
222 || (is_pmbr_valid(legacymbr) != 1)) {
richardretanubun07f3d782008-09-26 11:13:22 -0400223 return -1;
224 }
225 return 0;
226}
227
228/*
229 * Private functions
230 */
231/*
232 * pmbr_part_valid(): Check for EFI partition signature
233 *
234 * Returns: 1 if EFI GPT partition type is found.
235 */
236static int pmbr_part_valid(struct partition *part)
237{
238 if (part->sys_ind == EFI_PMBR_OSTYPE_EFI_GPT &&
Chang Hyun Parkfae2bf22012-12-11 11:09:45 +0100239 le32_to_cpu(part->start_sect) == 1UL) {
richardretanubun07f3d782008-09-26 11:13:22 -0400240 return 1;
241 }
242
243 return 0;
244}
245
246/*
247 * is_pmbr_valid(): test Protective MBR for validity
248 *
249 * Returns: 1 if PMBR is valid, 0 otherwise.
250 * Validity depends on two things:
251 * 1) MSDOS signature is in the last two bytes of the MBR
252 * 2) One partition of type 0xEE is found, checked by pmbr_part_valid()
253 */
254static int is_pmbr_valid(legacy_mbr * mbr)
255{
256 int i = 0;
257
Chang Hyun Parkfae2bf22012-12-11 11:09:45 +0100258 if (!mbr || le16_to_cpu(mbr->signature) != MSDOS_MBR_SIGNATURE)
richardretanubun07f3d782008-09-26 11:13:22 -0400259 return 0;
richardretanubun07f3d782008-09-26 11:13:22 -0400260
261 for (i = 0; i < 4; i++) {
262 if (pmbr_part_valid(&mbr->partition_record[i])) {
263 return 1;
264 }
265 }
266 return 0;
267}
268
269/**
270 * is_gpt_valid() - tests one GPT header and PTEs for validity
271 *
272 * lba is the logical block address of the GPT header to test
273 * gpt is a GPT header ptr, filled on return.
274 * ptes is a PTEs ptr, filled on return.
275 *
276 * Description: returns 1 if valid, 0 on error.
277 * If valid, returns pointers to PTEs.
278 */
279static int is_gpt_valid(block_dev_desc_t * dev_desc, unsigned long long lba,
280 gpt_header * pgpt_head, gpt_entry ** pgpt_pte)
281{
Chang Hyun Parkfae2bf22012-12-11 11:09:45 +0100282 u32 crc32_backup = 0;
283 u32 calc_crc32;
richardretanubun07f3d782008-09-26 11:13:22 -0400284 unsigned long long lastlba;
285
286 if (!dev_desc || !pgpt_head) {
Doug Andersondf70b1c2011-10-19 08:04:46 +0000287 printf("%s: Invalid Argument(s)\n", __func__);
richardretanubun07f3d782008-09-26 11:13:22 -0400288 return 0;
289 }
290
291 /* Read GPT Header from device */
292 if (dev_desc->block_read(dev_desc->dev, lba, 1, pgpt_head) != 1) {
293 printf("*** ERROR: Can't read GPT header ***\n");
294 return 0;
295 }
296
297 /* Check the GPT header signature */
Chang Hyun Parkfae2bf22012-12-11 11:09:45 +0100298 if (le64_to_cpu(pgpt_head->signature) != GPT_HEADER_SIGNATURE) {
richardretanubun07f3d782008-09-26 11:13:22 -0400299 printf("GUID Partition Table Header signature is wrong:"
300 "0x%llX != 0x%llX\n",
Chang Hyun Parkfae2bf22012-12-11 11:09:45 +0100301 le64_to_cpu(pgpt_head->signature),
302 GPT_HEADER_SIGNATURE);
richardretanubun07f3d782008-09-26 11:13:22 -0400303 return 0;
304 }
305
306 /* Check the GUID Partition Table CRC */
Chang Hyun Parkfae2bf22012-12-11 11:09:45 +0100307 memcpy(&crc32_backup, &pgpt_head->header_crc32, sizeof(crc32_backup));
308 memset(&pgpt_head->header_crc32, 0, sizeof(pgpt_head->header_crc32));
richardretanubun07f3d782008-09-26 11:13:22 -0400309
310 calc_crc32 = efi_crc32((const unsigned char *)pgpt_head,
Chang Hyun Parkfae2bf22012-12-11 11:09:45 +0100311 le32_to_cpu(pgpt_head->header_size));
richardretanubun07f3d782008-09-26 11:13:22 -0400312
Chang Hyun Parkfae2bf22012-12-11 11:09:45 +0100313 memcpy(&pgpt_head->header_crc32, &crc32_backup, sizeof(crc32_backup));
richardretanubun07f3d782008-09-26 11:13:22 -0400314
Chang Hyun Parkfae2bf22012-12-11 11:09:45 +0100315 if (calc_crc32 != le32_to_cpu(crc32_backup)) {
richardretanubun07f3d782008-09-26 11:13:22 -0400316 printf("GUID Partition Table Header CRC is wrong:"
Chang Hyun Parkfae2bf22012-12-11 11:09:45 +0100317 "0x%x != 0x%x\n",
318 le32_to_cpu(crc32_backup), calc_crc32);
richardretanubun07f3d782008-09-26 11:13:22 -0400319 return 0;
320 }
321
322 /* Check that the my_lba entry points to the LBA that contains the GPT */
Chang Hyun Parkfae2bf22012-12-11 11:09:45 +0100323 if (le64_to_cpu(pgpt_head->my_lba) != lba) {
richardretanubun07f3d782008-09-26 11:13:22 -0400324 printf("GPT: my_lba incorrect: %llX != %llX\n",
Chang Hyun Parkfae2bf22012-12-11 11:09:45 +0100325 le64_to_cpu(pgpt_head->my_lba),
326 lba);
richardretanubun07f3d782008-09-26 11:13:22 -0400327 return 0;
328 }
329
330 /* Check the first_usable_lba and last_usable_lba are within the disk. */
331 lastlba = (unsigned long long)dev_desc->lba;
Chang Hyun Parkfae2bf22012-12-11 11:09:45 +0100332 if (le64_to_cpu(pgpt_head->first_usable_lba) > lastlba) {
richardretanubun07f3d782008-09-26 11:13:22 -0400333 printf("GPT: first_usable_lba incorrect: %llX > %llX\n",
Chang Hyun Parkfae2bf22012-12-11 11:09:45 +0100334 le64_to_cpu(pgpt_head->first_usable_lba), lastlba);
richardretanubun07f3d782008-09-26 11:13:22 -0400335 return 0;
336 }
Chang Hyun Parkfae2bf22012-12-11 11:09:45 +0100337 if (le64_to_cpu(pgpt_head->last_usable_lba) > lastlba) {
richardretanubun07f3d782008-09-26 11:13:22 -0400338 printf("GPT: last_usable_lba incorrect: %llX > %llX\n",
Chang Hyun Parkfae2bf22012-12-11 11:09:45 +0100339 (u64) le64_to_cpu(pgpt_head->last_usable_lba), lastlba);
richardretanubun07f3d782008-09-26 11:13:22 -0400340 return 0;
341 }
342
343 debug("GPT: first_usable_lba: %llX last_usable_lba %llX last lba %llX\n",
Chang Hyun Parkfae2bf22012-12-11 11:09:45 +0100344 le64_to_cpu(pgpt_head->first_usable_lba),
345 le64_to_cpu(pgpt_head->last_usable_lba), lastlba);
richardretanubun07f3d782008-09-26 11:13:22 -0400346
347 /* Read and allocate Partition Table Entries */
348 *pgpt_pte = alloc_read_gpt_entries(dev_desc, pgpt_head);
349 if (*pgpt_pte == NULL) {
350 printf("GPT: Failed to allocate memory for PTE\n");
351 return 0;
352 }
353
354 /* Check the GUID Partition Table Entry Array CRC */
355 calc_crc32 = efi_crc32((const unsigned char *)*pgpt_pte,
Chang Hyun Parkfae2bf22012-12-11 11:09:45 +0100356 le32_to_cpu(pgpt_head->num_partition_entries) *
357 le32_to_cpu(pgpt_head->sizeof_partition_entry));
richardretanubun07f3d782008-09-26 11:13:22 -0400358
Chang Hyun Parkfae2bf22012-12-11 11:09:45 +0100359 if (calc_crc32 != le32_to_cpu(pgpt_head->partition_entry_array_crc32)) {
richardretanubun07f3d782008-09-26 11:13:22 -0400360 printf("GUID Partition Table Entry Array CRC is wrong:"
Chang Hyun Parkfae2bf22012-12-11 11:09:45 +0100361 "0x%x != 0x%x\n",
362 le32_to_cpu(pgpt_head->partition_entry_array_crc32),
richardretanubun07f3d782008-09-26 11:13:22 -0400363 calc_crc32);
364
Doug Andersondeb5ca82011-10-19 09:47:31 +0000365 free(*pgpt_pte);
richardretanubun07f3d782008-09-26 11:13:22 -0400366 return 0;
367 }
368
369 /* We're done, all's well */
370 return 1;
371}
372
373/**
374 * alloc_read_gpt_entries(): reads partition entries from disk
375 * @dev_desc
376 * @gpt - GPT header
377 *
378 * Description: Returns ptes on success, NULL on error.
379 * Allocates space for PTEs based on information found in @gpt.
380 * Notes: remember to free pte when you're done!
381 */
382static gpt_entry *alloc_read_gpt_entries(block_dev_desc_t * dev_desc,
383 gpt_header * pgpt_head)
384{
385 size_t count = 0;
386 gpt_entry *pte = NULL;
387
388 if (!dev_desc || !pgpt_head) {
Doug Andersondf70b1c2011-10-19 08:04:46 +0000389 printf("%s: Invalid Argument(s)\n", __func__);
richardretanubun07f3d782008-09-26 11:13:22 -0400390 return NULL;
391 }
392
Chang Hyun Parkfae2bf22012-12-11 11:09:45 +0100393 count = le32_to_cpu(pgpt_head->num_partition_entries) *
394 le32_to_cpu(pgpt_head->sizeof_partition_entry);
richardretanubun07f3d782008-09-26 11:13:22 -0400395
Chang Hyun Parkfae2bf22012-12-11 11:09:45 +0100396 debug("%s: count = %u * %u = %zu\n", __func__,
397 (u32) le32_to_cpu(pgpt_head->num_partition_entries),
398 (u32) le32_to_cpu(pgpt_head->sizeof_partition_entry), count);
richardretanubun07f3d782008-09-26 11:13:22 -0400399
400 /* Allocate memory for PTE, remember to FREE */
401 if (count != 0) {
Sanjeev Premi29b70422011-11-16 10:20:47 -0500402 pte = memalign(ARCH_DMA_MINALIGN, count);
richardretanubun07f3d782008-09-26 11:13:22 -0400403 }
404
405 if (count == 0 || pte == NULL) {
Taylor Hutt9936be32012-10-12 14:26:09 +0000406 printf("%s: ERROR: Can't allocate 0x%zX "
407 "bytes for GPT Entries\n",
Doug Andersondf70b1c2011-10-19 08:04:46 +0000408 __func__, count);
richardretanubun07f3d782008-09-26 11:13:22 -0400409 return NULL;
410 }
411
412 /* Read GPT Entries from device */
413 if (dev_desc->block_read (dev_desc->dev,
Chang Hyun Parkfae2bf22012-12-11 11:09:45 +0100414 le64_to_cpu(pgpt_head->partition_entry_lba),
richardretanubun07f3d782008-09-26 11:13:22 -0400415 (lbaint_t) (count / GPT_BLOCK_SIZE), pte)
416 != (count / GPT_BLOCK_SIZE)) {
417
418 printf("*** ERROR: Can't read GPT Entries ***\n");
419 free(pte);
420 return NULL;
421 }
422 return pte;
423}
424
425/**
426 * is_pte_valid(): validates a single Partition Table Entry
427 * @gpt_entry - Pointer to a single Partition Table Entry
428 *
429 * Description: returns 1 if valid, 0 on error.
430 */
431static int is_pte_valid(gpt_entry * pte)
432{
433 efi_guid_t unused_guid;
434
435 if (!pte) {
Doug Andersondf70b1c2011-10-19 08:04:46 +0000436 printf("%s: Invalid Argument(s)\n", __func__);
richardretanubun07f3d782008-09-26 11:13:22 -0400437 return 0;
438 }
439
440 /* Only one validation for now:
441 * The GUID Partition Type != Unused Entry (ALL-ZERO)
442 */
443 memset(unused_guid.b, 0, sizeof(unused_guid.b));
444
445 if (memcmp(pte->partition_type_guid.b, unused_guid.b,
446 sizeof(unused_guid.b)) == 0) {
447
Doug Andersondf70b1c2011-10-19 08:04:46 +0000448 debug("%s: Found an unused PTE GUID at 0x%08X\n", __func__,
Taylor Hutt9936be32012-10-12 14:26:09 +0000449 (unsigned int)(uintptr_t)pte);
richardretanubun07f3d782008-09-26 11:13:22 -0400450
451 return 0;
452 } else {
453 return 1;
454 }
455}
456#endif