mirror of
https://gitlab.com/qemu-project/openbios.git
synced 2024-02-13 08:34:06 +08:00
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:
committed by
Mark Cave-Ayland
parent
48af2808ba
commit
3330f2e126
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user