1 /* 2 * (C) Copyright 2000-2004 3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. 4 * 5 * SPDX-License-Identifier: GPL-2.0+ 6 */ 7 #ifndef _PART_H 8 #define _PART_H 9 10 #include <blk.h> 11 #include <ide.h> 12 #include <uuid.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 /* Misc _get_dev functions */ 73 #ifdef CONFIG_PARTITIONS 74 /** 75 * blk_get_dev() - get a pointer to a block device given its type and number 76 * 77 * Each interface allocates its own devices and typically struct blk_desc is 78 * contained with the interface's data structure. There is no global 79 * numbering for block devices, so the interface name must be provided. 80 * 81 * @ifname: Interface name (e.g. "ide", "scsi") 82 * @dev: Device number (0 for first device on that interface, 1 for 83 * second, etc. 84 * @return pointer to the block device, or NULL if not available, or an 85 * error occurred. 86 */ 87 struct blk_desc *blk_get_dev(const char *ifname, int dev); 88 89 struct blk_desc *mg_disk_get_dev(int dev); 90 int host_get_dev_err(int dev, struct blk_desc **blk_devp); 91 92 /* disk/part.c */ 93 int part_get_info(struct blk_desc *dev_desc, int part, disk_partition_t *info); 94 void part_print(struct blk_desc *dev_desc); 95 void part_init(struct blk_desc *dev_desc); 96 void dev_print(struct blk_desc *dev_desc); 97 98 /** 99 * blk_get_device_by_str() - Get a block device given its interface/hw partition 100 * 101 * Each interface allocates its own devices and typically struct blk_desc is 102 * contained with the interface's data structure. There is no global 103 * numbering for block devices, so the interface name must be provided. 104 * 105 * The hardware parition is not related to the normal software partitioning 106 * of a device - each hardware partition is effectively a separately 107 * accessible block device. When a hardware parition is selected on MMC the 108 * other hardware partitions become inaccessible. The same block device is 109 * used to access all hardware partitions, but its capacity may change when a 110 * different hardware partition is selected. 111 * 112 * When a hardware partition number is given, the block device switches to 113 * that hardware partition. 114 * 115 * @ifname: Interface name (e.g. "ide", "scsi") 116 * @dev_str: Device and optional hw partition. This can either be a string 117 * containing the device number (e.g. "2") or the device number 118 * and hardware partition number (e.g. "2.4") for devices that 119 * support it (currently only MMC). 120 * @dev_desc: Returns a pointer to the block device on success 121 * @return block device number (local to the interface), or -1 on error 122 */ 123 int blk_get_device_by_str(const char *ifname, const char *dev_str, 124 struct blk_desc **dev_desc); 125 126 /** 127 * blk_get_device_part_str() - Get a block device and partition 128 * 129 * This calls blk_get_device_by_str() to look up a device. It also looks up 130 * a partition and returns information about it. 131 * 132 * @dev_part_str is in the format: 133 * <dev>.<hw_part>:<part> where <dev> is the device number, 134 * <hw_part> is the optional hardware partition number and 135 * <part> is the partition number 136 * 137 * If ifname is "hostfs" then this function returns the sandbox host block 138 * device. 139 * 140 * If ifname is ubi, then this function returns 0, with @info set to a 141 * special UBI device. 142 * 143 * If @dev_part_str is NULL or empty or "-", then this function looks up 144 * the "bootdevice" environment variable and uses that string instead. 145 * 146 * If the partition string is empty then the first partition is used. If the 147 * partition string is "auto" then the first bootable partition is used. 148 * 149 * @ifname: Interface name (e.g. "ide", "scsi") 150 * @dev_part_str: Device and partition string 151 * @dev_desc: Returns a pointer to the block device on success 152 * @info: Returns partition information 153 * @allow_whole_dev: true to allow the user to select partition 0 154 * (which means the whole device), false to require a valid 155 * partition number >= 1 156 * @return partition number, or -1 on error 157 * 158 */ 159 int blk_get_device_part_str(const char *ifname, const char *dev_part_str, 160 struct blk_desc **dev_desc, 161 disk_partition_t *info, int allow_whole_dev); 162 163 /** 164 * part_get_info_by_name() - Search for a partition by name 165 * among all available registered partitions 166 * 167 * @param dev_desc - block device descriptor 168 * @param gpt_name - the specified table entry name 169 * @param info - returns the disk partition info 170 * 171 * @return - the partition number on match (starting on 1), -1 on no match, 172 * otherwise error 173 */ 174 int part_get_info_by_name(struct blk_desc *dev_desc, 175 const char *name, disk_partition_t *info); 176 177 /** 178 * part_set_generic_name() - create generic partition like hda1 or sdb2 179 * 180 * Helper function for partition tables, which don't hold partition names 181 * (DOS, ISO). Generates partition name out of the device type and partition 182 * number. 183 * 184 * @dev_desc: pointer to the block device 185 * @part_num: partition number for which the name is generated 186 * @name: buffer where the name is written 187 */ 188 void part_set_generic_name(const struct blk_desc *dev_desc, 189 int part_num, char *name); 190 191 extern const struct block_drvr block_drvr[]; 192 #else 193 static inline struct blk_desc *blk_get_dev(const char *ifname, int dev) 194 { return NULL; } 195 static inline struct blk_desc *mg_disk_get_dev(int dev) { return NULL; } 196 197 static inline int part_get_info(struct blk_desc *dev_desc, int part, 198 disk_partition_t *info) { return -1; } 199 static inline void part_print(struct blk_desc *dev_desc) {} 200 static inline void part_init(struct blk_desc *dev_desc) {} 201 static inline void dev_print(struct blk_desc *dev_desc) {} 202 static inline int blk_get_device_by_str(const char *ifname, const char *dev_str, 203 struct blk_desc **dev_desc) 204 { return -1; } 205 static inline int blk_get_device_part_str(const char *ifname, 206 const char *dev_part_str, 207 struct blk_desc **dev_desc, 208 disk_partition_t *info, 209 int allow_whole_dev) 210 { *dev_desc = NULL; return -1; } 211 #endif 212 213 /* 214 * We don't support printing partition information in SPL and only support 215 * getting partition information in a few cases. 216 */ 217 #ifdef CONFIG_SPL_BUILD 218 # define part_print_ptr(x) NULL 219 # if defined(CONFIG_SPL_EXT_SUPPORT) || defined(CONFIG_SPL_FAT_SUPPORT) || \ 220 defined(CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION) 221 # define part_get_info_ptr(x) x 222 # else 223 # define part_get_info_ptr(x) NULL 224 # endif 225 #else 226 #define part_print_ptr(x) x 227 #define part_get_info_ptr(x) x 228 #endif 229 230 231 struct part_driver { 232 const char *name; 233 int part_type; 234 const int max_entries; /* maximum number of entries to search */ 235 236 /** 237 * get_info() - Get information about a partition 238 * 239 * @dev_desc: Block device descriptor 240 * @part: Partition number (1 = first) 241 * @info: Returns partition information 242 */ 243 int (*get_info)(struct blk_desc *dev_desc, int part, 244 disk_partition_t *info); 245 246 /** 247 * print() - Print partition information 248 * 249 * @dev_desc: Block device descriptor 250 */ 251 void (*print)(struct blk_desc *dev_desc); 252 253 /** 254 * test() - Test if a device contains this partition type 255 * 256 * @dev_desc: Block device descriptor 257 * @return 0 if the block device appears to contain this partition 258 * type, -ve if not 259 */ 260 int (*test)(struct blk_desc *dev_desc); 261 }; 262 263 /* Declare a new U-Boot partition 'driver' */ 264 #define U_BOOT_PART_TYPE(__name) \ 265 ll_entry_declare(struct part_driver, __name, part_driver) 266 267 #if CONFIG_IS_ENABLED(EFI_PARTITION) 268 #include <part_efi.h> 269 /* disk/part_efi.c */ 270 /** 271 * write_gpt_table() - Write the GUID Partition Table to disk 272 * 273 * @param dev_desc - block device descriptor 274 * @param gpt_h - pointer to GPT header representation 275 * @param gpt_e - pointer to GPT partition table entries 276 * 277 * @return - zero on success, otherwise error 278 */ 279 int write_gpt_table(struct blk_desc *dev_desc, 280 gpt_header *gpt_h, gpt_entry *gpt_e); 281 282 /** 283 * gpt_fill_pte(): Fill the GPT partition table entry 284 * 285 * @param gpt_h - GPT header representation 286 * @param gpt_e - GPT partition table entries 287 * @param partitions - list of partitions 288 * @param parts - number of partitions 289 * 290 * @return zero on success 291 */ 292 int gpt_fill_pte(gpt_header *gpt_h, gpt_entry *gpt_e, 293 disk_partition_t *partitions, int parts); 294 295 /** 296 * gpt_fill_header(): Fill the GPT header 297 * 298 * @param dev_desc - block device descriptor 299 * @param gpt_h - GPT header representation 300 * @param str_guid - disk guid string representation 301 * @param parts_count - number of partitions 302 * 303 * @return - error on str_guid conversion error 304 */ 305 int gpt_fill_header(struct blk_desc *dev_desc, gpt_header *gpt_h, 306 char *str_guid, int parts_count); 307 308 /** 309 * gpt_restore(): Restore GPT partition table 310 * 311 * @param dev_desc - block device descriptor 312 * @param str_disk_guid - disk GUID 313 * @param partitions - list of partitions 314 * @param parts - number of partitions 315 * 316 * @return zero on success 317 */ 318 int gpt_restore(struct blk_desc *dev_desc, char *str_disk_guid, 319 disk_partition_t *partitions, const int parts_count); 320 321 /** 322 * is_valid_gpt_buf() - Ensure that the Primary GPT information is valid 323 * 324 * @param dev_desc - block device descriptor 325 * @param buf - buffer which contains the MBR and Primary GPT info 326 * 327 * @return - '0' on success, otherwise error 328 */ 329 int is_valid_gpt_buf(struct blk_desc *dev_desc, void *buf); 330 331 /** 332 * write_mbr_and_gpt_partitions() - write MBR, Primary GPT and Backup GPT 333 * 334 * @param dev_desc - block device descriptor 335 * @param buf - buffer which contains the MBR and Primary GPT info 336 * 337 * @return - '0' on success, otherwise error 338 */ 339 int write_mbr_and_gpt_partitions(struct blk_desc *dev_desc, void *buf); 340 341 /** 342 * gpt_verify_headers() - Function to read and CRC32 check of the GPT's header 343 * and partition table entries (PTE) 344 * 345 * As a side effect if sets gpt_head and gpt_pte so they point to GPT data. 346 * 347 * @param dev_desc - block device descriptor 348 * @param gpt_head - pointer to GPT header data read from medium 349 * @param gpt_pte - pointer to GPT partition table enties read from medium 350 * 351 * @return - '0' on success, otherwise error 352 */ 353 int gpt_verify_headers(struct blk_desc *dev_desc, gpt_header *gpt_head, 354 gpt_entry **gpt_pte); 355 356 /** 357 * gpt_verify_partitions() - Function to check if partitions' name, start and 358 * size correspond to '$partitions' env variable 359 * 360 * This function checks if on medium stored GPT data is in sync with information 361 * provided in '$partitions' environment variable. Specificially, name, start 362 * and size of the partition is checked. 363 * 364 * @param dev_desc - block device descriptor 365 * @param partitions - partition data read from '$partitions' env variable 366 * @param parts - number of partitions read from '$partitions' env variable 367 * @param gpt_head - pointer to GPT header data read from medium 368 * @param gpt_pte - pointer to GPT partition table enties read from medium 369 * 370 * @return - '0' on success, otherwise error 371 */ 372 int gpt_verify_partitions(struct blk_desc *dev_desc, 373 disk_partition_t *partitions, int parts, 374 gpt_header *gpt_head, gpt_entry **gpt_pte); 375 #endif 376 377 #if CONFIG_IS_ENABLED(DOS_PARTITION) 378 /** 379 * is_valid_dos_buf() - Ensure that a DOS MBR image is valid 380 * 381 * @param buf - buffer which contains the MBR 382 * 383 * @return - '0' on success, otherwise error 384 */ 385 int is_valid_dos_buf(void *buf); 386 387 /** 388 * write_mbr_partition() - write DOS MBR 389 * 390 * @param dev_desc - block device descriptor 391 * @param buf - buffer which contains the MBR 392 * 393 * @return - '0' on success, otherwise error 394 */ 395 int write_mbr_partition(struct blk_desc *dev_desc, void *buf); 396 397 #endif 398 399 400 #endif /* _PART_H */ 401