#uACPI - a portable and easy-to-integrate ACPI implementation
1 messages · Page 30 of 1
yeah LAI didnt survive the test very well
although some did pass
SUMMARY: AddressSanitizer: 5573531 byte(s) leaked in 30885 allocation(s). ☠️
can you send that, maybe it works better on qacpi too?
thanks
yeah
how did qacpi do
aml debug: 64-bit mode
aml debug: Release of parent ACPICA code 0x2
aml debug: Release of ASLTS test suite 0x16
aml debug: Settings of ASLTS test suite 0x5
aml debug: TEST (functional), Buffer Field
aml debug: m211 test started
aml debug: TEST: m211, Create 1-Bit Buffer Field:
aml debug: :CTST:functional:bfield:m211:PASS:
aml debug: m213 test started
aml debug: TEST: m213, Create 8-Bit Buffer Field:
aml debug: :CTST:functional:bfield:m213:PASS:
aml debug: m215 test started
aml debug: TEST: m215, Create 16-Bit Buffer Field:
0
aml debug: 64-bit mode
aml debug: Release of parent ACPICA code 0x2
aml debug: Release of ASLTS test suite 0x16
aml debug: Settings of ASLTS test suite 0x5
aml debug: TEST (functional), Buffer Field
aml debug: :CTST:functional:bfield:215:PASS:
aml debug: m211 test started
aml debug: TEST: m211, Create 1-Bit Buffer Field:
aml debug: :CTST:functional:bfield:m211:PASS:
aml debug: m213 test started
aml debug: TEST: m213, Create 8-Bit Buffer Field:
aml debug: :CTST:functional:bfield:m213:PASS:
aml debug: m215 test started
aml debug: TEST: m215, Create 16-Bit Buffer Field:
aml debug: :CTST:functional:bfield:m215:PASS:
aml debug: Run time (in seconds): 0x
aml debug: The total number of exceptions handled: 0x
aml debug: ========= ROOT METHODS SUMMARY (max 600):
aml debug: :STST:functional:bfield:m211:PASS:
aml debug: :STST:functional:bfield:m213:PASS:
aml debug: :STST:functional:bfield:215:PASS:
aml debug: :STST:functional:bfield:m211:PASS:
aml debug: :STST:functional:bfield:m213:PASS:
aml debug: :STST:functional:bfield:m215:PASS:
aml debug: ========= END.
aml debug: TEST ACPICA: 64-bit : PASS
back when i was just working on field read code (like a year ago) i was having some skill issues with edge cases in this case so tdb helped me with this bit_copy function
nice!
lol u log it the same way as lai
just with a space
also:
[uACPI][TRACE] [AML DEBUG] String => "========= ROOT METHODS SUMMARY (max 600):"
[uACPI][TRACE] [AML DEBUG] String => ":STST:functional:bfield:m211:PASS:"
[uACPI][TRACE] [AML DEBUG] String => ":STST:functional:bfield:m213:PASS:"
[uACPI][TRACE] [AML DEBUG] String => ":STST:functional:bfield:m215:PASS:"
[uACPI][TRACE] [AML DEBUG] String => ":STST:functional:bfield:m217:PASS:"
[uACPI][TRACE] [AML DEBUG] String => ":STST:functional:bfield:m219:PASS:"
[uACPI][TRACE] [AML DEBUG] String => ":STST:functional:bfield:m21d:PASS:"
[uACPI][TRACE] [AML DEBUG] String => "========= END."
U lost the m somewhere
and the last thing should be 21d i think
actually i might know why
did u run MAIN?
it already does it while loading the table to work in LAI
yes
if i run the body + MAIN i get this
[uACPI][TRACE] [AML DEBUG] String => "========= ROOT METHODS SUMMARY (max 600):"
[uACPI][TRACE] [AML DEBUG] String => ":STST:functional:bfield:m211:PASS:"
[uACPI][TRACE] [AML DEBUG] String => ":STST:functional:bfield:m213:PASS:"
[uACPI][TRACE] [AML DEBUG] String => ":STST:functional:bfield:m215:PASS:"
[uACPI][TRACE] [AML DEBUG] String => ":STST:functional:bfield:m217:PASS:"
[uACPI][TRACE] [AML DEBUG] String => ":STST:functional:bfield:m219:PASS:"
[uACPI][TRACE] [AML DEBUG] String => ":STST:functional:bfield:m21d:PASS:"
[uACPI][TRACE] [AML DEBUG] String => ":STST:functional:bfield:"
[uACPI][TRACE] [AML DEBUG] String => ":STST:functional:bfield:m211:PASS:"
[uACPI][TRACE] [AML DEBUG] String => ":STST:functional:bfield:m213:PASS:"
[uACPI][TRACE] [AML DEBUG] String => ":STST:functional:bfield:m215:PASS:"
[uACPI][TRACE] [AML DEBUG] String => ":STST:functional:bfield:m217:PASS:"
[uACPI][TRACE] [AML DEBUG] String => ":STST:functional:bfield:m219:PASS:"
[uACPI][TRACE] [AML DEBUG] String => ":STST:functional:bfield:m21d:PASS:"
[uACPI][TRACE] [AML DEBUG] String => "========= END."
somehow your array gets truncated or something
yeah idk
It prints these from a huge package
well qacpi doesn't log the type and lai logs it as a sexp of (type value)
a sexp? 
s expression
also about the arithmetic test I am not sure if its because of the data region or do I actually have that many broken things lol
did I hear lai
interesting integers ```
aml debug: **** Expected Result: 0xp004, (p004)
aml debug: **** Actual Result : 0x0x7, (7)
I can patch it for u
0xp004 and 0x0x7
yes idk what is that lol
or well the second one I can kinda know why
there is probably 0x as a part of the string and then it prints the integer after which itself adds 0x
it creates a lot of temporary nodes
i think those are leaked
And some strings are leaked as well yeah
☠️
I found two out of bounds shifts that it did and after adding checks for those I get aml debug: TEST ACPICA: 64-bit : FAIL : Errors # 0xJ, Failed tests # 0x1 and the failing one is FindSetLeftBit
Ah yes 0xJ
the new hex number
Concatenate (Local0, "FAIL:Errors # ", Local2) @mortal yoke your concatenate might be broken i guess?
or wait
Concatenate (Local0, "FAIL:Errors # ", Local2)
B000 = Local7
Concatenate (Local2, B000, Local0)
Concatenate (Local0, ":", Local1)
ERR6++
yeah
i guess your concatenate is not feeling welll
i remember the bit finding ops have slightly weird semantics
but should be simple to fix
uacpi_u8 uacpi_bit_scan_forward(uacpi_u64 value)
{
#ifdef _MSC_VER
unsigned char ret;
unsigned long index;
#ifdef _WIN64
ret = _BitScanForward64(&index, value);
if (ret == 0)
return 0;
return (uacpi_u8)index + 1;
#else
ret = _BitScanForward(&index, value);
if (ret == 0) {
ret = _BitScanForward(&index, value >> 32);
if (ret == 0)
return 0;
return (uacpi_u8)index + 33;
}
return (uacpi_u8)index + 1;
#endif
#else
return __builtin_ffsll(value);
#endif
}
i think i return this value raw
gnu on top their builtin maps onto aml directly 
lmao
gnu builtins designed specifically for aml
the backward one is slightly more ugly:
if (value == 0)
return 0;
return 64 - __builtin_clzll(value);
__builtin_ctzll?
perhaps, i dont remember what any of those do
iirc that compiles to bsf
why the hell is there a rep there lmao
don't think it does anything
probably just padding
https://godbolt.org/z/a9ncvWYPK
at -O1 it goes away
ah
oh this one is actually interesting, I think yeah it actually hangs because the SMI handler gets some bogus data from lai
idk if a spurious read can cause that tho
hmm i thought it was just due to the extra read from the smi register
usually the way this works is theres some NVS region that stores the SMM opcode + args
and then it just invokes SMI
but who knows how this specific one works
I don't understand how is that different from what I do which is basically that done manually (but somehow the result is different and idk why) ```c
result = 0;
for (int i = int_size * 8; i > 0; --i) {
if (int_value & uint64_t {1} << (i - 1)) {
result = (int_size * 8) - i + 1;
break;
}
}
maybe its because u dont do parens
like i have no idea what the order here is
& has less precedence than shifts
i guess if ur confident about that
dont see anything immediately wrong ig
oh right its the bit location, I though it was supposed to be the other way around (so if the msb would be set it would return 1 and if lsb then 64)
also the concat thing is because of ascii detection
wdym?
it tries to convert the rhs integer to a string as the lhs is a string using the same semantics as Store basically
the concat does have its own special to string impl but I only use it if the one with the store semantics fails, maybe I should just always use it
💀 what are you trying to change?
nvm it was the dumbest thing
i have like 99999 changes everywhere to support these special fields
ah
some of them also support direct read besides wtr
so i have to support propagating the response buffer from a normal read as well
anyway its just hoisting crap from one place to another everywhere
and also new structs for op attach and r/w
what are these special fields, of curiosity?
IPMI, SMBus, GenericSerialBus, FFixedHW, FCC, GeneralPurposeIO (less annoying to support), PCC (Even less annoying)
GenericSerialBus is the most annoying of all
not only do u have to propagate the smbus protocol, field attribute, i2c controller connection, but u also have to allocate correctly sized buffers for the response and then propagate back to aml
What's funny is SMBus is the address space to use for SMBus, but there isnt a single usage in any AML blobs nor does linux support it at all
They use GenericSerialBus for SMBus instead for whatever reason
❯ grep -rni ', GenericSerialBus' -l | wc -l
16
only 16 out of 500 blobs have it
thats why its generally a very niche thing
only needed for tablets and SoC
e.g. microsoft surface
for IPMI i have only one blob
❯ grep -rni ', GeneralPurposeIO' -l | wc -l
11
even less for gpio
❯ grep -rni ', SMBus' -l | wc -l
0
❯ grep -rni ', FCC' -l | wc -l
4
❯ grep -rni ', FFixedHW' -l | wc -l
0
❯ grep -rni ', IPMI' -l | wc -l
1
not much to work with
nvm, for FCC there's also 0, my expresion was just wrong
mhm
Waaaait
❯ grep -rni ', PlatformRtMechanism,'
Server/Intel/ArcherCity/ArcherCity/356135E81941:1842143: OperationRegion (PRMR, PlatformRtMechanism, 0x00, 0x01)
thats what its called apparently lmao
Device (PRMT)
{
Name (_HID, "80860223") // _HID: Hardware ID
Name (_CID, "80860223") // _CID: Compatible ID
Name (_DDN, "PRM Test Device") // _DDN: DOS Device Name
OperationRegion (PRMR, PlatformRtMechanism, 0x00, 0x01)
Field (PRMR, BufferAcc, NoLock, Preserve)
{
PRMF, 8
}
Method (RUNS, 1, NotSerialized)
{
Local0 = Buffer (0x1A) {}
CreateByteField (Local0, 0x00, PSTA)
CreateQWordField (Local0, 0x01, USTA)
CreateByteField (Local0, 0x09, CMD)
CreateField (Local0, 0x50, 0x80, GUID)
CMD = 0x00
GUID = Arg0
Local0 = PRMF = Local0
Return (PSTA) /* \_SB_.PRMT.RUNS.PSTA */
}
Method (LCKH, 1, NotSerialized)
{
Local0 = Buffer (0x1A) {}
CreateByteField (Local0, 0x00, STAT)
CreateByteField (Local0, 0x09, CMD)
CreateField (Local0, 0x50, 0x80, GUID)
CMD = 0x01
GUID = Arg0
Local0 = PRMF = Local0
Return (STAT) /* \_SB_.PRMT.LCKH.STAT */
}
Method (ULCK, 1, NotSerialized)
{
Local0 = Buffer (0x1A) {}
CreateByteField (Local0, 0x00, STAT)
CreateByteField (Local0, 0x09, CMD)
CreateField (Local0, 0x50, 0x80, GUID)
CMD = 0x02
GUID = Arg0
Local0 = PRMF = Local0
Return (STAT) /* \_SB_.PRMT.ULCK.STAT */
}
Method (_STA, 0, NotSerialized) // _STA: Status
{
Return (0x0B)
}
}
thats pretty cool
@mortal yoke see what it does with that PRMF field?
thats basically how you're supposed to do it from aml
and that field bit width u just ignore completely because why not
they dont even have to specify anything sane there
just 8 usually
if there are multiple fields do they all work the same too?
some protocols care about the absolute offset of the field relative to opregion base as that indicates some sort of command value
some protocols dont because they have a AccessAs + Connection before every field
like GPIO
OperationRegion (GPOP, GeneralPurposeIo, Zero, 0x0C)
Field (GPOP, ByteAcc, NoLock, Preserve)
{
Connection (
GpioIo (Exclusive, PullDefault, 0x0000, 0x0000, IoRestrictionOutputOnly,
"\\_SB.GPO1", 0x00, ResourceConsumer, ,
)
{ // Pin list
0x000F
}
),
BST5, 1,
Connection (
GpioIo (Exclusive, PullDefault, 0x0000, 0x0000, IoRestrictionOutputOnly,
"\\_SB.GPO1", 0x00, ResourceConsumer, ,
)
{ // Pin list
0x001A
}
),
TCD3, 1
}
example
interesting
here the offset of the field means absolutely nothing
because a Connection resets it
do you also expose the connection somehow? or is it just used internally
yup u do absolutely
the handler must be able to parse the resources from it
to know which i2c to talk to
typedef struct uacpi_region_gpio_rw_data
{
void *handler_context;
void *region_context;
uacpi_data_view connection;
uacpi_u32 pin_offset;
uacpi_u32 num_pins;
uacpi_u64 value;
} uacpi_region_gpio_rw_data;
this is what uACPI is going to provide for GPIO
pin offset is basically offset since previous Connection
num_pins is the bit width of the field
then u would use uacpi_get_resources_from_buffer to parse the connnection attribute
from that u know which i2c and which pin from that i2c
or which gpio in this case
GenericSerialBus is similar idea to this but way more complex
since there are a lot of SMBus protocols with AccessAs
Name (XPMC, ResourceTemplate ()
{
I2cSerialBusV2 (0x0034, ControllerInitiated, 0x00061A80,
AddressingMode7Bit, "\\_SB.I2C5",
0x00, ResourceConsumer, , Exclusive,
)
})
OperationRegion (XSCG, GenericSerialBus, Zero, 0x0100)
Field (XSCG, BufferAcc, NoLock, Preserve)
{
Connection (XPMC),
AccessAs (BufferAcc, AttribByte),
XP00, 8,
XP01, 8
}
Field (XSCG, BufferAcc, NoLock, Preserve)
{
Connection (XPMC),
Offset (0xB9),
AccessAs (BufferAcc, AttribByte),
XPB9, 8
}
Example for SMBus
AttribByte means this
there's like 10 types u must handle
lol
This is basically all windows provides too
Plus some extra windows specific stuff
nice
I think I finally fixed Load leaks in qacpi, it was mostly just me being dumb and doing ```cpp
if (method_frame.node_link) {
method_frame.node_link->link = context->all_nodes;
context->all_nodes = method_frame.node_link;
}
(method_frame.node_link starts a singly linked list and its link might not be null if its part of a larger chain so the other nodes would just be lost in the void)
what does this do?
oh those things
what's PlatformRtMechanism?
Elixir Cross Referencer - source code of Linux v6.13-rc3: drivers/acpi/prmt.c
this thing
AML talking to EFI firmware or something idk
lol
adds namespace nodes created inside Load to the context's node list that is used to keep track of all global nodes that are supposed to be deleted when the context is destroyed (originally they are added to the method frame's list and destroyed from there if the Load fails)
2 firmware teams couldn't talk to eachother so instead they invented a new mechanism for the firmware to talk to itself
lmao
basically
ohhh
so u support Load and LoadTable now?
Load yes but LoadTable no because I still haven't implemented the table api
though as LoadTable is basically exactly the same as Load but with data from the table api it should just work
yall made me curious and turns out my laptop only uses systemio, systemmemory, and a single instance of PCI_Config opregions
this is special niche stuff for a reason ig lol
ah ok
anything actually use the pci bar opregion?
thats the one im most unsure how id manage to implement so im curious
funny enough no
its not supported by linux nor used by anyone
(i should REALLY get to finishing off my new memory manager so i can do more device drivers and work more on uacpi zig bindings tbh)
oh interesting
wdym?
like isnt it just map(read_bar(), ...)
you can have io port bars too i think and overall im not sure how i plan to handle BAR management in general yet
unless i can rely on firmware setting up the BARs for me in which case yeah its probably just that
but "rely on firmware" is the sort of thing that sounds like a bad idea imo lol
yeah u have to have an abstraction layer for this
so that bar type isnt exposed to each user
since its not relevant
u just want like io_map io_read io_write etc
yeah
and io_read would dispatch to in/out or mmio
ive got that for pci config already and it works great. even lets me easily add some possible efficiency gains with the map_pci things
nice
i literally just allocate the structure that im already using for holding pci config access info for my drivers and my pci config read/write functions take that struct and the register offset its nice. im debating giving that a dedicated pool once i get allocation working more too
yeah thats pretty cool
im assuming issue 75 is the to-do for 1.0 btw?
its outdated but yeah
See if we need special handling for SMBus and similar address spaces basically im doing this
the other two are not important
Can confirm


lol
i think linux tries to claim the existing bar address (aka sanity check it and allocate internally)
if that fails it assigns a new address
mhm
but most firmware should be sane enough to do bar allocation correctly
cool
problems start appearing when u have devices with huge bars
not all firmware is ready for those
Does Windows implement all ACPI features?
(out of curiosity)
No idea, this isnt used by any firmware so I imagine its because of nt not supporting it
Maybe darkfire knows if windows supports PciBarTarget
I don’t think it is
Windows pci hasn’t gotten a lot of love in recent years
I haven’t investigated win11 pci though
How should an os do bar allocations? I haven't seen a mention about that in the pcie 5.0 specs (I searched for something else so I could have missed it).
So you know how currently random drivers are implemented in smm and acpi calls them? Well to avoid that now instead the firmware will give you PE files you will map yourself and run yourself (along side the MMIO regions they need), and a way for them to communicate with acpi
Funnily enough one of the features here is to allow line updates of these modules
Just by allocating arbitrary addresses outside of the reserved e820 ranges as far as I understand
Or rather, addresses outside of all ranges mentioned in e820
Depends a bit on controller, in x86 it can be pretty much anywhere not in ram
Ye
On alot of arm boards they have a specific decode range you can allocate from
Linux does reallocate bars on x86 for sriov
That's not true (that any address outside the e820/uefi map works on x86)
You should look at _CRS and allocate within the address regions
at crs of what?
The root bridge
really?
Yes, of course. You can't just allocate random addresses to the root bridge
And if the BARs is not directly behind the root bridge, you need to take the address windows of intermediate bridges into account as well
But these are in PCI config space, not in ACPI
ill double check that
Name (_CRS, ResourceTemplate () // _CRS: Current Resource Settings
{
WordBusNumber (ResourceProducer, MinFixed, MaxFixed, PosDecode,
0x0000, // Granularity
0x0000, // Range Minimum
0x00FF, // Range Maximum
0x0000, // Translation Offset
0x0100, // Length
,, )
IO (Decode16,
0x0CF8, // Range Minimum
0x0CF8, // Range Maximum
0x01, // Alignment
0x08, // Length
)
WordIO (ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange,
0x0000, // Granularity
0x0000, // Range Minimum
0x0CF7, // Range Maximum
0x0000, // Translation Offset
0x0CF8, // Length
,, , TypeStatic, DenseTranslation)
WordIO (ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange,
0x0000, // Granularity
0x0D00, // Range Minimum
0xFFFF, // Range Maximum
0x0000, // Translation Offset
0xF300, // Length
,, , TypeStatic, DenseTranslation)
DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, Cacheable, ReadWrite,
0x00000000, // Granularity
0x000A0000, // Range Minimum
0x000BFFFF, // Range Maximum
0x00000000, // Translation Offset
0x00020000, // Length
,, , AddressRangeMemory, TypeStatic)
DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, NonCacheable, ReadWrite,
0x00000000, // Granularity
0x08000000, // Range Minimum
0xAFFFFFFF, // Range Maximum
0x00000000, // Translation Offset
0xA8000000, // Length
,, , AddressRangeMemory, TypeStatic)
DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, NonCacheable, ReadWrite,
0x00000000, // Granularity
0xC0000000, // Range Minimum
0xFEBFFFFF, // Range Maximum
0x00000000, // Translation Offset
0x3EC00000, // Length
,, , AddressRangeMemory, TypeStatic)
QWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, Cacheable, ReadWrite,
0x0000000000000000, // Granularity
0x0000000100000000, // Range Minimum
0x00000008FFFFFFFF, // Range Maximum
0x0000000000000000, // Translation Offset
0x0000000800000000, // Length
,, , AddressRangeMemory, TypeStatic)
})
this is what they have on qemu
@flat badge does this mean u can place BARs in any of these?
It even specifies the allowed bus number range
pretty interesting
TIL
yes
so if u dont have an aml interpreter u cant even know where to allocate bars?
Yes. Unless you're the firmware I guess
or if you have a chipset driver that knows the allowed ranges
You need to have a bar allocator if you want to support USB 4/Thunderbolt, right?
There are situations where not BARs are allocated
Iirc omvf for example only initializes the first segment
And for arm/riscv you also need BAR allocation
wtf are sufrace laptops checking for 
microsoft had to add quirk handling to their own laptop
ADBG ("Let\'s bring TBT RPs out of D3Cold")
ADBG ("Drop TG0N due to it is already exit D3 cold")
indian outsource firmware
In QEMU ovmf allocated bards for me on RISC-V
@winter orbit btw I just realized, by default uACPI will respond true to _OSI queries up to Windows 11 22H2
u probably want to disable all that ReactOS doesnt support
lol
fyi its in the osi.h header
it should probably work as is, but idk if react os has an ec driver for example
which firmware might assume unconditional prescense of
etc
uacpi_latest_queried_vendor_interface would probably be funny to make try and just read the windows version from ntoskrnl properly
some kind of overload
i had to make one to boot win10
it's shoved inside acpi.sys
yeah
lmao
uACPI, the new standard implementation™️
yes, but uefi is not usable on all (most?) risc-v boards
btw, does anyone know of good cheap risc-v sbcs?
Which hardware does it have?
Like USB is XHCI and not prorietary weirdness like raspberry pi
?
oof
Looks like normal EHCI 
yeah i think it's xhci in general but it's wrapped into some priorietary device (the dwc3-spacemit thing)
the linux kernel patches to make this work are open source, but i haven't looked at them
for the NIC it doesn't look bad, no idea how it is for the usb
groundwork for esoteric field support done
A few more regions left, but they reuse the bulk of logic from IPMI
well and also the bulk from GPIO
IPMI?
The Intelligent Platform Management Interface (IPMI) is a set of computer interface specifications for an autonomous computer subsystem that provides management and monitoring capabilities independently of the host system's CPU, firmware (BIOS or UEFI) and operating system. IPMI defines a set of interfaces used by system administrators for out-o...
power management for server equipment
what does uacpi have to do with IPMI???
.
TLDR AML can access IPMI for various configuration & counters
in this case power meter device
does acpica do those?
Elixir Cross Referencer - source code of Linux v6.13-rc3: drivers/acpi/acpi_ipmi.c
that actually sounds quite useful
its pretty cool yeah
What do I need to implement in the kernel api for hooking power buttons ? (on systems which don't have ECDT)
Attaching IPMI
IPMI command deadbeef
[uACPI][TRACE] write-then-read from [\MAIN.VARM] IPMI[0x00000000DEADBEEF] = <buffer of 66 bytes>
[uACPI][TRACE] [AML DEBUG] Buffer @0000603000001cc0 (0000603000001d20) (66 bytes)
Yayy
OperationRegion (VARM, IPMI, 0xDEADBEEF, 0x08)
Field (VARM, BufferAcc, NoLock, Preserve) {
AccessAs (BufferAcc, 0x01),
FIL0, 32,
}
Debug = FIL0 = 123
all locking related stuff
and irq handler
and I can init it how it showed in wiki page ?
try and find out
if u want to be able to shutdown also u must implement every kernel api
well on qemu u can get away with less
but i cant tell u the exact subset
like this
uacpi 😭😭
on qemu you only need rawio
where did u get this fucked formatting from
i think
mobile
yeah on qemu u only need io & irq handling
word wrap
not much to wrap here
phone screen tho
bruh
qemu should add a _PTS method to make it more annoying
so that people dont get away with half assing uacpi kernel api
lol
perfect
there's a difference between just receiving the event and actually handling it
i kinda want to write a system emulator and if i do i will definitely run a riscv core
so that i can put a cros_ec there
to force you to go through the full uacpi experience
im gonna take a look at that cros_ec, im curious how its out of spec
no clue
like a second core on top of the main cpu
ofc
uacpi is so cruel
and include an ACPI spec test in _PTS
go through every feature i can find in the spec before i allow you to sleep
genius
Not having ECDT does not mean you don't have EC 
rm -rf home dir if the user doesnt do everything correctly
we don't need to be that dramatic
we can just make the user post a screenshot to discord
(ACPI cult)
showing their noncompliant impl
and shaming it
how about posting "L L L imagine using a BROKEN ACPI impl and thinking you could SLEEP!!! 🤣 🤣 🤣"
we need a sacrifice for the cult of ACPI
uACPI has the power to shut the computer down
Just no operating system for you if you're not compiant
(I can't type)
although your chromebook dump seems to have a standard embedded controller device
maybe cros ec is like an extension idk
so there are TWO ECs?
if i had to guess
there's a standard two-port interface for reading ec ram
well and writing it
its probably not EC ram
cros_ec does security stuff
whatever, abstract r/w interface over that address space
OperationRegion (ERAM, EmbeddedControl, Zero, 0x20)
Field (ERAM, ByteAcc, Lock, Preserve)
{
RAMV, 8,
TSTB, 8,
TSTC, 8,
KBLV, 8,
FAND, 8,
PATI, 8,
PATT, 8,
PATC, 8,
CHGL, 8,
TBMD, 1,
DDPN, 3,
Offset (0x0A),
DFUD, 1,
FLSH, 1,
PFAN, 1,
KBLE, 1,
LTBR, 1,
LEDC, 1,
MTNS, 1,
KEYB, 1,
PSTR, 1,
P80P, 1,
THRM, 1,
SBKL, 1,
WIFI, 1,
HOST, 1,
GPIO, 1,
I2CB, 1,
CHRG, 1,
BATT, 1,
SBAT, 1,
HANG, 1,
PMUI, 1,
DSEC, 1,
UPDC, 1,
UMUX, 1,
MSFF, 1,
TVST, 1,
TCMV, 1,
RTCD, 1,
FPRD, 1,
TPAD, 1,
RWSG, 1,
DEVE, 1,
Offset (0x12),
BTID, 8,
USPP, 8
}
these are the fields it seems to have
i wonder what the HANG field does lmao
its also funny that chromebook logs EC events to aml stdout
not even their internal debug ports, literal Debug =
lol
i dont even
this isnt actually DT
also its a normal linux thing
you can search up this uuid in the kernel code
include/acpi/acuuid.h:#define UUID_DEVICE_PROPERTIES "daffd814-6eba-4d8c-8a91-bc9bbf4aa301"
grep for daffd814
Infy what do I need to do to support i2c devices? (like touch screens)
message above
smbus driver
the funny thing is that the kernel driver only cares about the acpi id ```c
#ifdef CONFIG_ACPI
static const struct acpi_device_id cr50_i2c_acpi_id[] = {
{ "GOOG0005", 0 },
{}
};
MODULE_DEVICE_TABLE(acpi, cr50_i2c_acpi_id);
#endif
Documentation/arch/arm64/arm-acpi.rst explains this
and not the fake ass compatible
ye i know
this one is not even in the dump
wtf
theres GOOG{3,4,6,A,9999}
Device (PS2K)
{
Name (_UID, Zero) // _UID: Unique ID
Name (_ADR, Zero) // _ADR: Address
Name (_HID, "GOOG000A") // _HID: Hardware ID
Name (_CID, Package (0x02) // _CID: Compatible ID
{
EisaId ("PNP0303") /* IBM Enhanced Keyboard (101/102-key, PS/2 Mouse) */,
EisaId ("PNP030B")
})
ps2 keyboard is GOOG000A lol
the what
infy
its where you write your crash log when you panic
its peristent ram
ahhh
why is probe mentioned
and 3 is USB-PD
what firmware dev thought it was a good idea to mention probe
Device (CREC)
{
Name (_HID, "GOOG0004") // _HID: Hardware ID
Name (_UID, One) // _UID: Unique ID
Name (_DDN, "EC Command Device") // _DDN: DOS Device Name
Name (_PRW, Package (0x02) // _PRW: Power Resources for Wake
{
0x41,
0x05
})
Name (_CRS, ResourceTemplate () // _CRS: Current Resource Settings
{
Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive, ,, )
{
0x0000005D,
}
})
Method (_STA, 0, NotSerialized) // _STA: Status
{
Return (0x0B)
}
}
Okay that makes sense now
they have a custom ec device stub for this
they have a "normal" EC interface that would work with e.g. pmos ec driver
and then this thing on top
that is picked up by cros_ec driver
drivers/platform/chrome/cros_ec_lpc.c this is their ec
normal ec is drivers/acpi/ec.c
Why do you even need EC extensions?
because google
// This driver uses the ChromeOS EC byte-level message-based protocol for
// communicating the keyboard state (which keys are pressed) from a keyboard EC
// to the AP over some bus (such as i2c, lpc, spi). The EC does debouncing,
// but everything else (including deghosting) is done here. The main
// motivation for this is to keep the EC firmware as simple as possible, since
// it cannot be easily upgraded and EC flash/IRAM space is relatively
// expensive.
this just says "because its cheap to do in software"
So they're doing keyboard through EC?
yeah
ah the acpi shit is implemented here: https://source.chromium.org/chromiumos/chromiumos/codesearch/+/main:src/platform/ec/common/acpi.c;l=137
I mean AMD laptops do debouncing through the GPIO meme
for the power button yeah
oh this is like their ec firmware?
infy if u were a firmware dev would u remove the word probe like a sane person
or are u an alien whos gonna probe
why are u so triggered by this word
its what aliens do
oh yeah
they also do PS/2 emulation on the EC afaict
so they do read from the ec ram
its literally some mmaped range they have
yeah idk how it works tbh
That makes the meme even more appropriate because it was created when I was a teenager
apparently its so expensive to read they cache it
or it could be expensive
but yeah pretty interesting to see the software side of EC
or rather, the firmware side
yeah thats also cool
its close to what i would expect i guess
so they do this acpi compat layer and then whatever their platform needs, makes sense
btw how does uacpi pass some of the blob tests like the dell xps one, from what I can see it declares a field in ssdt6 but then it uses it in the top level of ssdt1?
OperationRegion (OPG0, SystemMemory, (XBAS + 0x8000), 0x1000)
and there that op region line it uses XBAS which is defined in a later ssdt from what I can see
[uACPI][ERROR] unable to lookup named object '\_SB_.CPID': not found
[uACPI][ERROR] aborting table load due to previous error: AML referenced an undefined object
[uACPI][ERROR] #0 in \()
[uACPI][WARN] failed to load 'SSDT' (OEM ID 'Intel ' OEM Table ID 'PegSsdt '): AML referenced an undefined object
[uACPI][WARN] unusable/empty operation region IO_D
[uACPI][WARN] unusable/empty operation region IO_P
[uACPI][INFO] loaded 16 AML blobs in 121ms (1 error)
[uACPI][INFO] namespace initialization done in 9ms: 256 devices, 1 thermal zones
this is what i get
yeah looks like a firmware bug
do u abort like literally everything if one load fails?
yes, maybe that's why
ig Ill just make the load method ignore the errors too
ig the remaining things are like 10 blobs that are somehow getting timed out even after the timeout stuff that I added, Ill have to take a look at those at some point
nice
do u handle nested whiles correctly?
like is the timeout value saved in this case
I am pretty sure they do work, ig I can test again to make sure
though tbh its likely not that important as on real hw there probably aren't that many hanging while loops hopefully
more important is the fact that you currently need to disable interrupts when installing a gpe handler to avoid races 
also I think I can implement loadtable + overrides + load prevention tomorrow as I got some kind of table api done
who knows 
wait why
well my theory is that you can get a sci in the middle of the enable function when it modifies the handlers array and then it gets screwed up
I haven't verified that but considering it works with an irq guard I think its something like that
sure u can but why cant u just do
handlers[gpe_idx] = handler;
enable_gpe(gpe_idx);
yes but handlers is not a constant size array so it may get resized
also your protection only works if SCI is configured to fire at the current cpu where the code is being executed
pretty sure Intel just fired a bunch more people like 8 hours ago
ah damn
i guess acpica is unmaintained now
if thats true
We’ll see I guess
100% yes
no because that would “just work” and Linux doesn’t like that

Also doesn't Linux enjoy taking in the entire source of the thing into the Linux repo
Instead of a submodule
some galaxybrain dev using mutex timeouts as sleep(): 
Oh I misread the message
anyway
you can rewrite them though lol
thats because they do private patches
and also convert acpica source style to linux style
Would they do the same to uacpi
uacpi is already linux style
how the fuck does that work lol
just no
wait
they have an entire C program for that
that's sad
yeah tbh
its like 5k loc total 💀
yeah lol
do they literally have an entire handrolled c parser there 
Linux would rather write a program to change source style than fix actual problems
its intels money sooo who cares 
lmao fair
did you choose Linux style so uACPI doesn't suffer the same faith?
nah its just what im used to lol
uACPI designed for support in every OS from the get go
wasn't that the gist of ACPICA?
script to convert to reactos style when 
ACPI spec is just replaced by uACPI source code in 2026
i mean
You can’t write a script to convert to a buggy mess
right now the acpi spec is whatever the fuck microsoft developers did
i wish it was that
yes you can, you can put __builtin_unreachable(); in a random selection of 30% of functions
right now the spec is full of lies
thats not the spec
it calls itself a spec
yeah ACPI.sys ignores 30% of the ACPI spec
but the spec is ACPI.sys
"hardware reduced platforms" 
true
It’s contracted work
oh god
is that why its so bad
I mean it’s why there’s 90 interfaces
acpi spec = subcontracted developers, probably in India
so brain damaged people 
those are not known for good code
Yeah
lmfao
firmware people writing windows code is even worse
hey buddy
you’re right
But that’s mean

I write code that’s like
Close to the spec 90% of the time

@winter orbit do u fetch the aml blobs from some rom, or do u construct them at runtime?
I fetch them from ROMs
I just know how to dump them out of the raw SPI partitions in most hardware
so they're mostly hardcoded by the mobo?
i guess bioses do patch them too depepnding on config
pretty much every device has some kind of device specific change in ACPI
Like two devices on the assembly line won’t have an identical ACPI
why is that?
so I can tell you why for thinkpads specifically
there’s a tool phoenix provides that is basically an all in one debugging / compiler service
It’s supports source debugging firmware etc super cool
Okay so when you’re compiling the entire bios with this tool you also flash it with the same tool
do you know how you generate project tags at runtime per commit sometimes
ye
it’s like that, you press play on visual studios, and it will write the entire thing to device
Take that concept and scale it to automated deployment on an assembly line
thats not everyone
and the 10% is the problem
You’re hoping every line uses the same code base 1:1 and even if that’s true there’s just going to be some autogenerated Stuff
That’s the tldr
the real problem is that what’s shipped to vendors as a basis from Intel is already flawed
Each chipset has a package that gets integrated into edk2
It includes ACPI stuff too as a basis
tbh its every single step of the way that did a half assed job
yup
ms did a half assed job and outsourced acpi.sys to firmware vendors
inte is doing a half assed job and wrote dodgy aml
then firmware devs do weird shit 10% of the time and making it even worse
mhmm. But you can’t really fix it at any spot
because what happens when we try to make our bios conform
Put uACPI in Windows 
u must have missed a video of windows 10 booting with uacpi
or whichever one that was
holy shit
I did see
But as the solution I mean
its not complete though right?
makes sense
but it’ll boot on win11 when it’s done
a conforming bios should work
Because windows already does completely stupid crap
fucking hell
like what
How does that work? Is this the ReactOS kernel or is there some shenanigans going on here?
just a uacpi-based driver exporting vtables expected by nt from acpi.sys
no its a driver
I actually don’t know anything off hand for win10/11
now that I think about it
maybe I’ll find something
what about linux?
would be fun to know the details
Linux is a disaster we’ve tried fighting with before
lying about the windows versions is a mess
actually I can go on about Linux for awhile but they’re refused to fix anything we’ve suggested
so it was disabled for a reason
like just make it unbootable

basically
genius
yeah but I know Ami and phoenix have both sat down and tried to get Linux to establish dome basic rules
Or just try and work with us to fix OSI(Linux)
behind the scenes, or?
like what?
brain damage

most of the UEFI board has been willing to dedicate effort to implementing Linux specific logic
But even now Linux sleep doesn’t even work
we wanted it too
what if you implement linux specific logic
my laptop doesn't sleep with linux
what was their argument exactly
that will make linux deal with ACPI correctly!
“Linux is an open environment and aligning with a close interpretation of the spec is against our values!”
i know a trick or two for fellow firmware devs to detect acpica aml abi 
fucking what
no thats not the point
but this conversation has been happening for 5+ years
Way before I joined phoenix
this means to get booting you need to pass the test
btw I have suggested this in the past https://github.com/acpica/acpica/discussions/956
I was in high school when Linux and phoenix/ami started beefing
yeah but the issue is we’re getting paid to do automated testing against several distros
I actually don’t think I can tell you which ones iirc

Now that I think about it
ubuntu
but you can probably figure it out
yeah lmao
anyway we’re doing this, and testing against latest windows
by the distros themselves?
I don’t know
who cares about suse
@slim panther
😢
Just the people with the money
i do
so u dont even test against older windows?
lol no
bruh
But idk everyone releases things for RHEL and Ubuntu
fun
we have big companies and governments as clients
Older windows aml interpreters couldnt even handle basic shit
Looking at you vista
rhel is dead
The university I study at uses suse
is it
well, that's what our stats say at least
we took over support for some eol distro
i think it was centos
because rh refuses to provide service for it
that means i gotta deal with ancient software though
the only thing I hate more than Linux is firmware devs
is windows firmware devs
windows doesn’t have firmware devs
I'm retarded
Even the surface bios was just made via contracting with phoenix and AMI
i read "linux firmware devs"
it’s funny too because there’s not that many firmware devs in the world
We can all fit in a building
So Intel, Ami, phoenix, insyde, Samsung all trade people often
samsung makes their firmware?
So does dell
Also dell is the most conformant since they control the whole process on their own devices
Go figure

btw, since u mentioned surface If (_OSI ("Intel-Ice-Lake-Low-Power-S0-Idle-Always-Set-XTAL-Bypass"))
know anything about this? 
I can’t really tell you

wow
Microsoft 
Damn
what is XTAL
Crystal
some global aml state
Don't ask why that's abbreviated the way it is
a byte in ram
In the hardware world, XTAL means crystal, which of course has to do with clocks.
Since we're talking about sleep states here, I think that's the more likely explanation: XTAL is an MMIO register.
its a boolean
Method (XCFG, 2, NotSerialized)
{
If ((Arg1 == Zero))
{
Local0 = 0x016E3600
Local1 = 0x005B8D80
Local2 = 0x7D
Local3 = 0x02
}
ElseIf ((Arg1 == One))
{
Local0 = 0x0249F000
Local1 = 0x00493E00
Local2 = 0x32
Local3 = 0x04
}
Depending on if its 1 or 0 some shit is configured with these values
Ok, not literally an MMIO register.
Still looks like it affects some MMIO stuff though
can you send the whole acpi table
Is Dell's firmware sane?
everything after 2008 iirc is the date
Yeah it’s better than most
why 2008
AMI->in-house bios
i assume it's just configuring some clock to remain on when going into a lower power state
Nah. Too many bits changed for that. I think it's setting a frequency.
Local0 and Local1 are clearly decimal numbers
oh
That looks like something related to clock speed to me.
If ((Arg1 == Zero))
{
Local0 = 24M
Local1 = 6M
Local2 = 125
Local3 = 2
}
ElseIf ((Arg1 == One))
{
Local0 = 38.4 M
Local1 = 4.8 M
Local2 = 50
Local3 = 4
}```
XCFG is probably XTAL configure
oh yeah its our favorite "definitely not FDT i swear" aml meme
yeah
I wonder if this is how MS feels when they watch me reverse their entire gpu architecture
so 38.4 M is the sdw ip clock
apparently
which is the clock for the Intel Soundwire Manager
lol
maybe that bypass thing makes firmware ignore this or smth
im assuming its windows only
which code path is the bypass one?
4.8 M is the clock for MIPI discovery and configuration
If (_OSI ("Intel-Ice-Lake-Low-Power-S0-Idle-Always-Set-XTAL-Bypass"))
{
S0I3 = Zero
}
MIPI is display stuff
S0I3 stuff
SoundWire is a new interface ratified in 2015 by the MIPI Alliance. SoundWire is used for transporting data typically related to audio functions. SoundWire interface is optimized to integrate audio devices in mobile or mobile inspired systems.
ah okay no its not display stuff
its audio stuff???
MIPI does all kinds of wacky standards
There's also stuff like I³C, which IIRC is also a MIPI standard
the linux code is in drivers/soundwire
/*
* The hardware relies on an internal counter, typically 4kHz,
* to generate the SoundWire SSP - which defines a 'safe'
* synchronization point between commands and audio transport
* and allows for multi link synchronization. The SYNCPRD value
* is only dependent on the oscillator clock provided to
* the IP, so adjust based on _DSD properties reported in DSDT
* tables. The values reported are based on either 24MHz
* (CNL/CML) or 38.4 MHz (ICL/TGL+). On MeteorLake additional
* frequencies are available with the MLCS clock source selection.
*/
24M is the clock when icelake xtal bypass is on
i cubed c?

But way more proprietary 💀
interesting
Just for the record, I don't have the MIPI I³C standards in a folder on my computer
Not really
Only proprietary because it hasn’t been used that much yet
I guess
so my guess is that when the bypass is on, they save power by downclocking the soundwire controller under the spec
or something
@winter orbit did he reverse it correctly? 
or alternatively, that the supposed crystal isnt a real crystal
and is derived by a clock divider or some such
and the clock its derived from slows down when in s0 idle
💀
if you ever apply somewhere I’ll be your reference

Oh Infy I remember him, back from the days before Reactos took over the world
lol
Join the dark side of breaking the spec
I just got a score of 65k ops/s in ROS
I think it’s because of our mutex implementation
It seems our implementation is 650 times slower than windows

💀
nyaux is faster than ros confirmed
confirmed
is this tcg?
no

Just fuzzing around a little I think it’s mutexs
So I think uACPI found a bug in ROS we willsee
u can try stubbing them to a no-op and seeing if that changes anytrhing
yeah it goes to like 1.1 million
ah
what sort of bug?
mutexs being 650 times slower than windows is a bug
yeah doesnt seem right
it should be one atomic op in case of uacpi init, there shouldnt be any contention
coooooool 
Pretty confident
Here I posted my os layer I’ve been using without the PCI logic
Since that needs like.. 10k lines of changes
where?
A free Windows-compatible Operating System. Contribute to DarkFire01/reactos development by creating an account on GitHub.
mind you the rsdp, PCI stuff all need the private dispatch tables
Which need to be separate PRs I guess
Looks like it should work for the most part
is you mapiospace smart enough to know which is a pio address and which is a phys address?
yeah I know it says Io but that’s not really what it does
does it do like if <= 0xFFFF: map_pio()?
yeah
OH WAIT
Good point

know what who needs break points
Failure aren’t real
Firmware devs are known for good code
btw, this is how i do nanoseseconds_since_boot on windows (for my userspace test runner)
uacpi_u64 uacpi_kernel_get_nanoseconds_since_boot(void)
{
#ifdef _WIN32
static LARGE_INTEGER frequency;
LARGE_INTEGER counter;
if (frequency.QuadPart == 0) {
if (!QueryPerformanceFrequency(&frequency)) {
puts("QueryPerformanceFrequency() returned an error");
std::abort();
}
}
if (!QueryPerformanceCounter(&counter)) {
puts("QueryPerformanceCounter() returned an error");
std::abort();
}
counter.QuadPart *= nanoseconds_per_second;
return counter.QuadPart / frequency.QuadPart;
is this wrong?
beacuse i noticed u do it differently
It’s actually the same exact thing
I just use kernel APIs
queryPeformanceCounter eventually just calls what I did there :)
ah ok
/* Thread ID must be non-zero */ is questionable, maybe that was an acpica constraint of some kind
uacpi would be mad only if u returned this: https://github.com/UltraOS/uACPI/blob/master/include/uacpi/platform/arch_helpers.h#L35
oh yeah
Cool
That won’t happen

its configurable in acpica as well i think, but maybe they also check for 0 as an error idk
i like how it calls it Fast mutexes 
petition to rename to ExceptionallySlowMutex 
You see the Unsafe call
yeah
You spend so much time doing stuff between mutex locks windows was switching threads
And it loses the IRQL
💀
how can you even lose an irql?
windows mutates need to be at APC
you don’t you just get dispatched
And that’s a higher priority
I should be making it so the thread running uACPI doesn’t go back into the scheduler on stall
But because of what I wrote there it will hit a delay and then get set to idle
wdym by stall exactly
any kind of wait
you arent allowed to sleep with a mutex held in ros?
lol np
uacpi does release the namespace write lock on SleepOp and AcquireOp etc btw
yeah it’s written write for windows drivers
I just need to enter a critical section tldr
written write 💀
ah
So if actually gets back to an IRQL of APC or below for release
the unsafe call is a way to make it ignore this fact
If you wanna SPEEEED
Wellll about that 
and don’t care if another processor takes the job
Windows scheduler is fully active by the time ACPI.sys is loaded
tbh maybe reactos loads this driver after everything is up and there's contention for the cpu, other osses init it befor smp even
that could explain the poor score
Maybe but windows was much faster
To be fair I don’t think this is a bad thing tbh
yeah
NTs main hybrid kernel trait is that it waits before it’s ready to load user mode before it loads any drivers
like the whole kernel starts up and is ready
Early Reactos was just a shel and the kernel
No drivers
or maybe i lied, i think i mixed up early uacpi init (aka just parsing the tables) and loading the namespace
i hope people do namespace_load after their scheduler is up
because that needs scheduler for aml
does that mean it has some builtin early acpi parser for smp startup etc
yeah
and numa stuff
yup
makes sense
Actually the bootloader even has some ACPI parsing



