libi386/biosacpi.c - bad RSDP checksum search
John Baldwin
jhb at freebsd.org
Tue Dec 8 13:36:05 UTC 2009
On Tuesday 08 December 2009 1:03:40 am Andrew Pantyukhin wrote:
> Our boot loader stops searching memory at the first occurrence of
> "RSD PTR" while there are BIOSes (e.g. some IBM System x) that
> have multiple such strings and the first one does not contain the
> correct checksum.
>
> The acpi-ca code does the right thing and continues the search.
>
> Any ACPI experts interested in fixing this? I'll be ready to
> test.
Are you sure? It looks like it keeps going if the checksum fails. Note the
'continue' after the printf() about a bad checksum.
/*
* Find the RSDP in low memory. See section 5.2.2 of the ACPI spec.
*/
static ACPI_TABLE_RSDP *
biosacpi_find_rsdp(void)
{
ACPI_TABLE_RSDP *rsdp;
uint16_t *addr;
/* EBDA is the 1 KB addressed by the 16 bit pointer at 0x40E. */
addr = (uint16_t *)PTOV(0x40E);
if ((rsdp = biosacpi_search_rsdp((char *)(*addr << 4), 0x400)) != NULL)
return (rsdp);
/* Check the upper memory BIOS space, 0xe0000 - 0xfffff. */
if ((rsdp = biosacpi_search_rsdp((char *)0xe0000, 0x20000)) != NULL)
return (rsdp);
return (NULL);
}
static ACPI_TABLE_RSDP *
biosacpi_search_rsdp(char *base, int length)
{
ACPI_TABLE_RSDP *rsdp;
u_int8_t *cp, sum;
int ofs, idx;
/* search on 16-byte boundaries */
for (ofs = 0; ofs < length; ofs += 16) {
rsdp = (ACPI_TABLE_RSDP *)PTOV(base + ofs);
/* compare signature, validate checksum */
if (!strncmp(rsdp->Signature, ACPI_SIG_RSDP, strlen(ACPI_SIG_RSDP))) {
cp = (u_int8_t *)rsdp;
sum = 0;
for (idx = 0; idx < RSDP_CHECKSUM_LENGTH; idx++)
sum += *(cp + idx);
if (sum != 0) {
printf("acpi: bad RSDP checksum (%d)\n", sum);
continue;
}
return(rsdp);
}
}
return(NULL);
}
--
John Baldwin
More information about the freebsd-acpi
mailing list