Page 1 of 1

ACPI RSDT address out of memory

Posted: Sat Nov 04, 2017 9:59 am
by Oxmose
Hi everyone!

So, I started adding ACPI support to my kernel but I stumbled upon a strange bug.
I'm scanning the memory to find the RSDP, which is successfully done since the OEM info I get is BOCHS.
But then, when getting the RSDT address, I get 0x07FE154E. Then trying to access this address make the kernel crash.
This thing is, when running the kernel I launch QEMU with 128Mb of memory, so my guess is that the address 0x07FE154E is definitely out of memory.

Can you try to tell me what I'm doing wrong here?
The RSDT address is retreived thanks to this code :
uint32_t rsdt_addr = *(uint32_t *)(rsdp_base + 16);

Then the code that make the kernel crash is :
rsdt_addr->length;

Thanks!

Re: ACPI RSDT address out of memory

Posted: Sat Nov 04, 2017 10:19 am
by Korona
What is the type of rsdp_base? Why don't you use a proper struct to extract the information? You'll have to show us more code if you want real help.

Re: ACPI RSDT address out of memory

Posted: Sat Nov 04, 2017 10:26 am
by Oxmose
Sorry for not posting too much code ^^ here is what I have

Code: Select all

typedef struct acpi_header
{
    uint32_t    signature;
    uint32_t    length;
    uint8_t     revision;
    uint8_t     checksum;

    uint8_t     oem[6];
    uint8_t     oem_table_id[8];
    uint32_t    oem_revision;

    uint32_t    creator_id;
    uint32_t    creator_revision;
} __attribute__((__packed__)) acpi_header_t;

Code: Select all

uint32_t rsdt_addr = *(uint32_t *)(rsdp_base + 16);
where rsdp_base is an uint8_t pointer

Then, rsdt_addr is sent to a function as a acpi_header_t pointer.

Then I am using the structure in this code:

Code: Select all

if(rsdt == NULL)
    {
        return OS_ERR_NULL_POINTER;
    }

    printf("PARSING RSDT 1");

    uint32_t *range_begin = (uint32_t *)(rsdt + 1);
    uint32_t *range_end = (uint32_t *)((uint8_t*)rsdt + rsdt->length);

    printf("PARSING RSDT 2\n");
the code crashes when reaching the rsdt->length access.

EDIT:
I've also tried to parse the descriptor like this

Code: Select all

static OS_RETURN_E acpi_parse_rsdp(rsdp_descriptor_t *rsdp_desc)
{
    if(rsdp_desc == NULL)
    {
        return OS_ERR_NULL_POINTER;
    }

    // Verify checksum
    uint8_t sum = 0;

    for (uint8_t i = 0; i < 20; ++i)
    {
        sum += ((uint8_t*)rsdp_desc)[i];
    }

    if (sum)
    {
        printf("Checksum failed\n");
        return OS_ERR_CHECKSUM_FAILED;
    }

    printf("OEM = %s\n", rsdp_desc->oemid);

    OS_RETURN_E err;

    // Check version
    if (rsdp_desc->revision == 0)
    {
        printf("ACPI Version 1\n");
        printf("ADDR  %p\n", rsdp_desc->rsdt_address);
        err = acpi_parse_rsdt((acpi_header_t *) rsdp_desc->rsdt_address);
        printf("PARSED RSDT\n");
        if(err != OS_NO_ERR)
        {
            return err;
        }
    }
}
where rsdp_descriptor_t is

Code: Select all

typedef struct rsdp_descriptor 
{
    char     signature[8];
    uint8_t  checksum;
    char     oemid[6];
    uint8_t  revision;
    uint32_t rsdt_address;
} __attribute__ ((packed)) rsdp_descriptor_t;

Re: ACPI RSDT address out of memory

Posted: Sat Nov 04, 2017 3:17 pm
by MichaelPetch
An observation: 0x07FE154E would still be within 128mb. I'm curious, is paging enabled and if it is have you properly identity mapped the region in question? Have you also enabled the A20 line (A20 gate)?

Re: ACPI RSDT address out of memory

Posted: Sat Nov 04, 2017 4:33 pm
by Oxmose
You are definitely right, my metal calculus was totally wrong! It is in the memory.
Paging is enabled.
A20 gate is untouched, I'm using multiboot to boostrap the kernel on qemu.
Though, if I recall great (I am not at home right now) I may have forgot to map the memory after 48Mb, which might be why I get this error. Thanks for the feedback I'll test that when I'm home.

Re: ACPI RSDT address out of memory

Posted: Sat Nov 04, 2017 4:57 pm
by MichaelPetch
Oxmose wrote:I may have forgot to map the memory after 48Mb, which might be why I get this error.
If you use multiboot compliant loader A20 is enabled so won't be an issue. I didn't know how you booted based on info given. With that being said, the address seems reasonable so I think it almost certainly a paging problem and that the area in question isn't identity mapped.

No problem with giving feedback, you are welcome.

Re: ACPI RSDT address out of memory

Posted: Sat Nov 04, 2017 5:17 pm
by Oxmose
Hey ! Thanks, that was a pagging issue, I started writting the kernel one year ago and completly forgot how I managed pagging back then!
Issue solved! (well, this one at least)