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>


git-svn-id: svn://coreboot.org/openbios/trunk/openbios-devel@821 f158a5a8-5612-0410-a976-696ce0be7e32
This commit is contained in:
Mark Cave-Ayland
2010-07-13 16:41:06 +00:00
committed by Mark Cave-Ayland
parent 48af2808ba
commit 3330f2e126
3 changed files with 80 additions and 79 deletions

View File

@@ -57,7 +57,7 @@ macparts_open( macparts_info_t *di )
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 @@ macparts_open( macparts_info_t *di )
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 @@ macparts_open( macparts_info_t *di )
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 */
for (parnum = 0; parnum <= __be32_to_cpu(par.pmMapBlkCnt); parnum++) {
SEEK( (bs * (parnum + 1)) );
READ( &par, sizeof(par) );
if( __be16_to_cpu(par.pmSig) != DESC_PART_SIGNATURE ||
!__be16_to_cpu(par.pmPartBlkCnt) )
break;
DPRINTF("found partition type: %s\n", par.pmPartType);
if (firstHFS == -1 &&
strcmp(par.pmPartType, "Apple_HFS") == 0)
firstHFS = parnum;
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;
}
ret = -1;
goto out;
}
}
/* not found */
if (firstHFS != -1) {
parnum = firstHFS;
goto found;
}
ret = 0;
goto out;
}
if (parnum == 0) {
di->blocksize =(uint)bs;
/*
* 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;
di->offs_hi = offs >> BITS;
di->offs_lo = offs & (ucell) -1;
size = (llong)__be32_to_cpu(dmap.sbBlkCount) * bs;
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 ||
!__be32_to_cpu(par.pmPartBlkCnt) )
break;
DPRINTF("found partition type: %s with status %x\n", par.pmPartType, __be32_to_cpu(par.pmPartStatus));
/* 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;
}
}
}
} else {
/* Another partition was explicitly requested */
SEEK( bs * parnum );
READ( &par, sizeof(par) );
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;
}
}
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 @@ static void
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;

View File

@@ -333,10 +333,15 @@ static void
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;

View File

@@ -265,10 +265,15 @@ static void
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;