Blame view

disk/part_efi.c 31.9 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>
07f3d789b   richardretanubun   Add support for C...
22

40684ddb8   Lukasz Majewski   gpt: Support for ...
23
  DECLARE_GLOBAL_DATA_PTR;
44ab2d325   Heinrich Schuchardt   efi_loader: avoid...
24
25
26
27
  /*
   * GUID for basic data partions.
   */
  static const efi_guid_t partition_basic_data_guid = PARTITION_BASIC_DATA_GUID;
1811a928c   Adam Ford   Move most CONFIG_...
28
  #ifdef CONFIG_HAVE_BLOCK_DEVICE
07f3d789b   richardretanubun   Add support for C...
29
30
31
32
33
34
35
  /**
   * 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_...
36
  static inline u32 efi_crc32(const void *buf, u32 len)
07f3d789b   richardretanubun   Add support for C...
37
38
39
40
41
42
43
44
45
46
  {
  	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...
47
  static int is_gpt_valid(struct blk_desc *dev_desc, u64 lba,
e04350d29   Steve Rae   disk: part_efi: c...
48
  				gpt_header *pgpt_head, gpt_entry **pgpt_pte);
4101f6879   Simon Glass   dm: Drop the bloc...
49
50
  static gpt_entry *alloc_read_gpt_entries(struct blk_desc *dev_desc,
  					 gpt_header *pgpt_head);
07f3d789b   richardretanubun   Add support for C...
51
  static int is_pte_valid(gpt_entry * pte);
6eecc0307   Lei Wen   part: show efi pa...
52
53
54
55
56
57
58
59
60
61
62
63
64
  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 ...
65
  static const efi_guid_t system_guid = PARTITION_SYSTEM_GUID;
b4414f4a4   Stephen Warren   disk: part_efi: s...
66
67
68
69
70
71
72
  
  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...
73
74
75
76
77
78
79
  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...
80
  	if (le64_to_cpu(gpt_h->signature) != GPT_HEADER_SIGNATURE_UBOOT) {
e1f6b0a02   Steve Rae   disk: part_efi: m...
81
82
83
84
  		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...
85
  		       GPT_HEADER_SIGNATURE_UBOOT);
e1f6b0a02   Steve Rae   disk: part_efi: m...
86
87
88
89
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
  		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;
  }
9b149c2a2   Ye Li   MLK-18591-3 andro...
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
  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...
159
160
161
162
163
164
165
166
167
168
  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)) {
9b149c2a2   Ye Li   MLK-18591-3 andro...
169
170
  		debug("%s: 0x%x != 0x%x
  ",
e1f6b0a02   Steve Rae   disk: part_efi: m...
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
  		       "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 ...
189
190
  	gpt_h->partition_entry_lba =
  			cpu_to_le64(le64_to_cpu(gpt_h->last_usable_lba) + 1);
e1f6b0a02   Steve Rae   disk: part_efi: m...
191
192
193
194
195
196
  	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...
197
  #if CONFIG_IS_ENABLED(EFI_PARTITION)
07f3d789b   richardretanubun   Add support for C...
198
199
200
  /*
   * Public Functions (include/part.h)
   */
73d6d18b7   Alison Chaiken   GPT: add accessor...
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
  /*
   * 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 */
  	if (is_gpt_valid(dev_desc, GPT_PRIMARY_PARTITION_TABLE_LBA,
  			 gpt_head, &gpt_pte) != 1) {
  		printf("%s: *** ERROR: Invalid GPT ***
  ", __func__);
  		if (is_gpt_valid(dev_desc, dev_desc->lba - 1,
  				 gpt_head, &gpt_pte) != 1) {
  			printf("%s: *** ERROR: Invalid Backup GPT ***
  ",
  			       __func__);
  			return -EINVAL;
  		} else {
  			printf("%s: ***        Using Backup GPT ***
  ",
  			       __func__);
  		}
  	}
  
  	guid_bin = gpt_head->disk_guid.b;
  	uuid_bin_to_str(guid_bin, guid, UUID_STR_FORMAT_GUID);
  
  	return 0;
  }
084bf4c24   Simon Glass   part: Rename test...
234
  void part_print_efi(struct blk_desc *dev_desc)
07f3d789b   richardretanubun   Add support for C...
235
  {
ae1768a72   Egbert Eich   disk/gpt: Fix GPT...
236
  	ALLOC_CACHE_ALIGN_BUFFER_PAD(gpt_header, gpt_head, 1, dev_desc->blksz);
deb5ca802   Doug Anderson   disk: part_efi: f...
237
  	gpt_entry *gpt_pte = NULL;
07f3d789b   richardretanubun   Add support for C...
238
  	int i = 0;
db9b6200a   Alison Chaiken   EFI: replace numb...
239
  	char uuid[UUID_STR_LEN + 1];
a96a0e615   Przemyslaw Marczak   part_efi: move uu...
240
  	unsigned char *uuid_bin;
07f3d789b   richardretanubun   Add support for C...
241

07f3d789b   richardretanubun   Add support for C...
242
243
  	/* This function validates AND fills in the GPT header and PTE */
  	if (is_gpt_valid(dev_desc, GPT_PRIMARY_PARTITION_TABLE_LBA,
4715a8113   Stephen Warren   disk: part_efi: f...
244
  			 gpt_head, &gpt_pte) != 1) {
df70b1c2e   Doug Anderson   cosmetic: Replace...
245
246
  		printf("%s: *** ERROR: Invalid GPT ***
  ", __func__);
ae95fad5a   Steve Rae   disk: part_efi: a...
247
248
249
250
251
252
253
254
255
256
257
  		if (is_gpt_valid(dev_desc, (dev_desc->lba - 1),
  				 gpt_head, &gpt_pte) != 1) {
  			printf("%s: *** ERROR: Invalid Backup GPT ***
  ",
  			       __func__);
  			return;
  		} else {
  			printf("%s: ***        Using Backup GPT ***
  ",
  			       __func__);
  		}
07f3d789b   richardretanubun   Add support for C...
258
  	}
deb5ca802   Doug Anderson   disk: part_efi: f...
259
260
  	debug("%s: gpt-entry at %p
  ", __func__, gpt_pte);
07f3d789b   richardretanubun   Add support for C...
261

788a8c1fc   Stephen Warren   disk: part_efi: r...
262
263
  	printf("Part\tStart LBA\tEnd LBA\t\tName
  ");
13bf2f55d   Stephen Warren   disk: part_efi: p...
264
265
  	printf("\tAttributes
  ");
d718ded05   Przemyslaw Marczak   lib: uuid: code r...
266
267
268
269
  	printf("\tType GUID
  ");
  	printf("\tPartition GUID
  ");
f07cd2c4c   Stephen Warren   disk: part_efi: p...
270

fae2bf22a   Chang Hyun Park   gpt: The leXX_to_...
271
  	for (i = 0; i < le32_to_cpu(gpt_head->num_partition_entries); i++) {
38a3021ed   Stephen Warren   disk: part_efi: r...
272
273
274
  		/* Stop at the first non valid PTE */
  		if (!is_pte_valid(&gpt_pte[i]))
  			break;
788a8c1fc   Stephen Warren   disk: part_efi: r...
275
276
  		printf("%3d\t0x%08llx\t0x%08llx\t\"%s\"
  ", (i + 1),
fae2bf22a   Chang Hyun Park   gpt: The leXX_to_...
277
278
  			le64_to_cpu(gpt_pte[i].starting_lba),
  			le64_to_cpu(gpt_pte[i].ending_lba),
788a8c1fc   Stephen Warren   disk: part_efi: r...
279
  			print_efiname(&gpt_pte[i]));
13bf2f55d   Stephen Warren   disk: part_efi: p...
280
281
  		printf("\tattrs:\t0x%016llx
  ", gpt_pte[i].attributes.raw);
a96a0e615   Przemyslaw Marczak   part_efi: move uu...
282
  		uuid_bin = (unsigned char *)gpt_pte[i].partition_type_guid.b;
d718ded05   Przemyslaw Marczak   lib: uuid: code r...
283
  		uuid_bin_to_str(uuid_bin, uuid, UUID_STR_FORMAT_GUID);
f07cd2c4c   Stephen Warren   disk: part_efi: p...
284
285
  		printf("\ttype:\t%s
  ", uuid);
bcb41dcae   Patrick Delaunay   uuid: add selecti...
286
287
288
289
290
  #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...
291
  		uuid_bin = (unsigned char *)gpt_pte[i].unique_partition_guid.b;
d718ded05   Przemyslaw Marczak   lib: uuid: code r...
292
293
294
  		uuid_bin_to_str(uuid_bin, uuid, UUID_STR_FORMAT_GUID);
  		printf("\tguid:\t%s
  ", uuid);
07f3d789b   richardretanubun   Add support for C...
295
  	}
30355b43d   Ji Luo   MA-14916-4 suppor...
296
  #if !defined(CONFIG_DUAL_BOOTLOADER) || !defined(CONFIG_SPL_BUILD)
07f3d789b   richardretanubun   Add support for C...
297
  	/* Remember to free pte */
deb5ca802   Doug Anderson   disk: part_efi: f...
298
  	free(gpt_pte);
30355b43d   Ji Luo   MA-14916-4 suppor...
299
  #endif
07f3d789b   richardretanubun   Add support for C...
300
301
  	return;
  }
3e8bd4695   Simon Glass   dm: part: Rename ...
302
303
  int part_get_info_efi(struct blk_desc *dev_desc, int part,
  		      disk_partition_t *info)
07f3d789b   richardretanubun   Add support for C...
304
  {
ae1768a72   Egbert Eich   disk/gpt: Fix GPT...
305
  	ALLOC_CACHE_ALIGN_BUFFER_PAD(gpt_header, gpt_head, 1, dev_desc->blksz);
deb5ca802   Doug Anderson   disk: part_efi: f...
306
  	gpt_entry *gpt_pte = NULL;
07f3d789b   richardretanubun   Add support for C...
307
308
  
  	/* "part" argument must be at least 1 */
4708a07c7   Simon Glass   part_efi: Drop NU...
309
  	if (part < 1) {
df70b1c2e   Doug Anderson   cosmetic: Replace...
310
311
  		printf("%s: Invalid Argument(s)
  ", __func__);
07f3d789b   richardretanubun   Add support for C...
312
313
314
315
316
  		return -1;
  	}
  
  	/* This function validates AND fills in the GPT header and PTE */
  	if (is_gpt_valid(dev_desc, GPT_PRIMARY_PARTITION_TABLE_LBA,
4715a8113   Stephen Warren   disk: part_efi: f...
317
  			gpt_head, &gpt_pte) != 1) {
9b149c2a2   Ye Li   MLK-18591-3 andro...
318
319
  		debug("%s: *** ERROR: Invalid GPT ***
  ", __func__);
ae95fad5a   Steve Rae   disk: part_efi: a...
320
321
322
323
324
325
326
  		if (is_gpt_valid(dev_desc, (dev_desc->lba - 1),
  				 gpt_head, &gpt_pte) != 1) {
  			printf("%s: *** ERROR: Invalid Backup GPT ***
  ",
  			       __func__);
  			return -1;
  		} else {
9b149c2a2   Ye Li   MLK-18591-3 andro...
327
328
  			debug("%s: ***        Using Backup GPT ***
  ",
ae95fad5a   Steve Rae   disk: part_efi: a...
329
330
  			       __func__);
  		}
07f3d789b   richardretanubun   Add support for C...
331
  	}
fae2bf22a   Chang Hyun Park   gpt: The leXX_to_...
332
  	if (part > le32_to_cpu(gpt_head->num_partition_entries) ||
c04d68c69   Stephen Warren   disk: part_efi: r...
333
  	    !is_pte_valid(&gpt_pte[part - 1])) {
6d2ee5a33   Mark Langsdorf   part_efi: make su...
334
335
  		debug("%s: *** ERROR: Invalid partition number %d ***
  ",
c04d68c69   Stephen Warren   disk: part_efi: r...
336
  			__func__, part);
30355b43d   Ji Luo   MA-14916-4 suppor...
337
  #if !defined(CONFIG_DUAL_BOOTLOADER) || !defined(CONFIG_SPL_BUILD)
6d2ee5a33   Mark Langsdorf   part_efi: make su...
338
  		free(gpt_pte);
30355b43d   Ji Luo   MA-14916-4 suppor...
339
  #endif
c04d68c69   Stephen Warren   disk: part_efi: r...
340
341
  		return -1;
  	}
e04350d29   Steve Rae   disk: part_efi: c...
342
343
  	/* 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...
344
  	/* The ending LBA is inclusive, to calculate size, add 1 to it */
e04350d29   Steve Rae   disk: part_efi: c...
345
  	info->size = (lbaint_t)le64_to_cpu(gpt_pte[part - 1].ending_lba) + 1
509708397   Richard Retanubun   part_efi: Fix par...
346
  		     - info->start;
ae1768a72   Egbert Eich   disk/gpt: Fix GPT...
347
  	info->blksz = dev_desc->blksz;
07f3d789b   richardretanubun   Add support for C...
348

6eecc0307   Lei Wen   part: show efi pa...
349
  	sprintf((char *)info->name, "%s",
deb5ca802   Doug Anderson   disk: part_efi: f...
350
  			print_efiname(&gpt_pte[part - 1]));
192bc6948   Ben Whitten   Fix GCC format-se...
351
  	strcpy((char *)info->type, "U-Boot");
b4414f4a4   Stephen Warren   disk: part_efi: s...
352
  	info->bootable = is_bootable(&gpt_pte[part - 1]);
b331cd620   Patrick Delaunay   cmd, disk: conver...
353
  #if CONFIG_IS_ENABLED(PARTITION_UUIDS)
d718ded05   Przemyslaw Marczak   lib: uuid: code r...
354
355
  	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...
356
  #endif
7561b258a   Patrick Delaunay   gpt: add optional...
357
358
359
360
  #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...
361

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

30355b43d   Ji Luo   MA-14916-4 suppor...
366
367
368
369
370
371
  #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...
372
  	free(gpt_pte);
30355b43d   Ji Luo   MA-14916-4 suppor...
373
  #endif
07f3d789b   richardretanubun   Add support for C...
374
375
  	return 0;
  }
084bf4c24   Simon Glass   part: Rename test...
376
  static int part_test_efi(struct blk_desc *dev_desc)
07f3d789b   richardretanubun   Add support for C...
377
  {
ae1768a72   Egbert Eich   disk/gpt: Fix GPT...
378
  	ALLOC_CACHE_ALIGN_BUFFER_PAD(legacy_mbr, legacymbr, 1, dev_desc->blksz);
07f3d789b   richardretanubun   Add support for C...
379
380
  
  	/* Read legacy MBR from block 0 and validate it */
2a981dc2c   Simon Glass   dm: block: Adjust...
381
  	if ((blk_dread(dev_desc, 0, 1, (ulong *)legacymbr) != 1)
f75dd584c   Anton staaf   part_efi: dcache:...
382
  		|| (is_pmbr_valid(legacymbr) != 1)) {
07f3d789b   richardretanubun   Add support for C...
383
384
385
386
  		return -1;
  	}
  	return 0;
  }
40684ddb8   Lukasz Majewski   gpt: Support for ...
387
388
389
390
391
392
  /**
   * 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...
393
  static int set_protective_mbr(struct blk_desc *dev_desc)
40684ddb8   Lukasz Majewski   gpt: Support for ...
394
  {
40684ddb8   Lukasz Majewski   gpt: Support for ...
395
  	/* Setup the Protective MBR */
3cc566117   Patrick Delaunay   disk: efi: correc...
396
  	ALLOC_CACHE_ALIGN_BUFFER_PAD(legacy_mbr, p_mbr, 1, dev_desc->blksz);
40684ddb8   Lukasz Majewski   gpt: Support for ...
397
398
399
400
401
  	if (p_mbr == NULL) {
  		printf("%s: calloc failed!
  ", __func__);
  		return -1;
  	}
e163a931a   Vincent Tinelli   cmd: gpt: backup ...
402
403
404
  
  	/* Read MBR to backup boot code if it exists */
  	if (blk_dread(dev_desc, 0, 1, p_mbr) != 1) {
9b643e312   Masahiro Yamada   treewide: replace...
405
406
  		pr_err("** Can't read from device %d **
  ", dev_desc->devnum);
e163a931a   Vincent Tinelli   cmd: gpt: backup ...
407
408
  		return -1;
  	}
955575c8d   Sam Protsenko   disk: efi: Correc...
409
410
411
  	/* 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 ...
412
413
414
415
  	/* 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...
416
  	p_mbr->partition_record[0].nr_sects = (u32) dev_desc->lba - 1;
40684ddb8   Lukasz Majewski   gpt: Support for ...
417
418
  
  	/* Write MBR sector to the MMC device */
2a981dc2c   Simon Glass   dm: block: Adjust...
419
  	if (blk_dwrite(dev_desc, 0, 1, p_mbr) != 1) {
40684ddb8   Lukasz Majewski   gpt: Support for ...
420
421
  		printf("** Can't write to device %d **
  ",
bcce53d04   Simon Glass   dm: block: Rename...
422
  			dev_desc->devnum);
40684ddb8   Lukasz Majewski   gpt: Support for ...
423
424
  		return -1;
  	}
40684ddb8   Lukasz Majewski   gpt: Support for ...
425
426
  	return 0;
  }
4101f6879   Simon Glass   dm: Drop the bloc...
427
  int write_gpt_table(struct blk_desc *dev_desc,
40684ddb8   Lukasz Majewski   gpt: Support for ...
428
429
  		gpt_header *gpt_h, gpt_entry *gpt_e)
  {
ae1768a72   Egbert Eich   disk/gpt: Fix GPT...
430
431
  	const int pte_blk_cnt = BLOCK_CNT((gpt_h->num_partition_entries
  					   * sizeof(gpt_entry)), dev_desc);
40684ddb8   Lukasz Majewski   gpt: Support for ...
432
  	u32 calc_crc32;
40684ddb8   Lukasz Majewski   gpt: Support for ...
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
  
  	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...
451
  	if (blk_dwrite(dev_desc, 1, 1, gpt_h) != 1)
40684ddb8   Lukasz Majewski   gpt: Support for ...
452
  		goto err;
02e43537b   Philipp Tomsich   part_efi: support...
453
454
  	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 ...
455
  		goto err;
e1f6b0a02   Steve Rae   disk: part_efi: m...
456
  	prepare_backup_gpt_header(gpt_h);
40684ddb8   Lukasz Majewski   gpt: Support for ...
457

2a981dc2c   Simon Glass   dm: block: Adjust...
458
459
  	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 ...
460
  		goto err;
2a981dc2c   Simon Glass   dm: block: Adjust...
461
462
  	if (blk_dwrite(dev_desc, (lbaint_t)le64_to_cpu(gpt_h->my_lba), 1,
  		       gpt_h) != 1)
40684ddb8   Lukasz Majewski   gpt: Support for ...
463
464
465
466
467
468
469
  		goto err;
  
  	debug("GPT successfully written to block device!
  ");
  	return 0;
  
   err:
bcce53d04   Simon Glass   dm: block: Rename...
470
471
  	printf("** Can't write to device %d **
  ", dev_desc->devnum);
40684ddb8   Lukasz Majewski   gpt: Support for ...
472
473
  	return -1;
  }
47d7ee47b   Maxime Ripard   part: efi: make g...
474
475
476
  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 ...
477
  {
e04350d29   Steve Rae   disk: part_efi: c...
478
  	lbaint_t offset = (lbaint_t)le64_to_cpu(gpt_h->first_usable_lba);
e04350d29   Steve Rae   disk: part_efi: c...
479
480
  	lbaint_t last_usable_lba = (lbaint_t)
  			le64_to_cpu(gpt_h->last_usable_lba);
40684ddb8   Lukasz Majewski   gpt: Support for ...
481
  	int i, k;
67cd4a634   Marek Vasut   disk: Fix possibl...
482
  	size_t efiname_len, dosname_len;
b331cd620   Patrick Delaunay   cmd, disk: conver...
483
  #if CONFIG_IS_ENABLED(PARTITION_UUIDS)
40684ddb8   Lukasz Majewski   gpt: Support for ...
484
  	char *str_uuid;
a96a0e615   Przemyslaw Marczak   part_efi: move uu...
485
  	unsigned char *bin_uuid;
40684ddb8   Lukasz Majewski   gpt: Support for ...
486
  #endif
7561b258a   Patrick Delaunay   gpt: add optional...
487
488
489
490
  #ifdef CONFIG_PARTITION_TYPE_GUID
  	char *str_type_guid;
  	unsigned char *bin_type_guid;
  #endif
79c5912e8   Maxime Ripard   part: efi: Disabl...
491
492
493
494
495
496
497
  	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 ...
498
499
500
  
  	for (i = 0; i < parts; i++) {
  		/* partition starting lba */
5276e8b62   Maxime Ripard   part: efi: rework...
501
502
  		lbaint_t start = partitions[i].start;
  		lbaint_t size = partitions[i].size;
40684ddb8   Lukasz Majewski   gpt: Support for ...
503
  		if (start) {
5276e8b62   Maxime Ripard   part: efi: rework...
504
  			offset = start + size;
40684ddb8   Lukasz Majewski   gpt: Support for ...
505
  		} else {
79c5912e8   Maxime Ripard   part: efi: Disabl...
506
  			start = offset;
5276e8b62   Maxime Ripard   part: efi: rework...
507
  			offset += size;
40684ddb8   Lukasz Majewski   gpt: Support for ...
508
  		}
79c5912e8   Maxime Ripard   part: efi: Disabl...
509
510
511
512
513
  
  		/*
  		 * If our partition overlaps with either the GPT
  		 * header, or the partition entry, reject it.
  		 */
ae0e0228e   Patrick Delaunay   disk: efi: correc...
514
515
  		if (((start < hdr_end && hdr_start < (start + size)) ||
  		     (start < pte_end && pte_start < (start + size)))) {
79c5912e8   Maxime Ripard   part: efi: Disabl...
516
517
518
519
520
521
  			printf("Partition overlap
  ");
  			return -1;
  		}
  
  		gpt_e[i].starting_lba = cpu_to_le64(start);
a56538676   Patrick Delaunay   disk: part_efi: f...
522
  		if (offset > (last_usable_lba + 1)) {
40684ddb8   Lukasz Majewski   gpt: Support for ...
523
524
525
526
527
  			printf("Partitions layout exceds disk size
  ");
  			return -1;
  		}
  		/* partition ending lba */
5276e8b62   Maxime Ripard   part: efi: rework...
528
  		if ((i == parts - 1) && (size == 0))
40684ddb8   Lukasz Majewski   gpt: Support for ...
529
530
531
532
  			/* 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...
533
534
535
536
537
538
539
540
541
542
543
544
545
546
  #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...
547
  			       &partition_basic_data_guid, 16);
7561b258a   Patrick Delaunay   gpt: add optional...
548
549
  		}
  #else
40684ddb8   Lukasz Majewski   gpt: Support for ...
550
551
  		/* partition type GUID */
  		memcpy(gpt_e[i].partition_type_guid.b,
44ab2d325   Heinrich Schuchardt   efi_loader: avoid...
552
  			&partition_basic_data_guid, 16);
7561b258a   Patrick Delaunay   gpt: add optional...
553
  #endif
40684ddb8   Lukasz Majewski   gpt: Support for ...
554

b331cd620   Patrick Delaunay   cmd, disk: conver...
555
  #if CONFIG_IS_ENABLED(PARTITION_UUIDS)
40684ddb8   Lukasz Majewski   gpt: Support for ...
556
  		str_uuid = partitions[i].uuid;
a96a0e615   Przemyslaw Marczak   part_efi: move uu...
557
  		bin_uuid = gpt_e[i].unique_partition_guid.b;
9da52f8f6   Vincent Tinelli   gpt: Fix uuid str...
558
  		if (uuid_str_to_bin(str_uuid, bin_uuid, UUID_STR_FORMAT_GUID)) {
40684ddb8   Lukasz Majewski   gpt: Support for ...
559
560
561
562
563
564
565
566
567
568
  			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...
569
570
  		if (partitions[i].bootable)
  			gpt_e[i].attributes.fields.legacy_bios_bootable = 1;
40684ddb8   Lukasz Majewski   gpt: Support for ...
571
  		/* partition name */
67cd4a634   Marek Vasut   disk: Fix possibl...
572
  		efiname_len = sizeof(gpt_e[i].partition_name)
40684ddb8   Lukasz Majewski   gpt: Support for ...
573
  			/ sizeof(efi_char16_t);
67cd4a634   Marek Vasut   disk: Fix possibl...
574
575
576
577
578
579
  		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 ...
580
581
  			gpt_e[i].partition_name[k] =
  				(efi_char16_t)(partitions[i].name[k]);
e04350d29   Steve Rae   disk: part_efi: c...
582
583
584
  		debug("%s: name: %s offset[%d]: 0x" LBAF
  		      " size[%d]: 0x" LBAF "
  ",
40684ddb8   Lukasz Majewski   gpt: Support for ...
585
  		      __func__, partitions[i].name, i,
5276e8b62   Maxime Ripard   part: efi: rework...
586
  		      offset, i, size);
40684ddb8   Lukasz Majewski   gpt: Support for ...
587
588
589
590
  	}
  
  	return 0;
  }
02e43537b   Philipp Tomsich   part_efi: support...
591
592
593
  static uint32_t partition_entries_offset(struct blk_desc *dev_desc)
  {
  	uint32_t offset_blks = 2;
89d33a2c0   Maxime Ripard   part: efi: Fix of...
594
  	uint32_t __maybe_unused offset_bytes;
02e43537b   Philipp Tomsich   part_efi: support...
595
596
597
598
599
600
601
602
603
604
605
  	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...
606
  	offset_bytes =
02e43537b   Philipp Tomsich   part_efi: support...
607
  		PAD_TO_BLOCKSIZE(CONFIG_EFI_PARTITION_ENTRIES_OFF, dev_desc);
89d33a2c0   Maxime Ripard   part: efi: Fix of...
608
  	offset_blks = offset_bytes / dev_desc->blksz;
02e43537b   Philipp Tomsich   part_efi: support...
609
610
611
612
613
614
615
616
617
618
619
  #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...
620
621
622
623
  	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...
624
625
626
627
628
629
630
631
632
633
634
635
636
637
  #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...
638
  int gpt_fill_header(struct blk_desc *dev_desc, gpt_header *gpt_h,
40684ddb8   Lukasz Majewski   gpt: Support for ...
639
640
  		char *str_guid, int parts_count)
  {
67b905226   Simon Glass   Rename GPT_HEADER...
641
  	gpt_h->signature = cpu_to_le64(GPT_HEADER_SIGNATURE_UBOOT);
40684ddb8   Lukasz Majewski   gpt: Support for ...
642
643
644
645
  	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 ...
646
  	gpt_h->last_usable_lba = cpu_to_le64(dev_desc->lba - 34);
02e43537b   Philipp Tomsich   part_efi: support...
647
648
649
650
  	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 ...
651
652
653
654
  	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...
655
  	if (uuid_str_to_bin(str_guid, gpt_h->disk_guid.b, UUID_STR_FORMAT_GUID))
40684ddb8   Lukasz Majewski   gpt: Support for ...
656
657
658
659
  		return -1;
  
  	return 0;
  }
4101f6879   Simon Glass   dm: Drop the bloc...
660
  int gpt_restore(struct blk_desc *dev_desc, char *str_disk_guid,
40684ddb8   Lukasz Majewski   gpt: Support for ...
661
662
  		disk_partition_t *partitions, int parts_count)
  {
bb021013b   Lukasz Majewski   gpt: Use cache al...
663
  	gpt_header *gpt_h;
ae1768a72   Egbert Eich   disk/gpt: Fix GPT...
664
  	gpt_entry *gpt_e;
bb021013b   Lukasz Majewski   gpt: Use cache al...
665
  	int ret, size;
ae1768a72   Egbert Eich   disk/gpt: Fix GPT...
666

bb021013b   Lukasz Majewski   gpt: Use cache al...
667
668
  	size = PAD_TO_BLOCKSIZE(sizeof(gpt_header), dev_desc);
  	gpt_h = malloc_cache_aligned(size);
40684ddb8   Lukasz Majewski   gpt: Support for ...
669
670
671
672
673
  	if (gpt_h == NULL) {
  		printf("%s: calloc failed!
  ", __func__);
  		return -1;
  	}
bb021013b   Lukasz Majewski   gpt: Use cache al...
674
  	memset(gpt_h, 0, size);
40684ddb8   Lukasz Majewski   gpt: Support for ...
675

bb021013b   Lukasz Majewski   gpt: Use cache al...
676
677
678
  	size = PAD_TO_BLOCKSIZE(GPT_ENTRY_NUMBERS * sizeof(gpt_entry),
  				dev_desc);
  	gpt_e = malloc_cache_aligned(size);
40684ddb8   Lukasz Majewski   gpt: Support for ...
679
680
681
682
683
684
  	if (gpt_e == NULL) {
  		printf("%s: calloc failed!
  ", __func__);
  		free(gpt_h);
  		return -1;
  	}
bb021013b   Lukasz Majewski   gpt: Use cache al...
685
  	memset(gpt_e, 0, size);
40684ddb8   Lukasz Majewski   gpt: Support for ...
686
687
688
689
690
691
692
  
  	/* 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...
693
  	ret = gpt_fill_pte(dev_desc, gpt_h, gpt_e, partitions, parts_count);
40684ddb8   Lukasz Majewski   gpt: Support for ...
694
695
696
697
698
699
700
701
702
703
704
  	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 ...
705

cef68bf90   Lukasz Majewski   gpt: part: Defini...
706
707
708
709
710
711
712
713
714
715
716
717
718
  static void gpt_convert_efi_name_to_char(char *s, efi_char16_t *es, int n)
  {
  	char *ess = (char *)es;
  	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...
719
  int gpt_verify_headers(struct blk_desc *dev_desc, gpt_header *gpt_head,
cef68bf90   Lukasz Majewski   gpt: part: Defini...
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
  		       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;
  	}
  	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...
744
  int gpt_verify_partitions(struct blk_desc *dev_desc,
cef68bf90   Lukasz Majewski   gpt: part: Defini...
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
  			  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...
761
762
  			pr_err("More partitions than allowed!
  ");
cef68bf90   Lukasz Majewski   gpt: part: Defini...
763
764
765
766
767
768
769
770
771
772
773
774
  			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...
775
776
  			pr_err("Partition name: %s does not match %s!
  ",
cef68bf90   Lukasz Majewski   gpt: part: Defini...
777
778
779
780
781
782
783
784
  			      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...
785
786
  		      (unsigned long long)gpt_part_size,
  		      (unsigned long long)partitions[i].size);
cef68bf90   Lukasz Majewski   gpt: part: Defini...
787
788
  
  		if (le64_to_cpu(gpt_part_size) != partitions[i].size) {
c2fdd3456   Kever Yang   cmd: gpt: fix the...
789
790
791
  			/* We do not check the extend partition size */
  			if ((i == parts - 1) && (partitions[i].size == 0))
  				continue;
9b643e312   Masahiro Yamada   treewide: replace...
792
793
  			pr_err("Partition %s size: %llu does not match %llu!
  ",
f8d6165d4   Simon Glass   dm: part: Correct...
794
795
  			      efi_str, (unsigned long long)gpt_part_size,
  			      (unsigned long long)partitions[i].size);
cef68bf90   Lukasz Majewski   gpt: part: Defini...
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
  			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...
813
  		      (unsigned long long)partitions[i].start);
cef68bf90   Lukasz Majewski   gpt: part: Defini...
814
815
  
  		if (le64_to_cpu(gpt_e[i].starting_lba) != partitions[i].start) {
9b643e312   Masahiro Yamada   treewide: replace...
816
817
  			pr_err("Partition %s start: %llu does not match %llu!
  ",
cef68bf90   Lukasz Majewski   gpt: part: Defini...
818
  			      efi_str, le64_to_cpu(gpt_e[i].starting_lba),
f8d6165d4   Simon Glass   dm: part: Correct...
819
  			      (unsigned long long)partitions[i].start);
cef68bf90   Lukasz Majewski   gpt: part: Defini...
820
821
822
823
824
825
  			return -1;
  		}
  	}
  
  	return 0;
  }
4101f6879   Simon Glass   dm: Drop the bloc...
826
  int is_valid_gpt_buf(struct blk_desc *dev_desc, void *buf)
0ff7e585d   Steve Rae   fastboot: handle ...
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
  {
  	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...
846
  int write_mbr_and_gpt_partitions(struct blk_desc *dev_desc, void *buf)
0ff7e585d   Steve Rae   fastboot: handle ...
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
  {
  	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...
871
  	if (blk_dwrite(dev_desc, lba, cnt, buf) != cnt) {
0ff7e585d   Steve Rae   fastboot: handle ...
872
873
874
875
876
877
878
879
880
  		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...
881
  	if (blk_dwrite(dev_desc, lba, cnt, gpt_h) != cnt) {
0ff7e585d   Steve Rae   fastboot: handle ...
882
883
884
885
886
887
888
889
  		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...
890
  	if (blk_dwrite(dev_desc, lba, cnt, gpt_e) != cnt) {
0ff7e585d   Steve Rae   fastboot: handle ...
891
892
893
894
895
896
897
898
899
900
901
  		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...
902
  	if (blk_dwrite(dev_desc, lba, cnt, gpt_e) != cnt) {
0ff7e585d   Steve Rae   fastboot: handle ...
903
904
905
906
907
908
909
910
  		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...
911
  	if (blk_dwrite(dev_desc, lba, cnt, gpt_h) != cnt) {
0ff7e585d   Steve Rae   fastboot: handle ...
912
913
914
915
916
917
918
919
  		printf("%s: failed writing '%s' (%d blks at 0x" LBAF ")
  ",
  		       __func__, "Backup GPT Header", cnt, lba);
  		return 1;
  	}
  
  	return 0;
  }
9b149c2a2   Ye Li   MLK-18591-3 andro...
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
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
  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 ...
975
  #endif
07f3d789b   richardretanubun   Add support for C...
976
977
978
979
980
981
982
983
984
985
986
  /*
   * 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...
987
  		get_unaligned_le32(&part->start_sect) == 1UL) {
07f3d789b   richardretanubun   Add support for C...
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
  		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_...
1005
  	if (!mbr || le16_to_cpu(mbr->signature) != MSDOS_MBR_SIGNATURE)
07f3d789b   richardretanubun   Add support for C...
1006
  		return 0;
07f3d789b   richardretanubun   Add support for C...
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
  
  	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.
   *
   * Description: returns 1 if valid,  0 on error.
   * If valid, returns pointers to PTEs.
   */
4101f6879   Simon Glass   dm: Drop the bloc...
1026
  static int is_gpt_valid(struct blk_desc *dev_desc, u64 lba,
e04350d29   Steve Rae   disk: part_efi: c...
1027
  			gpt_header *pgpt_head, gpt_entry **pgpt_pte)
07f3d789b   richardretanubun   Add support for C...
1028
  {
b351ccf11   Tom Rini   part_efi: In is_g...
1029
  	/* Confirm valid arguments prior to allocation. */
07f3d789b   richardretanubun   Add support for C...
1030
  	if (!dev_desc || !pgpt_head) {
df70b1c2e   Doug Anderson   cosmetic: Replace...
1031
1032
  		printf("%s: Invalid Argument(s)
  ", __func__);
07f3d789b   richardretanubun   Add support for C...
1033
1034
  		return 0;
  	}
3cc566117   Patrick Delaunay   disk: efi: correc...
1035
  	ALLOC_CACHE_ALIGN_BUFFER_PAD(legacy_mbr, mbr, 1, dev_desc->blksz);
b351ccf11   Tom Rini   part_efi: In is_g...
1036

ff98cb905   Peter Jones   part: extract MBR...
1037
1038
1039
1040
1041
1042
  	/* 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...
1043
  	/* Read GPT Header from device */
2a981dc2c   Simon Glass   dm: block: Adjust...
1044
  	if (blk_dread(dev_desc, (lbaint_t)lba, 1, pgpt_head) != 1) {
07f3d789b   richardretanubun   Add support for C...
1045
1046
1047
1048
  		printf("*** ERROR: Can't read GPT header ***
  ");
  		return 0;
  	}
e1f6b0a02   Steve Rae   disk: part_efi: m...
1049
  	if (validate_gpt_header(pgpt_head, (lbaint_t)lba, dev_desc->lba))
07f3d789b   richardretanubun   Add support for C...
1050
  		return 0;
07f3d789b   richardretanubun   Add support for C...
1051

ff98cb905   Peter Jones   part: extract MBR...
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
  	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...
1063
1064
1065
1066
1067
1068
1069
  	/* 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...
1070
  	if (validate_gpt_entries(pgpt_head, *pgpt_pte)) {
deb5ca802   Doug Anderson   disk: part_efi: f...
1071
  		free(*pgpt_pte);
07f3d789b   richardretanubun   Add support for C...
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
  		return 0;
  	}
  
  	/* We're done, all's well */
  	return 1;
  }
  
  /**
   * 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...
1088
1089
  static gpt_entry *alloc_read_gpt_entries(struct blk_desc *dev_desc,
  					 gpt_header *pgpt_head)
07f3d789b   richardretanubun   Add support for C...
1090
  {
ae1768a72   Egbert Eich   disk/gpt: Fix GPT...
1091
  	size_t count = 0, blk_cnt;
7c4213f6a   Stephen Warren   block: pass block...
1092
  	lbaint_t blk;
07f3d789b   richardretanubun   Add support for C...
1093
1094
1095
  	gpt_entry *pte = NULL;
  
  	if (!dev_desc || !pgpt_head) {
df70b1c2e   Doug Anderson   cosmetic: Replace...
1096
1097
  		printf("%s: Invalid Argument(s)
  ", __func__);
07f3d789b   richardretanubun   Add support for C...
1098
1099
  		return NULL;
  	}
fae2bf22a   Chang Hyun Park   gpt: The leXX_to_...
1100
1101
  	count = le32_to_cpu(pgpt_head->num_partition_entries) *
  		le32_to_cpu(pgpt_head->sizeof_partition_entry);
07f3d789b   richardretanubun   Add support for C...
1102

5afb8d151   Simon Glass   part_efi: Fix com...
1103
1104
  	debug("%s: count = %u * %u = %lu
  ", __func__,
fae2bf22a   Chang Hyun Park   gpt: The leXX_to_...
1105
  	      (u32) le32_to_cpu(pgpt_head->num_partition_entries),
5afb8d151   Simon Glass   part_efi: Fix com...
1106
1107
  	      (u32) le32_to_cpu(pgpt_head->sizeof_partition_entry),
  	      (ulong)count);
07f3d789b   richardretanubun   Add support for C...
1108

30355b43d   Ji Luo   MA-14916-4 suppor...
1109
1110
1111
1112
1113
1114
  	/* 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...
1115
  	if (count != 0) {
30355b43d   Ji Luo   MA-14916-4 suppor...
1116
1117
1118
  #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...
1119
1120
  		pte = memalign(ARCH_DMA_MINALIGN,
  			       PAD_TO_BLOCKSIZE(count, dev_desc));
30355b43d   Ji Luo   MA-14916-4 suppor...
1121
  #endif
07f3d789b   richardretanubun   Add support for C...
1122
1123
1124
  	}
  
  	if (count == 0 || pte == NULL) {
5afb8d151   Simon Glass   part_efi: Fix com...
1125
1126
1127
  		printf("%s: ERROR: Can't allocate %#lX bytes for GPT Entries
  ",
  		       __func__, (ulong)count);
07f3d789b   richardretanubun   Add support for C...
1128
1129
1130
1131
  		return NULL;
  	}
  
  	/* Read GPT Entries from device */
7c4213f6a   Stephen Warren   block: pass block...
1132
  	blk = le64_to_cpu(pgpt_head->partition_entry_lba);
ae1768a72   Egbert Eich   disk/gpt: Fix GPT...
1133
  	blk_cnt = BLOCK_CNT(count, dev_desc);
2a981dc2c   Simon Glass   dm: block: Adjust...
1134
  	if (blk_dread(dev_desc, blk, (lbaint_t)blk_cnt, pte) != blk_cnt) {
07f3d789b   richardretanubun   Add support for C...
1135
1136
  		printf("*** ERROR: Can't read GPT Entries ***
  ");
30355b43d   Ji Luo   MA-14916-4 suppor...
1137
  #if !defined(CONFIG_DUAL_BOOTLOADER) || !defined(CONFIG_SPL_BUILD)
07f3d789b   richardretanubun   Add support for C...
1138
  		free(pte);
30355b43d   Ji Luo   MA-14916-4 suppor...
1139
  #endif
07f3d789b   richardretanubun   Add support for C...
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
  		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...
1156
1157
  		printf("%s: Invalid Argument(s)
  ", __func__);
07f3d789b   richardretanubun   Add support for C...
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
  		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...
1168
1169
  		debug("%s: Found an unused PTE GUID at 0x%08X
  ", __func__,
9936be31f   Taylor Hutt   disk: Address cas...
1170
  		      (unsigned int)(uintptr_t)pte);
07f3d789b   richardretanubun   Add support for C...
1171
1172
1173
1174
1175
1176
  
  		return 0;
  	} else {
  		return 1;
  	}
  }
96e5b03c8   Simon Glass   dm: part: Convert...
1177
1178
1179
1180
1181
1182
1183
1184
1185
  
  /*
   * 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...
1186
  	.max_entries	= GPT_ENTRY_NUMBERS,
3e8bd4695   Simon Glass   dm: part: Rename ...
1187
  	.get_info	= part_get_info_ptr(part_get_info_efi),
084bf4c24   Simon Glass   part: Rename test...
1188
1189
  	.print		= part_print_ptr(part_print_efi),
  	.test		= part_test_efi,
96e5b03c8   Simon Glass   dm: part: Convert...
1190
  };
07f3d789b   richardretanubun   Add support for C...
1191
  #endif