diff options
Diffstat (limited to 'roms/u-boot/disk')
| -rw-r--r-- | roms/u-boot/disk/Makefile | 15 | ||||
| -rw-r--r-- | roms/u-boot/disk/part.c | 617 | ||||
| -rw-r--r-- | roms/u-boot/disk/part_amiga.c | 382 | ||||
| -rw-r--r-- | roms/u-boot/disk/part_amiga.h | 141 | ||||
| -rw-r--r-- | roms/u-boot/disk/part_dos.c | 270 | ||||
| -rw-r--r-- | roms/u-boot/disk/part_dos.h | 33 | ||||
| -rw-r--r-- | roms/u-boot/disk/part_efi.c | 669 | ||||
| -rw-r--r-- | roms/u-boot/disk/part_iso.c | 249 | ||||
| -rw-r--r-- | roms/u-boot/disk/part_iso.h | 144 | ||||
| -rw-r--r-- | roms/u-boot/disk/part_mac.c | 234 | ||||
| -rw-r--r-- | roms/u-boot/disk/part_mac.h | 83 | 
11 files changed, 2837 insertions, 0 deletions
diff --git a/roms/u-boot/disk/Makefile b/roms/u-boot/disk/Makefile new file mode 100644 index 00000000..6970cecc --- /dev/null +++ b/roms/u-boot/disk/Makefile @@ -0,0 +1,15 @@ +# +# (C) Copyright 2000-2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# SPDX-License-Identifier:	GPL-2.0+ +# + +#ccflags-y += -DET_DEBUG -DDEBUG + +obj-$(CONFIG_PARTITIONS) 	+= part.o +obj-$(CONFIG_MAC_PARTITION)   += part_mac.o +obj-$(CONFIG_DOS_PARTITION)   += part_dos.o +obj-$(CONFIG_ISO_PARTITION)   += part_iso.o +obj-$(CONFIG_AMIGA_PARTITION) += part_amiga.o +obj-$(CONFIG_EFI_PARTITION)   += part_efi.o diff --git a/roms/u-boot/disk/part.c b/roms/u-boot/disk/part.c new file mode 100644 index 00000000..b8c6aac8 --- /dev/null +++ b/roms/u-boot/disk/part.c @@ -0,0 +1,617 @@ +/* + * (C) Copyright 2001 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#include <common.h> +#include <command.h> +#include <ide.h> +#include <malloc.h> +#include <part.h> + +#undef	PART_DEBUG + +#ifdef	PART_DEBUG +#define	PRINTF(fmt,args...)	printf (fmt ,##args) +#else +#define PRINTF(fmt,args...) +#endif + +struct block_drvr { +	char *name; +	block_dev_desc_t* (*get_dev)(int dev); +}; + +static const struct block_drvr block_drvr[] = { +#if defined(CONFIG_CMD_IDE) +	{ .name = "ide", .get_dev = ide_get_dev, }, +#endif +#if defined(CONFIG_CMD_SATA) +	{.name = "sata", .get_dev = sata_get_dev, }, +#endif +#if defined(CONFIG_CMD_SCSI) +	{ .name = "scsi", .get_dev = scsi_get_dev, }, +#endif +#if defined(CONFIG_CMD_USB) && defined(CONFIG_USB_STORAGE) +	{ .name = "usb", .get_dev = usb_stor_get_dev, }, +#endif +#if defined(CONFIG_MMC) +	{ .name = "mmc", .get_dev = mmc_get_dev, }, +#endif +#if defined(CONFIG_SYSTEMACE) +	{ .name = "ace", .get_dev = systemace_get_dev, }, +#endif +#if defined(CONFIG_SANDBOX) +	{ .name = "host", .get_dev = host_get_dev, }, +#endif +	{ }, +}; + +DECLARE_GLOBAL_DATA_PTR; + +#ifdef HAVE_BLOCK_DEVICE +block_dev_desc_t *get_dev(const char *ifname, int dev) +{ +	const struct block_drvr *drvr = block_drvr; +	block_dev_desc_t* (*reloc_get_dev)(int dev); +	char *name; + +	if (!ifname) +		return NULL; + +	name = drvr->name; +#ifdef CONFIG_NEEDS_MANUAL_RELOC +	name += gd->reloc_off; +#endif +	while (drvr->name) { +		name = drvr->name; +		reloc_get_dev = drvr->get_dev; +#ifdef CONFIG_NEEDS_MANUAL_RELOC +		name += gd->reloc_off; +		reloc_get_dev += gd->reloc_off; +#endif +		if (strncmp(ifname, name, strlen(name)) == 0) +			return reloc_get_dev(dev); +		drvr++; +	} +	return NULL; +} +#else +block_dev_desc_t *get_dev(const char *ifname, int dev) +{ +	return NULL; +} +#endif + +#ifdef HAVE_BLOCK_DEVICE + +/* ------------------------------------------------------------------------- */ +/* + * reports device info to the user + */ + +#ifdef CONFIG_LBA48 +typedef uint64_t lba512_t; +#else +typedef lbaint_t lba512_t; +#endif + +/* + * Overflowless variant of (block_count * mul_by / div_by) + * when div_by > mul_by + */ +static lba512_t lba512_muldiv (lba512_t block_count, lba512_t mul_by, lba512_t div_by) +{ +	lba512_t bc_quot, bc_rem; + +	/* x * m / d == x / d * m + (x % d) * m / d */ +	bc_quot = block_count / div_by; +	bc_rem  = block_count - div_by * bc_quot; +	return bc_quot * mul_by + (bc_rem * mul_by) / div_by; +} + +void dev_print (block_dev_desc_t *dev_desc) +{ +	lba512_t lba512; /* number of blocks if 512bytes block size */ + +	if (dev_desc->type == DEV_TYPE_UNKNOWN) { +		puts ("not available\n"); +		return; +	} + +	switch (dev_desc->if_type) { +	case IF_TYPE_SCSI: +		printf ("(%d:%d) Vendor: %s Prod.: %s Rev: %s\n", +			dev_desc->target,dev_desc->lun, +			dev_desc->vendor, +			dev_desc->product, +			dev_desc->revision); +		break; +	case IF_TYPE_ATAPI: +	case IF_TYPE_IDE: +	case IF_TYPE_SATA: +		printf ("Model: %s Firm: %s Ser#: %s\n", +			dev_desc->vendor, +			dev_desc->revision, +			dev_desc->product); +		break; +	case IF_TYPE_SD: +	case IF_TYPE_MMC: +	case IF_TYPE_USB: +		printf ("Vendor: %s Rev: %s Prod: %s\n", +			dev_desc->vendor, +			dev_desc->revision, +			dev_desc->product); +		break; +	case IF_TYPE_DOC: +		puts("device type DOC\n"); +		return; +	case IF_TYPE_UNKNOWN: +		puts("device type unknown\n"); +		return; +	default: +		printf("Unhandled device type: %i\n", dev_desc->if_type); +		return; +	} +	puts ("            Type: "); +	if (dev_desc->removable) +		puts ("Removable "); +	switch (dev_desc->type & 0x1F) { +	case DEV_TYPE_HARDDISK: +		puts ("Hard Disk"); +		break; +	case DEV_TYPE_CDROM: +		puts ("CD ROM"); +		break; +	case DEV_TYPE_OPDISK: +		puts ("Optical Device"); +		break; +	case DEV_TYPE_TAPE: +		puts ("Tape"); +		break; +	default: +		printf ("# %02X #", dev_desc->type & 0x1F); +		break; +	} +	puts ("\n"); +	if (dev_desc->lba > 0L && dev_desc->blksz > 0L) { +		ulong mb, mb_quot, mb_rem, gb, gb_quot, gb_rem; +		lbaint_t lba; + +		lba = dev_desc->lba; + +		lba512 = (lba * (dev_desc->blksz/512)); +		/* round to 1 digit */ +		mb = lba512_muldiv(lba512, 10, 2048);	/* 2048 = (1024 * 1024) / 512 MB */ + +		mb_quot	= mb / 10; +		mb_rem	= mb - (10 * mb_quot); + +		gb = mb / 1024; +		gb_quot	= gb / 10; +		gb_rem	= gb - (10 * gb_quot); +#ifdef CONFIG_LBA48 +		if (dev_desc->lba48) +			printf ("            Supports 48-bit addressing\n"); +#endif +#if defined(CONFIG_SYS_64BIT_LBA) +		printf ("            Capacity: %ld.%ld MB = %ld.%ld GB (%Ld x %ld)\n", +			mb_quot, mb_rem, +			gb_quot, gb_rem, +			lba, +			dev_desc->blksz); +#else +		printf ("            Capacity: %ld.%ld MB = %ld.%ld GB (%ld x %ld)\n", +			mb_quot, mb_rem, +			gb_quot, gb_rem, +			(ulong)lba, +			dev_desc->blksz); +#endif +	} else { +		puts ("            Capacity: not available\n"); +	} +} +#endif + +#ifdef HAVE_BLOCK_DEVICE + +void init_part (block_dev_desc_t * dev_desc) +{ +#ifdef CONFIG_ISO_PARTITION +	if (test_part_iso(dev_desc) == 0) { +		dev_desc->part_type = PART_TYPE_ISO; +		return; +	} +#endif + +#ifdef CONFIG_MAC_PARTITION +	if (test_part_mac(dev_desc) == 0) { +		dev_desc->part_type = PART_TYPE_MAC; +		return; +	} +#endif + +/* must be placed before DOS partition detection */ +#ifdef CONFIG_EFI_PARTITION +	if (test_part_efi(dev_desc) == 0) { +		dev_desc->part_type = PART_TYPE_EFI; +		return; +	} +#endif + +#ifdef CONFIG_DOS_PARTITION +	if (test_part_dos(dev_desc) == 0) { +		dev_desc->part_type = PART_TYPE_DOS; +		return; +	} +#endif + +#ifdef CONFIG_AMIGA_PARTITION +	if (test_part_amiga(dev_desc) == 0) { +	    dev_desc->part_type = PART_TYPE_AMIGA; +	    return; +	} +#endif +	dev_desc->part_type = PART_TYPE_UNKNOWN; +} + + +#if defined(CONFIG_MAC_PARTITION) || \ +	defined(CONFIG_DOS_PARTITION) || \ +	defined(CONFIG_ISO_PARTITION) || \ +	defined(CONFIG_AMIGA_PARTITION) || \ +	defined(CONFIG_EFI_PARTITION) + +static void print_part_header (const char *type, block_dev_desc_t * dev_desc) +{ +	puts ("\nPartition Map for "); +	switch (dev_desc->if_type) { +	case IF_TYPE_IDE: +		puts ("IDE"); +		break; +	case IF_TYPE_SATA: +		puts ("SATA"); +		break; +	case IF_TYPE_SCSI: +		puts ("SCSI"); +		break; +	case IF_TYPE_ATAPI: +		puts ("ATAPI"); +		break; +	case IF_TYPE_USB: +		puts ("USB"); +		break; +	case IF_TYPE_DOC: +		puts ("DOC"); +		break; +	case IF_TYPE_MMC: +		puts ("MMC"); +		break; +	case IF_TYPE_HOST: +		puts("HOST"); +		break; +	default: +		puts ("UNKNOWN"); +		break; +	} +	printf (" device %d  --   Partition Type: %s\n\n", +			dev_desc->dev, type); +} + +#endif /* any CONFIG_..._PARTITION */ + +void print_part (block_dev_desc_t * dev_desc) +{ + +		switch (dev_desc->part_type) { +#ifdef CONFIG_MAC_PARTITION +	case PART_TYPE_MAC: +		PRINTF ("## Testing for valid MAC partition ##\n"); +		print_part_header ("MAC", dev_desc); +		print_part_mac (dev_desc); +		return; +#endif +#ifdef CONFIG_DOS_PARTITION +	case PART_TYPE_DOS: +		PRINTF ("## Testing for valid DOS partition ##\n"); +		print_part_header ("DOS", dev_desc); +		print_part_dos (dev_desc); +		return; +#endif + +#ifdef CONFIG_ISO_PARTITION +	case PART_TYPE_ISO: +		PRINTF ("## Testing for valid ISO Boot partition ##\n"); +		print_part_header ("ISO", dev_desc); +		print_part_iso (dev_desc); +		return; +#endif + +#ifdef CONFIG_AMIGA_PARTITION +	case PART_TYPE_AMIGA: +	    PRINTF ("## Testing for a valid Amiga partition ##\n"); +	    print_part_header ("AMIGA", dev_desc); +	    print_part_amiga (dev_desc); +	    return; +#endif + +#ifdef CONFIG_EFI_PARTITION +	case PART_TYPE_EFI: +		PRINTF ("## Testing for valid EFI partition ##\n"); +		print_part_header ("EFI", dev_desc); +		print_part_efi (dev_desc); +		return; +#endif +	} +	puts ("## Unknown partition table\n"); +} + +#endif /* HAVE_BLOCK_DEVICE */ + +int get_partition_info(block_dev_desc_t *dev_desc, int part +					, disk_partition_t *info) +{ +#ifdef HAVE_BLOCK_DEVICE + +#ifdef CONFIG_PARTITION_UUIDS +	/* The common case is no UUID support */ +	info->uuid[0] = 0; +#endif + +	switch (dev_desc->part_type) { +#ifdef CONFIG_MAC_PARTITION +	case PART_TYPE_MAC: +		if (get_partition_info_mac(dev_desc, part, info) == 0) { +			PRINTF("## Valid MAC partition found ##\n"); +			return 0; +		} +		break; +#endif + +#ifdef CONFIG_DOS_PARTITION +	case PART_TYPE_DOS: +		if (get_partition_info_dos(dev_desc, part, info) == 0) { +			PRINTF("## Valid DOS partition found ##\n"); +			return 0; +		} +		break; +#endif + +#ifdef CONFIG_ISO_PARTITION +	case PART_TYPE_ISO: +		if (get_partition_info_iso(dev_desc, part, info) == 0) { +			PRINTF("## Valid ISO boot partition found ##\n"); +			return 0; +		} +		break; +#endif + +#ifdef CONFIG_AMIGA_PARTITION +	case PART_TYPE_AMIGA: +		if (get_partition_info_amiga(dev_desc, part, info) == 0) { +			PRINTF("## Valid Amiga partition found ##\n"); +			return 0; +		} +		break; +#endif + +#ifdef CONFIG_EFI_PARTITION +	case PART_TYPE_EFI: +		if (get_partition_info_efi(dev_desc, part, info) == 0) { +			PRINTF("## Valid EFI partition found ##\n"); +			return 0; +		} +		break; +#endif +	default: +		break; +	} +#endif /* HAVE_BLOCK_DEVICE */ + +	return -1; +} + +int get_device(const char *ifname, const char *dev_str, +	       block_dev_desc_t **dev_desc) +{ +	char *ep; +	int dev; + +	dev = simple_strtoul(dev_str, &ep, 16); +	if (*ep) { +		printf("** Bad device specification %s %s **\n", +		       ifname, dev_str); +		return -1; +	} + +	*dev_desc = get_dev(ifname, dev); +	if (!(*dev_desc) || ((*dev_desc)->type == DEV_TYPE_UNKNOWN)) { +		printf("** Bad device %s %s **\n", ifname, dev_str); +		return -1; +	} + +	return dev; +} + +#define PART_UNSPECIFIED -2 +#define PART_AUTO -1 +#define MAX_SEARCH_PARTITIONS 16 +int get_device_and_partition(const char *ifname, const char *dev_part_str, +			     block_dev_desc_t **dev_desc, +			     disk_partition_t *info, int allow_whole_dev) +{ +	int ret = -1; +	const char *part_str; +	char *dup_str = NULL; +	const char *dev_str; +	int dev; +	char *ep; +	int p; +	int part; +	disk_partition_t tmpinfo; + +	/* If no dev_part_str, use bootdevice environment variable */ +	if (!dev_part_str || !strlen(dev_part_str) || +	    !strcmp(dev_part_str, "-")) +		dev_part_str = getenv("bootdevice"); + +	/* If still no dev_part_str, it's an error */ +	if (!dev_part_str) { +		printf("** No device specified **\n"); +		goto cleanup; +	} + +	/* Separate device and partition ID specification */ +	part_str = strchr(dev_part_str, ':'); +	if (part_str) { +		dup_str = strdup(dev_part_str); +		dup_str[part_str - dev_part_str] = 0; +		dev_str = dup_str; +		part_str++; +	} else { +		dev_str = dev_part_str; +	} + +	/* Look up the device */ +	dev = get_device(ifname, dev_str, dev_desc); +	if (dev < 0) +		goto cleanup; + +	/* Convert partition ID string to number */ +	if (!part_str || !*part_str) { +		part = PART_UNSPECIFIED; +	} else if (!strcmp(part_str, "auto")) { +		part = PART_AUTO; +	} else { +		/* Something specified -> use exactly that */ +		part = (int)simple_strtoul(part_str, &ep, 16); +		/* +		 * Less than whole string converted, +		 * or request for whole device, but caller requires partition. +		 */ +		if (*ep || (part == 0 && !allow_whole_dev)) { +			printf("** Bad partition specification %s %s **\n", +			    ifname, dev_part_str); +			goto cleanup; +		} +	} + +	/* +	 * No partition table on device, +	 * or user requested partition 0 (entire device). +	 */ +	if (((*dev_desc)->part_type == PART_TYPE_UNKNOWN) || +	    (part == 0)) { +		if (!(*dev_desc)->lba) { +			printf("** Bad device size - %s %s **\n", ifname, +			       dev_str); +			goto cleanup; +		} + +		/* +		 * If user specified a partition ID other than 0, +		 * or the calling command only accepts partitions, +		 * it's an error. +		 */ +		if ((part > 0) || (!allow_whole_dev)) { +			printf("** No partition table - %s %s **\n", ifname, +			       dev_str); +			goto cleanup; +		} + +		(*dev_desc)->log2blksz = LOG2((*dev_desc)->blksz); + +		info->start = 0; +		info->size = (*dev_desc)->lba; +		info->blksz = (*dev_desc)->blksz; +		info->bootable = 0; +		strcpy((char *)info->type, BOOT_PART_TYPE); +		strcpy((char *)info->name, "Whole Disk"); +#ifdef CONFIG_PARTITION_UUIDS +		info->uuid[0] = 0; +#endif + +		ret = 0; +		goto cleanup; +	} + +	/* +	 * Now there's known to be a partition table, +	 * not specifying a partition means to pick partition 1. +	 */ +	if (part == PART_UNSPECIFIED) +		part = 1; + +	/* +	 * If user didn't specify a partition number, or did specify something +	 * other than "auto", use that partition number directly. +	 */ +	if (part != PART_AUTO) { +		ret = get_partition_info(*dev_desc, part, info); +		if (ret) { +			printf("** Invalid partition %d **\n", part); +			goto cleanup; +		} +	} else { +		/* +		 * Find the first bootable partition. +		 * If none are bootable, fall back to the first valid partition. +		 */ +		part = 0; +		for (p = 1; p <= MAX_SEARCH_PARTITIONS; p++) { +			ret = get_partition_info(*dev_desc, p, info); +			if (ret) +				continue; + +			/* +			 * First valid partition, or new better partition? +			 * If so, save partition ID. +			 */ +			if (!part || info->bootable) +				part = p; + +			/* Best possible partition? Stop searching. */ +			if (info->bootable) +				break; + +			/* +			 * We now need to search further for best possible. +			 * If we what we just queried was the best so far, +			 * save the info since we over-write it next loop. +			 */ +			if (part == p) +				tmpinfo = *info; +		} +		/* If we found any acceptable partition */ +		if (part) { +			/* +			 * If we searched all possible partition IDs, +			 * return the first valid partition we found. +			 */ +			if (p == MAX_SEARCH_PARTITIONS + 1) +				*info = tmpinfo; +		} else { +			printf("** No valid partitions found **\n"); +			ret = -1; +			goto cleanup; +		} +	} +	if (strncmp((char *)info->type, BOOT_PART_TYPE, sizeof(info->type)) != 0) { +		printf("** Invalid partition type \"%.32s\"" +			" (expect \"" BOOT_PART_TYPE "\")\n", +			info->type); +		ret  = -1; +		goto cleanup; +	} + +	(*dev_desc)->log2blksz = LOG2((*dev_desc)->blksz); + +	ret = part; +	goto cleanup; + +cleanup: +	free(dup_str); +	return ret; +} diff --git a/roms/u-boot/disk/part_amiga.c b/roms/u-boot/disk/part_amiga.c new file mode 100644 index 00000000..260a3d5e --- /dev/null +++ b/roms/u-boot/disk/part_amiga.c @@ -0,0 +1,382 @@ +/* + * (C) Copyright 2001 + * Hans-Joerg Frieden, Hyperion Entertainment + * Hans-JoergF@hyperion-entertainment.com + * + * SPDX-License-Identifier:	GPL-2.0+ + */ +#include <common.h> +#include <command.h> +#include <ide.h> +#include "part_amiga.h" + +#ifdef HAVE_BLOCK_DEVICE + +#undef AMIGA_DEBUG + +#ifdef AMIGA_DEBUG +#define PRINTF(fmt, args...) printf(fmt ,##args) +#else +#define PRINTF(fmt, args...) +#endif + +struct block_header +{ +    u32 id; +    u32 summed_longs; +    s32 chk_sum; +}; + +static unsigned char block_buffer[DEFAULT_SECTOR_SIZE]; +static struct rigid_disk_block rdb = {0}; +static struct bootcode_block bootcode = {0}; + +/* + * Copy a bcpl to a c string + */ +static void bcpl_strcpy(char *to, char *from) +{ +    int len = *from++; + +    while (len) +    { +	*to++ = *from++; +	len--; +    } +    *to = 0; +} + +/* + * Print a BCPL String. BCPL strings start with a byte with the length + * of the string, and don't contain a terminating nul character + */ +static void bstr_print(char *string) +{ +    int len = *string++; +    char buffer[256]; +    int i; + +    i = 0; +    while (len) +    { +	buffer[i++] = *string++; +	len--; +    } + +    buffer[i] = 0; +    printf("%-10s", buffer); +} + +/* + * Sum a block. The checksum of a block must end up at zero + * to be valid. The chk_sum field is selected so that adding + * it yields zero. + */ +int sum_block(struct block_header *header) +{ +    s32 *block = (s32 *)header; +    u32 i; +    s32 sum = 0; + +    for (i = 0; i < header->summed_longs; i++) +	sum += *block++; + +    return (sum != 0); +} + +/* + * Print an AmigaOS disk type. Disk types are a four-byte identifier + * describing the file system. They are usually written as a three-letter + * word followed by a backslash and a version number. For example, + * DOS\0 would be the original file system. SFS\0 would be SmartFileSystem. + * DOS\1 is FFS. + */ +static void print_disk_type(u32 disk_type) +{ +    char buffer[6]; +    buffer[0] = (disk_type & 0xFF000000)>>24; +    buffer[1] = (disk_type & 0x00FF0000)>>16; +    buffer[2] = (disk_type & 0x0000FF00)>>8; +    buffer[3] = '\\'; +    buffer[4] = (disk_type & 0x000000FF) + '0'; +    buffer[5] = 0; +    printf("%s", buffer); +} + +/* + * Print the info contained within the given partition block + */ +static void print_part_info(struct partition_block *p) +{ +    struct amiga_part_geometry *g; + +    g = (struct amiga_part_geometry *)&(p->environment); + +    bstr_print(p->drive_name); +    printf("%6d\t%6d\t", +	   g->low_cyl * g->block_per_track * g->surfaces , +	   (g->high_cyl - g->low_cyl + 1) * g->block_per_track * g->surfaces - 1); +    print_disk_type(g->dos_type); +    printf("\t%5d\n", g->boot_priority); +} + +/* + * Search for the Rigid Disk Block. The rigid disk block is required + * to be within the first 16 blocks of a drive, needs to have + * the ID AMIGA_ID_RDISK ('RDSK') and needs to have a valid + * sum-to-zero checksum + */ +struct rigid_disk_block *get_rdisk(block_dev_desc_t *dev_desc) +{ +    int i; +    int limit; +    char *s; + +    s = getenv("amiga_scanlimit"); +    if (s) +	limit = simple_strtoul(s, NULL, 10); +    else +	limit = AMIGA_BLOCK_LIMIT; + +    for (i=0; i<limit; i++) +    { +	ulong res = dev_desc->block_read(dev_desc->dev, i, 1, +					 (ulong *)block_buffer); +	if (res == 1) +	{ +	    struct rigid_disk_block *trdb = (struct rigid_disk_block *)block_buffer; +	    if (trdb->id == AMIGA_ID_RDISK) +	    { +		PRINTF("Rigid disk block suspect at %d, checking checksum\n",i); +		if (sum_block((struct block_header *)block_buffer) == 0) +		{ +		    PRINTF("FOUND\n"); +		    memcpy(&rdb, trdb, sizeof(struct rigid_disk_block)); +		    return (struct rigid_disk_block *)&rdb; +		} +	    } +	} +    } +    PRINTF("Done scanning, no RDB found\n"); +    return NULL; +} + +/* + * Search for boot code + * Again, the first boot block must be located somewhere in the first 16 blocks, or rooted in the + * Ridgid disk block + */ + +struct bootcode_block *get_bootcode(block_dev_desc_t *dev_desc) +{ +    int i; +    int limit; +    char *s; + +    s = getenv("amiga_scanlimit"); +    if (s) +	limit = simple_strtoul(s, NULL, 10); +    else +	limit = AMIGA_BLOCK_LIMIT; + +    PRINTF("Scanning for BOOT from 0 to %d\n", limit); + +    for (i = 0; i < limit; i++) +    { +	ulong res = dev_desc->block_read(dev_desc->dev, i, 1, (ulong *)block_buffer); +	if (res == 1) +	{ +	    struct bootcode_block *boot = (struct bootcode_block *)block_buffer; +	    if (boot->id == AMIGA_ID_BOOT) +	    { +		PRINTF("BOOT block at %d, checking checksum\n", i); +		if (sum_block((struct block_header *)block_buffer) == 0) +		{ +		    PRINTF("Found valid bootcode block\n"); +		    memcpy(&bootcode, boot, sizeof(struct bootcode_block)); +		    return &bootcode; +		} +	    } +	} +    } + +    PRINTF("No boot code found on disk\n"); +    return 0; +} + +/* + * Test if the given partition has an Amiga partition table/Rigid + * Disk block + */ +int test_part_amiga(block_dev_desc_t *dev_desc) +{ +    struct rigid_disk_block *rdb; +    struct bootcode_block *bootcode; + +    PRINTF("test_part_amiga: Testing for an Amiga RDB partition\n"); + +    rdb = get_rdisk(dev_desc); +    if (rdb) +    { +	bootcode = get_bootcode(dev_desc); +	if (bootcode) +	    PRINTF("test_part_amiga: bootable Amiga disk\n"); +	else +	    PRINTF("test_part_amiga: non-bootable Amiga disk\n"); + +	return 0; +    } +    else +    { +	PRINTF("test_part_amiga: no RDB found\n"); +	return -1; +    } + +} + +/* + * Find partition number partnum on the given drive. + */ +static struct partition_block *find_partition(block_dev_desc_t *dev_desc, int partnum) +{ +    struct rigid_disk_block *rdb; +    struct partition_block *p; +    u32 block; + +    PRINTF("Trying to find partition block %d\n", partnum); +    rdb = get_rdisk(dev_desc); +    if (!rdb) +    { +	PRINTF("find_partition: no rdb found\n"); +	return NULL; +    } + +    PRINTF("find_partition: Scanning partition list\n"); + +    block = rdb->partition_list; +    PRINTF("find_partition: partition list at 0x%x\n", block); + +    while (block != 0xFFFFFFFF) +    { +	ulong res = dev_desc->block_read(dev_desc->dev, block, 1, +					 (ulong *)block_buffer); +	if (res == 1) +	{ +	    p = (struct partition_block *)block_buffer; +	    if (p->id == AMIGA_ID_PART) +	    { +		PRINTF("PART block suspect at 0x%x, checking checksum\n",block); +		if (sum_block((struct block_header *)p) == 0) +		{ +		    if (partnum == 0) break; +		    else +		    { +			partnum--; +			block = p->next; +		    } +		} +	    } else block = 0xFFFFFFFF; +	} else block = 0xFFFFFFFF; +    } + +    if (block == 0xFFFFFFFF) +    { +	PRINTF("PART block not found\n"); +	return NULL; +    } + +    return (struct partition_block *)block_buffer; +} + +/* + * Get info about a partition + */ +int get_partition_info_amiga (block_dev_desc_t *dev_desc, int part, disk_partition_t *info) +{ +    struct partition_block *p = find_partition(dev_desc, part-1); +    struct amiga_part_geometry *g; +    u32 disk_type; + +    if (!p) return -1; + +    g = (struct amiga_part_geometry *)&(p->environment); +    info->start = g->low_cyl  * g->block_per_track * g->surfaces; +    info->size  = (g->high_cyl - g->low_cyl + 1) * g->block_per_track * g->surfaces - 1; +    info->blksz = rdb.block_bytes; +    bcpl_strcpy(info->name, p->drive_name); + + +    disk_type = g->dos_type; + +    info->type[0] = (disk_type & 0xFF000000)>>24; +    info->type[1] = (disk_type & 0x00FF0000)>>16; +    info->type[2] = (disk_type & 0x0000FF00)>>8; +    info->type[3] = '\\'; +    info->type[4] = (disk_type & 0x000000FF) + '0'; +    info->type[5] = 0; + +    return 0; +} + +void print_part_amiga (block_dev_desc_t *dev_desc) +{ +    struct rigid_disk_block *rdb; +    struct bootcode_block *boot; +    struct partition_block *p; +    u32 block; +    int i = 1; + +    rdb = get_rdisk(dev_desc); +    if (!rdb) +    { +	PRINTF("print_part_amiga: no rdb found\n"); +	return; +    } + +    PRINTF("print_part_amiga: Scanning partition list\n"); + +    block = rdb->partition_list; +    PRINTF("print_part_amiga: partition list at 0x%x\n", block); + +    printf("Summary:  DiskBlockSize: %d\n" +	   "          Cylinders    : %d\n" +	   "          Sectors/Track: %d\n" +	   "          Heads        : %d\n\n", +	   rdb->block_bytes, rdb->cylinders, rdb->sectors, +	   rdb->heads); + +    printf("                 First   Num. \n" +	   "Nr.  Part. Name  Block   Block  Type        Boot Priority\n"); + +    while (block != 0xFFFFFFFF) +    { +	ulong res; + +	PRINTF("Trying to load block #0x%X\n", block); + +	res = dev_desc->block_read(dev_desc->dev, block, 1, +				   (ulong *)block_buffer); +	if (res == 1) +	{ +	    p = (struct partition_block *)block_buffer; +	    if (p->id == AMIGA_ID_PART) +	    { +		PRINTF("PART block suspect at 0x%x, checking checksum\n",block); +		if (sum_block((struct block_header *)p) == 0) +		{ +		    printf("%-4d ", i); i++; +		    print_part_info(p); +		    block = p->next; +		} +	    } else block = 0xFFFFFFFF; +	} else block = 0xFFFFFFFF; +    } + +    boot = get_bootcode(dev_desc); +    if (boot) +    { +	printf("Disk is bootable\n"); +    } +} + +#endif diff --git a/roms/u-boot/disk/part_amiga.h b/roms/u-boot/disk/part_amiga.h new file mode 100644 index 00000000..0f04e97e --- /dev/null +++ b/roms/u-boot/disk/part_amiga.h @@ -0,0 +1,141 @@ +/* + * (C) Copyright 2000 + * Hans-Joerg Frieden, Hyperion Entertainment + * Hans-JoergF@hyperion-entertainment.com + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#ifndef _DISK_PART_AMIGA_H +#define _DISK_PART_AMIGA_H +#include <common.h> + +#ifdef CONFIG_ISO_PARTITION +/* Make the buffers bigger if ISO partition support is enabled -- CD-ROMS +   have 2048 byte blocks */ +#define DEFAULT_SECTOR_SIZE   2048 +#else +#define DEFAULT_SECTOR_SIZE	512 +#endif + + +#define AMIGA_BLOCK_LIMIT 16 + +/* + * Amiga disks have a very open structure. The head for the partition table information + * is stored somewhere within the first 16 blocks on disk, and is called the + * "RigidDiskBlock". + */ + +struct rigid_disk_block +{ +    u32 id; +    u32 summed_longs; +    s32 chk_sum; +    u32 host_id; +    u32 block_bytes; +    u32 flags; +    u32 bad_block_list; +    u32 partition_list; +    u32 file_sys_header_list; +    u32 drive_init; +    u32 bootcode_block; +    u32 reserved_1[5]; + +    /* Physical drive geometry */ +    u32 cylinders; +    u32 sectors; +    u32 heads; +    u32 interleave; +    u32 park; +    u32 reserved_2[3]; +    u32 write_pre_comp; +    u32 reduced_write; +    u32 step_rate; +    u32 reserved_3[5]; + +    /* logical drive geometry */ +    u32 rdb_blocks_lo; +    u32 rdb_blocks_hi; +    u32 lo_cylinder; +    u32 hi_cylinder; +    u32 cyl_blocks; +    u32 auto_park_seconds; +    u32 high_rdsk_block; +    u32 reserved_4; + +    char disk_vendor[8]; +    char disk_product[16]; +    char disk_revision[4]; +    char controller_vendor[8]; +    char controller_product[16]; +    char controller_revision[4]; + +    u32 reserved_5[10]; +}; + +/* + * Each partition on this drive is defined by such a block + */ + +struct partition_block +{ +    u32 id; +    u32 summed_longs; +    s32 chk_sum; +    u32 host_id; +    u32 next; +    u32 flags; +    u32 reserved_1[2]; +    u32 dev_flags; +    char drive_name[32]; +    u32 reserved_2[15]; +    u32 environment[17]; +    u32 reserved_3[15]; +}; + +struct bootcode_block +{ +    u32   id; +    u32   summed_longs; +    s32   chk_sum; +    u32   host_id; +    u32   next; +    u32   load_data[123]; +}; + + +#define AMIGA_ID_RDISK                  0x5244534B +#define AMIGA_ID_PART                   0x50415254 +#define AMIGA_ID_BOOT                   0x424f4f54 + +/* + * The environment array in the partition block + * describes the partition + */ + +struct amiga_part_geometry +{ +    u32 table_size; +    u32 size_blocks; +    u32 unused1; +    u32 surfaces; +    u32 sector_per_block; +    u32 block_per_track; +    u32 reserved; +    u32 prealloc; +    u32 interleave; +    u32 low_cyl; +    u32 high_cyl; +    u32 num_buffers; +    u32 buf_mem_type; +    u32 max_transfer; +    u32 mask; +    s32 boot_priority; +    u32 dos_type; +    u32 baud; +    u32 control; +    u32 boot_blocks; +}; + +#endif /* _DISK_PART_AMIGA_H_ */ diff --git a/roms/u-boot/disk/part_dos.c b/roms/u-boot/disk/part_dos.c new file mode 100644 index 00000000..05c3933c --- /dev/null +++ b/roms/u-boot/disk/part_dos.c @@ -0,0 +1,270 @@ +/* + * (C) Copyright 2001 + * Raymond Lo, lo@routefree.com + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +/* + * Support for harddisk partitions. + * + * To be compatible with LinuxPPC and Apple we use the standard Apple + * SCSI disk partitioning scheme. For more information see: + * http://developer.apple.com/techpubs/mac/Devices/Devices-126.html#MARKER-14-92 + */ + +#include <common.h> +#include <command.h> +#include <ide.h> +#include "part_dos.h" + +#ifdef HAVE_BLOCK_DEVICE + +/* Convert char[4] in little endian format to the host format integer + */ +static inline int le32_to_int(unsigned char *le32) +{ +    return ((le32[3] << 24) + +	    (le32[2] << 16) + +	    (le32[1] << 8) + +	     le32[0] +	   ); +} + +static inline int is_extended(int part_type) +{ +    return (part_type == 0x5 || +	    part_type == 0xf || +	    part_type == 0x85); +} + +static inline int is_bootable(dos_partition_t *p) +{ +	return p->boot_ind == 0x80; +} + +static void print_one_part(dos_partition_t *p, int ext_part_sector, +			   int part_num, unsigned int disksig) +{ +	int lba_start = ext_part_sector + le32_to_int (p->start4); +	int lba_size  = le32_to_int (p->size4); + +	printf("%3d\t%-10d\t%-10d\t%08x-%02x\t%02x%s%s\n", +		part_num, lba_start, lba_size, disksig, part_num, p->sys_ind, +		(is_extended(p->sys_ind) ? " Extd" : ""), +		(is_bootable(p) ? " Boot" : "")); +} + +static int test_block_type(unsigned char *buffer) +{ +	int slot; +	struct dos_partition *p; + +	if((buffer[DOS_PART_MAGIC_OFFSET + 0] != 0x55) || +	    (buffer[DOS_PART_MAGIC_OFFSET + 1] != 0xaa) ) { +		return (-1); +	} /* no DOS Signature at all */ +	p = (struct dos_partition *)&buffer[DOS_PART_TBL_OFFSET]; +	for (slot = 0; slot < 3; slot++) { +		if (p->boot_ind != 0 && p->boot_ind != 0x80) { +			if (!slot && +			    (strncmp((char *)&buffer[DOS_PBR_FSTYPE_OFFSET], +				     "FAT", 3) == 0 || +			     strncmp((char *)&buffer[DOS_PBR32_FSTYPE_OFFSET], +				     "FAT32", 5) == 0)) { +				return DOS_PBR; /* is PBR */ +			} else { +				return -1; +			} +		} +	} +	return DOS_MBR;	    /* Is MBR */ +} + + +int test_part_dos (block_dev_desc_t *dev_desc) +{ +	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, buffer, dev_desc->blksz); + +	if (dev_desc->block_read(dev_desc->dev, 0, 1, (ulong *) buffer) != 1) +		return -1; + +	if (test_block_type(buffer) != DOS_MBR) +		return -1; + +	return 0; +} + +/*  Print a partition that is relative to its Extended partition table + */ +static void print_partition_extended(block_dev_desc_t *dev_desc, +				     int ext_part_sector, int relative, +				     int part_num, unsigned int disksig) +{ +	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, buffer, dev_desc->blksz); +	dos_partition_t *pt; +	int i; + +	if (dev_desc->block_read(dev_desc->dev, ext_part_sector, 1, (ulong *) buffer) != 1) { +		printf ("** Can't read partition table on %d:%d **\n", +			dev_desc->dev, ext_part_sector); +		return; +	} +	i=test_block_type(buffer); +	if (i != DOS_MBR) { +		printf ("bad MBR sector signature 0x%02x%02x\n", +			buffer[DOS_PART_MAGIC_OFFSET], +			buffer[DOS_PART_MAGIC_OFFSET + 1]); +		return; +	} + +	if (!ext_part_sector) +		disksig = le32_to_int(&buffer[DOS_PART_DISKSIG_OFFSET]); + +	/* Print all primary/logical partitions */ +	pt = (dos_partition_t *) (buffer + DOS_PART_TBL_OFFSET); +	for (i = 0; i < 4; i++, pt++) { +		/* +		 * fdisk does not show the extended partitions that +		 * are not in the MBR +		 */ + +		if ((pt->sys_ind != 0) && +		    (ext_part_sector == 0 || !is_extended (pt->sys_ind)) ) { +			print_one_part(pt, ext_part_sector, part_num, disksig); +		} + +		/* Reverse engr the fdisk part# assignment rule! */ +		if ((ext_part_sector == 0) || +		    (pt->sys_ind != 0 && !is_extended (pt->sys_ind)) ) { +			part_num++; +		} +	} + +	/* Follows the extended partitions */ +	pt = (dos_partition_t *) (buffer + DOS_PART_TBL_OFFSET); +	for (i = 0; i < 4; i++, pt++) { +		if (is_extended (pt->sys_ind)) { +			int lba_start = le32_to_int (pt->start4) + relative; + +			print_partition_extended(dev_desc, lba_start, +				ext_part_sector == 0  ? lba_start : relative, +				part_num, disksig); +		} +	} + +	return; +} + + +/*  Print a partition that is relative to its Extended partition table + */ +static int get_partition_info_extended (block_dev_desc_t *dev_desc, int ext_part_sector, +				 int relative, int part_num, +				 int which_part, disk_partition_t *info, +				 unsigned int disksig) +{ +	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, buffer, dev_desc->blksz); +	dos_partition_t *pt; +	int i; + +	if (dev_desc->block_read (dev_desc->dev, ext_part_sector, 1, (ulong *) buffer) != 1) { +		printf ("** Can't read partition table on %d:%d **\n", +			dev_desc->dev, ext_part_sector); +		return -1; +	} +	if (buffer[DOS_PART_MAGIC_OFFSET] != 0x55 || +		buffer[DOS_PART_MAGIC_OFFSET + 1] != 0xaa) { +		printf ("bad MBR sector signature 0x%02x%02x\n", +			buffer[DOS_PART_MAGIC_OFFSET], +			buffer[DOS_PART_MAGIC_OFFSET + 1]); +		return -1; +	} + +#ifdef CONFIG_PARTITION_UUIDS +	if (!ext_part_sector) +		disksig = le32_to_int(&buffer[DOS_PART_DISKSIG_OFFSET]); +#endif + +	/* Print all primary/logical partitions */ +	pt = (dos_partition_t *) (buffer + DOS_PART_TBL_OFFSET); +	for (i = 0; i < 4; i++, pt++) { +		/* +		 * fdisk does not show the extended partitions that +		 * are not in the MBR +		 */ +		if (((pt->boot_ind & ~0x80) == 0) && +		    (pt->sys_ind != 0) && +		    (part_num == which_part) && +		    (is_extended(pt->sys_ind) == 0)) { +			info->blksz = 512; +			info->start = ext_part_sector + le32_to_int (pt->start4); +			info->size  = le32_to_int (pt->size4); +			switch(dev_desc->if_type) { +				case IF_TYPE_IDE: +				case IF_TYPE_SATA: +				case IF_TYPE_ATAPI: +					sprintf ((char *)info->name, "hd%c%d", +						'a' + dev_desc->dev, part_num); +					break; +				case IF_TYPE_SCSI: +					sprintf ((char *)info->name, "sd%c%d", +						'a' + dev_desc->dev, part_num); +					break; +				case IF_TYPE_USB: +					sprintf ((char *)info->name, "usbd%c%d", +						'a' + dev_desc->dev, part_num); +					break; +				case IF_TYPE_DOC: +					sprintf ((char *)info->name, "docd%c%d", +						'a' + dev_desc->dev, part_num); +					break; +				default: +					sprintf ((char *)info->name, "xx%c%d", +						'a' + dev_desc->dev, part_num); +					break; +			} +			/* sprintf(info->type, "%d, pt->sys_ind); */ +			sprintf ((char *)info->type, "U-Boot"); +			info->bootable = is_bootable(pt); +#ifdef CONFIG_PARTITION_UUIDS +			sprintf(info->uuid, "%08x-%02x", disksig, part_num); +#endif +			return 0; +		} + +		/* Reverse engr the fdisk part# assignment rule! */ +		if ((ext_part_sector == 0) || +		    (pt->sys_ind != 0 && !is_extended (pt->sys_ind)) ) { +			part_num++; +		} +	} + +	/* Follows the extended partitions */ +	pt = (dos_partition_t *) (buffer + DOS_PART_TBL_OFFSET); +	for (i = 0; i < 4; i++, pt++) { +		if (is_extended (pt->sys_ind)) { +			int lba_start = le32_to_int (pt->start4) + relative; + +			return get_partition_info_extended (dev_desc, lba_start, +				 ext_part_sector == 0 ? lba_start : relative, +				 part_num, which_part, info, disksig); +		} +	} +	return -1; +} + +void print_part_dos (block_dev_desc_t *dev_desc) +{ +	printf("Part\tStart Sector\tNum Sectors\tUUID\t\tType\n"); +	print_partition_extended(dev_desc, 0, 0, 1, 0); +} + +int get_partition_info_dos (block_dev_desc_t *dev_desc, int part, disk_partition_t * info) +{ +	return get_partition_info_extended(dev_desc, 0, 0, 1, part, info, 0); +} + + +#endif diff --git a/roms/u-boot/disk/part_dos.h b/roms/u-boot/disk/part_dos.h new file mode 100644 index 00000000..0321d922 --- /dev/null +++ b/roms/u-boot/disk/part_dos.h @@ -0,0 +1,33 @@ +/* + * (C) Copyright 2000 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#ifndef _DISK_PART_DOS_H +#define _DISK_PART_DOS_H + +#define DOS_PART_DISKSIG_OFFSET	0x1b8 +#define DOS_PART_TBL_OFFSET	0x1be +#define DOS_PART_MAGIC_OFFSET	0x1fe +#define DOS_PBR_FSTYPE_OFFSET	0x36 +#define DOS_PBR32_FSTYPE_OFFSET	0x52 +#define DOS_PBR_MEDIA_TYPE_OFFSET	0x15 +#define DOS_MBR	0 +#define DOS_PBR	1 + +typedef struct dos_partition { +	unsigned char boot_ind;		/* 0x80 - active			*/ +	unsigned char head;		/* starting head			*/ +	unsigned char sector;		/* starting sector			*/ +	unsigned char cyl;		/* starting cylinder			*/ +	unsigned char sys_ind;		/* What partition type			*/ +	unsigned char end_head;		/* end head				*/ +	unsigned char end_sector;	/* end sector				*/ +	unsigned char end_cyl;		/* end cylinder				*/ +	unsigned char start4[4];	/* starting sector counting from 0	*/ +	unsigned char size4[4];		/* nr of sectors in partition		*/ +} dos_partition_t; + +#endif	/* _DISK_PART_DOS_H */ diff --git a/roms/u-boot/disk/part_efi.c b/roms/u-boot/disk/part_efi.c new file mode 100644 index 00000000..c74b7b91 --- /dev/null +++ b/roms/u-boot/disk/part_efi.c @@ -0,0 +1,669 @@ +/* + * Copyright (C) 2008 RuggedCom, Inc. + * Richard Retanubun <RichardRetanubun@RuggedCom.com> + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +/* + * Problems with CONFIG_SYS_64BIT_LBA: + * + * struct disk_partition.start in include/part.h is sized as ulong. + * When CONFIG_SYS_64BIT_LBA is activated, lbaint_t changes from ulong to uint64_t. + * For now, it is cast back to ulong at assignment. + * + * This limits the maximum size of addressable storage to < 2 Terra Bytes + */ +#include <asm/unaligned.h> +#include <common.h> +#include <command.h> +#include <ide.h> +#include <malloc.h> +#include <part_efi.h> +#include <linux/ctype.h> + +DECLARE_GLOBAL_DATA_PTR; + +#ifdef HAVE_BLOCK_DEVICE +/** + * 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 + */ +static inline u32 efi_crc32(const void *buf, u32 len) +{ +	return crc32(0, buf, len); +} + +/* + * Private function prototypes + */ + +static int pmbr_part_valid(struct partition *part); +static int is_pmbr_valid(legacy_mbr * mbr); +static int is_gpt_valid(block_dev_desc_t * dev_desc, unsigned long long lba, +				gpt_header * pgpt_head, gpt_entry ** pgpt_pte); +static gpt_entry *alloc_read_gpt_entries(block_dev_desc_t * dev_desc, +				gpt_header * pgpt_head); +static int is_pte_valid(gpt_entry * pte); + +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; +} + +static efi_guid_t system_guid = PARTITION_SYSTEM_GUID; + +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)); +} + +#ifdef CONFIG_EFI_PARTITION +/* + * Public Functions (include/part.h) + */ + +void print_part_efi(block_dev_desc_t * dev_desc) +{ +	ALLOC_CACHE_ALIGN_BUFFER_PAD(gpt_header, gpt_head, 1, dev_desc->blksz); +	gpt_entry *gpt_pte = NULL; +	int i = 0; +	char uuid[37]; +	unsigned char *uuid_bin; + +	if (!dev_desc) { +		printf("%s: Invalid Argument(s)\n", __func__); +		return; +	} +	/* 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 ***\n", __func__); +		if (is_gpt_valid(dev_desc, (dev_desc->lba - 1), +				 gpt_head, &gpt_pte) != 1) { +			printf("%s: *** ERROR: Invalid Backup GPT ***\n", +			       __func__); +			return; +		} else { +			printf("%s: ***        Using Backup GPT ***\n", +			       __func__); +		} +	} + +	debug("%s: gpt-entry at %p\n", __func__, gpt_pte); + +	printf("Part\tStart LBA\tEnd LBA\t\tName\n"); +	printf("\tAttributes\n"); +	printf("\tType GUID\n"); +	printf("\tPartition GUID\n"); + +	for (i = 0; i < le32_to_cpu(gpt_head->num_partition_entries); i++) { +		/* Stop at the first non valid PTE */ +		if (!is_pte_valid(&gpt_pte[i])) +			break; + +		printf("%3d\t0x%08llx\t0x%08llx\t\"%s\"\n", (i + 1), +			le64_to_cpu(gpt_pte[i].starting_lba), +			le64_to_cpu(gpt_pte[i].ending_lba), +			print_efiname(&gpt_pte[i])); +		printf("\tattrs:\t0x%016llx\n", gpt_pte[i].attributes.raw); +		uuid_bin = (unsigned char *)gpt_pte[i].partition_type_guid.b; +		uuid_bin_to_str(uuid_bin, uuid, UUID_STR_FORMAT_GUID); +		printf("\ttype:\t%s\n", uuid); +		uuid_bin = (unsigned char *)gpt_pte[i].unique_partition_guid.b; +		uuid_bin_to_str(uuid_bin, uuid, UUID_STR_FORMAT_GUID); +		printf("\tguid:\t%s\n", uuid); +	} + +	/* Remember to free pte */ +	free(gpt_pte); +	return; +} + +int get_partition_info_efi(block_dev_desc_t * dev_desc, int part, +				disk_partition_t * info) +{ +	ALLOC_CACHE_ALIGN_BUFFER_PAD(gpt_header, gpt_head, 1, dev_desc->blksz); +	gpt_entry *gpt_pte = NULL; + +	/* "part" argument must be at least 1 */ +	if (!dev_desc || !info || part < 1) { +		printf("%s: Invalid Argument(s)\n", __func__); +		return -1; +	} + +	/* 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 ***\n", __func__); +		if (is_gpt_valid(dev_desc, (dev_desc->lba - 1), +				 gpt_head, &gpt_pte) != 1) { +			printf("%s: *** ERROR: Invalid Backup GPT ***\n", +			       __func__); +			return -1; +		} else { +			printf("%s: ***        Using Backup GPT ***\n", +			       __func__); +		} +	} + +	if (part > le32_to_cpu(gpt_head->num_partition_entries) || +	    !is_pte_valid(&gpt_pte[part - 1])) { +		debug("%s: *** ERROR: Invalid partition number %d ***\n", +			__func__, part); +		free(gpt_pte); +		return -1; +	} + +	/* The ulong casting limits the maximum disk size to 2 TB */ +	info->start = (u64)le64_to_cpu(gpt_pte[part - 1].starting_lba); +	/* The ending LBA is inclusive, to calculate size, add 1 to it */ +	info->size = ((u64)le64_to_cpu(gpt_pte[part - 1].ending_lba) + 1) +		     - info->start; +	info->blksz = dev_desc->blksz; + +	sprintf((char *)info->name, "%s", +			print_efiname(&gpt_pte[part - 1])); +	sprintf((char *)info->type, "U-Boot"); +	info->bootable = is_bootable(&gpt_pte[part - 1]); +#ifdef CONFIG_PARTITION_UUIDS +	uuid_bin_to_str(gpt_pte[part - 1].unique_partition_guid.b, info->uuid, +			UUID_STR_FORMAT_GUID); +#endif + +	debug("%s: start 0x" LBAF ", size 0x" LBAF ", name %s", __func__, +	      info->start, info->size, info->name); + +	/* Remember to free pte */ +	free(gpt_pte); +	return 0; +} + +int test_part_efi(block_dev_desc_t * dev_desc) +{ +	ALLOC_CACHE_ALIGN_BUFFER_PAD(legacy_mbr, legacymbr, 1, dev_desc->blksz); + +	/* Read legacy MBR from block 0 and validate it */ +	if ((dev_desc->block_read(dev_desc->dev, 0, 1, (ulong *)legacymbr) != 1) +		|| (is_pmbr_valid(legacymbr) != 1)) { +		return -1; +	} +	return 0; +} + +/** + * set_protective_mbr(): Set the EFI protective MBR + * @param dev_desc - block device descriptor + * + * @return - zero on success, otherwise error + */ +static int set_protective_mbr(block_dev_desc_t *dev_desc) +{ +	/* Setup the Protective MBR */ +	ALLOC_CACHE_ALIGN_BUFFER(legacy_mbr, p_mbr, 1); +	memset(p_mbr, 0, sizeof(*p_mbr)); + +	if (p_mbr == NULL) { +		printf("%s: calloc failed!\n", __func__); +		return -1; +	} +	/* 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; +	p_mbr->partition_record[0].nr_sects = (u32) dev_desc->lba; + +	/* Write MBR sector to the MMC device */ +	if (dev_desc->block_write(dev_desc->dev, 0, 1, p_mbr) != 1) { +		printf("** Can't write to device %d **\n", +			dev_desc->dev); +		return -1; +	} + +	return 0; +} + +int write_gpt_table(block_dev_desc_t *dev_desc, +		gpt_header *gpt_h, gpt_entry *gpt_e) +{ +	const int pte_blk_cnt = BLOCK_CNT((gpt_h->num_partition_entries +					   * sizeof(gpt_entry)), dev_desc); +	u32 calc_crc32; +	u64 val; + +	debug("max lba: %x\n", (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 */ +	if (dev_desc->block_write(dev_desc->dev, 1, 1, gpt_h) != 1) +		goto err; + +	if (dev_desc->block_write(dev_desc->dev, 2, pte_blk_cnt, gpt_e) +	    != pte_blk_cnt) +		goto err; + +	/* 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); +	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); + +	if (dev_desc->block_write(dev_desc->dev, +				  le32_to_cpu(gpt_h->last_usable_lba + 1), +				  pte_blk_cnt, gpt_e) != pte_blk_cnt) +		goto err; + +	if (dev_desc->block_write(dev_desc->dev, +				  le32_to_cpu(gpt_h->my_lba), 1, gpt_h) != 1) +		goto err; + +	debug("GPT successfully written to block device!\n"); +	return 0; + + err: +	printf("** Can't write to device %d **\n", dev_desc->dev); +	return -1; +} + +int gpt_fill_pte(gpt_header *gpt_h, gpt_entry *gpt_e, +		disk_partition_t *partitions, int parts) +{ +	u32 offset = (u32)le32_to_cpu(gpt_h->first_usable_lba); +	ulong start; +	int i, k; +	size_t efiname_len, dosname_len; +#ifdef CONFIG_PARTITION_UUIDS +	char *str_uuid; +	unsigned char *bin_uuid; +#endif + +	for (i = 0; i < parts; i++) { +		/* partition starting lba */ +		start = partitions[i].start; +		if (start && (start < offset)) { +			printf("Partition overlap\n"); +			return -1; +		} +		if (start) { +			gpt_e[i].starting_lba = cpu_to_le64(start); +			offset = start + partitions[i].size; +		} else { +			gpt_e[i].starting_lba = cpu_to_le64(offset); +			offset += partitions[i].size; +		} +		if (offset >= gpt_h->last_usable_lba) { +			printf("Partitions layout exceds disk size\n"); +			return -1; +		} +		/* partition ending lba */ +		if ((i == parts - 1) && (partitions[i].size == 0)) +			/* 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); + +		/* partition type GUID */ +		memcpy(gpt_e[i].partition_type_guid.b, +			&PARTITION_BASIC_DATA_GUID, 16); + +#ifdef CONFIG_PARTITION_UUIDS +		str_uuid = partitions[i].uuid; +		bin_uuid = gpt_e[i].unique_partition_guid.b; + +		if (uuid_str_to_bin(str_uuid, bin_uuid, UUID_STR_FORMAT_STD)) { +			printf("Partition no. %d: invalid guid: %s\n", +				i, str_uuid); +			return -1; +		} +#endif + +		/* partition attributes */ +		memset(&gpt_e[i].attributes, 0, +		       sizeof(gpt_entry_attributes)); + +		/* partition name */ +		efiname_len = sizeof(gpt_e[i].partition_name) +			/ sizeof(efi_char16_t); +		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++) +			gpt_e[i].partition_name[k] = +				(efi_char16_t)(partitions[i].name[k]); + +		debug("%s: name: %s offset[%d]: 0x%x size[%d]: 0x" LBAF "\n", +		      __func__, partitions[i].name, i, +		      offset, i, partitions[i].size); +	} + +	return 0; +} + +int gpt_fill_header(block_dev_desc_t *dev_desc, gpt_header *gpt_h, +		char *str_guid, int parts_count) +{ +	gpt_h->signature = cpu_to_le64(GPT_HEADER_SIGNATURE); +	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); +	gpt_h->first_usable_lba = cpu_to_le64(34); +	gpt_h->last_usable_lba = cpu_to_le64(dev_desc->lba - 34); +	gpt_h->partition_entry_lba = cpu_to_le64(2); +	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; + +	if (uuid_str_to_bin(str_guid, gpt_h->disk_guid.b, UUID_STR_FORMAT_GUID)) +		return -1; + +	return 0; +} + +int gpt_restore(block_dev_desc_t *dev_desc, char *str_disk_guid, +		disk_partition_t *partitions, int parts_count) +{ +	int ret; + +	gpt_header *gpt_h = calloc(1, PAD_TO_BLOCKSIZE(sizeof(gpt_header), +						       dev_desc)); +	gpt_entry *gpt_e; + +	if (gpt_h == NULL) { +		printf("%s: calloc failed!\n", __func__); +		return -1; +	} + +	gpt_e = calloc(1, PAD_TO_BLOCKSIZE(GPT_ENTRY_NUMBERS +					       * sizeof(gpt_entry), +					       dev_desc)); +	if (gpt_e == NULL) { +		printf("%s: calloc failed!\n", __func__); +		free(gpt_h); +		return -1; +	} + +	/* 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 */ +	ret = gpt_fill_pte(gpt_h, gpt_e, partitions, parts_count); +	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; +} +#endif + +/* + * 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 && +		get_unaligned_le32(&part->start_sect) == 1UL) { +		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; + +	if (!mbr || le16_to_cpu(mbr->signature) != MSDOS_MBR_SIGNATURE) +		return 0; + +	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. + */ +static int is_gpt_valid(block_dev_desc_t * dev_desc, unsigned long long lba, +			gpt_header * pgpt_head, gpt_entry ** pgpt_pte) +{ +	u32 crc32_backup = 0; +	u32 calc_crc32; +	unsigned long long lastlba; + +	if (!dev_desc || !pgpt_head) { +		printf("%s: Invalid Argument(s)\n", __func__); +		return 0; +	} + +	/* Read GPT Header from device */ +	if (dev_desc->block_read(dev_desc->dev, lba, 1, pgpt_head) != 1) { +		printf("*** ERROR: Can't read GPT header ***\n"); +		return 0; +	} + +	/* Check the GPT header signature */ +	if (le64_to_cpu(pgpt_head->signature) != GPT_HEADER_SIGNATURE) { +		printf("GUID Partition Table Header signature is wrong:" +			"0x%llX != 0x%llX\n", +			le64_to_cpu(pgpt_head->signature), +			GPT_HEADER_SIGNATURE); +		return 0; +	} + +	/* Check the GUID Partition Table CRC */ +	memcpy(&crc32_backup, &pgpt_head->header_crc32, sizeof(crc32_backup)); +	memset(&pgpt_head->header_crc32, 0, sizeof(pgpt_head->header_crc32)); + +	calc_crc32 = efi_crc32((const unsigned char *)pgpt_head, +		le32_to_cpu(pgpt_head->header_size)); + +	memcpy(&pgpt_head->header_crc32, &crc32_backup, sizeof(crc32_backup)); + +	if (calc_crc32 != le32_to_cpu(crc32_backup)) { +		printf("GUID Partition Table Header CRC is wrong:" +			"0x%x != 0x%x\n", +		       le32_to_cpu(crc32_backup), calc_crc32); +		return 0; +	} + +	/* Check that the my_lba entry points to the LBA that contains the GPT */ +	if (le64_to_cpu(pgpt_head->my_lba) != lba) { +		printf("GPT: my_lba incorrect: %llX != %llX\n", +			le64_to_cpu(pgpt_head->my_lba), +			lba); +		return 0; +	} + +	/* Check the first_usable_lba and last_usable_lba are within the disk. */ +	lastlba = (unsigned long long)dev_desc->lba; +	if (le64_to_cpu(pgpt_head->first_usable_lba) > lastlba) { +		printf("GPT: first_usable_lba incorrect: %llX > %llX\n", +			le64_to_cpu(pgpt_head->first_usable_lba), lastlba); +		return 0; +	} +	if (le64_to_cpu(pgpt_head->last_usable_lba) > lastlba) { +		printf("GPT: last_usable_lba incorrect: %llX > %llX\n", +			(u64) le64_to_cpu(pgpt_head->last_usable_lba), lastlba); +		return 0; +	} + +	debug("GPT: first_usable_lba: %llX last_usable_lba %llX last lba %llX\n", +		le64_to_cpu(pgpt_head->first_usable_lba), +		le64_to_cpu(pgpt_head->last_usable_lba), lastlba); + +	/* 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\n"); +		return 0; +	} + +	/* Check the GUID Partition Table Entry Array CRC */ +	calc_crc32 = efi_crc32((const unsigned char *)*pgpt_pte, +		le32_to_cpu(pgpt_head->num_partition_entries) * +		le32_to_cpu(pgpt_head->sizeof_partition_entry)); + +	if (calc_crc32 != le32_to_cpu(pgpt_head->partition_entry_array_crc32)) { +		printf("GUID Partition Table Entry Array CRC is wrong:" +			"0x%x != 0x%x\n", +			le32_to_cpu(pgpt_head->partition_entry_array_crc32), +			calc_crc32); + +		free(*pgpt_pte); +		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! + */ +static gpt_entry *alloc_read_gpt_entries(block_dev_desc_t * dev_desc, +					 gpt_header * pgpt_head) +{ +	size_t count = 0, blk_cnt; +	gpt_entry *pte = NULL; + +	if (!dev_desc || !pgpt_head) { +		printf("%s: Invalid Argument(s)\n", __func__); +		return NULL; +	} + +	count = le32_to_cpu(pgpt_head->num_partition_entries) * +		le32_to_cpu(pgpt_head->sizeof_partition_entry); + +	debug("%s: count = %u * %u = %zu\n", __func__, +	      (u32) le32_to_cpu(pgpt_head->num_partition_entries), +	      (u32) le32_to_cpu(pgpt_head->sizeof_partition_entry), count); + +	/* Allocate memory for PTE, remember to FREE */ +	if (count != 0) { +		pte = memalign(ARCH_DMA_MINALIGN, +			       PAD_TO_BLOCKSIZE(count, dev_desc)); +	} + +	if (count == 0 || pte == NULL) { +		printf("%s: ERROR: Can't allocate 0x%zX " +		       "bytes for GPT Entries\n", +			__func__, count); +		return NULL; +	} + +	/* Read GPT Entries from device */ +	blk_cnt = BLOCK_CNT(count, dev_desc); +	if (dev_desc->block_read (dev_desc->dev, +		le64_to_cpu(pgpt_head->partition_entry_lba), +		(lbaint_t) (blk_cnt), pte) +		!= blk_cnt) { + +		printf("*** ERROR: Can't read GPT Entries ***\n"); +		free(pte); +		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) { +		printf("%s: Invalid Argument(s)\n", __func__); +		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) { + +		debug("%s: Found an unused PTE GUID at 0x%08X\n", __func__, +		      (unsigned int)(uintptr_t)pte); + +		return 0; +	} else { +		return 1; +	} +} +#endif diff --git a/roms/u-boot/disk/part_iso.c b/roms/u-boot/disk/part_iso.c new file mode 100644 index 00000000..2547c703 --- /dev/null +++ b/roms/u-boot/disk/part_iso.c @@ -0,0 +1,249 @@ +/* + * (C) Copyright 2001 + * Denis Peter, MPL AG Switzerland, d.peter@mpl.ch. + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#include <common.h> +#include <command.h> +#include "part_iso.h" + +#ifdef HAVE_BLOCK_DEVICE + +/* #define	ISO_PART_DEBUG */ + +#ifdef	ISO_PART_DEBUG +#define	PRINTF(fmt,args...)	printf (fmt ,##args) +#else +#define PRINTF(fmt,args...) +#endif + +/* enable this if CDs are written with the PowerPC Platform ID */ +#undef CHECK_FOR_POWERPC_PLATTFORM +#define CD_SECTSIZE 2048 + +static unsigned char tmpbuf[CD_SECTSIZE]; + +/* Convert char[4] in little endian format to the host format integer + */ +static inline unsigned long le32_to_int(unsigned char *le32) +{ +    return ((le32[3] << 24) + +	    (le32[2] << 16) + +	    (le32[1] << 8) + +	     le32[0] +	   ); +} +/* Convert char[2] in little endian format to the host format integer + */ +static inline unsigned short le16_to_int(unsigned char *le16) +{ +    return ((le16[1] << 8) + +	   le16[0] +	   ); +} + + +/* only boot records will be listed as valid partitions */ +int get_partition_info_iso_verb(block_dev_desc_t * dev_desc, int part_num, disk_partition_t * info, int verb) +{ +	int i,offset,entry_num; +	unsigned short *chksumbuf; +	unsigned short chksum; +	unsigned long newblkaddr,blkaddr,lastsect,bootaddr; +	iso_boot_rec_t *pbr = (iso_boot_rec_t	*)tmpbuf; /* boot record */ +	iso_pri_rec_t *ppr = (iso_pri_rec_t	*)tmpbuf;	/* primary desc */ +	iso_val_entry_t *pve = (iso_val_entry_t *)tmpbuf; +	iso_init_def_entry_t *pide; + +	if (dev_desc->blksz != CD_SECTSIZE) +		return -1; + +	/* the first sector (sector 0x10) must be a primary volume desc */ +	blkaddr=PVD_OFFSET; +	if (dev_desc->block_read (dev_desc->dev, PVD_OFFSET, 1, (ulong *) tmpbuf) != 1) +	return (-1); +	if(ppr->desctype!=0x01) { +		if(verb) +			printf ("** First descriptor is NOT a primary desc on %d:%d **\n", +				dev_desc->dev, part_num); +		return (-1); +	} +	if(strncmp((char *)ppr->stand_ident,"CD001",5)!=0) { +		if(verb) +			printf ("** Wrong ISO Ident: %s on %d:%d **\n", +				ppr->stand_ident,dev_desc->dev, part_num); +		return (-1); +	} +	lastsect= ((ppr->firstsek_LEpathtab1_LE & 0x000000ff)<<24) + +		  ((ppr->firstsek_LEpathtab1_LE & 0x0000ff00)<< 8) + +		  ((ppr->firstsek_LEpathtab1_LE & 0x00ff0000)>> 8) + +		  ((ppr->firstsek_LEpathtab1_LE & 0xff000000)>>24) ; +	info->blksz=ppr->secsize_BE; /* assuming same block size for all entries */ +	PRINTF(" Lastsect:%08lx\n",lastsect); +	for(i=blkaddr;i<lastsect;i++) { +		PRINTF("Reading block %d\n", i); +		if (dev_desc->block_read (dev_desc->dev, i, 1, (ulong *) tmpbuf) != 1) +		return (-1); +		if(ppr->desctype==0x00) +			break; /* boot entry found */ +		if(ppr->desctype==0xff) { +			if(verb) +				printf ("** No valid boot catalog found on %d:%d **\n", +					dev_desc->dev, part_num); +			return (-1); +		} +	} +	/* boot entry found */ +	if(strncmp(pbr->ident_str,"EL TORITO SPECIFICATION",23)!=0) { +		if(verb) +			printf ("** Wrong El Torito ident: %s on %d:%d **\n", +				pbr->ident_str,dev_desc->dev, part_num); +		return (-1); +	} +	bootaddr=le32_to_int(pbr->pointer); +	PRINTF(" Boot Entry at: %08lX\n",bootaddr); +	if (dev_desc->block_read (dev_desc->dev, bootaddr, 1, (ulong *) tmpbuf) != 1) { +		if(verb) +			printf ("** Can't read Boot Entry at %lX on %d:%d **\n", +				bootaddr,dev_desc->dev, part_num); +		return (-1); +	} +	chksum=0; +	chksumbuf = (unsigned short *)tmpbuf; +	for(i=0;i<0x10;i++) +		chksum+=((chksumbuf[i] &0xff)<<8)+((chksumbuf[i] &0xff00)>>8); +	if(chksum!=0) { +		if(verb) +			printf ("** Checksum Error in booting catalog validation entry on %d:%d **\n", +				dev_desc->dev, part_num); +		return (-1); +	} +	if((pve->key[0]!=0x55)||(pve->key[1]!=0xAA)) { +		if(verb) +			printf ("** Key 0x55 0xAA error on %d:%d **\n", +				dev_desc->dev, part_num); +		return(-1); +	} +#ifdef CHECK_FOR_POWERPC_PLATTFORM +	if(pve->platform!=0x01) { +		if(verb) +			printf ("** No PowerPC platform CD on %d:%d **\n", +				dev_desc->dev, part_num); +		return(-1); +	} +#endif +	/* the validation entry seems to be ok, now search the "partition" */ +	entry_num=0; +	offset=0x20; +	sprintf ((char *)info->type, "U-Boot"); +	switch(dev_desc->if_type) { +		case IF_TYPE_IDE: +		case IF_TYPE_SATA: +		case IF_TYPE_ATAPI: +			sprintf ((char *)info->name, "hd%c%d", +				'a' + dev_desc->dev, part_num); +			break; +		case IF_TYPE_SCSI: +			sprintf ((char *)info->name, "sd%c%d", +				'a' + dev_desc->dev, part_num); +			break; +		case IF_TYPE_USB: +			sprintf ((char *)info->name, "usbd%c%d", +				'a' + dev_desc->dev, part_num); +			break; +		case IF_TYPE_DOC: +			sprintf ((char *)info->name, "docd%c%d", +				'a' + dev_desc->dev, part_num); +			break; +		default: +			sprintf ((char *)info->name, "xx%c%d", +				'a' + dev_desc->dev, part_num); +			break; +	} +	/* the bootcatalog (including validation Entry) is limited to 2048Bytes +	 * (63 boot entries + validation entry) */ +	 while(offset<2048) { +		pide=(iso_init_def_entry_t *)&tmpbuf[offset]; +		if ((pide->boot_ind==0x88) || +		    (pide->boot_ind==0x00)) { /* Header Id for default Sections Entries */ +			if(entry_num==part_num) { /* part found */ +				goto found; +			} +			entry_num++; /* count partitions Entries (boot and non bootables */ +			offset+=0x20; +			continue; +		} +		if ((pide->boot_ind==0x90) ||	/* Section Header Entry */ +		    (pide->boot_ind==0x91) ||	/* Section Header Entry (last) */ +		    (pide->boot_ind==0x44)) {	/* Extension Indicator */ +			offset+=0x20; /* skip unused entries */ +		} +		else { +			if(verb) +				printf ("** Partition %d not found on device %d **\n", +					part_num,dev_desc->dev); +			return(-1); +		} +	} +	/* if we reach this point entire sector has been +	 * searched w/o succsess */ +	if(verb) +		printf ("** Partition %d not found on device %d **\n", +			part_num,dev_desc->dev); +	return(-1); +found: +	if(pide->boot_ind!=0x88) { +		if(verb) +			printf ("** Partition %d is not bootable on device %d **\n", +				part_num,dev_desc->dev); +		return (-1); +	} +	switch(pide->boot_media) { +		case 0x00: /* no emulation */ +			info->size=le16_to_int(pide->sec_cnt)>>2; +			break; +		case 0x01:	info->size=2400>>2; break; /* 1.2MByte Floppy */ +		case 0x02:	info->size=2880>>2; break; /* 1.44MByte Floppy */ +		case 0x03:	info->size=5760>>2; break; /* 2.88MByte Floppy */ +		case 0x04:	info->size=2880>>2; break; /* dummy (HD Emulation) */ +		default:	info->size=0; break; +	} +	newblkaddr=le32_to_int(pide->rel_block_addr); +	info->start=newblkaddr; +	PRINTF(" part %d found @ %lx size %lx\n",part_num,newblkaddr,info->size); +	return 0; +} + +int get_partition_info_iso(block_dev_desc_t * dev_desc, int part_num, disk_partition_t * info) +{ +	return(get_partition_info_iso_verb(dev_desc, part_num, info, 1)); +} + + +void print_part_iso(block_dev_desc_t * dev_desc) +{ +	disk_partition_t info; +	int i; +	if(get_partition_info_iso_verb(dev_desc,0,&info,0)==-1) { +		printf("** No boot partition found on device %d **\n",dev_desc->dev); +		return; +	} +	printf("Part   Start     Sect x Size Type\n"); +	i=0; +	do { +		printf(" %2d " LBAFU " " LBAFU " %6ld %.32s\n", +		       i, info.start, info.size, info.blksz, info.type); +		i++; +	} while (get_partition_info_iso_verb(dev_desc,i,&info,0)!=-1); +} + +int test_part_iso (block_dev_desc_t *dev_desc) +{ +	disk_partition_t info; + +	return(get_partition_info_iso_verb(dev_desc,0,&info,0)); +} + +#endif diff --git a/roms/u-boot/disk/part_iso.h b/roms/u-boot/disk/part_iso.h new file mode 100644 index 00000000..dace0f87 --- /dev/null +++ b/roms/u-boot/disk/part_iso.h @@ -0,0 +1,144 @@ +/* + * (C) Copyright 2001 + * Denis Peter, MPL AG Switzerland, d.peter@mpl.ch. + * + * SPDX-License-Identifier:	GPL-2.0+ + */ +#ifndef _PART_CD_H +#define _PART_CD_H + +#define BRVD	0x11 +#define PVD_OFFSET 0x10 + + +typedef struct iso_boot_rec { +	unsigned char desctype;			/* type of Volume descriptor: 0 = boot record, 1 = primary, 2 = Supplement, 3 = volume part 0xff trminator */ +	unsigned char stand_ident[5]; /* "CD001" */ +	unsigned char vers;					/* Version */ +	char					ident_str[0x20]; /* Ident String "EL TORITO SPECIFICATION" */ +	unsigned char unused[0x20];		/* unused */ +	unsigned char pointer[4];		/* absolute pointer to Boot Catalog */ +} iso_boot_rec_t; + + +typedef struct iso_pri_rec { +	unsigned char desctype;			/* type of Volume descriptor: 0 = boot record, 1 = primary, 2 = Supplement, 3 = volume part 0xff trminator */ +	unsigned char stand_ident[5]; /* "CD001" */ +	unsigned char vers;					/* Version */ +	unsigned char unused; +	char					sysid[32];		/* system Identifier */ +	char					volid[32];		/* volume Identifier */ +	unsigned char zeros1[8];		/* unused */ +	unsigned long volsiz_LE;		/* volume size Little Endian */ +	unsigned long volsiz_BE;		/* volume size Big Endian */ +	unsigned char zeros2[32];		/* unused */ +	unsigned short setsize_LE;	/* volume set size LE */ +	unsigned short setsize_BE;	/* volume set size BE */ +	unsigned short seqnum_LE;		/* volume sequence number LE */ +	unsigned short seqnum_BE;		/* volume sequence number BE */ +	unsigned short secsize_LE;	/* sector size LE */ +	unsigned short secsize_BE;	/* sector size BE */ +	unsigned long pathtablen_LE;/* Path Table size LE */ +	unsigned long pathtablen_BE;/* Path Table size BE */ +	unsigned long firstsek_LEpathtab1_LE; /* location of first occurrence of little endian type path table */ +	unsigned long firstsek_LEpathtab2_LE; /* location of optional occurrence of little endian type path table */ +	unsigned long firstsek_BEpathtab1_BE; /* location of first occurrence of big endian type path table */ +	unsigned long firstsek_BEpathtab2_BE; /* location of optional occurrence of big endian type path table */ +	unsigned char rootdir[34];	/* directory record for root dir */ +	char					volsetid[128];/* Volume set identifier */ +	char					pubid[128];		/* Publisher identifier */ +	char					dataprepid[128]; /* data preparer identifier */ +	char					appid[128];		/* application identifier */ +	char					copyr[37];		/* copyright string */ +	char					abstractfileid[37]; /* abstract file identifier */ +	char					bibliofileid[37]; /* bibliographic file identifier */ +	unsigned char creationdate[17]; /* creation date */ +	unsigned char modify[17];		/* modification date */ +	unsigned char expire[17];		/* expiring date */ +	unsigned char effective[17];/* effective date */ +	unsigned char filestruc_ver;	/* file structur version */ +} iso_pri_rec_t; + +typedef struct iso_sup_rec { +	unsigned char desctype;			/* type of Volume descriptor: 0 = boot record, 1 = primary, 2 = Supplement, 3 = volume part 0xff trminator */ +	unsigned char stand_ident[5]; /* "CD001" */ +	unsigned char vers;					/* Version */ +	unsigned char volumeflags;	/* if bit 0 = 0 => all escape sequences are according ISO 2375 */ +	char					sysid[32];		/* system Identifier */ +	char					volid[32];		/* volume Identifier */ +	unsigned char zeros1[8];		/* unused */ +	unsigned long volsiz_LE;		/* volume size Little Endian */ +	unsigned long volsiz_BE;		/* volume size Big Endian */ +	unsigned char escapeseq[32];/* Escape sequences */ +	unsigned short setsize_LE;	/* volume set size LE */ +	unsigned short setsize_BE;	/* volume set size BE */ +	unsigned short seqnum_LE;		/* volume sequence number LE */ +	unsigned short seqnum_BE;		/* volume sequence number BE */ +	unsigned short secsize_LE;	/* sector size LE */ +	unsigned short secsize_BE;	/* sector size BE */ +	unsigned long pathtablen_LE;/* Path Table size LE */ +	unsigned long pathtablen_BE;/* Path Table size BE */ +	unsigned long firstsek_LEpathtab1_LE; /* location of first occurrence of little endian type path table */ +	unsigned long firstsek_LEpathtab2_LE; /* location of optional occurrence of little endian type path table */ +	unsigned long firstsek_BEpathtab1_BE; /* location of first occurrence of big endian type path table */ +	unsigned long firstsek_BEpathtab2_BE; /* location of optional occurrence of big endian type path table */ +	unsigned char rootdir[34];	/* directory record for root dir */ +	char					volsetid[128];/* Volume set identifier */ +	char					pubid[128];		/* Publisher identifier */ +	char					dataprepid[128]; /* data preparer identifier */ +	char					appid[128];		/* application identifier */ +	char					copyr[37];		/* copyright string */ +	char					abstractfileid[37]; /* abstract file identifier */ +	char					bibliofileid[37]; /* bibliographic file identifier */ +	unsigned char creationdate[17]; /* creation date */ +	unsigned char modify[17];		/* modification date */ +	unsigned char expire[17];		/* expiring date */ +	unsigned char effective[17];/* effective date */ +	unsigned char filestruc_ver;	/* file structur version */ +}iso_sup_rec_t; + +typedef struct iso_part_rec { +	unsigned char desctype;			/* type of Volume descriptor: 0 = boot record, 1 = primary, 2 = Supplement, 3 = volume part 0xff trminator */ +	unsigned char stand_ident[5]; /* "CD001" */ +	unsigned char vers;					/* Version */ +	unsigned char unused; +	char					sysid[32];		 /* system Identifier */ +	char					volid[32];		/* volume partition Identifier */ +	unsigned long partloc_LE;		/* volume partition location LE */ +	unsigned long partloc_BE;		/* volume partition location BE */ +	unsigned long partsiz_LE;		/* volume partition size LE */ +	unsigned long partsiz_BE;		/* volume partition size BE */ +}iso_part_rec_t; + + +typedef struct iso_val_entry { +	unsigned char	header_id;		/* Header ID must be 0x01 */ +	unsigned char	platform;			/* Platform: 0=x86, 1=PowerPC, 2=MAC */ +	unsigned char res[2];				/* reserved */ +	char					manu_str[0x18]; /* Ident String of manufacturer/developer */ +	unsigned char chk_sum[2];	/* Check sum (all words must be zero)  */ +	unsigned char key[2];				/* key[0]=55, key[1]=0xAA */ +} iso_val_entry_t; + +typedef struct iso_header_entry { +	unsigned char	header_id;		/* Header ID must be 0x90 or 0x91 */ +	unsigned char	platform;			/* Platform: 0=x86, 1=PowerPC, 2=MAC */ +	unsigned char numentry[2];	/* number of entries */ +	char					id_str[0x1C]; /* Ident String of sectionr */ +} iso_header_entry_t; + + +typedef struct iso_init_def_entry { +	unsigned char	boot_ind;			/* Boot indicator 0x88=bootable 0=not bootable */ +	unsigned char	boot_media;		/* boot Media Type: 0=no Emulation, 1=1.2MB floppy, 2=1.44MB floppy, 3=2.88MB floppy 4=hd (0x80) */ +	unsigned char ld_seg[2];		/* Load segment (flat model=addr/10) */ +	unsigned char systype;			/* System Type copy of byte5 of part table */ +	unsigned char res;					/* reserved */ +	unsigned char sec_cnt[2];		/* sector count in VIRTUAL Blocks (0x200) */ +	unsigned char rel_block_addr[4];	/* relative Block address */ +} iso_init_def_entry_t; + + +void print_partition_cd(int dev); + +#endif /* _PART_CD_H */ diff --git a/roms/u-boot/disk/part_mac.c b/roms/u-boot/disk/part_mac.c new file mode 100644 index 00000000..cbcb995c --- /dev/null +++ b/roms/u-boot/disk/part_mac.c @@ -0,0 +1,234 @@ +/* + * (C) Copyright 2000 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +/* + * Support for harddisk partitions. + * + * To be compatible with LinuxPPC and Apple we use the standard Apple + * SCSI disk partitioning scheme. For more information see: + * http://developer.apple.com/techpubs/mac/Devices/Devices-126.html#MARKER-14-92 + */ + +#include <common.h> +#include <command.h> +#include <ide.h> +#include "part_mac.h" + +#ifdef HAVE_BLOCK_DEVICE + +/* stdlib.h causes some compatibility problems; should fixe these! -- wd */ +#ifndef __ldiv_t_defined +typedef struct { +	long int quot;		/* Quotient	*/ +	long int rem;		/* Remainder	*/ +} ldiv_t; +extern ldiv_t ldiv (long int __numer, long int __denom); +# define __ldiv_t_defined	1 +#endif + + +static int part_mac_read_ddb (block_dev_desc_t *dev_desc, mac_driver_desc_t *ddb_p); +static int part_mac_read_pdb (block_dev_desc_t *dev_desc, int part, mac_partition_t *pdb_p); + +/* + * Test for a valid MAC partition + */ +int test_part_mac (block_dev_desc_t *dev_desc) +{ +	ALLOC_CACHE_ALIGN_BUFFER(mac_driver_desc_t, ddesc, 1); +	ALLOC_CACHE_ALIGN_BUFFER(mac_partition_t, mpart, 1); +	ulong i, n; + +	if (part_mac_read_ddb (dev_desc, ddesc)) { +		/* error reading Driver Desriptor Block, or no valid Signature */ +		return (-1); +	} + +	n = 1;	/* assuming at least one partition */ +	for (i=1; i<=n; ++i) { +		if ((dev_desc->block_read(dev_desc->dev, i, 1, (ulong *)mpart) != 1) || +		    (mpart->signature != MAC_PARTITION_MAGIC) ) { +			return (-1); +		} +		/* update partition count */ +		n = mpart->map_count; +	} +	return (0); +} + + +void print_part_mac (block_dev_desc_t *dev_desc) +{ +	ulong i, n; +	ALLOC_CACHE_ALIGN_BUFFER(mac_driver_desc_t, ddesc, 1); +	ALLOC_CACHE_ALIGN_BUFFER(mac_partition_t, mpart, 1); +	ldiv_t mb, gb; + +	if (part_mac_read_ddb (dev_desc, ddesc)) { +		/* error reading Driver Desriptor Block, or no valid Signature */ +		return; +	} + +	n  = ddesc->blk_count; + +	mb = ldiv(n, ((1024 * 1024) / ddesc->blk_size)); /* MB */ +	/* round to 1 digit */ +	mb.rem *= 10 * ddesc->blk_size; +	mb.rem += 512 * 1024; +	mb.rem /= 1024 * 1024; + +	gb = ldiv(10 * mb.quot + mb.rem, 10240); +	gb.rem += 512; +	gb.rem /= 1024; + + +	printf ("Block Size=%d, Number of Blocks=%d, " +		"Total Capacity: %ld.%ld MB = %ld.%ld GB\n" +		"DeviceType=0x%x, DeviceId=0x%x\n\n" +		"   #:                 type name" +		"                   length   base       (size)\n", +		ddesc->blk_size, +		ddesc->blk_count, +		mb.quot, mb.rem, gb.quot, gb.rem, +		ddesc->dev_type, ddesc->dev_id +		); + +	n = 1;	/* assuming at least one partition */ +	for (i=1; i<=n; ++i) { +		ulong bytes; +		char c; + +		printf ("%4ld: ", i); +		if (dev_desc->block_read (dev_desc->dev, i, 1, (ulong *)mpart) != 1) { +			printf ("** Can't read Partition Map on %d:%ld **\n", +				dev_desc->dev, i); +			return; +		} + +		if (mpart->signature != MAC_PARTITION_MAGIC) { +			printf ("** Bad Signature on %d:%ld - " +				"expected 0x%04x, got 0x%04x\n", +				dev_desc->dev, i, MAC_PARTITION_MAGIC, mpart->signature); +			return; +		} + +		/* update partition count */ +		n = mpart->map_count; + +		c      = 'k'; +		bytes  = mpart->block_count; +		bytes /= (1024 / ddesc->blk_size);  /* kB; assumes blk_size == 512 */ +		if (bytes >= 1024) { +			bytes >>= 10; +			c = 'M'; +		} +		if (bytes >= 1024) { +			bytes >>= 10; +			c = 'G'; +		} + +		printf ("%20.32s %-18.32s %10u @ %-10u (%3ld%c)\n", +			mpart->type, +			mpart->name, +			mpart->block_count, +			mpart->start_block, +			bytes, c +			); +	} + +	return; +} + + +/* + * Read Device Descriptor Block + */ +static int part_mac_read_ddb (block_dev_desc_t *dev_desc, mac_driver_desc_t *ddb_p) +{ +	if (dev_desc->block_read(dev_desc->dev, 0, 1, (ulong *)ddb_p) != 1) { +		printf ("** Can't read Driver Desriptor Block **\n"); +		return (-1); +	} + +	if (ddb_p->signature != MAC_DRIVER_MAGIC) { +#if 0 +		printf ("** Bad Signature: expected 0x%04x, got 0x%04x\n", +			MAC_DRIVER_MAGIC, ddb_p->signature); +#endif +		return (-1); +	} +	return (0); +} + +/* + * Read Partition Descriptor Block + */ +static int part_mac_read_pdb (block_dev_desc_t *dev_desc, int part, mac_partition_t *pdb_p) +{ +	int n = 1; + +	for (;;) { +		/* +		 * We must always read the descritpor block for +		 * partition 1 first since this is the only way to +		 * know how many partitions we have. +		 */ +		if (dev_desc->block_read (dev_desc->dev, n, 1, (ulong *)pdb_p) != 1) { +			printf ("** Can't read Partition Map on %d:%d **\n", +				dev_desc->dev, n); +			return (-1); +		} + +		if (pdb_p->signature != MAC_PARTITION_MAGIC) { +			printf ("** Bad Signature on %d:%d: " +				"expected 0x%04x, got 0x%04x\n", +				dev_desc->dev, n, MAC_PARTITION_MAGIC, pdb_p->signature); +			return (-1); +		} + +		if (n == part) +			return (0); + +		if ((part < 1) || (part > pdb_p->map_count)) { +			printf ("** Invalid partition %d:%d [%d:1...%d:%d only]\n", +				dev_desc->dev, part, +				dev_desc->dev, +				dev_desc->dev, pdb_p->map_count); +			return (-1); +		} + +		/* update partition count */ +		n = part; +	} + +	/* NOTREACHED */ +} + +int get_partition_info_mac (block_dev_desc_t *dev_desc, int part, disk_partition_t *info) +{ +	ALLOC_CACHE_ALIGN_BUFFER(mac_driver_desc_t, ddesc, 1); +	ALLOC_CACHE_ALIGN_BUFFER(mac_partition_t, mpart, 1); + +	if (part_mac_read_ddb (dev_desc, ddesc)) { +		return (-1); +	} + +	info->blksz = ddesc->blk_size; + +	if (part_mac_read_pdb (dev_desc, part, mpart)) { +		return (-1); +	} + +	info->start = mpart->start_block; +	info->size  = mpart->block_count; +	memcpy (info->type, mpart->type, sizeof(info->type)); +	memcpy (info->name, mpart->name, sizeof(info->name)); + +	return (0); +} + +#endif diff --git a/roms/u-boot/disk/part_mac.h b/roms/u-boot/disk/part_mac.h new file mode 100644 index 00000000..7b754e16 --- /dev/null +++ b/roms/u-boot/disk/part_mac.h @@ -0,0 +1,83 @@ +/* + * (C) Copyright 2000 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +/* + * See also Linux sources, fs/partitions/mac.h + * + * This file describes structures and values related to the standard + * Apple SCSI disk partitioning scheme. For more information see: + * http://developer.apple.com/techpubs/mac/Devices/Devices-126.html#MARKER-14-92 + */ + +#ifndef	_DISK_PART_MAC_H +#define	_DISK_PART_MAC_H + +#define MAC_DRIVER_MAGIC	0x4552 + +/* + * Driver Descriptor Structure, in block 0. + * This block is (and shall remain) 512 bytes long. + * Note that there is an alignment problem for the driver descriptor map! + */ +typedef struct mac_driver_desc { +	__u16	signature;	/* expected to be MAC_DRIVER_MAGIC	*/ +	__u16	blk_size;	/* block size of device			*/ +	__u32	blk_count;	/* number of blocks on device		*/ +	__u16	dev_type;	/* device type				*/ +	__u16	dev_id;		/* device id				*/ +	__u32	data;		/* reserved				*/ +	__u16	drvr_cnt;	/* number of driver descriptor entries	*/ +	__u16	drvr_map[247];	/* driver descriptor map		*/ +} mac_driver_desc_t; + +/* + * Device Driver Entry + * (Cannot be included in mac_driver_desc because of alignment problems) + */ +typedef struct mac_driver_entry { +	__u32	block;		/* block number of starting block	*/ +	__u16	size;		/* size of driver, in 512 byte blocks	*/ +	__u16	type;		/* OS Type				*/ +} mac_driver_entry_t; + + +#define MAC_PARTITION_MAGIC	0x504d + +/* type field value for A/UX or other Unix partitions */ +#define APPLE_AUX_TYPE	"Apple_UNIX_SVR2" + +/* + * Each Partition Map entry (in blocks 1 ... N) has this format: + */ +typedef struct mac_partition { +	__u16	signature;	/* expected to be MAC_PARTITION_MAGIC	*/ +	__u16	sig_pad;	/* reserved				*/ +	__u32	map_count;	/* # blocks in partition map		*/ +	__u32	start_block;	/* abs. starting block # of partition	*/ +	__u32	block_count;	/* number of blocks in partition	*/ +	uchar	name[32];	/* partition name			*/ +	uchar	type[32];	/* string type description		*/ +	__u32	data_start;	/* rel block # of first data block	*/ +	__u32	data_count;	/* number of data blocks		*/ +	__u32	status;		/* partition status bits		*/ +	__u32	boot_start;	/* first block of boot code		*/ +	__u32	boot_size;	/* size of boot code, in bytes		*/ +	__u32	boot_load;	/* boot code load address		*/ +	__u32	boot_load2;	/* reserved				*/ +	__u32	boot_entry;	/* boot code entry point		*/ +	__u32	boot_entry2;	/* reserved				*/ +	__u32	boot_cksum;	/* boot code checksum			*/ +	uchar	processor[16];	/* Type of Processor			*/ +	__u16	part_pad[188];	/* reserved				*/ +#ifdef CONFIG_ISO_PARTITION +	uchar   iso_dummy[2048];/* Reservere enough room for an ISO partition block to fit */ +#endif +} mac_partition_t; + +#define MAC_STATUS_BOOTABLE	8	/* partition is bootable */ + +#endif	/* _DISK_PART_MAC_H */  | 
