Page 1 of 1
ACPI is only working on some devices
Posted: Wed Nov 18, 2015 4:07 pm
by Altenius
I've been trying to debug my OS for about 12 hours now and have read the wiki page on ACPI thoroughly, but I can only get ACPI to work on qemu and my desktop (It doesn't work on virtualbox or my laptop). My OS is extremely minimal right now, it loads the GDT, switches to protected mode, and immediately tries to set up ACPI. I'm able to find the RSDP table on all the devices but the RSDT table is just junk with virtualbox and my desktop. On virtualbox, which uses ACPI version 3, the XSDT pointer is 0x30 bytes after the RSDT pointer (I haven't checked this on my laptop), which I think makes sense. But when I follow the RSDT pointer it's just junk.
I really don't think there's a problem with my code but this is the code that should initialize ACPI minus the verification to keep it short.
Code: Select all
REVISION_OFFSET equ 15
ACPI_V1_SIZE equ 20
ACPI_V2_SIZE_EX equ 16
SDT_HDR_SIZE equ 36
FADT_SMI_CMD_OFFSET equ SDT_HDR_SIZE + 12
FADT_ACPI_ENABLE_OFFSET equ SDT_HDR_SIZE + 16
init_acpi:
call find_rsdp
test eax, eax
jz acpi_not_successful
mov [RSDP_TABLE_PTR], eax ; this is the RSDP pointer and it's correct on all devices
mov eax, [eax + RSDT_OFFSET] ; eax is set to the RSDT pointer. This is junk on virtualbox and the laptop
acpi_verified:
call rsdt_verify
test eax, eax
jz acpi_not_successful
After switching to protected mode, is there something I need to do before messing with ACPI?
Re: ACPI is only working on some devices
Posted: Wed Nov 18, 2015 4:41 pm
by intx13
From the wiki:
Xsdt Address
64-bit physical address of the XSDT table. If you detect ACPI Version 2.0 you should use this table instead of RSDT even on x86, casting the address to uint32_t.
Unless the ACPI version is 1, you need to use the XSDT pointer, not the RSDT pointer. Are you saying that
neither points to a valid RSDT/XSDT?
Re: ACPI is only working on some devices
Posted: Wed Nov 18, 2015 5:05 pm
by Altenius
intx13 wrote:From the wiki:
Xsdt Address
64-bit physical address of the XSDT table. If you detect ACPI Version 2.0 you should use this table instead of RSDT even on x86, casting the address to uint32_t.
Unless the ACPI version is 1, you need to use the XSDT pointer, not the RSDT pointer. Are you saying that
neither points to a valid RSDT/XSDT?
Neither the RSDT nor the XSDT are valid. The laptop uses ACPI version 1 and it still doesn't work.
Re: ACPI is only working on some devices
Posted: Wed Nov 18, 2015 5:20 pm
by Brendan
Hi,
Altenius wrote:I really don't think there's a problem with my code but this is the code that should initialize ACPI minus the verification to keep it short.
It's possible (as far as we can tell) that your code thinks its found the RSDP when it only found something that looks a bit like an RSDP (e.g. the signature was found but it didn't check the checksum), and that this is the reason the RSDT/XSDT pointers are dodgy.
Now; what do you mean by "initialize ACPI"? There's 2 possibilities here - only finding the ACPI tables and parsing them but not setting up a full AML interpreter and initialising it (which makes sense early during boot); or setting up a full AML interpreter and initialising it (which does not make sense without a lot of other framework for the AML interpreter to rely on).
The thing is, I suspect you mean the latter, and that you're doing something that's extremely complicated and potentially dangerous.
Think of it as 2 modes - "legacy mode" and "ACPI mode". In legacy mode when something involving power management occurs the hardware sends an SMI and the firmware's SMM code handles it (for example, if a temperature sensor detects that the computer is about to melt it sends an SMI and the firmware's SMM code increases fan speed or something to prevent hardware damage). In "ACPI mode" the hardware sends an SCI to the OS, the OS receives the event, and the OS uses an AML interpreter where the firmware's AML code handles the event (for example, if a temperature sensor detects that the computer is about to melt it sends an SCI and the firmware's AML code increases fan speed or something to prevent hardware damage).
To enable "ACPI mode" you send a command to enable it. If you send this command before you've got an AML interpreter (and before you've even got things like memory management, etc that the AML interpreter relies on to function properly); then (e.g.) a temperature sensor detects that the computer is about to melt and sends an SCI, but the OS doesn't have an AML interpreter and can't do anything about it (e.g. increasing fan speed), so the computer catches fire and burns down your house.
Note that it took experienced Intel programmers about 10 years to write ACPICA (an open source AML interpreter) and get it to a usable/reliable state. It's not something a beginner who has only just switched to protected mode should even consider until after they've got "legacy mode" working well.
Cheers,
Brendan
Re: ACPI is only working on some devices
Posted: Thu Nov 19, 2015 9:59 am
by intx13
To follow-up on what Brendan said, you don't have to enable OSPM (OS-directed power management) to access the ACPI tables. They will be in memory regardless. So even if you're not ready to handle all power management responsibilities, you can still refer to the ACPI tables to discover information about the system, such as the number of CPUs.
Can you post the source for your "find_rsdp" function?
Re: ACPI is only working on some devices
Posted: Thu Nov 19, 2015 10:16 am
by SpyderTL
ACPI tables definitely work in VirtualBox. My code finds the root table at 0xe0000, and since the source code for VirtualBox is open source and available online, it took me about 5 minutes to find the line of code responsible for this address.
https://www.virtualbox.org/browser/vbox ... .cpp#L2612
Code: Select all
2612 static uint32_t apicR3FindRsdpSpace(void)
2613 {
2614 return 0xe0000;
2615 }
Re: ACPI is only working on some devices
Posted: Thu Nov 19, 2015 10:17 am
by mallard
Brendan wrote:a temperature sensor detects that the computer is about to melt and sends an SCI, but the OS doesn't have an AML interpreter and can't do anything about it (e.g. increasing fan speed), so the computer catches fire and burns down your house.
Yeah, that won't happen. Failsafe thermal cut-outs are still alive and well in modern hardware. Temperature sensors don't trigger when "the computer is about to melt", they trigger when the hardware is approaching maximum recommended operating temperature. If the system ever does reach an unsafe temperature (which is entirely possible even with fully functioning AML; e.g. a blocked air intake) it will turn itself off without even triggering an NMI.
Re: ACPI is only working on some devices
Posted: Thu Nov 19, 2015 1:58 pm
by Altenius
Brendan wrote:Hi,
Altenius wrote:I really don't think there's a problem with my code but this is the code that should initialize ACPI minus the verification to keep it short.
It's possible (as far as we can tell) that your code thinks its found the RSDP when it only found something that looks a bit like an RSDP (e.g. the signature was found but it didn't check the checksum), and that this is the reason the RSDT/XSDT pointers are dodgy.
Now; what do you mean by "initialize ACPI"? There's 2 possibilities here - only finding the ACPI tables and parsing them but not setting up a full AML interpreter and initialising it (which makes sense early during boot); or setting up a full AML interpreter and initialising it (which does not make sense without a lot of other framework for the AML interpreter to rely on).
The thing is, I suspect you mean the latter, and that you're doing something that's extremely complicated and potentially dangerous.
Think of it as 2 modes - "legacy mode" and "ACPI mode". In legacy mode when something involving power management occurs the hardware sends an SMI and the firmware's SMM code handles it (for example, if a temperature sensor detects that the computer is about to melt it sends an SMI and the firmware's SMM code increases fan speed or something to prevent hardware damage). In "ACPI mode" the hardware sends an SCI to the OS, the OS receives the event, and the OS uses an AML interpreter where the firmware's AML code handles the event (for example, if a temperature sensor detects that the computer is about to melt it sends an SCI and the firmware's AML code increases fan speed or something to prevent hardware damage).
To enable "ACPI mode" you send a command to enable it. If you send this command before you've got an AML interpreter (and before you've even got things like memory management, etc that the AML interpreter relies on to function properly); then (e.g.) a temperature sensor detects that the computer is about to melt and sends an SCI, but the OS doesn't have an AML interpreter and can't do anything about it (e.g. increasing fan speed), so the computer catches fire and burns down your house.
Note that it took experienced Intel programmers about 10 years to write ACPICA (an open source AML interpreter) and get it to a usable/reliable state. It's not something a beginner who has only just switched to protected mode should even consider until after they've got "legacy mode" working well.
Cheers,
Brendan
All I'm trying to do right now is access the FADT table so I check if a PS/2 Controller exists. I shouldn't have said initialise.
intx13 wrote:To follow-up on what Brendan said, you don't have to enable OSPM (OS-directed power management) to access the ACPI tables. They will be in memory regardless. So even if you're not ready to handle all power management responsibilities, you can still refer to the ACPI tables to discover information about the system, such as the number of CPUs.
Can you post the source for your "find_rsdp" function?
It finds it and verified the checksum. The OEMID is also "VBOX" in virtualbox so I'm 100% sure the RSDP table is correct.
SpyderTL wrote:ACPI tables definitely work in VirtualBox. My code finds the root table at 0xe0000, and since the source code for VirtualBox is open source and available online, it took me about 5 minutes to find the line of code responsible for this address.
https://www.virtualbox.org/browser/vbox ... .cpp#L2612
Code: Select all
2612 static uint32_t apicR3FindRsdpSpace(void)
2613 {
2614 return 0xe0000;
2615 }
My code does get 0xE0000 as the RSDP table, it's the RSDT table that I can't find.
Re: ACPI is only working on some devices
Posted: Thu Nov 19, 2015 2:09 pm
by intx13
In that case, can you post the entirety of the RSDP as you see it in memory?
Re: ACPI is only working on some devices
Posted: Thu Nov 19, 2015 2:59 pm
by Altenius
intx13 wrote:In that case, can you post the entirety of the RSDP as you see it in memory?
This is the RSDP for virtualbox
Code: Select all
52 53 44 20 50 54 52 20 5A 56 42 4F 58 20 20 02 00 00 FF 07 24 00 00 00 30 00 FF 07 00 00 00 00 A6 00 00 00
Which is:
Signature: "RSD PTR "
Checksum: 0x5A
OEMID: "VBOX "
Revision: 0x02
RsdtAddress: 0x07FF0000
Length: 0x24
XsdtAddress: 0x0000000007FF0030
ExtendedChecksum: 0xA6
Reserved: 0x000000
Edit: This is the memory at the RSDT address, 0x07FF0000
Code: Select all
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
The XSDT address is the same
Re: ACPI is only working on some devices
Posted: Thu Nov 19, 2015 3:15 pm
by SpyderTL
The RDST/XDST changes depending on how much memory you have allocated to your VM.
At 32MB, they should be at 1FF0000/1FF0030, respectively.
At 256MB, they should be at FFF0000/FFF0030.
There's a small chance that other settings may affect these addresses, but you should be getting something in this neighborhood.
EDIT: Assuming there is nothing wrong with your code that dumps the memory at those addresses, I would create a whole new Virtual Machine in VirtualBox, and try it using that machine, instead. I've seen that fix these types of issues before.
EDIT 2: I'm assuming you have the A20 line enabled...
Re: ACPI is only working on some devices
Posted: Thu Nov 19, 2015 3:19 pm
by Altenius
SpyderTL wrote:The RDST/XDST changes depending on how much memory you have allocated to your VM.
At 32MB, they should be at 1FF0000/1FF0030, respectively.
At 256MB, they should be at FFF0000/FFF0030.
There's a small chance that other settings may affect these addresses, but you should be getting something in this neighborhood.
I allocated 256MB and it is FFF0000/FFF0030, but when I read those memory addresses they're still 0's
Re: ACPI is only working on some devices
Posted: Thu Nov 19, 2015 3:36 pm
by Altenius
SpyderTL wrote:EDIT 2: I'm assuming you have the A20 line enabled...
That solved it... How was I supposed to know about that
.
Thank you so much! Sorry for wasting your time with my dumbness
.
Edit: I see a mention of the A20 line in the bare bones tutorial now.... which I never read. ugh
Re: ACPI is only working on some devices
Posted: Thu Nov 19, 2015 3:47 pm
by intx13
Altenius wrote:SpyderTL wrote:EDIT 2: I'm assuming you have the A20 line enabled...
That solved it... How was I supposed to know about that
.
Thank you so much! Sorry for wasting your time with my dumbness
.
Edit: I see a mention of the A20 line in the bare bones tutorial now.... which I never read. ugh
Interesting, I'm surprised that VirtualBox and your laptop both start with the A20 line disabled! Is the laptop rather old?
Re: ACPI is only working on some devices
Posted: Thu Nov 19, 2015 3:54 pm
by Altenius
intx13 wrote:Altenius wrote:SpyderTL wrote:EDIT 2: I'm assuming you have the A20 line enabled...
That solved it... How was I supposed to know about that
.
Thank you so much! Sorry for wasting your time with my dumbness
.
Edit: I see a mention of the A20 line in the bare bones tutorial now.... which I never read. ugh
Interesting, I'm surprised that VirtualBox and your laptop both start with the A20 line disabled! Is the laptop rather old?
It's about 9 years old I think. I'm just using it to mess with os dev.