xref: /openbmc/u-boot/include/part.h (revision 1b0769f2ed17ffc1cf9b32ad057bc8b160cbcbae)
1  /* SPDX-License-Identifier: GPL-2.0+ */
2  /*
3   * (C) Copyright 2000-2004
4   * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
5   */
6  #ifndef _PART_H
7  #define _PART_H
8  
9  #include <blk.h>
10  #include <ide.h>
11  #include <uuid.h>
12  #include <linux/list.h>
13  
14  struct block_drvr {
15  	char *name;
16  	int (*select_hwpart)(int dev_num, int hwpart);
17  };
18  
19  #define LOG2(x) (((x & 0xaaaaaaaa) ? 1 : 0) + ((x & 0xcccccccc) ? 2 : 0) + \
20  		 ((x & 0xf0f0f0f0) ? 4 : 0) + ((x & 0xff00ff00) ? 8 : 0) + \
21  		 ((x & 0xffff0000) ? 16 : 0))
22  #define LOG2_INVALID(type) ((type)((sizeof(type)<<3)-1))
23  
24  /* Part types */
25  #define PART_TYPE_UNKNOWN	0x00
26  #define PART_TYPE_MAC		0x01
27  #define PART_TYPE_DOS		0x02
28  #define PART_TYPE_ISO		0x03
29  #define PART_TYPE_AMIGA		0x04
30  #define PART_TYPE_EFI		0x05
31  
32  /* maximum number of partition entries supported by search */
33  #define DOS_ENTRY_NUMBERS	8
34  #define ISO_ENTRY_NUMBERS	64
35  #define MAC_ENTRY_NUMBERS	64
36  #define AMIGA_ENTRY_NUMBERS	8
37  /*
38   * Type string for U-Boot bootable partitions
39   */
40  #define BOOT_PART_TYPE	"U-Boot"	/* primary boot partition type	*/
41  #define BOOT_PART_COMP	"PPCBoot"	/* PPCBoot compatibility type	*/
42  
43  /* device types */
44  #define DEV_TYPE_UNKNOWN	0xff	/* not connected */
45  #define DEV_TYPE_HARDDISK	0x00	/* harddisk */
46  #define DEV_TYPE_TAPE		0x01	/* Tape */
47  #define DEV_TYPE_CDROM		0x05	/* CD-ROM */
48  #define DEV_TYPE_OPDISK		0x07	/* optical disk */
49  
50  #define PART_NAME_LEN 32
51  #define PART_TYPE_LEN 32
52  #define MAX_SEARCH_PARTITIONS 64
53  
54  typedef struct disk_partition {
55  	lbaint_t	start;	/* # of first block in partition	*/
56  	lbaint_t	size;	/* number of blocks in partition	*/
57  	ulong	blksz;		/* block size in bytes			*/
58  	uchar	name[PART_NAME_LEN];	/* partition name			*/
59  	uchar	type[PART_TYPE_LEN];	/* string type description		*/
60  	int	bootable;	/* Active/Bootable flag is set		*/
61  #if CONFIG_IS_ENABLED(PARTITION_UUIDS)
62  	char	uuid[UUID_STR_LEN + 1];	/* filesystem UUID as string, if exists	*/
63  #endif
64  #ifdef CONFIG_PARTITION_TYPE_GUID
65  	char	type_guid[UUID_STR_LEN + 1];	/* type GUID as string, if exists	*/
66  #endif
67  #ifdef CONFIG_DOS_PARTITION
68  	uchar	sys_ind;	/* partition type 			*/
69  #endif
70  } disk_partition_t;
71  
72  struct disk_part {
73  	int partnum;
74  	disk_partition_t gpt_part_info;
75  	struct list_head list;
76  };
77  
78  /* Misc _get_dev functions */
79  #ifdef CONFIG_PARTITIONS
80  /**
81   * blk_get_dev() - get a pointer to a block device given its type and number
82   *
83   * Each interface allocates its own devices and typically struct blk_desc is
84   * contained with the interface's data structure. There is no global
85   * numbering for block devices, so the interface name must be provided.
86   *
87   * @ifname:	Interface name (e.g. "ide", "scsi")
88   * @dev:	Device number (0 for first device on that interface, 1 for
89   *		second, etc.
90   * @return pointer to the block device, or NULL if not available, or an
91   *	   error occurred.
92   */
93  struct blk_desc *blk_get_dev(const char *ifname, int dev);
94  
95  struct blk_desc *mg_disk_get_dev(int dev);
96  int host_get_dev_err(int dev, struct blk_desc **blk_devp);
97  
98  /* disk/part.c */
99  int part_get_info(struct blk_desc *dev_desc, int part, disk_partition_t *info);
100  /**
101   * part_get_info_whole_disk() - get partition info for the special case of
102   * a partition occupying the entire disk.
103   */
104  int part_get_info_whole_disk(struct blk_desc *dev_desc, disk_partition_t *info);
105  
106  void part_print(struct blk_desc *dev_desc);
107  void part_init(struct blk_desc *dev_desc);
108  void dev_print(struct blk_desc *dev_desc);
109  
110  /**
111   * blk_get_device_by_str() - Get a block device given its interface/hw partition
112   *
113   * Each interface allocates its own devices and typically struct blk_desc is
114   * contained with the interface's data structure. There is no global
115   * numbering for block devices, so the interface name must be provided.
116   *
117   * The hardware parition is not related to the normal software partitioning
118   * of a device - each hardware partition is effectively a separately
119   * accessible block device. When a hardware parition is selected on MMC the
120   * other hardware partitions become inaccessible. The same block device is
121   * used to access all hardware partitions, but its capacity may change when a
122   * different hardware partition is selected.
123   *
124   * When a hardware partition number is given, the block device switches to
125   * that hardware partition.
126   *
127   * @ifname:	Interface name (e.g. "ide", "scsi")
128   * @dev_str:	Device and optional hw partition. This can either be a string
129   *		containing the device number (e.g. "2") or the device number
130   *		and hardware partition number (e.g. "2.4") for devices that
131   *		support it (currently only MMC).
132   * @dev_desc:	Returns a pointer to the block device on success
133   * @return block device number (local to the interface), or -1 on error
134   */
135  int blk_get_device_by_str(const char *ifname, const char *dev_str,
136  			  struct blk_desc **dev_desc);
137  
138  /**
139   * blk_get_device_part_str() - Get a block device and partition
140   *
141   * This calls blk_get_device_by_str() to look up a device. It also looks up
142   * a partition and returns information about it.
143   *
144   * @dev_part_str is in the format:
145   *	<dev>.<hw_part>:<part> where <dev> is the device number,
146   *	<hw_part> is the optional hardware partition number and
147   *	<part> is the partition number
148   *
149   * If ifname is "hostfs" then this function returns the sandbox host block
150   * device.
151   *
152   * If ifname is ubi, then this function returns 0, with @info set to a
153   * special UBI device.
154   *
155   * If @dev_part_str is NULL or empty or "-", then this function looks up
156   * the "bootdevice" environment variable and uses that string instead.
157   *
158   * If the partition string is empty then the first partition is used. If the
159   * partition string is "auto" then the first bootable partition is used.
160   *
161   * @ifname:	Interface name (e.g. "ide", "scsi")
162   * @dev_part_str:	Device and partition string
163   * @dev_desc:	Returns a pointer to the block device on success
164   * @info:	Returns partition information
165   * @allow_whole_dev:	true to allow the user to select partition 0
166   *		(which means the whole device), false to require a valid
167   *		partition number >= 1
168   * @return partition number, or -1 on error
169   *
170   */
171  int blk_get_device_part_str(const char *ifname, const char *dev_part_str,
172  			    struct blk_desc **dev_desc,
173  			    disk_partition_t *info, int allow_whole_dev);
174  
175  /**
176   * part_get_info_by_name_type() - Search for a partition by name
177   *                                for only specified partition type
178   *
179   * @param dev_desc - block device descriptor
180   * @param gpt_name - the specified table entry name
181   * @param info - returns the disk partition info
182   * @param part_type - only search in partitions of this type
183   *
184   * @return - the partition number on match (starting on 1), -1 on no match,
185   * otherwise error
186   */
187  int part_get_info_by_name_type(struct blk_desc *dev_desc, const char *name,
188  			       disk_partition_t *info, int part_type);
189  
190  /**
191   * part_get_info_by_name() - Search for a partition by name
192   *                           among all available registered partitions
193   *
194   * @param dev_desc - block device descriptor
195   * @param gpt_name - the specified table entry name
196   * @param info - returns the disk partition info
197   *
198   * @return - the partition number on match (starting on 1), -1 on no match,
199   * otherwise error
200   */
201  int part_get_info_by_name(struct blk_desc *dev_desc,
202  			      const char *name, disk_partition_t *info);
203  
204  /**
205   * part_set_generic_name() - create generic partition like hda1 or sdb2
206   *
207   * Helper function for partition tables, which don't hold partition names
208   * (DOS, ISO). Generates partition name out of the device type and partition
209   * number.
210   *
211   * @dev_desc:	pointer to the block device
212   * @part_num:	partition number for which the name is generated
213   * @name:	buffer where the name is written
214   */
215  void part_set_generic_name(const struct blk_desc *dev_desc,
216  	int part_num, char *name);
217  
218  extern const struct block_drvr block_drvr[];
219  #else
blk_get_dev(const char * ifname,int dev)220  static inline struct blk_desc *blk_get_dev(const char *ifname, int dev)
221  { return NULL; }
mg_disk_get_dev(int dev)222  static inline struct blk_desc *mg_disk_get_dev(int dev) { return NULL; }
223  
part_get_info(struct blk_desc * dev_desc,int part,disk_partition_t * info)224  static inline int part_get_info(struct blk_desc *dev_desc, int part,
225  				disk_partition_t *info) { return -1; }
part_get_info_whole_disk(struct blk_desc * dev_desc,disk_partition_t * info)226  static inline int part_get_info_whole_disk(struct blk_desc *dev_desc,
227  					   disk_partition_t *info)
228  { return -1; }
part_print(struct blk_desc * dev_desc)229  static inline void part_print(struct blk_desc *dev_desc) {}
part_init(struct blk_desc * dev_desc)230  static inline void part_init(struct blk_desc *dev_desc) {}
dev_print(struct blk_desc * dev_desc)231  static inline void dev_print(struct blk_desc *dev_desc) {}
blk_get_device_by_str(const char * ifname,const char * dev_str,struct blk_desc ** dev_desc)232  static inline int blk_get_device_by_str(const char *ifname, const char *dev_str,
233  					struct blk_desc **dev_desc)
234  { return -1; }
blk_get_device_part_str(const char * ifname,const char * dev_part_str,struct blk_desc ** dev_desc,disk_partition_t * info,int allow_whole_dev)235  static inline int blk_get_device_part_str(const char *ifname,
236  					   const char *dev_part_str,
237  					   struct blk_desc **dev_desc,
238  					   disk_partition_t *info,
239  					   int allow_whole_dev)
240  { *dev_desc = NULL; return -1; }
241  #endif
242  
243  /*
244   * We don't support printing partition information in SPL and only support
245   * getting partition information in a few cases.
246   */
247  #ifdef CONFIG_SPL_BUILD
248  # define part_print_ptr(x)	NULL
249  # if defined(CONFIG_SPL_FS_EXT4) || defined(CONFIG_SPL_FS_FAT) || \
250  	defined(CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION)
251  #  define part_get_info_ptr(x)	x
252  # else
253  #  define part_get_info_ptr(x)	NULL
254  # endif
255  #else
256  #define part_print_ptr(x)	x
257  #define part_get_info_ptr(x)	x
258  #endif
259  
260  
261  struct part_driver {
262  	const char *name;
263  	int part_type;
264  	const int max_entries;	/* maximum number of entries to search */
265  
266  	/**
267  	 * get_info() - Get information about a partition
268  	 *
269  	 * @dev_desc:	Block device descriptor
270  	 * @part:	Partition number (1 = first)
271  	 * @info:	Returns partition information
272  	 */
273  	int (*get_info)(struct blk_desc *dev_desc, int part,
274  			disk_partition_t *info);
275  
276  	/**
277  	 * print() - Print partition information
278  	 *
279  	 * @dev_desc:	Block device descriptor
280  	 */
281  	void (*print)(struct blk_desc *dev_desc);
282  
283  	/**
284  	 * test() - Test if a device contains this partition type
285  	 *
286  	 * @dev_desc:	Block device descriptor
287  	 * @return 0 if the block device appears to contain this partition
288  	 *	   type, -ve if not
289  	 */
290  	int (*test)(struct blk_desc *dev_desc);
291  };
292  
293  /* Declare a new U-Boot partition 'driver' */
294  #define U_BOOT_PART_TYPE(__name)					\
295  	ll_entry_declare(struct part_driver, __name, part_driver)
296  
297  #include <part_efi.h>
298  
299  #if CONFIG_IS_ENABLED(EFI_PARTITION)
300  /* disk/part_efi.c */
301  /**
302   * write_gpt_table() - Write the GUID Partition Table to disk
303   *
304   * @param dev_desc - block device descriptor
305   * @param gpt_h - pointer to GPT header representation
306   * @param gpt_e - pointer to GPT partition table entries
307   *
308   * @return - zero on success, otherwise error
309   */
310  int write_gpt_table(struct blk_desc *dev_desc,
311  		  gpt_header *gpt_h, gpt_entry *gpt_e);
312  
313  /**
314   * gpt_fill_pte(): Fill the GPT partition table entry
315   *
316   * @param dev_desc - block device descriptor
317   * @param gpt_h - GPT header representation
318   * @param gpt_e - GPT partition table entries
319   * @param partitions - list of partitions
320   * @param parts - number of partitions
321   *
322   * @return zero on success
323   */
324  int gpt_fill_pte(struct blk_desc *dev_desc,
325  		 gpt_header *gpt_h, gpt_entry *gpt_e,
326  		 disk_partition_t *partitions, int parts);
327  
328  /**
329   * gpt_fill_header(): Fill the GPT header
330   *
331   * @param dev_desc - block device descriptor
332   * @param gpt_h - GPT header representation
333   * @param str_guid - disk guid string representation
334   * @param parts_count - number of partitions
335   *
336   * @return - error on str_guid conversion error
337   */
338  int gpt_fill_header(struct blk_desc *dev_desc, gpt_header *gpt_h,
339  		char *str_guid, int parts_count);
340  
341  /**
342   * gpt_restore(): Restore GPT partition table
343   *
344   * @param dev_desc - block device descriptor
345   * @param str_disk_guid - disk GUID
346   * @param partitions - list of partitions
347   * @param parts - number of partitions
348   *
349   * @return zero on success
350   */
351  int gpt_restore(struct blk_desc *dev_desc, char *str_disk_guid,
352  		disk_partition_t *partitions, const int parts_count);
353  
354  /**
355   * is_valid_gpt_buf() - Ensure that the Primary GPT information is valid
356   *
357   * @param dev_desc - block device descriptor
358   * @param buf - buffer which contains the MBR and Primary GPT info
359   *
360   * @return - '0' on success, otherwise error
361   */
362  int is_valid_gpt_buf(struct blk_desc *dev_desc, void *buf);
363  
364  /**
365   * write_mbr_and_gpt_partitions() - write MBR, Primary GPT and Backup GPT
366   *
367   * @param dev_desc - block device descriptor
368   * @param buf - buffer which contains the MBR and Primary GPT info
369   *
370   * @return - '0' on success, otherwise error
371   */
372  int write_mbr_and_gpt_partitions(struct blk_desc *dev_desc, void *buf);
373  
374  /**
375   * gpt_verify_headers() - Function to read and CRC32 check of the GPT's header
376   *                        and partition table entries (PTE)
377   *
378   * As a side effect if sets gpt_head and gpt_pte so they point to GPT data.
379   *
380   * @param dev_desc - block device descriptor
381   * @param gpt_head - pointer to GPT header data read from medium
382   * @param gpt_pte - pointer to GPT partition table enties read from medium
383   *
384   * @return - '0' on success, otherwise error
385   */
386  int gpt_verify_headers(struct blk_desc *dev_desc, gpt_header *gpt_head,
387  		       gpt_entry **gpt_pte);
388  
389  /**
390   * gpt_verify_partitions() - Function to check if partitions' name, start and
391   *                           size correspond to '$partitions' env variable
392   *
393   * This function checks if on medium stored GPT data is in sync with information
394   * provided in '$partitions' environment variable. Specificially, name, start
395   * and size of the partition is checked.
396   *
397   * @param dev_desc - block device descriptor
398   * @param partitions - partition data read from '$partitions' env variable
399   * @param parts - number of partitions read from '$partitions' env variable
400   * @param gpt_head - pointer to GPT header data read from medium
401   * @param gpt_pte - pointer to GPT partition table enties read from medium
402   *
403   * @return - '0' on success, otherwise error
404   */
405  int gpt_verify_partitions(struct blk_desc *dev_desc,
406  			  disk_partition_t *partitions, int parts,
407  			  gpt_header *gpt_head, gpt_entry **gpt_pte);
408  
409  
410  /**
411   * get_disk_guid() - Function to read the GUID string from a device's GPT
412   *
413   * This function reads the GUID string from a block device whose descriptor
414   * is provided.
415   *
416   * @param dev_desc - block device descriptor
417   * @param guid - pre-allocated string in which to return the GUID
418   *
419   * @return - '0' on success, otherwise error
420   */
421  int get_disk_guid(struct blk_desc *dev_desc, char *guid);
422  
423  #endif
424  
425  #if CONFIG_IS_ENABLED(DOS_PARTITION)
426  /**
427   * is_valid_dos_buf() - Ensure that a DOS MBR image is valid
428   *
429   * @param buf - buffer which contains the MBR
430   *
431   * @return - '0' on success, otherwise error
432   */
433  int is_valid_dos_buf(void *buf);
434  
435  /**
436   * write_mbr_partition() - write DOS MBR
437   *
438   * @param dev_desc - block device descriptor
439   * @param buf - buffer which contains the MBR
440   *
441   * @return - '0' on success, otherwise error
442   */
443  int write_mbr_partition(struct blk_desc *dev_desc, void *buf);
444  
445  #endif
446  
447  
448  #endif /* _PART_H */
449