Integer assignment yields unexpected results in ACPICA code

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
yvrv
Posts: 4
Joined: Mon Oct 26, 2020 12:33 pm

Integer assignment yields unexpected results in ACPICA code

Post by yvrv »

So i've been porting ACPICA recently and up to this moment everything was going pretty well. A few tweaks here and there, a bit of time spent reading documentation - nothing unusual. However, what i saw next made me wonder for a few days. I never encountered anything like that.

There is this perfectly normal integer assignment at tables/tbutils.c that just doesn't work. I think it's better to just show my GDB session logs.
(i use qemu+gdb as described in: https://wiki.osdev.org/Kernel_Debugging ... _with_QEMU)

Code: Select all

(gdb) set disassemble-next-line on
(gdb) set disassembly-flavor intel
(gdb) where
#0  AcpiTbParseRootTable (RsdpAddress=1006368) at acpica/tables/tbutils.c:432
#1  0xc004a83a in AcpiInitializeTables (InitialTableArray=0x0, InitialTableCount=16, AllowResize=0 '\000')
    at acpica/tables/tbxface.c:268
#2  0xc0002fbb in acpi_do_sth () at kernel/kmain.c:42
#3  0xc0003115 in kmain (mb_info=0x9500, mb_magic=732803074) at kernel/kmain.c:80
#4  0xc0002885 in start_hhalf () at kernel/start.s:41
(gdb) f
#0  AcpiTbParseRootTable (RsdpAddress=1006368) at acpica/tables/tbutils.c:432
432             Address = (ACPI_PHYSICAL_ADDRESS) Rsdp->RsdtPhysicalAddress;
=> 0xc004aaf9 <AcpiTbParseRootTable+163>:       8b 45 e0        mov    eax,DWORD PTR [ebp-0x20]
   0xc004aafc <AcpiTbParseRootTable+166>:       8b 40 10        mov    eax,DWORD PTR [eax+0x10]
(gdb) p sizeof(Address)
$1 = 8
(gdb) p sizeof(Rsdp->RsdtPhysicalAddress)
$2 = 4
(gdb) p &Address
$3 = (ACPI_PHYSICAL_ADDRESS *) 0xc003ffc8
(gdb) p &Rsdp->RsdtPhysicalAddress 
$4 = (UINT32 *) 0xc0054b30
(gdb) p Rsdp
$5 = (ACPI_TABLE_RSDP *) 0xc0054b20
(gdb) p/x Rsdp->RsdtPhysicalAddress 
$6 = 0x7fe18fe
(gdb) i r ebp
ebp            0xc003ffe0          0xc003ffe0
(gdb) i r eax
eax            0x0                 0
(gdb) si
0xc004aafc      432             Address = (ACPI_PHYSICAL_ADDRESS) Rsdp->RsdtPhysicalAddress;
   0xc004aaf9 <AcpiTbParseRootTable+163>:       8b 45 e0        mov    eax,DWORD PTR [ebp-0x20]
=> 0xc004aafc <AcpiTbParseRootTable+166>:       8b 40 10        mov    eax,DWORD PTR [eax+0x10]
(gdb) i r eax
eax            0xc0054b20          -1073394912
(gdb) si
432             Address = (ACPI_PHYSICAL_ADDRESS) Rsdp->RsdtPhysicalAddress;
=> 0xc004aaff <AcpiTbParseRootTable+169>:       89 45 e8        mov    DWORD PTR [ebp-0x18],eax
   0xc004ab02 <AcpiTbParseRootTable+172>:       c7 45 ec 00 00 00 00    mov    DWORD PTR [ebp-0x14],0x0
(gdb) i r eax
eax            0x0                 0
(gdb) si
0xc004ab02      432             Address = (ACPI_PHYSICAL_ADDRESS) Rsdp->RsdtPhysicalAddress;
   0xc004aaff <AcpiTbParseRootTable+169>:       89 45 e8        mov    DWORD PTR [ebp-0x18],eax
=> 0xc004ab02 <AcpiTbParseRootTable+172>:       c7 45 ec 00 00 00 00    mov    DWORD PTR [ebp-0x14],0x0
(gdb) si
433             TableEntrySize = ACPI_RSDT_ENTRY_SIZE;
=> 0xc004ab09 <AcpiTbParseRootTable+179>:       c7 45 f4 04 00 00 00    mov    DWORD PTR [ebp-0xc],0x4
(gdb) p/x Address 
$8 = 0x0
You can clearly see here when i start "si"-ing, the instruction that is evidently supposed to place 0x7fe18fe to eax, somehow places 0 instead.

I tried:
- using 32-bit ACPI_PHYSICAL_ADDRESS by defining ACPI_32BIT_PHYSICAL_ADDRESS
- updating my cross-compiler
- various hack combinations, like using memcpy instead
- disabling caching of virtual memory that RSDP gets mapped to
Nothing works.

Also i tried using kprintf to output values before and after assignment. It gaves the following output both on qemu and real hardware, with 32-bit or 64-bit ACPI_PHYSICAL_ADDRESS:

Code: Select all

&Rsdp->RsdtPhysicalAddress == 0xc0054b30
before assignment: Rsdp->RsdtPhysicalAddress == 0x0
after assignment: Address == 0x0; Rsdp->RsdtPhysicalAddress == 0x0
RSDP is located and verified correctly in the previous step (it uses AcpiFindRootPointer() to do so). I used kprintf() to output Rsdp->RsdtPhysicalAddress at that point and all works as expected.
RSDP memory region then gets unmapped and mapped at AcpiTbParseRootTable() again. And then it's already like that.

I have no assumptions about what might cause this and where to look for any hints. Any help would be much appreciated.
Here is the link to the file in ACPICA github repo where this assignment is located: https://github.com/acpica/acpica/blob/m ... /tbutils.c, line 432.
Octocontrabass
Member
Member
Posts: 5568
Joined: Mon Mar 25, 2013 7:01 pm

Re: Integer assignment yields unexpected results in ACPICA c

Post by Octocontrabass »

Have you checked your segment registers?
Gigasoft
Member
Member
Posts: 856
Joined: Sat Nov 21, 2009 5:11 pm

Re: Integer assignment yields unexpected results in ACPICA c

Post by Gigasoft »

TLB not flushed?
yvrv
Posts: 4
Joined: Mon Oct 26, 2020 12:33 pm

Re: Integer assignment yields unexpected results in ACPICA c

Post by yvrv »

Octocontrabass wrote:Have you checked your segment registers?
Yup. My segment registers are definitely set up properly.
Gigasoft wrote:TLB not flushed?
I tried placing asm volatile("wbinvd") both before and after RSDP memory mapping. Nothing.
Octocontrabass
Member
Member
Posts: 5568
Joined: Mon Mar 25, 2013 7:01 pm

Re: Integer assignment yields unexpected results in ACPICA c

Post by Octocontrabass »

yvrv wrote:Yup. My segment registers are definitely set up properly.
Prove it: use "info registers" in the QEMU monitor to dump them.
nullplan
Member
Member
Posts: 1790
Joined: Wed Aug 30, 2017 8:24 am

Re: Integer assignment yields unexpected results in ACPICA c

Post by nullplan »

Is the memory accessible to any other processes in the system at that point? Could someone else be overwriting the memory? What happens if you write there using the debugger?
Carpe diem!
yvrv
Posts: 4
Joined: Mon Oct 26, 2020 12:33 pm

Re: Integer assignment yields unexpected results in ACPICA c

Post by yvrv »

Octocontrabass wrote: Prove it: use "info registers" in the QEMU monitor to dump them.

Code: Select all

(gdb) i r
...
cs             0x8                 8
ss             0x10                16
ds             0x10                16
es             0x10                16
fs             0x10                16
gs             0x10                16
...
(gdb) x/8xb &gdt_table[0]
0xc003e020 <gdt_table>:         0x00    0x00    0x00    0x00    0x00    0x00    0x00    0x00
(gdb) x/8xb &gdt_table[1]
0xc003e028 <gdt_table+8>:       0xff    0xff    0x00    0x00    0x00    0x9a    0xcf    0x00
(gdb) x/8xb &gdt_table[2]
0xc003e030 <gdt_table+16>:      0xff    0xff    0x00    0x00    0x00    0x93    0xcf    0x00
Here it is. It seems OK to me, but maybe there are some problems here that i can't see, who knows.
nullplan wrote: Is the memory accessible to any other processes in the system at that point? Could someone else be overwriting the memory?
No. Right now, my OS is single-processor, monotasking system. Actually, it's rather no-tasking system, since i can't execute userspace code yet.
nullplan wrote: What happens if you write there using the debugger?
Now that is an interesting suggestion. I tried placing memset(Rsdp, 0xAD, sizeof(*Rsdp)) right before all the kprintf() calls. And somehow, it magically fixed everything - Rsdp->RsdtPhysicalAddress is back to what it should have been.
However, after that, at line 444 ACPICA maps RSDT. The same problem: Table->Length is 52 in my debugger, but 0 in the actual runtime. And memset() hack doesn't work this time.
I have no idea what's happening here.
Gigasoft
Member
Member
Posts: 856
Joined: Sat Nov 21, 2009 5:11 pm

Re: Integer assignment yields unexpected results in ACPICA c

Post by Gigasoft »

yvrv wrote:I tried placing asm volatile("wbinvd") both before and after RSDP memory mapping. Nothing.
Wrong instruction. Use mov to cr3 to flush the entire TLB, or invlpg for individual pages.
8infy
Member
Member
Posts: 185
Joined: Sun Apr 05, 2020 1:01 pm

Re: Integer assignment yields unexpected results in ACPICA c

Post by 8infy »

Gigasoft wrote:
yvrv wrote:I tried placing asm volatile("wbinvd") both before and after RSDP memory mapping. Nothing.
Wrong instruction. Use mov to cr3 to flush the entire TLB, or invlpg for individual pages.
> No. Right now, my OS is single-processor, monotasking system. Actually, it's rather no-tasking system, since i can't execute userspace code yet.

Unless he never calls invlpg it cannot be a problem.
yvrv
Posts: 4
Joined: Mon Oct 26, 2020 12:33 pm

Re: Integer assignment yields unexpected results in ACPICA c

Post by yvrv »

Gigasoft wrote:Wrong instruction. Use mov to cr3 to flush the entire TLB, or invlpg for individual pages.
8infy wrote:Unless he never calls invlpg it cannot be a problem.
Yeah. Turns out i didn't know i should use invlpg in munmap() function. Now that i do, everything works as expected. Thank you, 8infy, Gigasoft, and other kind gentlemen who have spent their time helping me.

Now excuse me as i go read intel's manual on TLB.
Post Reply