Blame view

disk/part_efi.c 32.3 KB
83d290c56   Tom Rini   SPDX: Convert all...
1
  // SPDX-License-Identifier: GPL-2.0+
07f3d789b   richardretanubun   Add support for C...
2
3
4
  /*
   * Copyright (C) 2008 RuggedCom, Inc.
   * Richard Retanubun <RichardRetanubun@RuggedCom.com>
07f3d789b   richardretanubun   Add support for C...
5
6
7
   */
  
  /*
e04350d29   Steve Rae   disk: part_efi: c...
8
9
10
   * NOTE:
   *   when CONFIG_SYS_64BIT_LBA is not defined, lbaint_t is 32 bits; this
   *   limits the maximum size of addressable storage to < 2 Terra Bytes
07f3d789b   richardretanubun   Add support for C...
11
   */
8faefadb7   Marc Dietrich   disk: fix unalign...
12
  #include <asm/unaligned.h>
07f3d789b   richardretanubun   Add support for C...
13
14
  #include <common.h>
  #include <command.h>
02e43537b   Philipp Tomsich   part_efi: support...
15
  #include <fdtdec.h>
07f3d789b   richardretanubun   Add support for C...
16
17
  #include <ide.h>
  #include <malloc.h>
cf92e05c0   Simon Glass   Move ALLOC_CACHE_...
18
  #include <memalign.h>
fae2bf22a   Chang Hyun Park   gpt: The leXX_to_...
19
  #include <part_efi.h>
02e43537b   Philipp Tomsich   part_efi: support...
20
  #include <linux/compiler.h>
6eecc0307   Lei Wen   part: show efi pa...
21
  #include <linux/ctype.h>
3db711085   Simon Glass   crc32: Use the cr...
22
  #include <u-boot/crc.h>
07f3d789b   richardretanubun   Add support for C...
23

40684ddb8   Lukasz Majewski   gpt: Support for ...
24
  DECLARE_GLOBAL_DATA_PTR;
44ab2d325   Heinrich Schuchardt   efi_loader: avoid...
25
26
27
28
  /*
   * GUID for basic data partions.
   */
  static const efi_guid_t partition_basic_data_guid = PARTITION_BASIC_DATA_GUID;
1811a928c   Adam Ford   Move most CONFIG_...
29
  #ifdef CONFIG_HAVE_BLOCK_DEVICE
07f3d789b   richardretanubun   Add support for C...
30
31
32
33
34
35
36
  /**
   * efi_crc32() - EFI version of crc32 function
   * @buf: buffer to calculate crc32 of
   * @len - length of buf
   *
   * Description: Returns EFI-style CRC32 value for @buf
   */
fae2bf22a   Chang Hyun Park   gpt: The leXX_to_...
37
  static inline u32 efi_crc32(const void *buf, u32 len)
07f3d789b   richardretanubun   Add support for C...
38
39
40
41
42
43
44
45
46
47
  {
  	return crc32(0, buf, len);
  }
  
  /*
   * Private function prototypes
   */
  
  static int pmbr_part_valid(struct partition *part);
  static int is_pmbr_valid(legacy_mbr * mbr);
4101f6879   Simon Glass   dm: Drop the bloc...
48
  static int is_gpt_valid(struct blk_desc *dev_desc, u64 lba,
e04350d29   Steve Rae   disk: part_efi: c...
49
  				gpt_header *pgpt_head, gpt_entry **pgpt_pte);
4101f6879   Simon Glass   dm: Drop the bloc...
50
51
  static gpt_entry *alloc_read_gpt_entries(struct blk_desc *dev_desc,
  					 gpt_header *pgpt_head);
07f3d789b   richardretanubun   Add support for C...
52
  static int is_pte_valid(gpt_entry * pte);
20c568cae   Urja Rannikko   disk: efi: unify ...
53
54
  static int find_valid_gpt(struct blk_desc *dev_desc, gpt_header *gpt_head,
  			  gpt_entry **pgpt_pte);
07f3d789b   richardretanubun   Add support for C...
55

6eecc0307   Lei Wen   part: show efi pa...
56
57
58
59
60
61
62
63
64
65
66
67
68
  static char *print_efiname(gpt_entry *pte)
  {
  	static char name[PARTNAME_SZ + 1];
  	int i;
  	for (i = 0; i < PARTNAME_SZ; i++) {
  		u8 c;
  		c = pte->partition_name[i] & 0xff;
  		c = (c && !isprint(c)) ? '.' : c;
  		name[i] = c;
  	}
  	name[PARTNAME_SZ] = 0;
  	return name;
  }
7de24b27d   Heinrich Schuchardt   disk: efi: GUIDs ...
69
  static const efi_guid_t system_guid = PARTITION_SYSTEM_GUID;
b4414f4a4   Stephen Warren   disk: part_efi: s...
70
71
72
73
74
75
76
  
  static inline int is_bootable(gpt_entry *p)
  {
  	return p->attributes.fields.legacy_bios_bootable ||
  		!memcmp(&(p->partition_type_guid), &system_guid,
  			sizeof(efi_guid_t));
  }
e1f6b0a02   Steve Rae   disk: part_efi: m...
77
78
79
80
81
82
83
  static int validate_gpt_header(gpt_header *gpt_h, lbaint_t lba,
  		lbaint_t lastlba)
  {
  	uint32_t crc32_backup = 0;
  	uint32_t calc_crc32;
  
  	/* Check the GPT header signature */
67b905226   Simon Glass   Rename GPT_HEADER...
84
  	if (le64_to_cpu(gpt_h->signature) != GPT_HEADER_SIGNATURE_UBOOT) {
e1f6b0a02   Steve Rae   disk: part_efi: m...
85
86
87
88
  		printf("%s signature is wrong: 0x%llX != 0x%llX
  ",
  		       "GUID Partition Table Header",
  		       le64_to_cpu(gpt_h->signature),
67b905226   Simon Glass   Rename GPT_HEADER...
89
  		       GPT_HEADER_SIGNATURE_UBOOT);
e1f6b0a02   Steve Rae   disk: part_efi: m...
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
  		return -1;
  	}
  
  	/* Check the GUID Partition Table CRC */
  	memcpy(&crc32_backup, &gpt_h->header_crc32, sizeof(crc32_backup));
  	memset(&gpt_h->header_crc32, 0, sizeof(gpt_h->header_crc32));
  
  	calc_crc32 = efi_crc32((const unsigned char *)gpt_h,
  		le32_to_cpu(gpt_h->header_size));
  
  	memcpy(&gpt_h->header_crc32, &crc32_backup, sizeof(crc32_backup));
  
  	if (calc_crc32 != le32_to_cpu(crc32_backup)) {
  		printf("%s CRC is wrong: 0x%x != 0x%x
  ",
  		       "GUID Partition Table Header",
  		       le32_to_cpu(crc32_backup), calc_crc32);
  		return -1;
  	}
  
  	/*
  	 * Check that the my_lba entry points to the LBA that contains the GPT
  	 */
  	if (le64_to_cpu(gpt_h->my_lba) != lba) {
  		printf("GPT: my_lba incorrect: %llX != " LBAF "
  ",
  		       le64_to_cpu(gpt_h->my_lba),
  		       lba);
  		return -1;
  	}
  
  	/*
  	 * Check that the first_usable_lba and that the last_usable_lba are
  	 * within the disk.
  	 */
  	if (le64_to_cpu(gpt_h->first_usable_lba) > lastlba) {
  		printf("GPT: first_usable_lba incorrect: %llX > " LBAF "
  ",
  		       le64_to_cpu(gpt_h->first_usable_lba), lastlba);
  		return -1;
  	}
  	if (le64_to_cpu(gpt_h->last_usable_lba) > lastlba) {
  		printf("GPT: last_usable_lba incorrect: %llX > " LBAF "
  ",
  		       le64_to_cpu(gpt_h->last_usable_lba), lastlba);
  		return -1;
  	}
  
  	debug("GPT: first_usable_lba: %llX last_usable_lba: %llX last lba: "
  	      LBAF "
  ", le64_to_cpu(gpt_h->first_usable_lba),
  	      le64_to_cpu(gpt_h->last_usable_lba), lastlba);
  
  	return 0;
  }
a2018ab0d   Ye Li   MLK-18591-3 andro...
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
  static void prepare_last_lba_gpt_header(struct blk_desc *dev_desc, gpt_header *gpt_h)
  {
  	uint32_t calc_crc32;
  	uint64_t val;
  
  	/* recalculate the values for the Backup GPT Header */
  	val = le64_to_cpu(gpt_h->my_lba);
  	gpt_h->my_lba = cpu_to_le64(dev_desc->lba - 1);;
  	gpt_h->alternate_lba = cpu_to_le64(val);
  	gpt_h->last_usable_lba = cpu_to_le64(dev_desc->lba - 34);
  	gpt_h->partition_entry_lba =
  			cpu_to_le64(le64_to_cpu(gpt_h->last_usable_lba) + 1);
  	gpt_h->header_crc32 = 0;
  
  	calc_crc32 = efi_crc32((const unsigned char *)gpt_h,
  			       le32_to_cpu(gpt_h->header_size));
  	gpt_h->header_crc32 = cpu_to_le32(calc_crc32);
  }
e1f6b0a02   Steve Rae   disk: part_efi: m...
163
164
165
166
167
168
169
170
171
172
  static int validate_gpt_entries(gpt_header *gpt_h, gpt_entry *gpt_e)
  {
  	uint32_t calc_crc32;
  
  	/* Check the GUID Partition Table Entry Array CRC */
  	calc_crc32 = efi_crc32((const unsigned char *)gpt_e,
  		le32_to_cpu(gpt_h->num_partition_entries) *
  		le32_to_cpu(gpt_h->sizeof_partition_entry));
  
  	if (calc_crc32 != le32_to_cpu(gpt_h->partition_entry_array_crc32)) {
a2018ab0d   Ye Li   MLK-18591-3 andro...
173
174
  		debug("%s: 0x%x != 0x%x
  ",
e1f6b0a02   Steve Rae   disk: part_efi: m...
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
  		       "GUID Partition Table Entry Array CRC is wrong",
  		       le32_to_cpu(gpt_h->partition_entry_array_crc32),
  		       calc_crc32);
  		return -1;
  	}
  
  	return 0;
  }
  
  static void prepare_backup_gpt_header(gpt_header *gpt_h)
  {
  	uint32_t calc_crc32;
  	uint64_t val;
  
  	/* recalculate the values for the Backup GPT Header */
  	val = le64_to_cpu(gpt_h->my_lba);
  	gpt_h->my_lba = gpt_h->alternate_lba;
  	gpt_h->alternate_lba = cpu_to_le64(val);
0ff7e585d   Steve Rae   fastboot: handle ...
193
194
  	gpt_h->partition_entry_lba =
  			cpu_to_le64(le64_to_cpu(gpt_h->last_usable_lba) + 1);
e1f6b0a02   Steve Rae   disk: part_efi: m...
195
196
197
198
199
200
  	gpt_h->header_crc32 = 0;
  
  	calc_crc32 = efi_crc32((const unsigned char *)gpt_h,
  			       le32_to_cpu(gpt_h->header_size));
  	gpt_h->header_crc32 = cpu_to_le32(calc_crc32);
  }
bd42a9426   Patrick Delaunay   disk: convert CON...
201
  #if CONFIG_IS_ENABLED(EFI_PARTITION)
07f3d789b   richardretanubun   Add support for C...
202
203
204
  /*
   * Public Functions (include/part.h)
   */
73d6d18b7   Alison Chaiken   GPT: add accessor...
205
206
207
208
209
210
211
212
213
214
215
  /*
   * UUID is displayed as 32 hexadecimal digits, in 5 groups,
   * separated by hyphens, in the form 8-4-4-4-12 for a total of 36 characters
   */
  int get_disk_guid(struct blk_desc * dev_desc, char *guid)
  {
  	ALLOC_CACHE_ALIGN_BUFFER_PAD(gpt_header, gpt_head, 1, dev_desc->blksz);
  	gpt_entry *gpt_pte = NULL;
  	unsigned char *guid_bin;
  
  	/* This function validates AND fills in the GPT header and PTE */
20c568cae   Urja Rannikko   disk: efi: unify ...
216
217
  	if (find_valid_gpt(dev_desc, gpt_head, &gpt_pte) != 1)
  		return -EINVAL;
73d6d18b7   Alison Chaiken   GPT: add accessor...
218
219
220
  
  	guid_bin = gpt_head->disk_guid.b;
  	uuid_bin_to_str(guid_bin, guid, UUID_STR_FORMAT_GUID);
1cfe96947   Eugeniu Rosca   disk: efi: Fix me...
221
222
  	/* Remember to free pte */
  	free(gpt_pte);
73d6d18b7   Alison Chaiken   GPT: add accessor...
223
224
  	return 0;
  }
084bf4c24   Simon Glass   part: Rename test...
225
  void part_print_efi(struct blk_desc *dev_desc)
07f3d789b   richardretanubun   Add support for C...
226
  {
ae1768a72   Egbert Eich   disk/gpt: Fix GPT...
227
  	ALLOC_CACHE_ALIGN_BUFFER_PAD(gpt_header, gpt_head, 1, dev_desc->blksz);
deb5ca802   Doug Anderson   disk: part_efi: f...
228
  	gpt_entry *gpt_pte = NULL;
07f3d789b   richardretanubun   Add support for C...
229
  	int i = 0;
db9b6200a   Alison Chaiken   EFI: replace numb...
230
  	char uuid[UUID_STR_LEN + 1];
a96a0e615   Przemyslaw Marczak   part_efi: move uu...
231
  	unsigned char *uuid_bin;
07f3d789b   richardretanubun   Add support for C...
232

07f3d789b   richardretanubun   Add support for C...
233
  	/* This function validates AND fills in the GPT header and PTE */
20c568cae   Urja Rannikko   disk: efi: unify ...
234
235
  	if (find_valid_gpt(dev_desc, gpt_head, &gpt_pte) != 1)
  		return;
07f3d789b   richardretanubun   Add support for C...
236

deb5ca802   Doug Anderson   disk: part_efi: f...
237
238
  	debug("%s: gpt-entry at %p
  ", __func__, gpt_pte);
07f3d789b   richardretanubun   Add support for C...
239

788a8c1fc   Stephen Warren   disk: part_efi: r...
240
241
  	printf("Part\tStart LBA\tEnd LBA\t\tName
  ");
13bf2f55d   Stephen Warren   disk: part_efi: p...
242
243
  	printf("\tAttributes
  ");
d718ded05   Przemyslaw Marczak   lib: uuid: code r...
244
245
246
247
  	printf("\tType GUID
  ");
  	printf("\tPartition GUID
  ");
f07cd2c4c   Stephen Warren   disk: part_efi: p...
248

fae2bf22a   Chang Hyun Park   gpt: The leXX_to_...
249
  	for (i = 0; i < le32_to_cpu(gpt_head->num_partition_entries); i++) {
38a3021ed   Stephen Warren   disk: part_efi: r...
250
251
252
  		/* Stop at the first non valid PTE */
  		if (!is_pte_valid(&gpt_pte[i]))
  			break;
788a8c1fc   Stephen Warren   disk: part_efi: r...
253
254
  		printf("%3d\t0x%08llx\t0x%08llx\t\"%s\"
  ", (i + 1),
fae2bf22a   Chang Hyun Park   gpt: The leXX_to_...
255
256
  			le64_to_cpu(gpt_pte[i].starting_lba),
  			le64_to_cpu(gpt_pte[i].ending_lba),
788a8c1fc   Stephen Warren   disk: part_efi: r...
257
  			print_efiname(&gpt_pte[i]));
13bf2f55d   Stephen Warren   disk: part_efi: p...
258
259
  		printf("\tattrs:\t0x%016llx
  ", gpt_pte[i].attributes.raw);
a96a0e615   Przemyslaw Marczak   part_efi: move uu...
260
  		uuid_bin = (unsigned char *)gpt_pte[i].partition_type_guid.b;
d718ded05   Przemyslaw Marczak   lib: uuid: code r...
261
  		uuid_bin_to_str(uuid_bin, uuid, UUID_STR_FORMAT_GUID);
f07cd2c4c   Stephen Warren   disk: part_efi: p...
262
263
  		printf("\ttype:\t%s
  ", uuid);
bcb41dcae   Patrick Delaunay   uuid: add selecti...
264
265
266
267
268
  #ifdef CONFIG_PARTITION_TYPE_GUID
  		if (!uuid_guid_get_str(uuid_bin, uuid))
  			printf("\ttype:\t%s
  ", uuid);
  #endif
a96a0e615   Przemyslaw Marczak   part_efi: move uu...
269
  		uuid_bin = (unsigned char *)gpt_pte[i].unique_partition_guid.b;
d718ded05   Przemyslaw Marczak   lib: uuid: code r...
270
271
272
  		uuid_bin_to_str(uuid_bin, uuid, UUID_STR_FORMAT_GUID);
  		printf("\tguid:\t%s
  ", uuid);
07f3d789b   richardretanubun   Add support for C...
273
  	}
ed915f7d4   Ji Luo   MA-14916-4 suppor...
274
  #if !defined(CONFIG_DUAL_BOOTLOADER) || !defined(CONFIG_SPL_BUILD)
07f3d789b   richardretanubun   Add support for C...
275
  	/* Remember to free pte */
deb5ca802   Doug Anderson   disk: part_efi: f...
276
  	free(gpt_pte);
ed915f7d4   Ji Luo   MA-14916-4 suppor...
277
  #endif
07f3d789b   richardretanubun   Add support for C...
278
279
  	return;
  }
3e8bd4695   Simon Glass   dm: part: Rename ...
280
281
  int part_get_info_efi(struct blk_desc *dev_desc, int part,
  		      disk_partition_t *info)
07f3d789b   richardretanubun   Add support for C...
282
  {
ae1768a72   Egbert Eich   disk/gpt: Fix GPT...
283
  	ALLOC_CACHE_ALIGN_BUFFER_PAD(gpt_header, gpt_head, 1, dev_desc->blksz);
deb5ca802   Doug Anderson   disk: part_efi: f...
284
  	gpt_entry *gpt_pte = NULL;
07f3d789b   richardretanubun   Add support for C...
285
286
  
  	/* "part" argument must be at least 1 */
4708a07c7   Simon Glass   part_efi: Drop NU...
287
  	if (part < 1) {
df70b1c2e   Doug Anderson   cosmetic: Replace...
288
289
  		printf("%s: Invalid Argument(s)
  ", __func__);
07f3d789b   richardretanubun   Add support for C...
290
291
292
293
  		return -1;
  	}
  
  	/* This function validates AND fills in the GPT header and PTE */
20c568cae   Urja Rannikko   disk: efi: unify ...
294
295
  	if (find_valid_gpt(dev_desc, gpt_head, &gpt_pte) != 1)
  		return -1;
07f3d789b   richardretanubun   Add support for C...
296

fae2bf22a   Chang Hyun Park   gpt: The leXX_to_...
297
  	if (part > le32_to_cpu(gpt_head->num_partition_entries) ||
c04d68c69   Stephen Warren   disk: part_efi: r...
298
  	    !is_pte_valid(&gpt_pte[part - 1])) {
6d2ee5a33   Mark Langsdorf   part_efi: make su...
299
300
  		debug("%s: *** ERROR: Invalid partition number %d ***
  ",
c04d68c69   Stephen Warren   disk: part_efi: r...
301
  			__func__, part);
ed915f7d4   Ji Luo   MA-14916-4 suppor...
302
  #if !defined(CONFIG_DUAL_BOOTLOADER) || !defined(CONFIG_SPL_BUILD)
6d2ee5a33   Mark Langsdorf   part_efi: make su...
303
  		free(gpt_pte);
ed915f7d4   Ji Luo   MA-14916-4 suppor...
304
  #endif
c04d68c69   Stephen Warren   disk: part_efi: r...
305
306
  		return -1;
  	}
e04350d29   Steve Rae   disk: part_efi: c...
307
308
  	/* The 'lbaint_t' casting may limit the maximum disk size to 2 TB */
  	info->start = (lbaint_t)le64_to_cpu(gpt_pte[part - 1].starting_lba);
509708397   Richard Retanubun   part_efi: Fix par...
309
  	/* The ending LBA is inclusive, to calculate size, add 1 to it */
e04350d29   Steve Rae   disk: part_efi: c...
310
  	info->size = (lbaint_t)le64_to_cpu(gpt_pte[part - 1].ending_lba) + 1
509708397   Richard Retanubun   part_efi: Fix par...
311
  		     - info->start;
ae1768a72   Egbert Eich   disk/gpt: Fix GPT...
312
  	info->blksz = dev_desc->blksz;
07f3d789b   richardretanubun   Add support for C...
313

5375ee508   Heinrich Schuchardt   disk: efi: buffer...
314
315
  	snprintf((char *)info->name, sizeof(info->name), "%s",
  		 print_efiname(&gpt_pte[part - 1]));
192bc6948   Ben Whitten   Fix GCC format-se...
316
  	strcpy((char *)info->type, "U-Boot");
b4414f4a4   Stephen Warren   disk: part_efi: s...
317
  	info->bootable = is_bootable(&gpt_pte[part - 1]);
b331cd620   Patrick Delaunay   cmd, disk: conver...
318
  #if CONFIG_IS_ENABLED(PARTITION_UUIDS)
d718ded05   Przemyslaw Marczak   lib: uuid: code r...
319
320
  	uuid_bin_to_str(gpt_pte[part - 1].unique_partition_guid.b, info->uuid,
  			UUID_STR_FORMAT_GUID);
894bfbbfb   Stephen Warren   disk: part_efi: p...
321
  #endif
7561b258a   Patrick Delaunay   gpt: add optional...
322
323
324
325
  #ifdef CONFIG_PARTITION_TYPE_GUID
  	uuid_bin_to_str(gpt_pte[part - 1].partition_type_guid.b,
  			info->type_guid, UUID_STR_FORMAT_GUID);
  #endif
07f3d789b   richardretanubun   Add support for C...
326

60bf94169   Steve Rae   disk: part_efi: a...
327
328
  	debug("%s: start 0x" LBAF ", size 0x" LBAF ", name %s
  ", __func__,
04735e9c5   Frederic Leroy   Fix ext2/ext4 fil...
329
  	      info->start, info->size, info->name);
07f3d789b   richardretanubun   Add support for C...
330

ed915f7d4   Ji Luo   MA-14916-4 suppor...
331
332
333
334
335
336
  #if !defined(CONFIG_DUAL_BOOTLOADER) || !defined(CONFIG_SPL_BUILD)
  	/* Heap memory is very limited in SPL, if the dual bootloader is
  	 * enabled, just load pte to dram instead of oc-ram. In such case,
  	 * this part of  memory shouldn't be freed. But in common routine,
  	 * don't forget to free the memory after use.
  	 */
deb5ca802   Doug Anderson   disk: part_efi: f...
337
  	free(gpt_pte);
ed915f7d4   Ji Luo   MA-14916-4 suppor...
338
  #endif
07f3d789b   richardretanubun   Add support for C...
339
340
  	return 0;
  }
084bf4c24   Simon Glass   part: Rename test...
341
  static int part_test_efi(struct blk_desc *dev_desc)
07f3d789b   richardretanubun   Add support for C...
342
  {
ae1768a72   Egbert Eich   disk/gpt: Fix GPT...
343
  	ALLOC_CACHE_ALIGN_BUFFER_PAD(legacy_mbr, legacymbr, 1, dev_desc->blksz);
07f3d789b   richardretanubun   Add support for C...
344
345
  
  	/* Read legacy MBR from block 0 and validate it */
2a981dc2c   Simon Glass   dm: block: Adjust...
346
  	if ((blk_dread(dev_desc, 0, 1, (ulong *)legacymbr) != 1)
f75dd584c   Anton staaf   part_efi: dcache:...
347
  		|| (is_pmbr_valid(legacymbr) != 1)) {
07f3d789b   richardretanubun   Add support for C...
348
349
350
351
  		return -1;
  	}
  	return 0;
  }
40684ddb8   Lukasz Majewski   gpt: Support for ...
352
353
354
355
356
357
  /**
   * set_protective_mbr(): Set the EFI protective MBR
   * @param dev_desc - block device descriptor
   *
   * @return - zero on success, otherwise error
   */
4101f6879   Simon Glass   dm: Drop the bloc...
358
  static int set_protective_mbr(struct blk_desc *dev_desc)
40684ddb8   Lukasz Majewski   gpt: Support for ...
359
  {
40684ddb8   Lukasz Majewski   gpt: Support for ...
360
  	/* Setup the Protective MBR */
3cc566117   Patrick Delaunay   disk: efi: correc...
361
  	ALLOC_CACHE_ALIGN_BUFFER_PAD(legacy_mbr, p_mbr, 1, dev_desc->blksz);
40684ddb8   Lukasz Majewski   gpt: Support for ...
362
363
364
365
366
  	if (p_mbr == NULL) {
  		printf("%s: calloc failed!
  ", __func__);
  		return -1;
  	}
e163a931a   Vincent Tinelli   cmd: gpt: backup ...
367
368
369
  
  	/* Read MBR to backup boot code if it exists */
  	if (blk_dread(dev_desc, 0, 1, p_mbr) != 1) {
9b643e312   Masahiro Yamada   treewide: replace...
370
371
  		pr_err("** Can't read from device %d **
  ", dev_desc->devnum);
e163a931a   Vincent Tinelli   cmd: gpt: backup ...
372
373
  		return -1;
  	}
955575c8d   Sam Protsenko   disk: efi: Correc...
374
375
376
  	/* Clear all data in MBR except of backed up boot code */
  	memset((char *)p_mbr + MSDOS_MBR_BOOT_CODE_SIZE, 0, sizeof(*p_mbr) -
  			MSDOS_MBR_BOOT_CODE_SIZE);
40684ddb8   Lukasz Majewski   gpt: Support for ...
377
378
379
380
  	/* Append signature */
  	p_mbr->signature = MSDOS_MBR_SIGNATURE;
  	p_mbr->partition_record[0].sys_ind = EFI_PMBR_OSTYPE_EFI_GPT;
  	p_mbr->partition_record[0].start_sect = 1;
b349abbfe   Maxime Ripard   gpt: Fix the prot...
381
  	p_mbr->partition_record[0].nr_sects = (u32) dev_desc->lba - 1;
40684ddb8   Lukasz Majewski   gpt: Support for ...
382
383
  
  	/* Write MBR sector to the MMC device */
2a981dc2c   Simon Glass   dm: block: Adjust...
384
  	if (blk_dwrite(dev_desc, 0, 1, p_mbr) != 1) {
40684ddb8   Lukasz Majewski   gpt: Support for ...
385
386
  		printf("** Can't write to device %d **
  ",
bcce53d04   Simon Glass   dm: block: Rename...
387
  			dev_desc->devnum);
40684ddb8   Lukasz Majewski   gpt: Support for ...
388
389
  		return -1;
  	}
40684ddb8   Lukasz Majewski   gpt: Support for ...
390
391
  	return 0;
  }
4101f6879   Simon Glass   dm: Drop the bloc...
392
  int write_gpt_table(struct blk_desc *dev_desc,
40684ddb8   Lukasz Majewski   gpt: Support for ...
393
394
  		gpt_header *gpt_h, gpt_entry *gpt_e)
  {
ae1768a72   Egbert Eich   disk/gpt: Fix GPT...
395
396
  	const int pte_blk_cnt = BLOCK_CNT((gpt_h->num_partition_entries
  					   * sizeof(gpt_entry)), dev_desc);
40684ddb8   Lukasz Majewski   gpt: Support for ...
397
  	u32 calc_crc32;
40684ddb8   Lukasz Majewski   gpt: Support for ...
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
  
  	debug("max lba: %x
  ", (u32) dev_desc->lba);
  	/* Setup the Protective MBR */
  	if (set_protective_mbr(dev_desc) < 0)
  		goto err;
  
  	/* Generate CRC for the Primary GPT Header */
  	calc_crc32 = efi_crc32((const unsigned char *)gpt_e,
  			      le32_to_cpu(gpt_h->num_partition_entries) *
  			      le32_to_cpu(gpt_h->sizeof_partition_entry));
  	gpt_h->partition_entry_array_crc32 = cpu_to_le32(calc_crc32);
  
  	calc_crc32 = efi_crc32((const unsigned char *)gpt_h,
  			      le32_to_cpu(gpt_h->header_size));
  	gpt_h->header_crc32 = cpu_to_le32(calc_crc32);
  
  	/* Write the First GPT to the block right after the Legacy MBR */
2a981dc2c   Simon Glass   dm: block: Adjust...
416
  	if (blk_dwrite(dev_desc, 1, 1, gpt_h) != 1)
40684ddb8   Lukasz Majewski   gpt: Support for ...
417
  		goto err;
02e43537b   Philipp Tomsich   part_efi: support...
418
419
  	if (blk_dwrite(dev_desc, le64_to_cpu(gpt_h->partition_entry_lba),
  		       pte_blk_cnt, gpt_e) != pte_blk_cnt)
40684ddb8   Lukasz Majewski   gpt: Support for ...
420
  		goto err;
e1f6b0a02   Steve Rae   disk: part_efi: m...
421
  	prepare_backup_gpt_header(gpt_h);
40684ddb8   Lukasz Majewski   gpt: Support for ...
422

2a981dc2c   Simon Glass   dm: block: Adjust...
423
424
  	if (blk_dwrite(dev_desc, (lbaint_t)le64_to_cpu(gpt_h->last_usable_lba)
  		       + 1, pte_blk_cnt, gpt_e) != pte_blk_cnt)
40684ddb8   Lukasz Majewski   gpt: Support for ...
425
  		goto err;
2a981dc2c   Simon Glass   dm: block: Adjust...
426
427
  	if (blk_dwrite(dev_desc, (lbaint_t)le64_to_cpu(gpt_h->my_lba), 1,
  		       gpt_h) != 1)
40684ddb8   Lukasz Majewski   gpt: Support for ...
428
429
430
431
432
433
434
  		goto err;
  
  	debug("GPT successfully written to block device!
  ");
  	return 0;
  
   err:
bcce53d04   Simon Glass   dm: block: Rename...
435
436
  	printf("** Can't write to device %d **
  ", dev_desc->devnum);
40684ddb8   Lukasz Majewski   gpt: Support for ...
437
438
  	return -1;
  }
47d7ee47b   Maxime Ripard   part: efi: make g...
439
440
441
  int gpt_fill_pte(struct blk_desc *dev_desc,
  		 gpt_header *gpt_h, gpt_entry *gpt_e,
  		 disk_partition_t *partitions, int parts)
40684ddb8   Lukasz Majewski   gpt: Support for ...
442
  {
e04350d29   Steve Rae   disk: part_efi: c...
443
  	lbaint_t offset = (lbaint_t)le64_to_cpu(gpt_h->first_usable_lba);
e04350d29   Steve Rae   disk: part_efi: c...
444
445
  	lbaint_t last_usable_lba = (lbaint_t)
  			le64_to_cpu(gpt_h->last_usable_lba);
40684ddb8   Lukasz Majewski   gpt: Support for ...
446
  	int i, k;
67cd4a634   Marek Vasut   disk: Fix possibl...
447
  	size_t efiname_len, dosname_len;
b331cd620   Patrick Delaunay   cmd, disk: conver...
448
  #if CONFIG_IS_ENABLED(PARTITION_UUIDS)
40684ddb8   Lukasz Majewski   gpt: Support for ...
449
  	char *str_uuid;
a96a0e615   Przemyslaw Marczak   part_efi: move uu...
450
  	unsigned char *bin_uuid;
40684ddb8   Lukasz Majewski   gpt: Support for ...
451
  #endif
7561b258a   Patrick Delaunay   gpt: add optional...
452
453
454
455
  #ifdef CONFIG_PARTITION_TYPE_GUID
  	char *str_type_guid;
  	unsigned char *bin_type_guid;
  #endif
79c5912e8   Maxime Ripard   part: efi: Disabl...
456
457
458
459
460
461
462
  	size_t hdr_start = gpt_h->my_lba;
  	size_t hdr_end = hdr_start + 1;
  
  	size_t pte_start = gpt_h->partition_entry_lba;
  	size_t pte_end = pte_start +
  		gpt_h->num_partition_entries * gpt_h->sizeof_partition_entry /
  		dev_desc->blksz;
40684ddb8   Lukasz Majewski   gpt: Support for ...
463
464
465
  
  	for (i = 0; i < parts; i++) {
  		/* partition starting lba */
5276e8b62   Maxime Ripard   part: efi: rework...
466
467
  		lbaint_t start = partitions[i].start;
  		lbaint_t size = partitions[i].size;
40684ddb8   Lukasz Majewski   gpt: Support for ...
468
  		if (start) {
5276e8b62   Maxime Ripard   part: efi: rework...
469
  			offset = start + size;
40684ddb8   Lukasz Majewski   gpt: Support for ...
470
  		} else {
79c5912e8   Maxime Ripard   part: efi: Disabl...
471
  			start = offset;
5276e8b62   Maxime Ripard   part: efi: rework...
472
  			offset += size;
40684ddb8   Lukasz Majewski   gpt: Support for ...
473
  		}
79c5912e8   Maxime Ripard   part: efi: Disabl...
474
475
476
477
478
  
  		/*
  		 * If our partition overlaps with either the GPT
  		 * header, or the partition entry, reject it.
  		 */
ae0e0228e   Patrick Delaunay   disk: efi: correc...
479
480
  		if (((start < hdr_end && hdr_start < (start + size)) ||
  		     (start < pte_end && pte_start < (start + size)))) {
79c5912e8   Maxime Ripard   part: efi: Disabl...
481
482
483
484
485
486
  			printf("Partition overlap
  ");
  			return -1;
  		}
  
  		gpt_e[i].starting_lba = cpu_to_le64(start);
a56538676   Patrick Delaunay   disk: part_efi: f...
487
  		if (offset > (last_usable_lba + 1)) {
40684ddb8   Lukasz Majewski   gpt: Support for ...
488
489
490
491
492
  			printf("Partitions layout exceds disk size
  ");
  			return -1;
  		}
  		/* partition ending lba */
5276e8b62   Maxime Ripard   part: efi: rework...
493
  		if ((i == parts - 1) && (size == 0))
40684ddb8   Lukasz Majewski   gpt: Support for ...
494
495
496
497
  			/* extend the last partition to maximuim */
  			gpt_e[i].ending_lba = gpt_h->last_usable_lba;
  		else
  			gpt_e[i].ending_lba = cpu_to_le64(offset - 1);
7561b258a   Patrick Delaunay   gpt: add optional...
498
499
500
501
502
503
504
505
506
507
508
509
510
511
  #ifdef CONFIG_PARTITION_TYPE_GUID
  		str_type_guid = partitions[i].type_guid;
  		bin_type_guid = gpt_e[i].partition_type_guid.b;
  		if (strlen(str_type_guid)) {
  			if (uuid_str_to_bin(str_type_guid, bin_type_guid,
  					    UUID_STR_FORMAT_GUID)) {
  				printf("Partition no. %d: invalid type guid: %s
  ",
  				       i, str_type_guid);
  				return -1;
  			}
  		} else {
  			/* default partition type GUID */
  			memcpy(bin_type_guid,
44ab2d325   Heinrich Schuchardt   efi_loader: avoid...
512
  			       &partition_basic_data_guid, 16);
7561b258a   Patrick Delaunay   gpt: add optional...
513
514
  		}
  #else
40684ddb8   Lukasz Majewski   gpt: Support for ...
515
516
  		/* partition type GUID */
  		memcpy(gpt_e[i].partition_type_guid.b,
44ab2d325   Heinrich Schuchardt   efi_loader: avoid...
517
  			&partition_basic_data_guid, 16);
7561b258a   Patrick Delaunay   gpt: add optional...
518
  #endif
40684ddb8   Lukasz Majewski   gpt: Support for ...
519

b331cd620   Patrick Delaunay   cmd, disk: conver...
520
  #if CONFIG_IS_ENABLED(PARTITION_UUIDS)
40684ddb8   Lukasz Majewski   gpt: Support for ...
521
  		str_uuid = partitions[i].uuid;
a96a0e615   Przemyslaw Marczak   part_efi: move uu...
522
  		bin_uuid = gpt_e[i].unique_partition_guid.b;
9da52f8f6   Vincent Tinelli   gpt: Fix uuid str...
523
  		if (uuid_str_to_bin(str_uuid, bin_uuid, UUID_STR_FORMAT_GUID)) {
40684ddb8   Lukasz Majewski   gpt: Support for ...
524
525
526
527
528
529
530
531
532
533
  			printf("Partition no. %d: invalid guid: %s
  ",
  				i, str_uuid);
  			return -1;
  		}
  #endif
  
  		/* partition attributes */
  		memset(&gpt_e[i].attributes, 0,
  		       sizeof(gpt_entry_attributes));
cfdaf4caa   Patrick Delaunay   part:efi: add boo...
534
535
  		if (partitions[i].bootable)
  			gpt_e[i].attributes.fields.legacy_bios_bootable = 1;
40684ddb8   Lukasz Majewski   gpt: Support for ...
536
  		/* partition name */
67cd4a634   Marek Vasut   disk: Fix possibl...
537
  		efiname_len = sizeof(gpt_e[i].partition_name)
40684ddb8   Lukasz Majewski   gpt: Support for ...
538
  			/ sizeof(efi_char16_t);
67cd4a634   Marek Vasut   disk: Fix possibl...
539
540
541
542
543
544
  		dosname_len = sizeof(partitions[i].name);
  
  		memset(gpt_e[i].partition_name, 0,
  		       sizeof(gpt_e[i].partition_name));
  
  		for (k = 0; k < min(dosname_len, efiname_len); k++)
40684ddb8   Lukasz Majewski   gpt: Support for ...
545
546
  			gpt_e[i].partition_name[k] =
  				(efi_char16_t)(partitions[i].name[k]);
e04350d29   Steve Rae   disk: part_efi: c...
547
548
549
  		debug("%s: name: %s offset[%d]: 0x" LBAF
  		      " size[%d]: 0x" LBAF "
  ",
40684ddb8   Lukasz Majewski   gpt: Support for ...
550
  		      __func__, partitions[i].name, i,
5276e8b62   Maxime Ripard   part: efi: rework...
551
  		      offset, i, size);
40684ddb8   Lukasz Majewski   gpt: Support for ...
552
553
554
555
  	}
  
  	return 0;
  }
02e43537b   Philipp Tomsich   part_efi: support...
556
557
558
  static uint32_t partition_entries_offset(struct blk_desc *dev_desc)
  {
  	uint32_t offset_blks = 2;
89d33a2c0   Maxime Ripard   part: efi: Fix of...
559
  	uint32_t __maybe_unused offset_bytes;
02e43537b   Philipp Tomsich   part_efi: support...
560
561
562
563
564
565
566
567
568
569
570
  	int __maybe_unused config_offset;
  
  #if defined(CONFIG_EFI_PARTITION_ENTRIES_OFF)
  	/*
  	 * Some architectures require their SPL loader at a fixed
  	 * address within the first 16KB of the disk.  To avoid an
  	 * overlap with the partition entries of the EFI partition
  	 * table, the first safe offset (in bytes, from the start of
  	 * the disk) for the entries can be set in
  	 * CONFIG_EFI_PARTITION_ENTRIES_OFF.
  	 */
89d33a2c0   Maxime Ripard   part: efi: Fix of...
571
  	offset_bytes =
02e43537b   Philipp Tomsich   part_efi: support...
572
  		PAD_TO_BLOCKSIZE(CONFIG_EFI_PARTITION_ENTRIES_OFF, dev_desc);
89d33a2c0   Maxime Ripard   part: efi: Fix of...
573
  	offset_blks = offset_bytes / dev_desc->blksz;
02e43537b   Philipp Tomsich   part_efi: support...
574
575
576
577
578
579
580
581
582
583
584
  #endif
  
  #if defined(CONFIG_OF_CONTROL)
  	/*
  	 * Allow the offset of the first partition entires (in bytes
  	 * from the start of the device) to be specified as a property
  	 * of the device tree '/config' node.
  	 */
  	config_offset = fdtdec_get_config_int(gd->fdt_blob,
  					      "u-boot,efi-partition-entries-offset",
  					      -EINVAL);
89d33a2c0   Maxime Ripard   part: efi: Fix of...
585
586
587
588
  	if (config_offset != -EINVAL) {
  		offset_bytes = PAD_TO_BLOCKSIZE(config_offset, dev_desc);
  		offset_blks = offset_bytes / dev_desc->blksz;
  	}
02e43537b   Philipp Tomsich   part_efi: support...
589
590
591
592
593
594
595
596
597
598
599
600
601
602
  #endif
  
  	debug("efi: partition entries offset (in blocks): %d
  ", offset_blks);
  
  	/*
  	 * The earliest LBA this can be at is LBA#2 (i.e. right behind
  	 * the (protective) MBR and the GPT header.
  	 */
  	if (offset_blks < 2)
  		offset_blks = 2;
  
  	return offset_blks;
  }
4101f6879   Simon Glass   dm: Drop the bloc...
603
  int gpt_fill_header(struct blk_desc *dev_desc, gpt_header *gpt_h,
40684ddb8   Lukasz Majewski   gpt: Support for ...
604
605
  		char *str_guid, int parts_count)
  {
67b905226   Simon Glass   Rename GPT_HEADER...
606
  	gpt_h->signature = cpu_to_le64(GPT_HEADER_SIGNATURE_UBOOT);
40684ddb8   Lukasz Majewski   gpt: Support for ...
607
608
609
610
  	gpt_h->revision = cpu_to_le32(GPT_HEADER_REVISION_V1);
  	gpt_h->header_size = cpu_to_le32(sizeof(gpt_header));
  	gpt_h->my_lba = cpu_to_le64(1);
  	gpt_h->alternate_lba = cpu_to_le64(dev_desc->lba - 1);
40684ddb8   Lukasz Majewski   gpt: Support for ...
611
  	gpt_h->last_usable_lba = cpu_to_le64(dev_desc->lba - 34);
02e43537b   Philipp Tomsich   part_efi: support...
612
613
614
615
  	gpt_h->partition_entry_lba =
  		cpu_to_le64(partition_entries_offset(dev_desc));
  	gpt_h->first_usable_lba =
  		cpu_to_le64(le64_to_cpu(gpt_h->partition_entry_lba) + 32);
40684ddb8   Lukasz Majewski   gpt: Support for ...
616
617
618
619
  	gpt_h->num_partition_entries = cpu_to_le32(GPT_ENTRY_NUMBERS);
  	gpt_h->sizeof_partition_entry = cpu_to_le32(sizeof(gpt_entry));
  	gpt_h->header_crc32 = 0;
  	gpt_h->partition_entry_array_crc32 = 0;
d718ded05   Przemyslaw Marczak   lib: uuid: code r...
620
  	if (uuid_str_to_bin(str_guid, gpt_h->disk_guid.b, UUID_STR_FORMAT_GUID))
40684ddb8   Lukasz Majewski   gpt: Support for ...
621
622
623
624
  		return -1;
  
  	return 0;
  }
4101f6879   Simon Glass   dm: Drop the bloc...
625
  int gpt_restore(struct blk_desc *dev_desc, char *str_disk_guid,
40684ddb8   Lukasz Majewski   gpt: Support for ...
626
627
  		disk_partition_t *partitions, int parts_count)
  {
bb021013b   Lukasz Majewski   gpt: Use cache al...
628
  	gpt_header *gpt_h;
ae1768a72   Egbert Eich   disk/gpt: Fix GPT...
629
  	gpt_entry *gpt_e;
bb021013b   Lukasz Majewski   gpt: Use cache al...
630
  	int ret, size;
ae1768a72   Egbert Eich   disk/gpt: Fix GPT...
631

bb021013b   Lukasz Majewski   gpt: Use cache al...
632
633
  	size = PAD_TO_BLOCKSIZE(sizeof(gpt_header), dev_desc);
  	gpt_h = malloc_cache_aligned(size);
40684ddb8   Lukasz Majewski   gpt: Support for ...
634
635
636
637
638
  	if (gpt_h == NULL) {
  		printf("%s: calloc failed!
  ", __func__);
  		return -1;
  	}
bb021013b   Lukasz Majewski   gpt: Use cache al...
639
  	memset(gpt_h, 0, size);
40684ddb8   Lukasz Majewski   gpt: Support for ...
640

bb021013b   Lukasz Majewski   gpt: Use cache al...
641
642
643
  	size = PAD_TO_BLOCKSIZE(GPT_ENTRY_NUMBERS * sizeof(gpt_entry),
  				dev_desc);
  	gpt_e = malloc_cache_aligned(size);
40684ddb8   Lukasz Majewski   gpt: Support for ...
644
645
646
647
648
649
  	if (gpt_e == NULL) {
  		printf("%s: calloc failed!
  ", __func__);
  		free(gpt_h);
  		return -1;
  	}
bb021013b   Lukasz Majewski   gpt: Use cache al...
650
  	memset(gpt_e, 0, size);
40684ddb8   Lukasz Majewski   gpt: Support for ...
651
652
653
654
655
656
657
  
  	/* Generate Primary GPT header (LBA1) */
  	ret = gpt_fill_header(dev_desc, gpt_h, str_disk_guid, parts_count);
  	if (ret)
  		goto err;
  
  	/* Generate partition entries */
47d7ee47b   Maxime Ripard   part: efi: make g...
658
  	ret = gpt_fill_pte(dev_desc, gpt_h, gpt_e, partitions, parts_count);
40684ddb8   Lukasz Majewski   gpt: Support for ...
659
660
661
662
663
664
665
666
667
668
669
  	if (ret)
  		goto err;
  
  	/* Write GPT partition table */
  	ret = write_gpt_table(dev_desc, gpt_h, gpt_e);
  
  err:
  	free(gpt_e);
  	free(gpt_h);
  	return ret;
  }
0ff7e585d   Steve Rae   fastboot: handle ...
670

06e921b18   Heinrich Schuchardt   disk: efi: avoid ...
671
672
673
674
675
676
677
678
679
680
  /**
   * gpt_convert_efi_name_to_char() - convert u16 string to char string
   *
   * TODO: this conversion only supports ANSI characters
   *
   * @s:	target buffer
   * @es:	u16 string to be converted
   * @n:	size of target buffer
   */
  static void gpt_convert_efi_name_to_char(char *s, void *es, int n)
cef68bf90   Lukasz Majewski   gpt: part: Defini...
681
  {
06e921b18   Heinrich Schuchardt   disk: efi: avoid ...
682
  	char *ess = es;
cef68bf90   Lukasz Majewski   gpt: part: Defini...
683
684
685
686
687
688
689
690
691
692
  	int i, j;
  
  	memset(s, '\0', n);
  
  	for (i = 0, j = 0; j < n; i += 2, j++) {
  		s[j] = ess[i];
  		if (!ess[i])
  			return;
  	}
  }
4101f6879   Simon Glass   dm: Drop the bloc...
693
  int gpt_verify_headers(struct blk_desc *dev_desc, gpt_header *gpt_head,
cef68bf90   Lukasz Majewski   gpt: part: Defini...
694
695
696
697
698
699
700
701
702
703
704
705
706
707
  		       gpt_entry **gpt_pte)
  {
  	/*
  	 * This function validates AND
  	 * fills in the GPT header and PTE
  	 */
  	if (is_gpt_valid(dev_desc,
  			 GPT_PRIMARY_PARTITION_TABLE_LBA,
  			 gpt_head, gpt_pte) != 1) {
  		printf("%s: *** ERROR: Invalid GPT ***
  ",
  		       __func__);
  		return -1;
  	}
716f919d2   Eugeniu Rosca   disk: efi: Fix me...
708
709
710
  
  	/* Free pte before allocating again */
  	free(*gpt_pte);
cef68bf90   Lukasz Majewski   gpt: part: Defini...
711
712
713
714
715
716
717
718
719
720
  	if (is_gpt_valid(dev_desc, (dev_desc->lba - 1),
  			 gpt_head, gpt_pte) != 1) {
  		printf("%s: *** ERROR: Invalid Backup GPT ***
  ",
  		       __func__);
  		return -1;
  	}
  
  	return 0;
  }
4101f6879   Simon Glass   dm: Drop the bloc...
721
  int gpt_verify_partitions(struct blk_desc *dev_desc,
cef68bf90   Lukasz Majewski   gpt: part: Defini...
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
  			  disk_partition_t *partitions, int parts,
  			  gpt_header *gpt_head, gpt_entry **gpt_pte)
  {
  	char efi_str[PARTNAME_SZ + 1];
  	u64 gpt_part_size;
  	gpt_entry *gpt_e;
  	int ret, i;
  
  	ret = gpt_verify_headers(dev_desc, gpt_head, gpt_pte);
  	if (ret)
  		return ret;
  
  	gpt_e = *gpt_pte;
  
  	for (i = 0; i < parts; i++) {
  		if (i == gpt_head->num_partition_entries) {
9b643e312   Masahiro Yamada   treewide: replace...
738
739
  			pr_err("More partitions than allowed!
  ");
cef68bf90   Lukasz Majewski   gpt: part: Defini...
740
741
742
743
744
745
746
747
748
749
750
751
  			return -1;
  		}
  
  		/* Check if GPT and ENV partition names match */
  		gpt_convert_efi_name_to_char(efi_str, gpt_e[i].partition_name,
  					     PARTNAME_SZ + 1);
  
  		debug("%s: part: %2d name - GPT: %16s, ENV: %16s ",
  		      __func__, i, efi_str, partitions[i].name);
  
  		if (strncmp(efi_str, (char *)partitions[i].name,
  			    sizeof(partitions->name))) {
9b643e312   Masahiro Yamada   treewide: replace...
752
753
  			pr_err("Partition name: %s does not match %s!
  ",
cef68bf90   Lukasz Majewski   gpt: part: Defini...
754
755
756
757
758
759
760
761
  			      efi_str, (char *)partitions[i].name);
  			return -1;
  		}
  
  		/* Check if GPT and ENV sizes match */
  		gpt_part_size = le64_to_cpu(gpt_e[i].ending_lba) -
  			le64_to_cpu(gpt_e[i].starting_lba) + 1;
  		debug("size(LBA) - GPT: %8llu, ENV: %8llu ",
f8d6165d4   Simon Glass   dm: part: Correct...
762
763
  		      (unsigned long long)gpt_part_size,
  		      (unsigned long long)partitions[i].size);
cef68bf90   Lukasz Majewski   gpt: part: Defini...
764
765
  
  		if (le64_to_cpu(gpt_part_size) != partitions[i].size) {
c2fdd3456   Kever Yang   cmd: gpt: fix the...
766
767
768
  			/* We do not check the extend partition size */
  			if ((i == parts - 1) && (partitions[i].size == 0))
  				continue;
9b643e312   Masahiro Yamada   treewide: replace...
769
770
  			pr_err("Partition %s size: %llu does not match %llu!
  ",
f8d6165d4   Simon Glass   dm: part: Correct...
771
772
  			      efi_str, (unsigned long long)gpt_part_size,
  			      (unsigned long long)partitions[i].size);
cef68bf90   Lukasz Majewski   gpt: part: Defini...
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
  			return -1;
  		}
  
  		/*
  		 * Start address is optional - check only if provided
  		 * in '$partition' variable
  		 */
  		if (!partitions[i].start) {
  			debug("
  ");
  			continue;
  		}
  
  		/* Check if GPT and ENV start LBAs match */
  		debug("start LBA - GPT: %8llu, ENV: %8llu
  ",
  		      le64_to_cpu(gpt_e[i].starting_lba),
f8d6165d4   Simon Glass   dm: part: Correct...
790
  		      (unsigned long long)partitions[i].start);
cef68bf90   Lukasz Majewski   gpt: part: Defini...
791
792
  
  		if (le64_to_cpu(gpt_e[i].starting_lba) != partitions[i].start) {
9b643e312   Masahiro Yamada   treewide: replace...
793
794
  			pr_err("Partition %s start: %llu does not match %llu!
  ",
cef68bf90   Lukasz Majewski   gpt: part: Defini...
795
  			      efi_str, le64_to_cpu(gpt_e[i].starting_lba),
f8d6165d4   Simon Glass   dm: part: Correct...
796
  			      (unsigned long long)partitions[i].start);
cef68bf90   Lukasz Majewski   gpt: part: Defini...
797
798
799
800
801
802
  			return -1;
  		}
  	}
  
  	return 0;
  }
4101f6879   Simon Glass   dm: Drop the bloc...
803
  int is_valid_gpt_buf(struct blk_desc *dev_desc, void *buf)
0ff7e585d   Steve Rae   fastboot: handle ...
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
  {
  	gpt_header *gpt_h;
  	gpt_entry *gpt_e;
  
  	/* determine start of GPT Header in the buffer */
  	gpt_h = buf + (GPT_PRIMARY_PARTITION_TABLE_LBA *
  		       dev_desc->blksz);
  	if (validate_gpt_header(gpt_h, GPT_PRIMARY_PARTITION_TABLE_LBA,
  				dev_desc->lba))
  		return -1;
  
  	/* determine start of GPT Entries in the buffer */
  	gpt_e = buf + (le64_to_cpu(gpt_h->partition_entry_lba) *
  		       dev_desc->blksz);
  	if (validate_gpt_entries(gpt_h, gpt_e))
  		return -1;
  
  	return 0;
  }
4101f6879   Simon Glass   dm: Drop the bloc...
823
  int write_mbr_and_gpt_partitions(struct blk_desc *dev_desc, void *buf)
0ff7e585d   Steve Rae   fastboot: handle ...
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
  {
  	gpt_header *gpt_h;
  	gpt_entry *gpt_e;
  	int gpt_e_blk_cnt;
  	lbaint_t lba;
  	int cnt;
  
  	if (is_valid_gpt_buf(dev_desc, buf))
  		return -1;
  
  	/* determine start of GPT Header in the buffer */
  	gpt_h = buf + (GPT_PRIMARY_PARTITION_TABLE_LBA *
  		       dev_desc->blksz);
  
  	/* determine start of GPT Entries in the buffer */
  	gpt_e = buf + (le64_to_cpu(gpt_h->partition_entry_lba) *
  		       dev_desc->blksz);
  	gpt_e_blk_cnt = BLOCK_CNT((le32_to_cpu(gpt_h->num_partition_entries) *
  				   le32_to_cpu(gpt_h->sizeof_partition_entry)),
  				  dev_desc);
  
  	/* write MBR */
  	lba = 0;	/* MBR is always at 0 */
  	cnt = 1;	/* MBR (1 block) */
2a981dc2c   Simon Glass   dm: block: Adjust...
848
  	if (blk_dwrite(dev_desc, lba, cnt, buf) != cnt) {
0ff7e585d   Steve Rae   fastboot: handle ...
849
850
851
852
853
854
855
856
857
  		printf("%s: failed writing '%s' (%d blks at 0x" LBAF ")
  ",
  		       __func__, "MBR", cnt, lba);
  		return 1;
  	}
  
  	/* write Primary GPT */
  	lba = GPT_PRIMARY_PARTITION_TABLE_LBA;
  	cnt = 1;	/* GPT Header (1 block) */
2a981dc2c   Simon Glass   dm: block: Adjust...
858
  	if (blk_dwrite(dev_desc, lba, cnt, gpt_h) != cnt) {
0ff7e585d   Steve Rae   fastboot: handle ...
859
860
861
862
863
864
865
866
  		printf("%s: failed writing '%s' (%d blks at 0x" LBAF ")
  ",
  		       __func__, "Primary GPT Header", cnt, lba);
  		return 1;
  	}
  
  	lba = le64_to_cpu(gpt_h->partition_entry_lba);
  	cnt = gpt_e_blk_cnt;
2a981dc2c   Simon Glass   dm: block: Adjust...
867
  	if (blk_dwrite(dev_desc, lba, cnt, gpt_e) != cnt) {
0ff7e585d   Steve Rae   fastboot: handle ...
868
869
870
871
872
873
874
875
876
877
878
  		printf("%s: failed writing '%s' (%d blks at 0x" LBAF ")
  ",
  		       __func__, "Primary GPT Entries", cnt, lba);
  		return 1;
  	}
  
  	prepare_backup_gpt_header(gpt_h);
  
  	/* write Backup GPT */
  	lba = le64_to_cpu(gpt_h->partition_entry_lba);
  	cnt = gpt_e_blk_cnt;
2a981dc2c   Simon Glass   dm: block: Adjust...
879
  	if (blk_dwrite(dev_desc, lba, cnt, gpt_e) != cnt) {
0ff7e585d   Steve Rae   fastboot: handle ...
880
881
882
883
884
885
886
887
  		printf("%s: failed writing '%s' (%d blks at 0x" LBAF ")
  ",
  		       __func__, "Backup GPT Entries", cnt, lba);
  		return 1;
  	}
  
  	lba = le64_to_cpu(gpt_h->my_lba);
  	cnt = 1;	/* GPT Header (1 block) */
2a981dc2c   Simon Glass   dm: block: Adjust...
888
  	if (blk_dwrite(dev_desc, lba, cnt, gpt_h) != cnt) {
0ff7e585d   Steve Rae   fastboot: handle ...
889
890
891
892
893
894
895
896
  		printf("%s: failed writing '%s' (%d blks at 0x" LBAF ")
  ",
  		       __func__, "Backup GPT Header", cnt, lba);
  		return 1;
  	}
  
  	return 0;
  }
a2018ab0d   Ye Li   MLK-18591-3 andro...
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
  int write_backup_gpt_partitions(struct blk_desc *dev_desc, void *buf)
  {
  	gpt_header *gpt_h;
  	gpt_entry *gpt_e;
  	int gpt_e_blk_cnt;
  	lbaint_t lba;
  	int cnt;
  
  	if (is_valid_gpt_buf(dev_desc, buf))
  		return -1;
  
  	/* determine start of GPT Header in the buffer */
  	gpt_h = buf + (GPT_PRIMARY_PARTITION_TABLE_LBA *
  		       dev_desc->blksz);
  
  	/* determine start of GPT Entries in the buffer */
  	gpt_e = buf + (le64_to_cpu(gpt_h->partition_entry_lba) *
  		       dev_desc->blksz);
  	gpt_e_blk_cnt = BLOCK_CNT((le32_to_cpu(gpt_h->num_partition_entries) *
  				   le32_to_cpu(gpt_h->sizeof_partition_entry)),
  				  dev_desc);
  
  	/* write MBR */
  	lba = 0;	/* MBR is always at 0 */
  	cnt = 1;	/* MBR (1 block) */
  	if (blk_dwrite(dev_desc, lba, cnt, buf) != cnt) {
  		printf("%s: failed writing '%s' (%d blks at 0x" LBAF ")
  ",
  		       __func__, "MBR", cnt, lba);
  		return 1;
  	}
  
  	prepare_last_lba_gpt_header(dev_desc, gpt_h);
  
  	/* write Backup GPT */
  	lba = le64_to_cpu(gpt_h->partition_entry_lba);
  	cnt = gpt_e_blk_cnt;
  	if (blk_dwrite(dev_desc, lba, cnt, gpt_e) != cnt) {
  		printf("%s: failed writing '%s' (%d blks at 0x" LBAF ")
  ",
  		       __func__, "Backup GPT Entries", cnt, lba);
  		return 1;
  	}
  
  	lba = le64_to_cpu(gpt_h->my_lba);
  	cnt = 1;	/* GPT Header (1 block) */
  	if (blk_dwrite(dev_desc, lba, cnt, gpt_h) != cnt) {
  		printf("%s: failed writing '%s' (%d blks at 0x" LBAF ")
  ",
  		       __func__, "Backup GPT Header", cnt, lba);
  		return 1;
  	}
  
  	return 0;
  }
40684ddb8   Lukasz Majewski   gpt: Support for ...
952
  #endif
07f3d789b   richardretanubun   Add support for C...
953
954
955
956
957
958
959
960
961
962
963
  /*
   * Private functions
   */
  /*
   * pmbr_part_valid(): Check for EFI partition signature
   *
   * Returns: 1 if EFI GPT partition type is found.
   */
  static int pmbr_part_valid(struct partition *part)
  {
  	if (part->sys_ind == EFI_PMBR_OSTYPE_EFI_GPT &&
8faefadb7   Marc Dietrich   disk: fix unalign...
964
  		get_unaligned_le32(&part->start_sect) == 1UL) {
07f3d789b   richardretanubun   Add support for C...
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
  		return 1;
  	}
  
  	return 0;
  }
  
  /*
   * is_pmbr_valid(): test Protective MBR for validity
   *
   * Returns: 1 if PMBR is valid, 0 otherwise.
   * Validity depends on two things:
   *  1) MSDOS signature is in the last two bytes of the MBR
   *  2) One partition of type 0xEE is found, checked by pmbr_part_valid()
   */
  static int is_pmbr_valid(legacy_mbr * mbr)
  {
  	int i = 0;
fae2bf22a   Chang Hyun Park   gpt: The leXX_to_...
982
  	if (!mbr || le16_to_cpu(mbr->signature) != MSDOS_MBR_SIGNATURE)
07f3d789b   richardretanubun   Add support for C...
983
  		return 0;
07f3d789b   richardretanubun   Add support for C...
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
  
  	for (i = 0; i < 4; i++) {
  		if (pmbr_part_valid(&mbr->partition_record[i])) {
  			return 1;
  		}
  	}
  	return 0;
  }
  
  /**
   * is_gpt_valid() - tests one GPT header and PTEs for validity
   *
   * lba is the logical block address of the GPT header to test
   * gpt is a GPT header ptr, filled on return.
   * ptes is a PTEs ptr, filled on return.
   *
0557d46b6   Urja Rannikko   disk: efi: ignore...
1000
   * Description: returns 1 if valid,  0 on error, 2 if ignored header
07f3d789b   richardretanubun   Add support for C...
1001
1002
   * If valid, returns pointers to PTEs.
   */
4101f6879   Simon Glass   dm: Drop the bloc...
1003
  static int is_gpt_valid(struct blk_desc *dev_desc, u64 lba,
e04350d29   Steve Rae   disk: part_efi: c...
1004
  			gpt_header *pgpt_head, gpt_entry **pgpt_pte)
07f3d789b   richardretanubun   Add support for C...
1005
  {
b351ccf11   Tom Rini   part_efi: In is_g...
1006
  	/* Confirm valid arguments prior to allocation. */
07f3d789b   richardretanubun   Add support for C...
1007
  	if (!dev_desc || !pgpt_head) {
df70b1c2e   Doug Anderson   cosmetic: Replace...
1008
1009
  		printf("%s: Invalid Argument(s)
  ", __func__);
07f3d789b   richardretanubun   Add support for C...
1010
1011
  		return 0;
  	}
3cc566117   Patrick Delaunay   disk: efi: correc...
1012
  	ALLOC_CACHE_ALIGN_BUFFER_PAD(legacy_mbr, mbr, 1, dev_desc->blksz);
b351ccf11   Tom Rini   part_efi: In is_g...
1013

ff98cb905   Peter Jones   part: extract MBR...
1014
1015
1016
1017
1018
1019
  	/* Read MBR Header from device */
  	if (blk_dread(dev_desc, 0, 1, (ulong *)mbr) != 1) {
  		printf("*** ERROR: Can't read MBR header ***
  ");
  		return 0;
  	}
07f3d789b   richardretanubun   Add support for C...
1020
  	/* Read GPT Header from device */
2a981dc2c   Simon Glass   dm: block: Adjust...
1021
  	if (blk_dread(dev_desc, (lbaint_t)lba, 1, pgpt_head) != 1) {
07f3d789b   richardretanubun   Add support for C...
1022
1023
1024
1025
  		printf("*** ERROR: Can't read GPT header ***
  ");
  		return 0;
  	}
0557d46b6   Urja Rannikko   disk: efi: ignore...
1026
1027
1028
1029
1030
1031
  	/* Invalid but nothing to yell about. */
  	if (le64_to_cpu(pgpt_head->signature) == GPT_HEADER_CHROMEOS_IGNORE) {
  		debug("ChromeOS 'IGNOREME' GPT header found and ignored
  ");
  		return 2;
  	}
e1f6b0a02   Steve Rae   disk: part_efi: m...
1032
  	if (validate_gpt_header(pgpt_head, (lbaint_t)lba, dev_desc->lba))
07f3d789b   richardretanubun   Add support for C...
1033
  		return 0;
07f3d789b   richardretanubun   Add support for C...
1034

ff98cb905   Peter Jones   part: extract MBR...
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
  	if (dev_desc->sig_type == SIG_TYPE_NONE) {
  		efi_guid_t empty = {};
  		if (memcmp(&pgpt_head->disk_guid, &empty, sizeof(empty))) {
  			dev_desc->sig_type = SIG_TYPE_GUID;
  			memcpy(&dev_desc->guid_sig, &pgpt_head->disk_guid,
  			      sizeof(empty));
  		} else if (mbr->unique_mbr_signature != 0) {
  			dev_desc->sig_type = SIG_TYPE_MBR;
  			dev_desc->mbr_sig = mbr->unique_mbr_signature;
  		}
  	}
07f3d789b   richardretanubun   Add support for C...
1046
1047
1048
1049
1050
1051
1052
  	/* Read and allocate Partition Table Entries */
  	*pgpt_pte = alloc_read_gpt_entries(dev_desc, pgpt_head);
  	if (*pgpt_pte == NULL) {
  		printf("GPT: Failed to allocate memory for PTE
  ");
  		return 0;
  	}
e1f6b0a02   Steve Rae   disk: part_efi: m...
1053
  	if (validate_gpt_entries(pgpt_head, *pgpt_pte)) {
deb5ca802   Doug Anderson   disk: part_efi: f...
1054
  		free(*pgpt_pte);
07f3d789b   richardretanubun   Add support for C...
1055
1056
1057
1058
1059
1060
1061
1062
  		return 0;
  	}
  
  	/* We're done, all's well */
  	return 1;
  }
  
  /**
20c568cae   Urja Rannikko   disk: efi: unify ...
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
   * find_valid_gpt() - finds a valid GPT header and PTEs
   *
   * gpt is a GPT header ptr, filled on return.
   * ptes is a PTEs ptr, filled on return.
   *
   * Description: returns 1 if found a valid gpt,  0 on error.
   * If valid, returns pointers to PTEs.
   */
  static int find_valid_gpt(struct blk_desc *dev_desc, gpt_header *gpt_head,
  			  gpt_entry **pgpt_pte)
  {
0557d46b6   Urja Rannikko   disk: efi: ignore...
1074
1075
1076
1077
1078
1079
1080
  	int r;
  
  	r = is_gpt_valid(dev_desc, GPT_PRIMARY_PARTITION_TABLE_LBA, gpt_head,
  			 pgpt_pte);
  
  	if (r != 1) {
  		if (r != 2)
a2018ab0d   Ye Li   MLK-18591-3 andro...
1081
1082
  			debug("%s: *** ERROR: Invalid GPT ***
  ", __func__);
0557d46b6   Urja Rannikko   disk: efi: ignore...
1083
1084
1085
  
  		if (is_gpt_valid(dev_desc, (dev_desc->lba - 1), gpt_head,
  				 pgpt_pte) != 1) {
20c568cae   Urja Rannikko   disk: efi: unify ...
1086
1087
1088
1089
1090
  			printf("%s: *** ERROR: Invalid Backup GPT ***
  ",
  			       __func__);
  			return 0;
  		}
0557d46b6   Urja Rannikko   disk: efi: ignore...
1091
  		if (r != 2)
a2018ab0d   Ye Li   MLK-18591-3 andro...
1092
1093
  			debug("%s: ***        Using Backup GPT ***
  ",
0557d46b6   Urja Rannikko   disk: efi: ignore...
1094
  			       __func__);
20c568cae   Urja Rannikko   disk: efi: unify ...
1095
1096
1097
1098
1099
  	}
  	return 1;
  }
  
  /**
07f3d789b   richardretanubun   Add support for C...
1100
1101
1102
1103
1104
1105
1106
1107
   * alloc_read_gpt_entries(): reads partition entries from disk
   * @dev_desc
   * @gpt - GPT header
   *
   * Description: Returns ptes on success,  NULL on error.
   * Allocates space for PTEs based on information found in @gpt.
   * Notes: remember to free pte when you're done!
   */
4101f6879   Simon Glass   dm: Drop the bloc...
1108
1109
  static gpt_entry *alloc_read_gpt_entries(struct blk_desc *dev_desc,
  					 gpt_header *pgpt_head)
07f3d789b   richardretanubun   Add support for C...
1110
  {
ae1768a72   Egbert Eich   disk/gpt: Fix GPT...
1111
  	size_t count = 0, blk_cnt;
7c4213f6a   Stephen Warren   block: pass block...
1112
  	lbaint_t blk;
07f3d789b   richardretanubun   Add support for C...
1113
1114
1115
  	gpt_entry *pte = NULL;
  
  	if (!dev_desc || !pgpt_head) {
df70b1c2e   Doug Anderson   cosmetic: Replace...
1116
1117
  		printf("%s: Invalid Argument(s)
  ", __func__);
07f3d789b   richardretanubun   Add support for C...
1118
1119
  		return NULL;
  	}
fae2bf22a   Chang Hyun Park   gpt: The leXX_to_...
1120
1121
  	count = le32_to_cpu(pgpt_head->num_partition_entries) *
  		le32_to_cpu(pgpt_head->sizeof_partition_entry);
07f3d789b   richardretanubun   Add support for C...
1122

5afb8d151   Simon Glass   part_efi: Fix com...
1123
1124
  	debug("%s: count = %u * %u = %lu
  ", __func__,
fae2bf22a   Chang Hyun Park   gpt: The leXX_to_...
1125
  	      (u32) le32_to_cpu(pgpt_head->num_partition_entries),
5afb8d151   Simon Glass   part_efi: Fix com...
1126
1127
  	      (u32) le32_to_cpu(pgpt_head->sizeof_partition_entry),
  	      (ulong)count);
07f3d789b   richardretanubun   Add support for C...
1128

ed915f7d4   Ji Luo   MA-14916-4 suppor...
1129
1130
1131
1132
1133
1134
  	/* Allocate memory for PTE.
  	 * Heap memory is very limited in SPL, if the dual bootloader is
  	 * enabled, just load pte to dram instead of oc-ram. In such case,
  	 * this part of  memory shouldn't be freed. But in common routine,
  	 * don't forget to free the memory after use.
  	 */
07f3d789b   richardretanubun   Add support for C...
1135
  	if (count != 0) {
ed915f7d4   Ji Luo   MA-14916-4 suppor...
1136
1137
1138
  #if defined(CONFIG_DUAL_BOOTLOADER) && defined(CONFIG_SPL_BUILD)
  		pte = (gpt_entry *)CONFIG_SYS_SPL_PTE_RAM_BASE;
  #else
ae1768a72   Egbert Eich   disk/gpt: Fix GPT...
1139
1140
  		pte = memalign(ARCH_DMA_MINALIGN,
  			       PAD_TO_BLOCKSIZE(count, dev_desc));
ed915f7d4   Ji Luo   MA-14916-4 suppor...
1141
  #endif
07f3d789b   richardretanubun   Add support for C...
1142
1143
1144
  	}
  
  	if (count == 0 || pte == NULL) {
5afb8d151   Simon Glass   part_efi: Fix com...
1145
1146
1147
  		printf("%s: ERROR: Can't allocate %#lX bytes for GPT Entries
  ",
  		       __func__, (ulong)count);
07f3d789b   richardretanubun   Add support for C...
1148
1149
1150
1151
  		return NULL;
  	}
  
  	/* Read GPT Entries from device */
7c4213f6a   Stephen Warren   block: pass block...
1152
  	blk = le64_to_cpu(pgpt_head->partition_entry_lba);
ae1768a72   Egbert Eich   disk/gpt: Fix GPT...
1153
  	blk_cnt = BLOCK_CNT(count, dev_desc);
2a981dc2c   Simon Glass   dm: block: Adjust...
1154
  	if (blk_dread(dev_desc, blk, (lbaint_t)blk_cnt, pte) != blk_cnt) {
07f3d789b   richardretanubun   Add support for C...
1155
1156
  		printf("*** ERROR: Can't read GPT Entries ***
  ");
ed915f7d4   Ji Luo   MA-14916-4 suppor...
1157
  #if !defined(CONFIG_DUAL_BOOTLOADER) || !defined(CONFIG_SPL_BUILD)
07f3d789b   richardretanubun   Add support for C...
1158
  		free(pte);
ed915f7d4   Ji Luo   MA-14916-4 suppor...
1159
  #endif
07f3d789b   richardretanubun   Add support for C...
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
  		return NULL;
  	}
  	return pte;
  }
  
  /**
   * is_pte_valid(): validates a single Partition Table Entry
   * @gpt_entry - Pointer to a single Partition Table Entry
   *
   * Description: returns 1 if valid,  0 on error.
   */
  static int is_pte_valid(gpt_entry * pte)
  {
  	efi_guid_t unused_guid;
  
  	if (!pte) {
df70b1c2e   Doug Anderson   cosmetic: Replace...
1176
1177
  		printf("%s: Invalid Argument(s)
  ", __func__);
07f3d789b   richardretanubun   Add support for C...
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
  		return 0;
  	}
  
  	/* Only one validation for now:
  	 * The GUID Partition Type != Unused Entry (ALL-ZERO)
  	 */
  	memset(unused_guid.b, 0, sizeof(unused_guid.b));
  
  	if (memcmp(pte->partition_type_guid.b, unused_guid.b,
  		sizeof(unused_guid.b)) == 0) {
df70b1c2e   Doug Anderson   cosmetic: Replace...
1188
1189
  		debug("%s: Found an unused PTE GUID at 0x%08X
  ", __func__,
9936be31f   Taylor Hutt   disk: Address cas...
1190
  		      (unsigned int)(uintptr_t)pte);
07f3d789b   richardretanubun   Add support for C...
1191
1192
1193
1194
1195
1196
  
  		return 0;
  	} else {
  		return 1;
  	}
  }
96e5b03c8   Simon Glass   dm: part: Convert...
1197
1198
1199
1200
1201
1202
1203
1204
1205
  
  /*
   * Add an 'a_' prefix so it comes before 'dos' in the linker list. We need to
   * check EFI first, since a DOS partition is often used as a 'protective MBR'
   * with EFI.
   */
  U_BOOT_PART_TYPE(a_efi) = {
  	.name		= "EFI",
  	.part_type	= PART_TYPE_EFI,
87b8530fe   Petr Kulhavy   disk: part: imple...
1206
  	.max_entries	= GPT_ENTRY_NUMBERS,
3e8bd4695   Simon Glass   dm: part: Rename ...
1207
  	.get_info	= part_get_info_ptr(part_get_info_efi),
084bf4c24   Simon Glass   part: Rename test...
1208
1209
  	.print		= part_print_ptr(part_print_efi),
  	.test		= part_test_efi,
96e5b03c8   Simon Glass   dm: part: Convert...
1210
  };
07f3d789b   richardretanubun   Add support for C...
1211
  #endif