#uACPI - a portable and easy-to-integrate ACPI implementation
1 messages · Page 62 of 1
(besides managarm)
well yes
Free95 will soon take over
managram
BTW @fiery turtle what happened to the idea of you testing all the ISOs yourself for the leaderboard?
it's test-by-request
Kinda sent that at 3 am feeling like crap but I still dont want it there
Not giving up just other reasons
Hm okay
:(
I dont get enough new submissions to care atm, maybe later
honest to god we should just typosquat this with a mirror of managarm that simply has s/managarm/managram/g
So I just run the benchmark myself?
yes
or ask someone else to run it that has already been running tests for the leaderboard
Hey I have a more general question about ACPI
As a side effect of my project, I'm invalidating the effect of the global lock: the global lock no longer provides synchronization between the OSPM and the firmware.
I was wondering how frequently is the global lock really used in modern ASL and firmware nowadays, and whether this synchronization invalidation is relevant?
I looked at uACPI's code, and I did not see any use of the global lock acquiring implementation, which led me to assume the global lock isn't really relevant.
i tried to reply to your email but it was blocked by your proton thing
are you making a uacpi-like project or your own hardware?
I looked at uACPI's code, and I did not see any use of the global lock acquiring implementation, which led me to assume the global lock isn't really relevant.
You didn't look very well i guess
it's acquired whenever firmware accesses a locked field (pretty common) or does an Acquire(\_GL) (less common)
I'm making a project that uses uacpi. It's just software, no hardware
what do u mean by " I'm invalidating the effect of the global lock:"
https://github.com/uACPI/uACPI/blob/a6eb761f267eb83f3f05ef85005b646b23f9e2c7/source/mutex.c#L225 this is where the global lock is acquired
Ah I see. I was looking for calls to uacpi_acquire_global_lock*, but it uses the global_lock_mutex
Are you alright with moving to DM?
this is to prevent the global lock from breaking if e.g. CopyObject(..., \_GL) happens, i have this for a few predefined objects
any reason why this has to be in DMs? Is it like a secret project?
Not secret, I'd just rather keep the internals low key atm until it's done
okay
yo hey uacpi people, this new qemu patch intentionally generates malformed ACPI tables as a workaround for a windows bug
https://gitlab.com/qemu-project/qemu/-/commit/0b053391985#eaf463cffb2377a83b4491abd809d5aa6a314493
here is the patch
it causes this behavior:
unable to lookup named object '���' within (or above) scope '\_SB_.PCI0': invalid AML name string
aborting method invocation due to previous error: invalid AML name string
And it seems like these lines of code from said patch are the culprit
aml_append(ifctx, aml_store(aml_call2("AIDX", bnum, sunum), acpi_index));
aml_append(ifctx, aml_store(pkg, ret));
/*
* Windows calls func=7 without checking if it's available,
* as workaround Microsoft has suggested to return invalid for func7
* Package, so return 2 elements package but only initialize elements
* when acpi_index is supported and leave them uninitialized, which
* leads elements to being Uninitialized ObjectType and should trip
* Windows into discarding result as an unexpected and prevent setting
* bogus 'PCI Label' on the device.
*/
ifctx1 = aml_if(aml_lnot(aml_lor(
aml_equal(acpi_index, zero), aml_equal(acpi_index, not_supp)
)));
{
aml_append(ifctx1, aml_store(acpi_index, aml_index(ret, zero)));
/*
* optional, if not impl. should return null string
*/
aml_append(ifctx1, aml_store(aml_string("%s", ""),
aml_index(ret, one)));
}
uacpi is correct for rejecting this and throwing the error but yea qemu ppl wrote some stuff that caused that to start happening, just putting this out there in case anyone else runs into this issue
qemu versions 10.0.3 and later are affected
so much for qemu following the spec to the letter. imho such "features" in qemu should have toggles.
Nah I dont think thats what it is
This makes a package, and uACPI seems to encounter a bogus name
Have you verified that this is actually what happens and this commit is at fault?
Also you're saying you call _DSM in your code?
I'm afraid that uACPI error is a bug in your code, not qemu generating malformed acpi
That patch just makes it return an empty package from _DSM to signify lack of support for some feature
so, i know why uACPI was so slow in its 'benchmark' figure on init, its my allocator
my allocator is always O(n), correctness over speed. if i want speedy, i'd need to give uACPI its own allocation algorithm thats faster
O(n) where n is allocation size, or where n is allocation count?
Either way, that's slow enough you probably don't want to use it at all.
I only encounter this bug on the one machine I have that uses the latest uacpi version
it only recently started appearing
before this version nothing was wrong
and I reverted to a known good commit and the bug was still here
it kind of doesn't make sense how this bug would start appearing when reverting to a known good version that used to work, but doesn't work on this new version
allocation count
it doesnt matter for the most part, most of my stuff doesnt just indiscriminately call kmalloc()
yea i reverted all the way back to a commit that i made from this machine on the new qemu version (meaning it should've worked fine) and uacpi is encountering this error
it works fine in CI/CD
nothing goes wrong there and that's on the older qemu versino
i'll try an OS that couldnt have broken code then
i'll try and boot managarm
I don't get anything like that with uacpi on qemu 10.0.3
if you want something small to test
hmmm yeah it seems ok with your image, i did notice that my logs show a different RSDP address from yours
ohh yeah you're using a custom acpi parser
neat
ok yea my hunch is that something odd on my side is happening then, i'll see if this same behavior happens on linux x86 hosts running 10.0.3, since this is on my mac and it might be different here
I believe my other intel mac is using 10.0.3 since it runs arch which likes to run newer versions of packaegs, and it worked fine there, but i'll go home and double check (in a few days)
👍
👍
[0]: [uACPI] successfully loaded 1 AML blob, 1760 ops in 4ms (avg 375496/s)
[0]: [uACPI] namespace initialization done in 2ms: 44 devices, 0 thermal zones
[0]: init_uacpi done. Peak allocation: 259648 Current allocation: 240128
i should enter for your chart on the github.
processor : 31
vendor_id : GenuineIntel
cpu family : 6
model : 45
model name : Intel(R) Xeon(R) CPU E5-2680 0 @ 2.70GHz
stepping : 7
microcode : 0x71a
cpu MHz : 1200.000
Yes
bro like
its literally the same exact fucking name
with a different suffix corresponding to the type
how can u be this bad at searching code
can i enter that figure onto the chart, how do i do so? do i just raise a PR?
lol
i just improved my allocator a bit more 😄
[0]: [uACPI] successfully loaded 1 AML blob, 1760 ops in 3ms (avg 441329/s)
[0]: [uACPI] namespace initialization done in 1ms: 44 devices, 0 thermal zones
[0]: init_uacpi done. Peak allocation: 268096 Current allocation: 259328
i'll be pushing this soon 😄
That's cool
he figured it out
Please explain uACPI in Factorio terms
oil refinery
i hate how that immediately feels accurate lmao
@fiery turtle If I'm calling uacpi_setup_early_table_access at a point in time where I do have a functional kernel memory allocator and I want uACPI to allocate from there instead of using the internal buffer, is there any way to achieve that?
uacpi_initialize
the only thing that happens in uacpi_initialize is tables yeah
oh, nice
at the very least initialize doesnt do gpe/sci or namespace etc stuff afaik
yeah that sort of thing should not happen until much much later
"Enters ACPI mode." but there's a flag to disable that right?
i ended up thinking i was going to get rid of my early tables stuff and i still might tbh, depends on how i end up handling smp information (e.g. get from limine and give in and use limine's smp boot or get from acpi)
Ok. great!
Np
how do i get the acpi pm timer port with uacpi?
i tried parsing it myself, but my real hardware returns a bogus address 0x4004 when it should give out 0x4008, i dont know if thats on me reading it wrong, or if thats on the machine. best thing would be for me to NOT read this myself and use the right tool for the job.
uacpi_gas helpers
any docs on that?
It has map and read_mapped
The header
Idr off the top of my head
found some reference in uacpi/io.h but its not really commented
U just pass the gas to the map function and then use read_mapped
how do i get the gas?
and dont say from a gas pipe 
i mean in my code im parsing for the FACP
from uacpi_get_fadt()
fadt not facp?
hmmm, i cant find that symbol
Or just uacpi_fadt
Tables.h
Just steal @torpid root code for it
hm?
uacpi_table_fadt?
you really dont wanna see my homebrew attempt for it btw, its horriffic
oh acpi pm
Pm timer management
Ye
i want this, yes?
struct acpi_gas x_pm_tmr_blk;
yes
map_gas it
then read mapped
24 bit timer overflows in like 4 seconds iirc
so use it only for calibrating other timers
map_gas? is this a memory mapping function? (i wont need it if so)
this is what im using it for
to calibrate my local apic timer
but, i get a bogus address on real hardware, qemu is fine (with my own code) which is why i want to check in uacpi to see if yet again my firmware is crap
uacpi_map_gas
if it's using io, it won't map
if it uses mmio, it will
The pm timer is a GAS, that means it can exist in any address space
This is why the function abstracts it away
wdym by that?
everything is identity mapped
ah yes i rtfs'd
it calls uacpi_kernel_map, on my kernel its a nop
This structure is a generic address structure, that means it has a field specifying the address space the register is located in, there are tons of various address spaces besides io
i wrote this to replace my crappy table scan code
struct acpi_fadt *fadt = NULL;
st = uacpi_table_fadt(&fadt);
if (!uacpi_unlikely_error(st) && fadt) {
struct acpi_gas *gas = &fadt->x_pm_tmr_blk;
if (gas->address_space_id == 1) {
// System I/O
pm_timer_port = (uint16_t)gas->address;
pm_timer_is_io = true;
kprintf("Using PM timer IO port 0x%04lx\n", pm_timer_port);
} else if (gas->address_space_id == 0) {
// System memory (MMIO)
pm_timer_port = (uintptr_t)gas->address;
pm_timer_is_io = false;
kprintf("Using PM timer MMIO 0x%lx\n", pm_timer_port);
} else {
kprintf("Unsupported PM timer space_id %u\n", gas->address_space_id);
pm_timer_port = 0;
}
pm_timer_32bit = (gas->register_bit_width == 32);
kprintf("PM timer bit width=%u, offset=%u\n",
gas->register_bit_width, gas->register_bit_offset);
} else {
kprintf("FADT not found, no PM timer available\n");
pm_timer_port = 0;
}
it works, on real hardware and in qemu
basically sets 3 static globals, pm_timer_port, pm_timer_is_io and pm_timer_32bit
which i then use in a timer read function:
uint32_t pm_timer_read(void) {
if (pm_timer_port == 0) {
return 0; // not available
}
uint32_t mask = pm_timer_32bit ? 0xFFFFFFFF : 0xFFFFFF;
if (pm_timer_is_io) {
// Always use a 32-bit port read
return inl((uint16_t)pm_timer_port) & mask;
} else {
// MMIO read
volatile uint32_t *reg = (volatile uint32_t *)(uintptr_t)pm_timer_port;
return *reg & mask;
}
}
i should fix that 'always use 32 bit'
because i really should be using the width from the gas
right?
its just convenient that right now both hardware and qemu give me 32
Why not just map_gas/read_mapped?
Yes, but the whole point is u dont have to read it yourself
but ist it just reading a value from the struct?
or are you talking about read_mapped for the pm_timer_read function?
i cant there, i tear down uacpi when im done with it
Eh anyway, whatever works
thanks for putting up with my probing (see what i did there? port puns)
@fiery turtle I have a kernel spinlock which uses a percpu counter to disable interrupts. As a consequence of this, my kernel doesn't cope with not unlocking a spinlock (it leaves the caller with an unbalanced IRQ disable counter). Does uACPI free any spinlocks without first unlocking them?
same here
No ofc not, why would it do that?
That would break any kernel that disables interrupts
Without knowledge of this, it is easy to make the (faulty) assumption that if you are already holding some other ("outer") lock, it is fine to free an inner lock without unlocking it:
Spinlock *outer, *inner;
outer = new Spinlock;
inner = new Spinlock;
outer.lock();
inner.lock();
delete inner; // BUG!
outer.unlock();
Nah that's not an assumption uACPI makes since its stupid af, also its spinlocks are mostly static lifetime
great
If you encounter one let me know
I have the following in my uacpi_kernel_free_spinlock:
BUG_ON(!lock->trylock());
lock->unlock();
so I will catch this if you ever do it 
Sure lol
And couple lines below it you can see the stall function that actually uses the port
Technically I should be masking the timer to 24bit for this to correctly work but yeah
Aka I skip the gas :^)
UACPI os lol
ultra 2
what happened to that aml os
too lazy so turned it into an example of uacpi
damn
I think u even had a python to aml compiler?
BUG_ON(! is such a nice replacement for assert
it actually tells you what an assert is for
not for if then panic s

But assert and ensure are different
definitions are close enough
IMO this is better than ensure:
#define assume(expr) do { \
if (expr) \
; \
else \
__builtin_unreachable(); \
} while(0)
because I think it is more obvious that assert and assume are different things.
assert - panic if a condition is not met
assume - invoke undefined behavior if a condition is not met
why the if else instead of if (!(expr)) __builtin_unreachable()
if expr expands to some C++ object whose type has no operator!, that might be needed, but idk
is that a thing
operator!?
I don't remember ever having implemented a custom operator! at least.
ah right c++ exists
(goddangit aligning the backslashes is hard to do on phone discord)
yeah, sorry for reminding you 
👎
C++ is actually a good language believe it or not.
That doesn't mean that you have to use it.
But C++ is not a bad language.
prepend "modern" and you're unironically right
oh yeah no doubt about it, it's just not my preferred kind of language
I never use it and so for snippets that look more like C I tend not to consider its existence
well this is valid C, too.
yeah exactly
the "modern" parts of C++ that I use are mainly some constexpr and template stuff
otherwise most of the language features I use have been a thing in the standard since ~C++11 or even before
probably doesn't help that my only semi recent experiences with it have been porting mlibc (where i pretty much just treat it as c with namespaces) and trying to backport c++20 code to compile on OpenWatcom
Being able to template on a member field of a struct is sooooo useful. It allows me to do things like
struct ListHead { /* ... */ };
template<class T, ListHead T::*F>
class TypedList {
/* ... */
void insert(T *item)
{
m_list.insert(&(item->*F));
}
/* ... */
};
struct Foo {
ListHead entry;
/* ... */
};
typedef TypedList<Foo, &Foo::entry> FooList;
which lets me make so much better wrapper types around all sorts of data structures, primarily intrusive ones.
IIRC that is a relatively recent feature.
why dont you just push the flags onto the stack, pop off into rax, then store IF when you lock the spinlock, and in the unlock spinlock function pass those flags back in and reverse the process
then after saving flags, do CLI
so that on exit from the spinlock, the IF state is preserved but interrupts are always disabled
this is what i do
except when it breaks compilers (GCC) 
if you don't explicitly delete it, I believe implicit operator exists by default
even then, if it's convertible to bool, you can just do that
so if (!(bool)(x))
The Message Proxy (MPXY) extension allows the supervisor software to send and receive messages through
the SBI implementation.
Will we finally getPOST /pciroot/0/port/5/power<{"state": "on"}firmware?
unironically that would be pretty nice
This document describes the RISC-V Platform Management Interface (RPMI), which is an OS-agnostic, firmware-agnostic, scalable and extensible interface for platform management and control from dedicated microcontrollers (also referred to as platform microcontroller or PuC).
The RPMI defines a message based communication between multiple application processors (APs) and platform microcontrollers (PuCs) for system management and control. This message based communication can also be virtualized by the machine-mode firmware or hypervisors using the SBI MPXY extension cite:[SBI].
damn is RISC-V straight up stealing my ideas?

it's happening
based based based based based
i really need to update uacpi for nyaux, id assume a lot of changes happened
not to the api
mostly bug fixes afaik

I don't know how old your uacpi is
Its been mostly bug fixes and support for bogus table sizes
fair
epic
also maybe an api to iterate all existing tables
Has anybody compiled this on MSVC? Lots of compiler errors:
External\uACPI\source\default_handlers.c(128): error C2664: 'uacpi_status pci_region_attach(uacpi_region_attach_data *)': cannot convert argument 1 from 'uacpi_handle' to 'uacpi_region_attach_data *'
External\uACPI\source\default_handlers.c(128): note: Conversion from 'void*' to pointer to non-'void' requires an explicit cast
External\uACPI\source\default_handlers.c(43): note: see declaration of 'pci_region_attach'
External\uACPI\source\default_handlers.c(128): note: while trying to match the argument list '(uacpi_handle)'
i think it is meant to work
but maybe turn off whatever nonconformant bs that diagnostic comes from :^)
are you compiling in c++ mode?
I was when I got those errors, good catch. Compiling for C is giving another set of errors:
External\uACPI\include\uacpi/platform/types.h(55): error C2143: syntax error: missing ')' before '!'
External\uACPI\include\uacpi/platform/types.h(55): error C2143: syntax error: missing '{' before '!'
External\uACPI\include\uacpi/platform/types.h(55): error C2059: syntax error: '!'
I can see in the headers there are checks for _MSC_VER so I'm probably just missing something
yes, uacpi definitely compiles under msvc with default flags
thats how i debug it exclusively
target_compile_options(
${NAME}
PRIVATE
/W3 /WX
/wd4200 /wd4267 /wd4244
)
these are the flags i use
note: Conversion from 'void*' to pointer to non-'void' requires an explicit cast
you are compiling C code in C++ mode
huh, why?
because i daily drive windows
sure, but clang-cl exists
yeah, just extra effort to install and worse visual studio integration
Ok I found the issue with the syntax error:
diff --git a/include/uacpi/platform/compiler.h b/include/uacpi/platform/compiler.h
index 563a1c5..e9554bf 100644
--- a/include/uacpi/platform/compiler.h
+++ b/include/uacpi/platform/compiler.h
@@ -16,7 +16,7 @@
#elif defined(__cplusplus)
#define UACPI_STATIC_ASSERT static_assert
#else
-#define UACPI_STATIC_ASSERT _Static_assert
+#define UACPI_STATIC_ASSERT static_assert
#endif
are you still compiling it in C++ mode?
cl /c Acpi/Acpi.c /Fo"..\build\moskrnl_acpi" -IExternal\uACPI\source -IExternal\uACPI\include
strange
i've seen some msvc issues around static_assert before
idk how they work tho
are there different editions?
because this definitely compiles for me
like vs19 vs 22
and github CI as well
yeah
If you're compile for C how is __cplusplus defined?
it isnt
it's undef
hence why i said it was weird
because _Static_assert is a C version of static_assert
This is from ucrt:
#ifdef __cplusplus
#ifndef _STATIC_ASSERT
#define _STATIC_ASSERT(expr) static_assert((expr), #expr)
#endif
#else
#ifndef _STATIC_ASSERT
#ifdef __clang__
#define _STATIC_ASSERT(expr) _Static_assert((expr), #expr)
#else
#define _STATIC_ASSERT(expr) typedef char __static_assert_t[(expr) != 0]
#endif
#endif
#endif
C23 has static_assert
And that just has 1 param?
no, it should take either one or two params
I'm really not sure shrug sorry for all the Q's
c23 deprecates _Static_assert
with that change it does compile all for me.
C:\Users\todds\GitHub\toddsharpe\MetalOS\build>cl
Microsoft (R) C/C++ Optimizing Compiler Version 19.43.34810 for x64
Copyright (C) Microsoft Corporation. All rights reserved.
#1217009725711847465 message
still, uacpi should work without changes on c23
I think I compile it in c23 mode with clang
Yeah dunno, ill investigate how msvc handles static assert at some point
No problem, thanks guys
I'm in the process of porting my OS from ACPICA to uACPI
/std:c23 iirc
or at least that was the syntax for c++ standards iirc
okay i just tried all three compilers in c23 mode
they all both accept the C11 and C23 form
also funny
nice static assert
did it turn it into an fn call with an implicit fn definition?
hence the error at global scope
lmaoooo they interpret the old form as an implicit function call
yeah this is incorrect
idk about you but call __Static_assert doesn't look compile-time to me
this is MSVC?
yes
best msvc codegen
average MSVC experience
i mean hence why a static assert outside a function is an error
but still
why do they allow implicit function declarations
but then they don't recognize _Static_assert 
that's like cherry picking shit from the spec
I also think the uses of: #include <intrin.h> need to be wrapped in UACPI_OVERRIDE_TYPES or else you risk pulling in all of vcruntime
in atomic.h and compiler.h
Hm? Override is for overriding, why would it include something else?
The platform/ headers are meant to be overridable by platforms, so if intrin.h is a problem for your platform you are free to modify/make an override header as you see fit
Okay that works. My build doesn't use any vs headers, so ive got an intrin.h i populate as needed
So it should include your version right?
Btw is your kernel nt like?
Since you use msvc
unix-like
names functions with nt prefixes
uses mvsc
refuses to elaborate
Yep, I'm doing a big rewrite of my OS for a unity build, so just removing those includes is fine for now
My OS is NT like, the kernel/user images are all PE's
I'm doing a big rewrite for a number of reasons (I mostly hate how i did memory management). its on github:
https://github.com/toddsharpe/MetalOS
why do unity builds?
Cool
msvc lto
as if msvc can actually optimize
LTCG is nice for OPT, but not for build speed
in the first place
Is it going for nt compat?
No, just inspired by it
Ah
Though i did manage to get windbg working somehow, barely
What does it require?
I had to read a lot of ReactOS source for that., hard part was getting the module lists and init structs correct. then finding out the subset of API that needed to be implemented
and then a kernel thread to handle the requests while the rest of the scheduler is halted of course
Interesting
paging Dr @surreal current
Many thanks, working great:
\
Name: \
Desc: (null)
HID : (null)
\_SB_
Name: _SB_
Desc: (null)
HID : (null)
\_SB_.VMOD
Name: VMOD
Desc: Module Device
HID : ACPI0004
\_SB_.VMOD.APIC
Name: APIC
Desc: IO-APIC Interrupt Controller
HID : PNP0003
\_SB_.VMOD.VMBS
Name: VMBS
Desc: (null)
HID : MSFT1000
\_SB_.UAR1
Name: UAR1
Desc: 16550A-compatible COM Serial Port
HID : PNP0501
\_SB_.UAR2
Name: UAR2
Desc: 16550A-compatible COM Serial Port
HID : PNP0501
\_SB_.GENC
Name: GENC
Desc: (null)
HID : MSFT1002
\_SB_.RTC0
Name: RTC0
Desc: AT Real-Time Clock
HID : PNP0B00
\P001
Name: P001
Desc: Processor Device
HID : ACPI0007
👍
is it possible to use uacpi to detect if efi booting is possible? even if the OS didnt boot via UEFI. i want it as a simple check "is this machine UEFI boot capable?" before i lay down an ESP in my installer. if it isnt, the installer will say nope, retro rocket isnt for your retro hardware.
the live CD can boot in 'legacy' mode (as per limine) where it just uses el torito and no uefi stuff, but that doesnt mean the system itself is incapable
i'm not aware of such possibility, i'd say if you really want to make sure people don't mess it up just build the limine iso without bios support to make sure it can't be booted on a legacy system :^)
hah that's a good way to do it I guess
I heard though that there's a non standard ACPI table called _EFI or UEFI that you can scan for
added by uefi... but if it's non standard....
not present on my system
i think you can look for the BGRT table
it's probably not gonna be present on non-uefi systems
but idk if it's guaranteed to be present on all uefi systems either
I think you should be able to detect UEFI support via dmidecode
you could combine that with an efi runtime services table limine request
or try what leo said
¯_(ツ)_/¯
what leo said
so is this reliable? if so how do i query for it?
smbios
a bunch of variable length entries but it's well documented and standard
i'm too lazy to look for the spec sorry
i can scan for that in the first meg cant i, just look for aligned _SM_
Limine can give it to you as well 🙂
supported == actually booted?
not sure, the spec probably tells you
good question, idk, for example my spare pc boots my os cd from legacy boot, but supports uefi
so if it was just 'actually booted' this would evaluate to false
however, how many systems made in the past 15 years dont support uefi boot? pretty much none?
why do you even care about !UEFI boot
because i dont support MBR oldschool boot from hard disk at all
clean slate, decided i dont want to support legacy cruft
neither do i, my solution is to just not install limine bios
those two dont go side by side, do they? windows supported it way before uefi was standard, in windows 2000... just couldnt boot off it
i always install an ESP and EFI loader in my images
and only ESP/EFI?
yes
actually is the only sane choice imho, MBR is a clusterfudge, and the whole "pick a number from 1 to 200 for your OS to identify its filesystem" like what
i mean my kernel only knows about memory blobs, it assumes the bootloader has already loaded the files into ram
It is, limine can give it to you via a request
No, smbios is static
Its just a bunch of structs describing the hardware and firmware
yeah so it's not reliable for UEFI boot detection
Well Linux uses it for quirk detection
that would mean it is reliable, right? if its static, its there or not there, it doesnt 'go away' if you boot legacy
yes but it doesn't actually tell you anything about how it's booted
We have no way on knowing without checking out a collection of smbios dumps, but I would expect the UEFI bit to be set unconditionally
Yeah
for me that doesnt matter to know how the current boot was done, just if future boots are uefi capable
But thats not what they want
For how it was booted limine can tell it
its just an installer sanity check, so i dont waste my time flattening a drive that cant boot
You can have GPT + MBR boot as well
(though it was broken with limine the last time I checked)
yeah, its not something i want to support for hard disks
i have no reason to be supporting legacy cruft
You first run in the loader, where you can get what is the environment and only then you get into the kernel where you observe acpi, why in your view it's all upside down?
I don't understand your wording here
I'm not sure what you mean by loader, do you mean bootloader? that's limine I don't write that bit.
what do you mean by upside down?
I think instead of trying to detect this, you should just allow your kernel to panic on systems that don't meet minimum specifications.
but then the user has already installed it and wasted their time
The loader knows what firmware it ran in and it passes to the kernel that information, pretty sure limine does too. For example UEFI system table, where you can get not only the firmware type, but the version of it. Acpi is not the place to get what the firmware was, it can be either uefi or bios. You should get this info from the loader.
Wouldn't your installer, like, not work either if it uses your kernel?
I don't care for what it used to boot the cd, this is not relavent to if the system can boot UEFI. for example my system boots CDs in legacy mode only but can boot hard disk from an esp
no, there's a difference, the live cd uses limine and el torito, the bootable hard disk install boots only from gpt and an esp
Either way I think you're not helping yourself with this. It's not like 64-bit Linux will gracefully tell you you're using it on a 32-bit CPU, it'll just triple fault instantly.
it's not quite as obvious as that
el torito has nothing to do with booting
do you need an esp tho?
the el torito boot cd will boot fine. but it doesn't mean the hard disk can
It's just how you made it
it's all about user convenience
because you can do legacy boot from gpt
yes it's all I support for hard disks
legacy boot is ass
So install Limine to do it for you
limine is not my installer.
ah are the files installed to the esp?
then how can limine tell me if a device I didn't boot from is uefi capable
A device isn't UEFI capable, the firmware is (or is not)
yes, my os has an installer on its live cd that flattens a hard disk and writes an esp and data partition to it
I don't want to do that if it isn't going to work after reboot
basically save the user trouble as a system requirements check
What boot protocol do you use for your kernel?
but I can't just make the cd uefi only because some systems dont support that where they do support it for hard disks (like my older gigabyte board)
limine boot protocol and limine 4
I'm probably going to update at some point but I really don't want to retest everything rn
Then you should literally just install the Limine bootloader, because it supports legacy boot
I don't see the problem here
I don't want to support legacy boot
have you seen how limine does legacy boot...? it writes it's loader to spare space in the gpt
it's flaky. I'm sure they said they want to remove it
Yes, this is how Legacy boot works literally at all, GPT or MBR.
Haha no that's never happening
well, I refuse to support legacy boot, can talk about that till the cows come home
I have a neat and tidy disk layout right now
legacy boot makes it unclean by making parts of the boot process not live on the esp
which makes it more complex to write and debug
Then you have two options:
- Get over it and install Limine-BIOS anyway
- Stop torturing yourself with trying to detect the incredibly weird edge case of a computer modern enough to run your kernel not having UEFI.
remember I can't use limines tools to write the installer to disk
but surely "stop torturing" is a misnomer, we are osdevs we love torture

I personally like to think we do this for fun
yeah same
but it can be challenging and frustrating, I wouldn't do it if it was easy id get bored
I kinda feel I'm whacking through weeds in rarely trodden territory tbh many hobby oses never made installers so don't have to worry about system requirements checks. you're right that if the kernel booted on the live cd it already passed 99% of any system requirements and the only one left is "got an ahci writeable device with enough space?"
and "you sure you want to do this?" as a final step
OK so fun fact: I'm pretty sure even Managarm can't install itself from scratch
Even funner fact: An installer is going to be the first major userspace goal of mine
I mean I could ask further questions about timezone and keymap but these aren't requirements checks and more bout personalisation so that's a different discussion
You could put those in an OOBE
the interesting bit is parts of it need to step outside userspace or have raw access to block devices you don't give to normal user apps, for writing the partition etc
parts of it need to step outside userspace
Well yes, those are called "syscalls"
my installer is all in-kernel as the os doesn't support running native code as a user process, it checks a kernel command line and if it says installer it starts an install stub else it starts the multitasking scheduler and boots /programs/init (a BASIC program)
What
I also have no syscall interface no privilege separation and no paying beyond identity map
intentionally... won't add them later
It's a BASIC kernel anyways. 
Do you mean to tell me you don't have a proper userspace yet fuss about supporting BIOS boot?
In an esoteric kernel that runs BASIC, of all things?
yes, it behaves like oldschool 8 and 16 bit systems. want to poke that address? glhf. you brick it you keep it. it's a learning experience
rather than protecting a user from themselves (also it's a single user system)
This is only more reason to support BIOS boot
If you don't want to support legacy boot after installation, you should warn your users to not use it before. uefi only systems must support booting from cds (el torito). If some machine can't it's better off to give up on such. Installer is a user program it runs after the loader and os init, so it would know the environment. You shouldn't require the user: switch to legacy bios for booting installation session, then switch to uefi only after. It's request for troubles. Esp. given you don't use your loader nor even want to do a normal installer. Do you plan usung UEFI boot/load option (BOOTX variable) for installation persistence/recognizabilty?
your idea of a "proper" userspace is influenced by Linux, windows, bsd. I was raised on OSes that let you do literally anything. people learned from it. it was fun.
you have a different target audience if paging, memory protection etc are important to your use case
No, I said this because your very idea of how you want your OS to be conflicts with the way you made your installer.
Logically, the entire installer should be in BASIC
I don't see how.
Of course it needs to run commands that manipulate disks directly!
Leaving that to the kernel (which probably does this in C) is a cop-out IMO
no? it could be, but I didn't want it to be. I could have just pivoted which basic program launches yes, like /programs/install. but I don't want to write basic keywords to write to raw hard disk sectors, at least not right now
Also we should probably stop hijacking this thread
the idea is interesting, but something for a future contributor to raise a pr for
true lol
I suppose if someone has something to say re uacpi they'd speak up and ask
I'm not the gatekeeper 
Yeah but this convo arguably should be in #esoterics 
I never even saw this channel, say hello to my new 2nd home
It shows a message that you have wrong CPU
Sometimes a device is UEFI capable, but it is broken and you're better off booting with BIOS..?
I had a laptop which came with a BIOS install of Windows, and while the firmware supported UEFI, its power management didn't work properly with UEFI install
that's a them problem then, not really out to cover every eventuality of hardware, that's a losing battle I don't have enough lifetimes for
some would say "but an os has to support everything or nobody will use it", not too concerned
it's a slippery slope from there to "why don't you support mbr partitions"
The "user has decided to boot with BIOS for some reason but the system supports UEFI so I'm gonna carry on" is gonna lead to a broken install
Yes, why don't you support them?
Also, don't you need to add a boot entry for UEFI, which requires being booted with it?
because I don't want to and therefore aren't forced to, I'm 43 and I have limited free time, if I try to support everything I'll never release anything
Like if the user boots with BIOS, and you don't want to support that, you just don't
so many dead projects on here that never got past a dummy shell that prints hello world this is why
If UEFI booting from the CD is broken, can you really trust everything else?
no you can just:
- depend on the user to do it, or:
- plonk yourself in as BOOTX64.EFI.
are these good solutions? no. but plausible?
that's why I want to detect it not waste their time, there's a difference between not supporting it, and letting the user waste their time and not being honest up front
like if windows let you install windows 2000 on a machine with 4mb ram
Like this detection is probably more effort than just supporting BIOS
Yes, because people follow a (usually shitty) tutorial, which doesn't lead anywhere, and give up
Because a fancy "let's write a boot sector, target ia32, PS/2 driver that only works in QEMU and a kernel shell" YouTube tutorial is not cutting it
this is a reason, but it is not the only reason.
It's the usual reason
hey I started with a tutorial
like in 2009 or so
it didn't lead to what I wanted to create, just a other Unix clone, so I binned off 99% of it
I'm pretty sure that now 16 years later none of the tutorial remains
also the jamesm tutorial is full of bugs (that's the one I used)
for many overreach is a reason, they go down a rabbit hole of supporting every single system feature every processor feature, every mmu feature, adding drivers for everything they can get spec sheets for.... and it eats time, we are mortal and have finite amounts of it. my approach is targeted to just get a stable system up as quickly as possible and encourage others to build on it
yup... exactly.
that and they want a gui too and a window manager and ....
the fourth hardest thing in programming... scope creep
osdev is a tunnel of scope creep
people here try and lead me down the scope creep tunnel every now and again and it's "is this detour worth it to me"
They are not. 1. A really good load option would be invariant to the port where your disk is attached to, it's easy to achieve putting into the bootx variable a relative UEFI device path, that would identify your storage device, it's via HD() node, works both for mbr and gpt. How do you expect a user to do that? To write a bootx variable with a specific set of data. It's your installer work. 2. This is just lame. It's for live start for install. Moreso, it's only guaranteed to be processed for removable storages. For nonremovables, implementations may vote to not bother processing it, because it's a resort path if there are no other installations. Obviously, it won't work at all if the firmware will see boot variables from other installed oses. But eh, sigh, that's too "esoteric".
it depends on boot order
also all decent firmwares should recognize BOOTX64.EFI even on non-removable and at least give it as an option when explicitly entering the boot menu, I usually install grub both as removable and as non-removable for the reason that even if the nvram vars get nuked then it can be booted (though on modern pc fw's that's not so big of an issue as you usually have an efi shell/other way of choosing the efi file from the fs)
If a machine has at least 1 installation (bootx), the firmware will load it and will not load boot<arch>. efi in the "default" path. It's written out in the specification along with the optional nature of the "default" path processing for non removable storages. That is, it's optional even if the firmware didn't find anything "registered" to load (bootx). It's said, that then it should go and check for the default path on enumerated removable storages in no particular order and if there is nothing to load still, then, optionally, it may do the same for non removable ones. This far it's been put. Since it was not meant as a normal way for an OS installation (because of obvious reasons). Then if you are so inclined on using bootx64.efi allways, you'll have to break into firmware boot manager on every boot and go to that special entry. As of which, yes, it's very decent if the firmware has such, it's normally a "load from file" one, but then it doesn't need to be in the default path still, even better if it allows a full file system navigation through all the recognised partitions and allows to pick any efi file to start and still it's not an installation, it's rather a smart way of allowing for an OS to run the 1st time for the live or installation session. Oh, this reminded me how some vendors screw the boot manager, fkn aliens, yes, xiaomi, you, in the 1st place. 😂
bootx64.efi is the recognised fallback. in the case of retro rocket I flatten the disk so there's no other os to worry about. I just write out the efi part to boot only that
i basically started out by making a bootable image with limines installer and customised it a bit, then I write that to the esp
my pc have it
but why this table exists
@fiery turtle question
uacpi/types.h says UACPI_ITERATION_DECISION_NEXT_PEER is only applicable for uacpi_namespace_for_each_child, but in the wiki.osdev.org article its used in a uacpi_find_devices callback
which one is right 
match_ps2k also should take an extra param
both
uacpi_find_devices is a utility function
it just calls for_each_child under the hood
but ig the comment should be adjusted
to something like "only applicable for namespace iteration"
yeah the wiki is slightly outdated
what is the difference
like between NEXT_PEER and CONTINUE
continue makes it continue to the child, so depth first iteration
next_peer makes it ignore all children and move on to the next peer
for example if you detect that the parent is not present via _STA there's no reason to check children
np
Finally added a uacpi_for_each_subtable API for uACPI, no more handrolling MADT iteration
also updated the leaderboard, and fixed a comment from mathewnd
drafting a 3.1.0 release now
CC @dense steppe
good to know. thanks
new release, finally
mom my complaint is in the uacpoi changelogs I'm famous
real
real
Lmfao
@fiery turtle loongarch support wen
Wdym? It works on loongarch
and uacpi-rs should work out of the box there too
My OS supports it and it can shut the vm down with a power button press
then my uacpi was outdated 
maybe there are more bugs in uACPI 
What happens
There isn't any special code for loongarch support
i didnt see any code for the lpic
What sort of code? Like tables or what
yes
ah nvm i'm just blind
Yeah this was added very recently
Does this parse non-aml tables too in some way
so the kernel can get the data from them
or nah
@fiery turtle
im assuming no
Non aml? You mean acpi tables that don't contain aml?
Uacpi has helpers to access all acpi defined tables + maybe some more
thanks
It has a barebones mode that disables aml completely
kay
we have uACPI, when are we getting uDT - the next logical step 
i'm assuming it's another joke on the uXXX, but still - device tree support doesn't need much more than parsing a few fields, it honestly doesn't make much sense
when do we get uClksAndRegulators
nah, we need uKernel
LINuX 
ulibc
uDesktop & uBinutils
uOperatingSystem!
all you need to do is #include the header and call uInit_OpSys() and it gives you a fully working SMP capable multitasking network enabled kernel with ext4
imagine how many people you'd get saying they "made an os"...
cosmos
their Recommendations section makes this look really sus ngl
im trying to understand what is going on in an acpi dump (not mine) but its like
very weird
there are tons of methods that are just, not implemented???
Wdym by that
like iasl -d has External (_SB_.PC00.LPCB.H_EC.DPTF.SFHE, MethodObj) // 1 Arguments
and ```
Method (SFHT, 1, Serialized)
{
_SB.PC00.LPCB.H_EC.DPTF.SFHE (Arg0)
}
and nothing else containing the literal string "SFHT" in the entire dump
So you mean not called, not not implemented?
You mean SFHE?
Have you looked at SSDTs
whoever thought that four character names are a good idea
well yeah i mean this is from the ssdt
or what do you mean
Basically you've looked through every file but nothing contains the impl?
Load?
like for LoadTable or whatever
Is SFHT ever called?
ok no
but i have others that are called
Called from where
the OS
FN04._OFF looks like this: ```
Local0 = Acquire (FMT4, 0x03E8)
If ((Local0 == Zero))
{
CVF4 = Zero
Release (FMT4)
}
FNCL ()
the last instruction in FNCL is \_SB.PC00.LPCB.UPFS (ETMD, Local0, Local1)
UPFS has no impl either
What's FN04
fan number 4
Device (FAN4)
{
Name (_HID, EisaId ("PNP0C0B") /* Fan (Thermal Solution) */) // _HID: Hardware ID
Name (_UID, 0x04) // _UID: Unique ID
Name (_PR0, Package (0x01) // _PR0: Power Resources for D0
{
FN04
})
}
Its possible that either its STA will return 0, or that its never constructed in the first place because its behind some if
Or maybe its parents sta etc
wait how does STA returning zero work
Sta returning 0 means device doesnt exist
lmao what
Method (_STA, 0, Serialized) // _STA: Status
{
Local1 = Zero
Local0 = Acquire (FMT4, 0x03E8)
If ((Local0 == Zero))
{
Local1 = CVF4 /* \_TZ_.CVF4 */
Release (FMT4)
}
Return (Local1)
}
Method (_ON, 0, Serialized) // _ON_: Power On
{
Local0 = Acquire (FMT4, 0x03E8)
If ((Local0 == Zero))
{
CVF4 = One
Release (FMT4)
}
FNCL ()
}
Method (_OFF, 0, Serialized) // _OFF: Power Off
{
Local0 = Acquire (FMT4, 0x03E8)
If ((Local0 == Zero))
{
CVF4 = Zero
Release (FMT4)
}
FNCL ()
}
Yeah
this is the full code for FN04
Yeah as you can see its hardcoded as 0
well no
acquire returns zero if it succeeded?
Yeah
yea
i mean CVF4 is controlled by _ON and _OFF
which is what makes it even more confusing lol
Non present vs being off are different things
yeah
which is also like. weird.
Even if it returned 1
Sure, _OFF will get aborted
At the end
The os will just ignore the error
No one gets hurt
Firmware devs wouldn't even notice
Yeah errors like these are mostly silent, you can do anything
If it shuts down and boots just ship it
also there is some sort of interaction between their magic special windows driver and presumably the embedded controller that makes fans work after suspend
WMI?
Windows instrumentation stuff
i see
Some platform control via an XML inside an aml blob
do you know if there is some sort of api for doing EC stuff on windows?
Or something like that
Not that I know of
But there probably is
i see
@winter orbit might know more
i was wondering if this is the kind of thing the os would maybe fill out but ig not?
It’s kinda dependent on the era of windows
What are you trying to do
Nah thats not a thing
im trying to figure out how the fan control stuff on windows fits together
Like undefined references are very common on real hw, you just live with them
Especially on cutting edge stuff
In windows?
There’s a few things,
But pretty much the most common one is a interface guid Po asks for from ACPI
Ah
they wouldnt ship broken fans on windows
True lol
Is there any example / TLDR on how to use table only mode?
define UACPI_BAREBONES_MODE and use uacpi_setup_early_table_access
UACPI doesn't compile in eir 
since it includes intrin.h if _MSC_VER is set but the latter is true for UEFI binaries
and intrin.h is apparently unusable in freestanding
or wait, this may be a skill issue on my side
yeah nvm
Isn't intrin.h freestanding 
At least I think under clang it comes with the freestanding headers
Intrin should definitely be freestanding
yeah, ffreestanding was not passed correctly
Ah
uacpi in mscv mode on clang throws a lot of warnings
What sort of warnings?
i think all those should go away on latest aside from the mismatch sign check
maybe
i wonder why the warnings differ between msvc mode and non-msvc clang
becasue when compiling into thor we didn't get any warnings at all
uacpi used to check for _MSC_VER and disable half of the attribute macros
which clang defines as well apparently
ah
so the checks were reordered to check clang first
that would be appreciated
There is a function to check the current init level but AFAICT there is no way to check if early table access is set up, is there?
Is that something that the OS itself needs to track or would it be reasonable to add this API?
This would be useful when creating kernel images that support both DT and ACPI
PR made for DBG2 and SPCR
I didn't add all uarts in the DBG2 definition as constants so far, just the most useful ones
namely ns16550 and pl011
thanks, ill review them tomorrow
Wait what? Is this uACPI support for UARTs?
uART
uUART
How's uacpi-rs going
@rustic compass
well, uACPI doesn't get UART drivers, it just gets support for the ACPI tables that advertise UARTs
work for v1.0 is currently on hold until i finished my exams next week
Good luck
after that i try to focus on tables only mode first
however the table template code should already be finished, so you can implement tables if you want
ping for the review
Working atm
reviewed
those ACPI tables are horrible (not the implmenetation)
why?
They don't give you the full interrupt configuration
Stuff like polarity, if it's level triggered and so on
Unless I've missed something
well they give u GSI from which u can derive that no?
re:
Other tables in this file call this gsi
I tried to match the names in the Microsoft documentation for all field names. But I can also usegsiif consistency with the existing structs is more important
yeah id say consistency vs existing is more important
but no strong opinion if u think otherwise
nice
How do I derive it?
isa has default polarity/triggering
well, you can drive them in polling mode until you have full ACPI set up
which madt can override
and then you can use the namespace name to get the proper node and look up the full configuration
cool
(On loongarch)
uarts are not necessarily ISA though
i thought GSIs were always default config which matches ISA
unless specified otherwise
the issue with AML objects is that it gives you the UARTs, but you don't know if you can use them for logs
What if you have something other than terminal connected to them
yeah but both SPCR/DBG2 link to the AML nodes via the namespace_string field
Oh, ok
yeah
it gives u the path
Also why is DBG2 so weird
Why do they explicitly feel the need to specify the offset and count
¯_(ツ)_/¯
i also wonder if there is any uart in existence that has more than one base address 
probably not
lol
like firmware can just say ->offset = end;
and basically disable the table without doing anything
you can embed tables into tables 
i think it's more likely that it's done for forward compat
such that they could add fixed offset fields before the variable offset ones in a future revision
this has already been done in the past for SPCR if you look at the revision history
Changed Table Revision to 3 and created field for UART Clock Frequency. Edited formatting.
ohhh
for clarification: bit fields should still be #define, right?
yep
should i add all the obscure dbg2 uart types that are only found on weird boards? :^)
The more the merrier
Come on people, 1 more star till nice!
done (the PR comments)
Great thanks, in bed rn but will take a look tmrw
ping
pong
Reviewed like 10 hours ago lol
ah didn't see that
damn, infy you're really anal about coding style lol 
i'll fix it in a min
Just use clang-format 
Yes
doesn't exist
atp it'd have been faster if you added the tables yourself lol
well
What is it in uACPI style that clang-format can't express btw?
i didn't know that adding // Constants for foo instead of // foo was harmful
Code style violations cannot really be harmful
But why break existing code style where its not helpful
fixed
Thanks!
you can push to my branch and fix it
I dont think I can push into a fork?
you can push to PRd branches unless the PR owner opts out
best gh feature hands down
Ill read up on it
Isn't faster if u just do it if you're at your PC?
I'm on my phone atm
I can add you to the org if u want btw
So u get access to ci and branch creation etc
done
you should be able to approve the CI anyway
Yeah but id have to approve it every time, every force push and every pr etc
Started CI
nice thank you!
you know whats amusing is that it took me 3 attempts to get a PR merged into frigg because I (or rather my editor) kept stuffing up the whitespace 😅
neovim supremacy 
well yeah that was the problem lmao
good read
404?
fixed
ah
Insane
Least fucked up firmware
what in the actual fuck
this shouldn't be allowed
Jesus fucking christ this is bad
Who let the junior program an interrupt handler???
only good use of chatgpt so far

they fixed it since
They've had this bug for at least 3 years but are just now finding out about it 
bruh
just goes to show the only testing they do is booting and shutting down
They don't always even shutdown

Or well, reboot
A friend of mine has an Asus laptop and when they warm reboot it will halt the entire os couple minutes after the boot
It could be in the bios menu, in Linux or windows
More proof the average firmware dev is a moron
Btw the warm reboot problem doesn't affect Linux
jsut to make sure the Asus TUF GAMING B850-PLUS doesnt have such horrible aml or at least no (serious) problems are known?
How can I be sure that I implemented my uacpi glue correctly?
Hey buddy
Don’t reveal our secrets like that

You've been been doing a bad job guarding them, then

assuming it's not too far off from the tuf b650m-plus wifi then it's perfectly fine
Initialization sequence and using the APIs
Ah then my kernel works correct. Thanks g
Np
Wakeup babe a new acpi impl has dropped https://github.com/KaiNorberg/PatchworkOS/tree/main/src/kernel/acpi/aml
Seems like it's single pass (?)
uacpi in shambles
https://www.reddit.com/r/osdev/comments/1nr14jf/comment/nghc7ct/ according to this list its pretty incomplete
also looks recursive(?)
Yeah it looks incomplete
Recursive is not that problematic
when i wrote lai i made sure that it was mostly iterative
but now in retrospect i think that was a mistake
And it would be better to just use recursion while limiting the recursion depth
why is that?
Because it's far more sane to always run acpi on a large stack
there are real hardware blobs that have like 30 nested expressions
imo an aml interpreter shouldnt consume more stack than any other kernel thread
just throwing more stack at the problem doesnt solve it
it just delays the inveitable overflow 
I'm not saying that you should evaluate all expressions recursively
because you were writing a microkernel?
which part should be recursive then?
Probably function calls and edge cases
such as evaluation of _BBN when a opregion is initially used
yeah
It's just not worth it to make that iterative
Index fields are another really hard to solve problem
since they require other field access which may in turn also be Index fields
so unless u make a queue of field accesses its recursive
If we're talking about computational opcodes, these should ofc be iterative
imo the core interpreter must be iterative, but stuff like edge cases that are near impossible to trigger in the real world shouldnt be
yeah
yeah
thats what i meant initially because uacpi doesnt even try to solve those iteratively
but a recursive interpretaion of opcodes is kinda insane imo
even though they are designed recursively
hell, acpica doesnt even try to do Load/LoadTable iteratively
which violates nt compat also
yeah for most opcodes an iterative implementation is better
and probably even easier due to the context sensitivity of some aml
but i get why beginners try to do it recursively since its just so easy to get stuff working that way
like u just
parse_add()
val0 = parse_term_arg();
val1 = parse_term_arg():
return add(val0, val1)
until you notice that for example the interpretation of names depends on the context 
yeah thats the fun part
callop is for the weak
there are also fields that are sometimes read and sometimes not read depending on context
you have to know what called you to know what to do
its insane stuff
I refuse to believe they accidentally designed something so insane
It has to be intentional
uacpi_aml_op new_op = UACPI_AML_OP_InternalOpNamedObject;
uacpi_object *obj;
if (item->node == UACPI_NULL) {
if (!op_allows_unresolved(prev_op))
ret = UACPI_STATUS_NOT_FOUND;
break;
}
obj = uacpi_namespace_node_get_object(item->node);
switch (obj->type) {
case UACPI_OBJECT_METHOD: {
uacpi_bool should_invoke;
switch (prev_op) {
case UACPI_PARSE_OP_TERM_ARG_OR_NAMED_OBJECT:
case UACPI_PARSE_OP_TERM_ARG_OR_NAMED_OBJECT_OR_UNRESOLVED:
should_invoke = UACPI_FALSE;
break;
default:
should_invoke = !op_wants_supername(prev_op);
}
if (!should_invoke)
break;
new_op = UACPI_AML_OP_InternalOpMethodCall0Args;
new_op += obj->method->args;
break;
}
case UACPI_OBJECT_BUFFER_FIELD:
case UACPI_OBJECT_FIELD_UNIT: {
uacpi_object_type type;
if (!op_wants_term_arg_or_operand(prev_op))
break;
ret = field_get_read_type(obj, &type);
if (uacpi_unlikely_error(ret)) {
const uacpi_char *field_path;
field_path = uacpi_namespace_node_generate_absolute_path(
item->node
);
uacpi_error(
"unable to perform a read from field %s: "
"parent opregion gone\n", field_path
);
uacpi_free_absolute_path(field_path);
}
switch (type) {
case UACPI_OBJECT_BUFFER:
new_op = UACPI_AML_OP_InternalOpReadFieldAsBuffer;
break;
case UACPI_OBJECT_INTEGER:
new_op = UACPI_AML_OP_InternalOpReadFieldAsInteger;
break;
default:
ret = UACPI_STATUS_INVALID_ARGUMENT;
continue;
}
break;
}
default:
break;
}
op_ctx->pc = 0;
op_ctx->op = uacpi_get_op_spec(new_op);
break;
This is the bulk of logic in uACPI that decides what to do when it encounters a namestring, as u can see it only knows based on prev_op
No, i think it's just incremental changes by Microsoft without thinking about the broader context
How different is the current aml to acpi 1 aml
I'm 100% convinced that they didn't realize that RefOp can be used to create reference cycles etc
Can we retcon acpi into wasm
they didnt realize u can take a reference of a reference
Or that the handling of names within packages is insane
well tbh thats acpica shooting itself in the foot
nt doesnt handle names in a package
it just converts them to a string object
well yeah but then the caller needs to eval them in same cases


