Author: mcayland Date: Tue Jul 13 18:41:06 2010 New Revision: 821 URL: http://tracker.coreboot.org/trac/openbios/changeset/821
Log: Fix a thinko in packages/mac-parts and then rework the open method so it more accurately reflects the CHRP boot specification. Also add seek limits to each partition type, since some existing code uses this to detect bootloader code. This fixes the quik bootloader problem for PPC as reported by Aurelian Jarno.
Signed-off-by: Mark Cave-Ayland mark.cave-ayland@siriusit.co.uk
Modified: trunk/openbios-devel/packages/mac-parts.c trunk/openbios-devel/packages/pc-parts.c trunk/openbios-devel/packages/sun-parts.c
Modified: trunk/openbios-devel/packages/mac-parts.c ============================================================================== --- trunk/openbios-devel/packages/mac-parts.c Mon Jul 12 00:41:34 2010 (r820) +++ trunk/openbios-devel/packages/mac-parts.c Tue Jul 13 18:41:06 2010 (r821) @@ -57,7 +57,7 @@ int ret = 0; int want_bootcode = 0; phandle_t ph; - ducell offs, size; + ducell offs = 0, size = -1;
DPRINTF("macparts_open '%s'\n", str );
@@ -102,8 +102,10 @@ parnum = atol(parstr);
/* Detect if we are looking for the bootcode */ - if (strcmp(argstr, "%BOOT") == 0) + if (strcmp(argstr, "%BOOT") == 0) { want_bootcode = 1; + argstr = strdup(""); + } } }
@@ -136,100 +138,84 @@ if (__be16_to_cpu(par.pmSig) != DESC_PART_SIGNATURE) goto out;
- if (parnum == -1) { - int firstHFS = -1; - /* search a bootable partition */ - /* see PowerPC Microprocessor CHRP bindings */ + /* + * Implement partition selection as per the PowerPC Microprocessor CHRP bindings + */ + + if (str == NULL || parnum == 0) { + /* According to the spec, partition 0 as well as no arguments means the whole disk */ + offs = (llong)0; + size = (llong)__be32_to_cpu(dmap.sbBlkCount) * bs; + + di->blocksize = (uint)bs;
- for (parnum = 0; parnum <= __be32_to_cpu(par.pmMapBlkCnt); parnum++) { - SEEK( (bs * (parnum + 1)) ); + di->offs_hi = offs >> BITS; + di->offs_lo = offs & (ucell) -1; + + di->size_hi = size >> BITS; + di->size_lo = size & (ucell) -1; + + ret = -1; + goto out; + + } else if (parnum == -1) { + + DPRINTF("mac-parts: counted %d partitions\n", __be32_to_cpu(par.pmMapBlkCnt)); + + /* No partition was explicitly requested, so find one */ + for (parnum = 1; parnum <= __be32_to_cpu(par.pmMapBlkCnt); parnum++) { + SEEK( bs * parnum ); READ( &par, sizeof(par) ); if( __be16_to_cpu(par.pmSig) != DESC_PART_SIGNATURE || - !__be16_to_cpu(par.pmPartBlkCnt) ) + !__be32_to_cpu(par.pmPartBlkCnt) ) break;
- DPRINTF("found partition type: %s\n", par.pmPartType); - - if (firstHFS == -1 && - strcmp(par.pmPartType, "Apple_HFS") == 0) - firstHFS = parnum; + DPRINTF("found partition type: %s with status %x\n", par.pmPartType, __be32_to_cpu(par.pmPartStatus));
- if( (__be32_to_cpu(par.pmPartStatus) & kPartitionAUXIsBootValid) && - (__be32_to_cpu(par.pmPartStatus) & kPartitionAUXIsValid) && - (__be32_to_cpu(par.pmPartStatus) & kPartitionAUXIsAllocated) && - (__be32_to_cpu(par.pmPartStatus) & kPartitionAUXIsReadable) && - (strcmp(par.pmProcessor, "PowerPC") == 0) ) { - di->blocksize =(uint)bs; - - offs = (llong)(__be32_to_cpu(par.pmPyPartStart)) * bs; - di->offs_hi = offs >> BITS; - di->offs_lo = offs & (ucell) -1; - - size = (llong)(__be32_to_cpu(par.pmPartBlkCnt)) * bs; - di->size_hi = size >> BITS; - di->size_lo = size & (ucell) -1; - - if (want_bootcode) { - offs = (llong)(__be32_to_cpu(par.pmLgBootStart)) * bs; - di->offs_hi = offs >> BITS; - di->offs_lo = offs & (ucell) -1; - - size = (llong)(__be32_to_cpu(par.pmBootSize)) * bs; - di->size_hi = size >> BITS; - di->size_lo = size & (ucell) -1; + /* Ignore any partition maps when searching */ + if (strcmp(par.pmPartType, "Apple_partition_map")) { + if( (__be32_to_cpu(par.pmPartStatus) & kPartitionAUXIsValid) && + (__be32_to_cpu(par.pmPartStatus) & kPartitionAUXIsAllocated) && + (__be32_to_cpu(par.pmPartStatus) & kPartitionAUXIsReadable) ) { + offs = (llong)__be32_to_cpu(par.pmPyPartStart) * bs; + size = (llong)__be32_to_cpu(par.pmPartBlkCnt) * bs; + + goto found; } - ret = -1; - goto out; } } - /* not found */ - if (firstHFS != -1) { - parnum = firstHFS; - goto found; - } - ret = 0; - goto out; - }
- if (parnum == 0) { - di->blocksize =(uint)bs; - - offs = (llong)0; - di->offs_hi = offs >> BITS; - di->offs_lo = offs & (ucell) -1; + } else { + /* Another partition was explicitly requested */ + SEEK( bs * parnum ); + READ( &par, sizeof(par) );
- size = (llong)__be32_to_cpu(dmap.sbBlkCount) * bs; - di->size_hi = size >> BITS; - di->size_lo = size & (ucell) -1; + if( (__be32_to_cpu(par.pmPartStatus) & kPartitionAUXIsValid) && + (__be32_to_cpu(par.pmPartStatus) & kPartitionAUXIsAllocated) && + (__be32_to_cpu(par.pmPartStatus) & kPartitionAUXIsReadable) ) {
- ret = -1; - goto out; + offs = (llong)__be32_to_cpu(par.pmPyPartStart) * bs; + size = (llong)__be32_to_cpu(par.pmPartBlkCnt) * bs; + } }
- if( parnum > __be32_to_cpu(par.pmMapBlkCnt)) + /* If we couldn't find a partition, exit */ + if (size == -1) { + DPRINTF("Unable to automatically find partition!\n"); goto out; + }
found: - SEEK( (bs * (parnum + 1)) ); - READ( &par, sizeof(par) ); - if( __be16_to_cpu(par.pmSig) != DESC_PART_SIGNATURE || !__be32_to_cpu(par.pmPartBlkCnt) ) - goto out; - if( !(__be32_to_cpu(par.pmPartStatus) & kPartitionAUXIsValid) || - !(__be32_to_cpu(par.pmPartStatus) & kPartitionAUXIsAllocated) || - !(__be32_to_cpu(par.pmPartStatus) & kPartitionAUXIsReadable) ) - goto out; - - ret = -1; - di->blocksize = (uint)bs; - - offs = (llong)__be32_to_cpu(par.pmPyPartStart) * bs; - size = (llong)__be32_to_cpu(par.pmPartBlkCnt) * bs;
+ /* If the filename was set to %BOOT, we actually want the bootcode instead */ if (want_bootcode) { offs += (llong)__be32_to_cpu(par.pmLgBootStart) * bs; size = (llong)__be32_to_cpu(par.pmBootSize); }
+ ret = -1; + di->blocksize = (uint)bs; + di->offs_hi = offs >> BITS; di->offs_lo = offs & (ucell) -1;
@@ -308,10 +294,15 @@ macparts_seek(macparts_info_t *di ) { llong pos = DPOP(); - llong offs; + llong offs, size;
DPRINTF("macparts_seek %llx:\n", pos);
+ /* Seek is invalid if we reach the end of the device */ + size = ((ducell)di->size_hi << BITS) | di->size_lo; + if (pos > size) + RET( -1 ); + /* Calculate the seek offset for the parent */ offs = ((ducell)di->offs_hi << BITS) | di->offs_lo; offs += pos;
Modified: trunk/openbios-devel/packages/pc-parts.c ============================================================================== --- trunk/openbios-devel/packages/pc-parts.c Mon Jul 12 00:41:34 2010 (r820) +++ trunk/openbios-devel/packages/pc-parts.c Tue Jul 13 18:41:06 2010 (r821) @@ -333,10 +333,15 @@ pcparts_seek(pcparts_info_t *di ) { llong pos = DPOP(); - llong offs; + llong offs, size;
DPRINTF("pcparts_seek %llx:\n", pos);
+ /* Seek is invalid if we reach the end of the device */ + size = ((ducell)di->size_hi << BITS) | di->size_lo; + if (pos > size) + RET( -1 ); + /* Calculate the seek offset for the parent */ offs = ((ducell)di->offs_hi << BITS) | di->offs_lo; offs += pos;
Modified: trunk/openbios-devel/packages/sun-parts.c ============================================================================== --- trunk/openbios-devel/packages/sun-parts.c Mon Jul 12 00:41:34 2010 (r820) +++ trunk/openbios-devel/packages/sun-parts.c Tue Jul 13 18:41:06 2010 (r821) @@ -265,10 +265,15 @@ sunparts_seek(sunparts_info_t *di ) { llong pos = DPOP(); - llong offs; + llong offs, size;;
DPRINTF("sunparts_seek %llx:\n", pos);
+ /* Seek is invalid if we reach the end of the device */ + size = ((ducell)di->size_hi << BITS) | di->size_lo; + if (pos > size) + RET( -1 ); + /* Calculate the seek offset for the parent */ offs = ((ducell)di->offs_hi << BITS) | di->offs_lo; offs += pos;