libi386/biosacpi.c - bad RSDP checksum search

Moore, Robert robert.moore at intel.com
Wed Dec 9 18:46:39 UTC 2009


Might be a dumb question, but why is the bootloader looking around for ACPI tables in the first place?

Thanks,
Bob


>-----Original Message-----
>From: owner-freebsd-acpi at freebsd.org [mailto:owner-freebsd-
>acpi at freebsd.org] On Behalf Of John Baldwin
>Sent: Tuesday, December 08, 2009 4:50 AM
>To: freebsd-acpi at freebsd.org
>Cc: Andrew Pantyukhin
>Subject: Re: libi386/biosacpi.c - bad RSDP checksum search
>
>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
>_______________________________________________
>freebsd-acpi at freebsd.org mailing list
>http://lists.freebsd.org/mailman/listinfo/freebsd-acpi
>To unsubscribe, send any mail to "freebsd-acpi-unsubscribe at freebsd.org"


More information about the freebsd-acpi mailing list