#uACPI - a portable and easy-to-integrate ACPI implementation

1 messages · Page 6 of 1

fiery turtle
#

0 undefined references now

#

this means i can now up the coverage for real hardware blobs by a huge amount

#

before this i would get a whole bunch of errors while loading the DSDT

#

now the only error is

#

it hangs trying to poll for SMM response

#
Method (SMI, 5, Serialized)
{
    Acquire (MSMI, 0xFFFF)
    CMD = Arg0
    ERR = One
    PAR0 = Arg1
    PAR1 = Arg2
    PAR2 = Arg3
    PAR3 = Arg4
    APMC = 0xF5
    While ((ERR == One))
    {
        Sleep (One)
        APMC = 0xF5
    }

    Local0 = PAR0 /* \PAR0 */
    Release (MSMI)
    Return (Local0)
}
#

like bro

#

who tf designed this

vast kestrel
#

The only solution is to obviously port modern chipset to qemu and run the real bios in qemu

sterile egret
#

Don't take the coward's way out meme

flat badge
#

it's no surprise that tables from physical machines don't work in qemu

fiery turtle
flat badge
#

or userland, yeah

#

it'd say that's not even cursed, it's what ACPI is supposed to do, right?

#

abstract from the chipset

fiery turtle
#

yeah

#

except some tables don't have any time outs or anything like that and just wait forever

#

not all of them but a lot

#

so it makes it hard to test properly

#

and obviously there's no hardware to reply to their mmio write sadmeme

kindred beacon
#

you might be able to actually map some ranges using sysfs

#

so that you could perform mmio

#

(linux-only ig tho)

rustic compass
#

maybe QEMU needs a ACPI Hardware Emulator

fiery turtle
#

Indeed

fiery turtle
#

Let's see what the corporation ©️ has to say

left orbit
kindred beacon
#

Yeah that's not something for random blobs, more like for debugging your own shit

loud ice
#

i can assure you linux would not be happy with userspace doing its own acpi

fiery turtle
#

yeah that might uh

#

lets just say confuse the firmware

kindred beacon
#

Minor details

vast kestrel
#

just enable acpi mode again, whats the worst that could happen :^)

fiery turtle
#

or at least the ACPICA maintainer from intel is interested

hollow crescent
#

@fiery turtle Looking to add uACPI to Boron in the future. I noticed this API: https://github.com/UltraOS/uACPI/blob/master/include/uacpi/kernel_api.h#L85 void *uacpi_kernel_map(uacpi_phys_addr addr, uacpi_size len); and void uacpi_kernel_unmap(void *addr, uacpi_size len);

Boron's memory manager is a bit different in terms of these. Of course, it allows someone to reserve a range of memory in the kernel heap (called pool), however, the APIs for them look like this:

MIPOOL_SPACE_HANDLE MiReservePoolSpaceTagged(size_t SizeInPages, void** OutputAddress, int Tag, uintptr_t UserData);

void MiFreePoolSpace(MIPOOL_SPACE_HANDLE Handle);
#

I accidentally sent it too early, sorry

fiery turtle
#

wait how is this related to the kernel heap?

#

it maps a physical address

hollow crescent
#

It maps a physical address into memory

#

On AMD64 I could just add the HHDM offset to the physical address and be done but I may have ambitions of porting it to 32-bit x86 later

hollow crescent
#

you can map physical memory into a range you allocate with MiReservePoolSpaceTagged

fiery turtle
#

anyway, the only difference is your unmap function doesnt take in a size?

hollow crescent
#

no, the difference is that i have a special cookie identifying the range instead of the address being the cookie

#

it's done because tacking on a 4KB header to the memory range would be incredibly wasteful

#

so I slab allocate the headers separately

hollow crescent
fiery turtle
#

oh ok, well linux keeps a hash table of ACPICA mappings

#

you can do the same for uacpi

#

virt addr -> handle

hollow crescent
#

I was thinking of using an AVL tree for that but I don't like the prospect of having a log n access time

#

hash table sounds good but I don't have a facility for it in Rtl

#

so I'll want to implement it too

fiery turtle
#

yeah an avl tree might be overkill here

#

these map/unmap calls don't happen very often, so log n is definitely fine

#

mapping mostly happens on first opregion access lazily

#

if it goes out of scope then its unmapped

#

which usually doesn't happen since they're global "variables"

hollow crescent
#

I was thinking that maybe you'd want to add a cookie value returned by uacpi_kernel_map and passed into uacpi_kernel_unmap, but it's understandable if you don't want to

#

I could then pass my BIG_MEMORY_HANDLEs into that

#

but maybe I should just use a hashtable or whatever

fiery turtle
#

that's something to think about I guess

#

if more use cases for that come up I might do it like i did for sized frees for example

#

but its very unusual to have a handle in this case

#

why do you do it and whats the advantage?

hollow crescent
#

I do it because I want a way to track the memory regions dished out by the kernel pool manager and I don't want to tack on a 4KB header to each range nor do I want to give up the page aligned-ness of the ranges dished out

#

and I don't know of a better way to manage them without creating a circular reference, I guess

fiery turtle
#

why not have a separate data structure tracking these?

hollow crescent
#

thats the thing: the handles are actually just pointers to MIPOOL_ENTRY

#

which tracks that stuff

#

they're in a list tracked by the kernel

fiery turtle
#

and im guessing you dont have anything like struct page in your kernel?

#

that would save you the hassle

hollow crescent
#

I do, it's called the PFN database

#

but it manages physical memory

#

actually no struct page does that too

#

ignore my redundant comment

fiery turtle
#

couldnt your pfn database have a pointer back to MIPOOL_ENTRY?

#

for each phys page

hollow crescent
#

it could, but I only track usable memory with it, not MMIO

fiery turtle
#

hmm

tired crater
#

Doesnt a pfn db track what vas are mapped to a pas?

hollow crescent
#

and you give the kernel the virtual memory pointer that was returned in uacpi_kernel_map

hollow crescent
#

it really doesn't

#

that'd be horribly inefficient

tired crater
#

Oh so it‘s just some sort of struct page for you

#

Just differently implemented

hollow crescent
#

yes, my pfn database is the equivalent of the struct page database

tired crater
#

I see, sorry for interrupting: )

hollow crescent
#

Here's the definition of the PFN on Windows NT

#

Depending on its purpose

fiery turtle
#

how does windows solve this

hollow crescent
#

I don't know

tired crater
#

||read the source code galaxybrain||

hollow crescent
#

if only...

#

what I know is the PFN database has nothing to do with it

fiery turtle
#

yeah that makes sense

#

pfn database would only track actual memory

hollow crescent
#

anyway yeah probably just going to use a hash table

fiery turtle
#

id love to know how windows tackles this

hollow crescent
#

actually that goes in Ex I think since it'd use memory APIs, Rtl is strictly forbidden from doing so

hollow crescent
fiery turtle
#

but a hash table seems optimal as a solution for now

hollow crescent
#

like being able to use a pointer to a vm range to free it up

#

instead of requiring a handle to said range

fiery turtle
#

yeah but it still stores the entry somewhere

#

like theres still some metadata somewhere

hollow crescent
#

ye

#

maybe it doesn't even map physical memory into the kernel pool

fiery turtle
#

probably

surreal current
hollow crescent
#

this is about memory range management

surreal current
#

yes

hollow crescent
#

I don't remember

surreal current
#

there is a range of kernel space mapped by "system PTEs" which are allocated by a free list threaded thru the PTEs themselves

#

thats what they allocate virtual space out of

#

they free via the virtual address

hollow crescent
#

how is it threaded through the PTEs themselves

#

as in the PTE for 1 page below the first address is completely invalid and only stores the link to the next range or what?

surreal current
hollow crescent
#

but the way I'd do it with a free list heap is to shove in a small block above it to store details about the memory such as range and the entry within the list of entries, or whatever

#

so that's not going to work

surreal current
#

how does that not work

#

PTEs are just memory dude

#

they dont have to have meaningful values just make sure bit 0 is off

hollow crescent
#

.

hollow crescent
#

by completely invalid I meant, its present bit is zero

#

not actually completely invalid sorry

#

yknow this way also has the benefit of introducing a "guard page" type thing

#

the PTE whose present bit is zero and it has the pointer to the mipool_entry won't be treated as valid by the MMU so itll basically be like that

#

how didn't I think of this...

fiery turtle
#

thats actually pretty smart

fiery turtle
#

So right now I have this log message

#

Im thinking of maybe adding something like (N ops in N ms)

#

overkill or not?

#

e.g. successfully loaded & executed 25 AML blobs (129312 ops in 3ms)

#

or maybe even (1233 ops/s)

mortal yoke
#

I guess those could be fun statistics to know

fiery turtle
#

this is my thinkpad t14s

#

at O3 it runs 19611 in 92ms

#

O0 with ASAN is 1300ms

north holly
#

I can't wait to port uACPI to OBOS rewrite 5

#

and watch as all goes to shit it successfully initializes

fiery turtle
#

lol

north holly
#

right now I have to deal with the VMM nooo

fiery turtle
#

good luck

north holly
north holly
kind mantle
#

Last time I got stuck on ACPI before even trying VMM, thinking I needed to do it first :P

#

Since then I've learned to reinvent the wheel less, so I'm going to use uACPI

#

But that's gonna take a bit

fiery turtle
#

gl

#

Also since ACPICA fixed their broken ToHexString I had to come up with a different NT incompatibility example in the readme LULW

mortal yoke
#

also have you added or changed any of the tests recently? just curious because then I need to rerun them on qacpi lol

kind mantle
#

What's so different about it? Is this another case of Windows messing up and then "It's not a bug, it's a feature!" happening?

fiery turtle
#

but nothing huge

surreal current
fiery turtle
#

and since windows dominates the market it gets to decide whats right

kind mantle
#

Ah yes

north holly
#

Never forget, firmware devs are dumbdumbs

kind mantle
fiery turtle
#

like i'd say 50% of AML behavior is not covered by the specification at all

#

some simple things like ToHexString let alone complex stuff like reference semantics, or object lifetimes

mortal yoke
fiery turtle
#

to be fair it was mostly for testing uacpi API for table overrides lol

mortal yoke
#

yeah I don't have all of those reported (and the test runner part would fail too)

fiery turtle
#

funny enough acpica reports "AnotherTestString" as supported

#

because acpiexec enables it to test the api

mortal yoke
fiery turtle
#

btw qwinci if you have any input here you're welcome to post it: #1217009725711847465 message

#

perhaps you would be interested as well

fiery turtle
#

i have made a proper subsystem for that now

#

because i looked at how other systems use it

#

and its often enabled and disabled at runtime

#

e.g. from the kernel command line

#

or procfs

fiery turtle
#

its relatively small and should cover all use cases i think

mortal yoke
fiery turtle
#

yeah like js has a giant test-262 suite that covers literally everything

#

aml should have one as well

mortal yoke
fiery turtle
#

you can technically dynamically create new aml code as well

#

like IfOp EqualOp Arg0op StringOp

#

just "recompile" the method whenever a new interface is enabled or disabled

mortal yoke
#

ig that would work and its only a few ops so it wouldn't be that hard

fiery turtle
#

yeah u can even hardcode them as a byte sequence

#

well not hardcode because if has a package which has a length which depends on StringOp length

#

but idk if this is easier than just making a native method lol

mortal yoke
#

yeah for a native method it would basically just be a function pointer inside the method object and nothing more

#
  • a check for that function inside the place where a method call is dispatched
#

anyway this isn't really related to uacpi :p

fiery turtle
#

my native methods are kind of bad

#

like i didnt bother implementing it to an extent where it can be exposed to user

#

and i dont think its a feature that anyone needs anyway

#

my native methods just get passed the entire execution context and the return value object

mortal yoke
#

I guess you could do some fun stuff like load an almost empty dsdt with whatever scopes you need and then add methods to the scopes implemented as c functions

fiery turtle
#

yeah

kind mantle
mortal yoke
#

but yeah I don't really see a practical use for that other than doing it for the fun of it

fiery turtle
kind mantle
#

lol

fiery turtle
#

so its an opaque handle in this case

#

i need to deal with interpreter.c in the future anyway since its a giant 5.5k loc file

kind mantle
#

oof

#

That's big

fiery turtle
#

yeah its kind of annoying to navigate as well

kind mantle
#

I can imagine

fiery turtle
kind mantle
#

When files hit 1000 lines you have to consider whether it should be multiple

fiery turtle
#

probably

kind mantle
mortal yoke
fiery turtle
#

luckily i dont have a huge switch but rather a triply indirect array of function pointers instead LULW

kind mantle
#

What causes it?

mortal yoke
#

well it basically just doesn't merge the space that the variables you have inside the cases take, eg. c switch (whatever) { case 0: { Some4KbStruct a {}; break; } case 1: { Some4KbStruct b {}; break; } } this would take in total 8kb from the stack on debug builds because it reserves space for all the variables inside all cases not considering the fact that not all of the cases are ever entered at once (so it could use the same stack storage for a and b)

kind mantle
#

Oh it's that

fiery turtle
#

really strange considering there's a break

kind mantle
#

I avoid declaring any variables in switch cases

fiery turtle
#

like its impossible for both to be accessible

fiery turtle
#

oh nvm u literally do

#

even more strange

kind mantle
#

This is probably due in part to the fact that switch cases are labels in the compilers' eyes.

#

So it's like jumping to some label in arbitrary code, which kind of implies all of the stack is there.

#

And this would be an optimizer didn't see it type situation.

mortal yoke
#

actually it looks like gcc does merge them even without opts but clang doesn't

fiery turtle
#

u could probably even say its a bug

#

because its clearly unreachable from other branches

mortal yoke
#

yeah might be but considering its kind of an optimization to use the same storage for them I am not sure. I might ask in the llvm discord

fiery turtle
#

wouldnt u expect that storage to be allocated upon entry in the said branch tho

#

especially in debug

dawn pine
fiery turtle
#

somehow only appleclang complains when i forget to wrap my switches

kind mantle
#

I don't wrap my switches (yes, boo.) but I also never declare any variables within the confines of a switch case.

dawn pine
#

if not, doesnt matter

fiery turtle
dawn pine
#

oh

#

im pretty sure the standard says they have to have their own scope to declare variables but maybe im wrong

fiery turtle
#

for c++ definitely makes sense

#

for c i dont think it matters too much but probably

dawn pine
#

sometimes i forget C has different rules for this stuff

fiery turtle
#

yeah c doesnt have "constructed" object state i think so

kind mantle
fiery turtle
#

@mortal yoke speaking of tests, I also recently added infinite recursion and infinite while loop tests, Im guessing you probably dont handle that as well?

fiery turtle
#

Now that the test runner can load any extra number of SSDT I made it so the "large" tests that run 500 hw blobs against the runner also dump SSDTs and feed them along with DSDTs

#

That should really bump the coverage by a lot

#

because now all the undefined references should be gone

#

And apparently that already found a new leak

#

no other bugs unfortunately but still nice

#

this is how tests are generated

#

and each directory contains the tables

#
Method (_INI, 0, Serialized)  // _INI: Initialize
{
    ADBG ("Hello World!")
    If ((GGGG () == One))
    {
        GGGC = (GGGC | 0x00040000)
    }

    GGGC = (GGGC | 0x10)
    GGGC = (GGGC | 0x20)
    GGGC = (GGGC | 0x40)
    PFM0 ()
    GGGC = (GGGC | 0x80)
    GGGC = (GGGC | 0x00010000)
    PDS2 ()
    GGGC = (GGGC | 0x0800)
    EVT0 ()
    GGGC = (GGGC | 0x2000)
    EZV5 ()
    DIM0 ()
    GGGC = (GGGC | 0x00080000)
    PTC0 ()
}
#

what the fuck

#

me when i ship debug "hello world" logs in release build

#

also something is telling me the way i generate checksum is wrong lol

#

oh nice i can reproduce it from just feeding ssdt8 alone

#

what the fuck

#

Name (MARK lmao

#

aight found the memory leak, pretty nice

#

anyway that aml was so brain damanged i think i lost a few braincells

#

this was the code causing the memory leak

#

should I email this mark guy and tell him that this is insane

#

imagine creating operation region and fields in local scope

torpid root
#

noice

fiery turtle
#

ngl this shit is really annoying

hollow elm
fiery turtle
#

Lol

hollow elm
#

perhaps we should do another round of fuzzing

fiery turtle
#

Lol

#

Now that it can load ssdts from the command line perhaps the coverage could go up

loud ice
#

if you have a problem you know which hw engineer you need to complain to

fiery turtle
#

Its funny that he made it an actual global object that has to consume memory at runtime

loud ice
#

does it matter

#

its like 10 bytes

fiery turtle
#

Well the namespace node overhead as well

#

And all the metadata

loud ice
#

oh wow yeah another 8 bytes

#

so bad

#

how will we recover from this crazy loss of less than one page table

fiery turtle
#

Yeah on uACPI it would take up about 40 ish bytes

loud ice
#

how much memory does uacpi use, total?

#

and have you heard of pointer compression :^)

fiery turtle
#

He could make it a method and store the string there tbh, then it wouldn't even consume anything

loud ice
#

harder

#

probably

#

or something

#

anyway you have his email

fiery turtle
loud ice
#

so lol

loud ice
#

you store uint32(pointer - offset)

#

v8 does this btw

fiery turtle
#

Offset to what tho

loud ice
#

the place where all the pointers go

fiery turtle
#

Like a separate table?

#

I feel like to implement this properly you would need the client to coordinate with you

loud ice
fiery turtle
loud ice
#

i mean

#

with the average aml

#

you have lots of aml, just calculate heap usage per byte of aml

fiery turtle
#

Average aml is probably a thousand objects, maybe 64-128 kib

loud ice
#

thats quite a bit, huh

fiery turtle
#

Yeah it's pretty huge

loud ice
#

implement pointer compression then :^)

fiery turtle
#

Dtbs are also probably in the neighborhood tho are they not?

fiery turtle
loud ice
#

in memory they are expanded, i guess

loud ice
fiery turtle
#

But for pointer compression I would need the host kernel to promise me some invariant about the heap location

loud ice
#

true

fiery turtle
#

I could make it optional ofc

loud ice
#

or play weird games around allocations

#

like, allocate memory in chunks of X

#

and then have your own malloc over those chunks

fiery turtle
#

Ye probably

loud ice
#

and then store the index into the chunk or something

#

that sounds quite ugly ngl

fiery turtle
#

All of aml memory is pageable tbh so

fiery turtle
loud ice
fiery turtle
#

You can probably page most of it and it will never be touched again

loud ice
#

for most things

fiery turtle
#

Like that Marc object

fiery turtle
#

Like the kernel knows the heap limits

#

Especially if its a per object heap

loud ice
#

my object heap is bounded to [base of direct map + phys base of first usable entry, base of direct map + phys end of last usable entry)

#

(and it's per-object slabs already)

fiery turtle
#

Thats quite large right

loud ice
#

yeah quite possibly

#

and its not compile time known either

#

i guess it depends on how you architect your kernel heap though

fiery turtle
#

Yeah

loud ice
#

if you have a paged kernel heap then you can probably guarantee that much more easily

#

or possibly just give uacpi a private heap

fiery turtle
#

Yeah thats what I would do

#

Just allocate a paged heap

#

There are some objects you need more often, like stuff used for polling fan/power usage/battery

#

But other stuff is just dead forever

loud ice
#

implement an AML JIT to compile only the parts of AML that you want to optimized code :^)

#

i mean technically they could use dynamic aml loading or whatever but like, what if no

loud ice
fiery turtle
#

Probably doable

loud ice
#

honestly that might be not even too crazy

#

like if the aml isn't recursive, then you can probably just inline everything aggressively

#

and do a linear scan regalloc or something over that

fiery turtle
#

Problem is aml byte code is super high level

#

You would have to compile it into a lower lever bytecode

loud ice
#

i mean you always do lowering when doing jit

fiery turtle
#

Then yeah

hollow elm
#

at least this 2 year old copy i have is

fiery turtle
#

And thats a flat version so yeah

#

Expanded will be way bigger

rustic compass
#

Can I access the acpi tables without heap allocations ?

loud ice
#

yes

rustic compass
#

Perfect

fiery turtle
#

they're stored in ACPI reclaim memory

#

if u dont reclaim it u can keep using it

rustic compass
#

And uacpi doesn't need the heap to make them accessible via its table api?

fiery turtle
#

not directly, no
but they're installed as part of uacpi_initialize, which absolutely does use heap a lot

#

primarily to allocate mutexes etc

rustic compass
#

Would be cool if at least the Numa tables are accessible via a basic no heap api

#

Like acpica does it with a table init (which sadly needs at least some heap and can't use the tables directly from memory)

rustic compass
#

For example the srat table should be read before you start to init the pmm to prevent any pmm internal allocator from crossing a Numa domain, and for that it's sufficient if i could iterate over the srat or index it like a array to get the needed ranges one by one without any heap allocation

#

Sure I could do it myself for my kernel but it would be thematically better located in uacpi if possible

fiery turtle
#

Ill add this to the to-do issue

fiery turtle
#

I might even prioritize this tbh

#

its ridiculous to not have table api available before pmm init

rustic compass
fiery turtle
#

this 1995 motherboard says ACPI BIOS in the settings

#

would be so cool to get a dump from that

leaden fox
#

🙏🙏🙏

rain nimbus
#

Alternatively you could always just build a time machine and just go back to 1996 :>

rain nimbus
#

Yes

kind mantle
#

sound advice

fiery turtle
#

Alright ship me the parts ill build one

dawn pine
#

my delorean is on the way

sterile egret
#

ah wait lol

sterile egret
#

heh, the release notes are included inside the BIOS flash disk image

#

It's just slightly too old. It uses the PIIX3 chipset, and ACPI support was added with the PIIX4, which corresponds with a 430TX or 440LX northbridge, Then "PIIX4E updated the ACPI support", which would be 440BX, 440GX, and also 440EX, 440ZX, and 450NX (fucking Intel with shitty naming schemes amiright?)

#

Hmm, 86box lists a 440LX machine...

sterile egret
#

what a bios though lmao

#

Okay, some of the 440*X machines in 86box do have ACPI support

hollow elm
left orbit
#

why would the bios setup screen have an anti virus option lol

#

honestly this looks more usable than most modern firmware uis

surreal current
#

boot sector viruses were a big thing then

left orbit
#

thats cool i guess, sort of makes sense

rain nimbus
surreal current
#

probably that

sterile egret
sterile egret
#

well, more like 2/3 but still lol

rain nimbus
#

motherboard manufacturer: how large of a bios rom do you need?
American Megatrends: yes

surreal current
#

could easily fit all that in 128-256k

#

macs had 2mb roms by then

rain nimbus
#

Yes but at the time that would be a lot...

surreal current
#

not rly

#

mid 90s? nah

rain nimbus
#

For a bios rom it would've been xD

surreal current
#

no

rain nimbus
#

Iirc my motherboard only has a 256 MB one lmao

hollow elm
#

i don't think it needs that much rom?

#

that looks like text mode with a custom char set to me

rain nimbus
#

Yeah probably

hollow elm
rain nimbus
#

Nvm it's a 256 Mbit rom

#

So 32 MB

hollow elm
#

that sounds much more plausible

rain nimbus
#

Same as how much storage I'm putting on led matrix panels O_O

#

because who knows how much storage is needed during development

hollow elm
#

i wouldn't be surprised if dev versions of motherboards had larger flash chips

rain nimbus
#

Time to buy a 4 Gbit rom and swap out the one on my motherboard kekw

fiery turtle
#

I see that ACPICA has an ability to disable early table verification, which allows not to map the entire table but only the header initially

#

so all early mappings are 4k only

#

What im not sure about is whether this is needed or useful

#

it breaks the invariant that i currently have which is all tables in the array are mapped and valid

#

if a kernel can map 4k it can alos map a multiple of 4k i assume??

#

okay I see linux needs it because it has a limited number of early map slots

#

jesus ACPICA has so many workarounds for linux lol

#

init functions that check random things that are client dependant and generate errors based on that

rustic compass
fiery turtle
#

and ACPICA optionally always maps only the header which is fixed size

#

(during early init)

#

which is a workaround for when u dont have enough slots to map things during early init

#

which makes sense but idk if this complexity is needed

#

e.g. for stuff like limine it would just do hhdm + phys addr

rustic compass
#

Imho I would take the simple route but add the possibility (like table_init(tables_not_mapped: bool) that later allows to support the complex path in a sane way (like using internal buffers for all of the static stuff and reading any acpi tables with a x pages big moveable virt to phys window )

#

Or add it as a compiler flag

#

The question is what percentage of currently used bootloader for 64bit systems don't provide any kind of identity map.

#

In the long run uacpi should support both paths but for now implement the simple route and think about sane ways for the complex path

left orbit
#

limine doesn't do identity mapping

#

as of protocol base revision 2 that is

#

or 1, i dont remember

rustic compass
left orbit
#

yeah, that's hhdm

#

you'd somehow have to make uacpi aware of that

rustic compass
#

Maybe give it the Offset directly

#

Or let it make the usual map requests and you can simply return the virt address

left orbit
#

so... basically force the kernel to "deal with it"

#

back to square one

rustic compass
#

It boils down to two paths:
Acpi tables premapped by the bootloader
Acpi tables not mapped

#

Only the second path needs discussions

rustic compass
#

As a side note making uacpi identity-offset-mapped + detail level (only tables, tables + acpi NV memory, ....) aware could be a nice optional feature

rustic compass
fiery turtle
#

Thoughts on:

  • Pass RSDP pointer to uACPI directly
  • Have uACPI request the RSDP pointer via some API
#

The latter is what ACPICA does

#

the idea is that each arch has its own way to store it so you would have to make a per-arch wrapper to get RSDP

#

but if you're using stuff like limine your RSDP is always in the same place so its not needed

#

Any ideas whats better

fiery turtle
#

thats what i think as well

#

i dont get the idea of making some mandatory api that will be called exactly once

#

I was thinking like what do I do if i'm unable to allocate some ciritical data structure during init, like a mutex, or a spinlock, or a predefined namespace object, etc etc

#

so I just added this

#

I wanted to prevent being able to spam uacpi_initialize multiple times and cause it to enter an invalid state

#

now this init level locked_up should prevent that

hasty plinth
loud ice
#

i.e. first allocate the entire required reservation

#

then do any init required

fiery turtle
#

so some inititialization must be done before another can proceed

#

which requires allocations to begin

loud ice
fiery turtle
#

well technically everything is possible

loud ice
#

i mean okay

#

i'll reword it

#

why does parsing the FADT require memory allocation

fiery turtle
#

basically

#

GPE block creation happens after namespace initialization

#

because u need to match AML handlers

#

which only exist after u parse the namespace

#

so its very very late init

#

its not even FADT tbh

loud ice
#

i see

#

can you execute arbitrary aml before this point?

fiery turtle
#

yeah, after uacpi_namespace_load and before uacpi_namespace_initialize u can execute anything

#

gpe creation happens in namespace_initialize

loud ice
#

ah i see

fiery turtle
#

like its probably even dangerous to operate the computer if u enter acpi mode and then event initialization fails

#

because if firmware wants to run aml to do something relating to power or fans and u dont have SCI set up u wont run it

loud ice
#

nah its probably fine

#

its not like good

#

but its also like

fiery turtle
#

worst case it will auto shutdown

loud ice
#

yeah

#

which is fine

#

well "fine"

fiery turtle
#

ye

loud ice
#

honestly, how much aml is written to assume oom won't happen

fiery turtle
#

all of it lmao

loud ice
#

then don't handle oom

#

at all

#

force the os to sleep

#

or alternatively write your interpreter with coroutines

fiery turtle
#

aml doesnt even have a notion of oom or any failure whatsoever

loud ice
#

so you can suspend execution

surreal current
fiery turtle
#

yeah

surreal current
#

for that reason

#

i mean im just guessing

#

good way to avoid oom since you can allocate like 200gb paged pool

fiery turtle
#

like we're talking non existant cases here to be clear

loud ice
#

imo: don't handle oom

fiery turtle
#

allocations happen very early when u dont even have userspace brought up

loud ice
#

just crash if you experience it

#

or hang until you do have memory

#

or something

fiery turtle
#

so u have all the memory in the world

loud ice
#

there's literally nothing you can do about it

fiery turtle
surreal current
#

oom during initialization is usually a failure case anyway

#

i mean

#

thats when you want to move all the oom cases ideally

#

is to initialization

#

of whatever thing

#

oom at runtime is the scary thing

fiery turtle
#

my policy has been no panic handlers or fatal failures from uacpi, so i just return the failure to the caller from the init function and make sure uacpi state is locked up, and all further calls to any api will return UACPI_STATUS_INIT_LEVEL_MISMATCH

surreal current
fiery turtle
#

like ooms when u run normal aml are fully handled in uacpi, they dont lead to state corruption or anything

#

its the early init that allocates critical stuff that matters

loud ice
fiery turtle
#

well they abort the call

loud ice
#

is aml written to handle such aborts?

fiery turtle
#

nope

loud ice
#

(no)

fiery turtle
#

u just stop executing it and say sorry no memory

loud ice
#

well then aml state will be fucked afterwards anyway

#

just crash

fiery turtle
#

yeah it would be unpredictable

loud ice
#

which is not good

#

crash, or sleep

fiery turtle
#

the "global variable" state

loud ice
#

those are the two options

surreal current
#

its probably fine if all AML were written to do all allocations at initialization time

#

but i doubt thats the case

fiery turtle
#

well that's up to the kernel in uacpi_kernel_alloc, i would just use the flag that makes the allocator spin forever

#

thats really not a place u want to fail an allocation

fiery turtle
#

imagine using a ridiculously high level language for firmware runtime

loud ice
#

yeahhhh

#

but i don't think it matters

#

its not realtime

fiery turtle
#

eh

#

considering it may lead to state corruption

loud ice
#

you dont really have to write oom-safe code

#

because you can just wait for the oom to not be oom anymore

#

and then proceed on allocating

fiery turtle
#

yeah

#

it's oom safe in the sense that it won't segfault or leak any more memory on oom

#

i think its a good goal to have for a generic library

torpid ferry
fiery turtle
#

I'm scrapping this

#

any fatal uACPI initialization error will just cause uACPI to automatically call uacpi_reset_state

#

which will just free everything and zero global state

#

so u can just spam uacpi_intialize to your hearts content

#

the problem is i must first implement uacpi_reset_state...

#

this helper will also be useful for will who wanted an ability for uACPI to free anything heap allocated prior to shutdown

#

in order to detect leaks easily

#

i'll add something like a uacpi_cleanup_state_at_shutdown(true)

#

(at some point TM)

fiery turtle
#

also just merged@jaunty fox

rustic compass
#

whats the current problem with pre heap table init if any?

fiery turtle
#

it's not implemented LULW

#

thats the problem atm

#

it's blocked on another issue, which is blocked on another issue

#

some internal refactoring before i get there

rustic compass
rustic compass
fiery turtle
#

uhh well not sure, maybe once i figure out the exact steps

#

is this something you're blocked on?

rustic compass
#

nope just bored

fiery turtle
#

i see

rustic compass
#

it would be a problem if i were that far with my code that i need numa from the start LiPerformDelisquesceUponObjectW

fiery turtle
#

lol

#

atm the problem is in order to implement early table init I need (or want):

  1. design API to either enable or disable early full table mapping, which requires:
    • "table array only contains verified and usable tables" invariant breakage
    • introduction of flags for current table state
    • distinguish between "early" mappings and "late" mappings, because this might need different in-kernel mechanisms to map, which requires:
      • mapping ref-count
      • "table always mapped" invariant breakage
  2. Additional code for accepting fixed early storage for the table array
#

basically lots of annoying things that together need a lot of mental gymnastics

#

thats just off the top of my head

#

basically everything i need to do in uACPI is composed of these annoying recursive problems

#

but i will have to do all of it to get to 1.0

#

initially i got rid of table mappings ref-count because i thought well tables are so small that it doesnt matter i can just keep them mapped at all times

#

and the ref count system was making everything harder than it needed to be

#

but now i have to bring it back

#

as well as any api surrounding it

#

like uacpi_table_put/unref

#

like its possible to hack together a shitty early table init system very quickly

#

but it would be shitty and non extensible

#

i kinda try to do things the right way with uacpi

#

Thats why its easier to procrastinate KEKW

rustic compass
#

i feel the same

north holly
#

best way to procrastinate is by playing mc

#

I delayed fixing a bug by about 2 weeks by doing that

fiery turtle
rustic compass
#

how about splitting the table init into a heapless and a heap version which are independent from each other

#

the number of tables that could be relevant at pre heap is small and that api could work with in place accesses and iterators

fiery turtle
#

I want to steal the ACPICA approach where its optionally supplied with a fixed length buffer at init, then replaced with a heap array when subsystem_initialize is called

rustic compass
#

"but why"

fiery turtle
#

And it also accepts extra flags like whether its allowed to resize the array etc

fiery turtle
#

And the pre heap buffer can live in an init section that is freed by the kernel after init

#

Like __init in Linux

rustic compass
#

but then you have the problem that you cant know the required size for the buffer

fiery turtle
#

I mean, uacpi doesn't know either right

#

It depends on the system

#

Just allocate a reasonable large one

rustic compass
#

well that what the in place reads would be for

#

1GB KEKW

fiery turtle
#

U mean like dont store the metadata anywhere at all?

#

Just walk the xsdt every time?

rustic compass
#

either that or store fixed size addresses and tables and fall back to iteration for dynamically sized tables

fiery turtle
#

Can u elaborate, im not entirely sure what u mean

rustic compass
#

the pre heap system would work with a known table list so each table that has a fixed size by the spec can be read into compile time allocated storage and for all tables that have a unknown size a iterator would be used where the table would be accessed like a array

#

if you need allocations do it in a way that is known at compile time

fiery turtle
#

Oh I see

#

I already do this sort of for FADT

#

Problem is NUMA tables are variable width KEKW

#

The ACPICA approach is metadata goes into a kernel provided storage buffer, and the tables are mapped on demand

#

The tables themselves are not copied anywhere

#

Metadata is just refcount, flags, address, signature , length

rustic compass
#

the metadata is also known at compile time, number of possible entry types and their layout

fiery turtle
#

Not this sort of metadata

#

Like internal bookkeeping

#

Every table listed in xsdt gets an entry in this array

#

So u can look them up quickly

#

And then map when requested by the early code

#

And obviously with limine and stuff this mapping is also almost a no op

#

So it solves the issue I think

rustic compass
#

" address, signature , length" those are compile time known sizes if the amount of accessible tables is known at compile time, which it is for the pre heap api

fiery turtle
#

U mean like the struct is known size?

rustic compass
#

the ability to make uacpi aware of identity offset mapped acpi tables/nvs could be usefull

fiery turtle
#

Well yes

rustic compass
#

yes

fiery turtle
#

The only reason why the kernel reserves this static buffer and not the library is to wrap it in a special section optionally or not provide it at all

#

Which frankly all current users of uacpi will end up doing

#

But I could wrap it in a macro ofc

rustic compass
#

maybe a compile time flag to disable the preheap api to reduce filesize if thats a concern?

#

or what exactly is your concern?

fiery turtle
#

Just a useless pre heap array

#

That cant be reclaimed back and wont even be used

rustic compass
#

Then the api would need to walk the table tree each time or move the metadata on the stack

fiery turtle
#

noo, just let the kernel provide the static buffer for the metadata

#

which uacpi will be using prior to heap availability

#

my point is since this is a feature for advanced kernels making it more opt-in is better imo

rustic compass
#

I will write down a example tomorrow

#

Just don't use the pre heap api

#

And write down it's ub to use it after heap table load

fiery turtle
#

i think im also not communicating super clearly, ill give u an example of how this will work later

#

or not will, rather the idea that i had at least

rustic compass
#

Anything will be helpfull

fiery turtle
#

yeah

#

too bad i found this mc modpack which takes 4000 hours to beat

tired crater
#

which one is it

sterile egret
median crest
#

can agree, procrastinating by playing factorio rn

fiery turtle
north holly
#

forge mod I assume?

tired crater
fiery turtle
#

This one

tired crater
#

Oh

#

I thought of distant horizons

#

Which runs like crap on my igpu

jaunty fox
jaunty fox
#

i want to implement NUMA-partitioned allocator for keyronex in the future and i'll need to look at acpi's slit and srat as part of allocator init

fiery turtle
#

yeah thats the usecase

loud ice
fiery turtle
#

I mean it has a finite quest book and a surprising amount of people have beaten it

#

Even multiple times

loud ice
#

i mean

#

4000 hours, 12 hours a day, is like

#

a year of minecraft

fiery turtle
#

Yeah

loud ice
#

or you mean 400 not 4000

fiery turtle
#

No, 4000

#

Its a famously hardcore pack

#

Its a lot of chemistry and automation and stuff

#

U need millions of resources for end game machines

loud ice
#

jesus christ

#

that sounds not fun

#

i'll stick to factorio where "long" is defined as something closer to 400 not 4000 hours

fiery turtle
#

Since the progression is so slow every minor milestone feels rewarding af

north holly
fiery turtle
#

yeah

#

end game there is crazy, like giant multiblock machines

north holly
#

if I were to install it, would my computer be killed near-instantly

#

actually let me reword that

#

is it resource-intensive

fiery turtle
#

i was able to run it just fine on my steamdeck

#

5gb of ram is recommended

north holly
#

is it graphics intensive

fiery turtle
#

its the normal 1.7.10 minecraft

north holly
#

then I guess I'll install it (later)

fiery turtle
#

the quest book is super good as well

#

it tells u what to do and gives advice and stuff

#

u unlock more stuff as u progress

#

branches

#

u can automate renewable energy, or use oil, or use steam etc

loud ice
north holly
#

of course

fiery turtle
#

its basically a different game tbh, since they redid everything

#

all recipies, mobs, ore spawning, biomes

loud ice
#

still

fiery turtle
#

they backported new mods to it

#

the pack is 10 years old

north holly
fiery turtle
#

very polished and coherent basically

fiery turtle
#

if u found iron, u found thousands of it

#

etc

north holly
#

oh I thought you meant 1.7.10 was that different from newer mc

fiery turtle
#

nah

north holly
#

anyway I have a stupid bug to find

fiery turtle
#

gl

north holly
#

a page that is pageable, and paged out, is reported as non-pageable and paged-in

#

in its page node

fiery turtle
#

lol

#

asan not finding anything?

north holly
#

nope

#

and the rest of the node is fine too

fiery turtle
#

damn

north holly
#

the protection field says the page is present (it's not)

fiery turtle
#

lol

north holly
#

it also happens on a different address each time it crashes like this

hollow elm
north holly
#

anyway that's enough littering your thread

north holly
#

not just the mapping part

#

silly me

fiery turtle
#

does it work now

north holly
#

I think

fiery turtle
#

nice

north holly
#

time to make the PR to merge the VMM with master

rustic compass
loud ice
#

not 4000

#

so yeah

rustic compass
#

@fiery turtle here is my example, currently only extended for the srat
all required metadata is stored in the table structs on the kernel stack

struct SRAT {
    address: u64,
    version: u64,
    valid: bool,
    entry_type_length: [u64; 0],
    entry_type_index: [u64; 0]
} //System Resource Affinity Table


struct SLIT {} //System Locality Information Table

struct PPTT {} //Processor Properties Topology Table

struct PMTT {} //Platform Memory Topology Table


fn RSDP_get_SRAT() -> Option<SRAT> {}
fn RSDP_get_SLIT() -> Option<SLIT> {}
fn RSDP_get_PPTT() -> Option<PPTT> {}
fn RSDP_get_PMTT() -> Option<PMTT> {}


//SRAT
fn SRAT_isvalid() -> bool {}
fn SRAT_version() -> u64 {}

fn SRAT_get_number_entries_S_APIC(&SRAT) -> u64 {}
fn SRAT_getEntry_S_APIC(&SRAT, index:u64) -> Option<APICEntry> {}
fn SRAT_getEntry_S_APIC_Iterator(&SRAT) -> Option<APICEntry> {}

fn SRAT_get_number_entries_Memory(&SRAT) -> u64 {}
fn SRAT_getEntry_Memory(&SRAT, index:u64) -> Option<MemoryEntry> {}
fn SRAT_getEntry_Memory_Iterator(&SRAT) -> Option<MemoryEntry> {}

fn SRAT_get_number_entries_x2APIC(&SRAT) -> u64 {}
fn SRAT_getEntry_x2APIC(&SRAT, index:u64) -> Option<x2APICEntry> {}
fn SRAT_getEntry_S_APIC_Iterator(&SRAT) -> Option<x2APICEntry> {}

fn SRAT_get_number_entries_GICC(&SRAT) -> u64 {}
fn SRAT_getEntry_GICC(&SRAT, index:u64) -> Option<GICCEntry> {}
fn SRAT_getEntry_GICC_Iterator(&SRAT) -> Option<GICCEntry> {}

fn SRAT_get_number_entries_GIC_ITS(&SRAT) -> u64 {}
fn SRAT_getEntry_GIC_ITS(&SRAT, index:u64) -> Option<GIC_ITS> {}
fn SRAT_getEntry_GIC_ITS_Iterator(&SRAT) -> Option<GIC_ITS> {}

fn SRAT_get_number_entries_Generic_Initiator(&SRAT) -> u64 {}
fn SRAT_getEntry_Generic_Initiator(&SRAT,index:u64) -> Option<Generic_Initiator> {}
fn SRAT_getEntry_Generic_Initiator_Iterator(&SRAT) -> Option<Generic_Initiator> {}
fiery turtle
#

like why do we want to store it somewhere

#

its already in reclaimable memory

rustic compass
#

The return value only contains additional Metadata the tables stay in reclaimable memory

#

You can access the api without a heap and only need the stack and the required memory is known at compile time

fiery turtle
#

but why is this api needed?

rustic compass
#

The returned struct could also contain static parts of the table if you want to optimize it

fiery turtle
#

why cant u just use the normal uacpi_table_find api

#

then cast the pointer to the SRAT table

rustic compass
#

Because it needs heap?

fiery turtle
#

why?

#

if you mean as it currently stands, then yeah

#

but it doesnt inherently need heap

rustic compass
#

Well it needs managing chunks of memory doesn't it?

fiery turtle
#

managing how? it just maps the address pointed to by the XSDP

#

currently there's an array of table descriptors that uses heap

#

but a -- its tiny, and b -- i can request the kernel to provide a placeholder buffer before the heap is available

#
struct uacpi_installed_table {
    uacpi_object_name signature;
    uacpi_phys_addr phys_addr;
    union {
        void *ptr;
        struct acpi_sdt_hdr *hdr;
    };
    uacpi_u32 length;

#define UACPI_TABLE_LOADED (1 << 0)
    uacpi_u8 flags;
    uacpi_u8 origin;
};
#

this internal struct is used for each table, these structs live in an array

#

the array currently has a fixed static length of 16, after which it grows into heap

#

i want to redesign it so that its always heap unless user explicitly provides a static buffer

#
#ifndef UACPI_STATIC_TABLE_ARRAY_LEN
    #define UACPI_STATIC_TABLE_ARRAY_LEN 16
#endif

DYNAMIC_ARRAY_WITH_INLINE_STORAGE(
    table_array, struct uacpi_installed_table, UACPI_STATIC_TABLE_ARRAY_LEN
)
#

this is the current impl

#

what i dont like about this is they leak the internal table descriptor into a public header to allow proper storage sizing

#

but its not necessary, u can just take an annoymous byte buffer

vast kestrel
#

I mean, you really don't need acpi as early as before you initialize a simple heap

#

So requiring a heap is really not that out of the question

fiery turtle
#

because heap init really depends on numa

vast kestrel
#

For a simple early alloc it really doesn't matter

fiery turtle
#

probably, but linux decided it does

vast kestrel
#

If it really wants to access srat that early just parse it yourself

#

It's not like parsing acpi tables is a complex task

fiery turtle
#

tbh

vast kestrel
#

Like have an early get table that just parses in place

fiery turtle
#

its also not hard to give access to tables without a heap

#

so whatever works

vast kestrel
#

Like, you need to be able to map memory anyways, which requires at the very least a page allocator

#

Idk how many allocations the table init does but if it fragments up to a single page size it really doesn't matter

#

And that small array wouldn't go over a page size anyways

fiery turtle
#

but u must unmap everything before it proceeds to later init

vast kestrel
#

For I in memory map
If bigger than needed for alloc
Length -= size
Return ptr

#

a l l o c a t o r

#

But tbh if all you need is like srat for early init, have a function to parse the rsdp in place every time and use that

fiery turtle
#

but like

#

u just imported that giant acpi library

#

so would be nice if it provided thta functionality

#

especially since u dont really need the heap for table iteration

vast kestrel
#

You can expose your table iteration as a function that takes a callback

#

So that it also does map&unmap as required

fiery turtle
#

i actually have that internally lol

#

its just not exposed

vast kestrel
#

You could expose that then and have that be the API

fiery turtle
#

yeah

vast kestrel
#

Have it map and unmap internally so nothing would leak and then the early slots would be happy

#

And if someone wants to save pointers into that data it's their job to figure how to allocate it

fiery turtle
#

acpica just says "u figure it out lol"

#

if u dont unmap then it logs a warning during late acpica init

#

if u try to unmap it later the kernel will crash

#

because it will use late unmap for early mappings

#

it just has a ref-count per table of how many times it was requested

vast kestrel
#

I always prefer to have the allocator be the one that frees unless it's absolutely required someone else will do it

fiery turtle
#

yeah

vast kestrel
#

Linux has some very annoying functions where on some failure paths you need to free and on other failures or success paths you don't need to free

#

And it always causes strange leaks

fiery turtle
#

true

vast kestrel
#

I have found multiple net drivers where in a failure path from the hardware they would accidently leak the skb it's just annoying

fiery turtle
#

giant net drivers written by 2 outsourced people are a constant source of rces lol

#

they have like 20k loc .c files

#

that no one ever reviewed

rustic compass
#

So when the temp buffer in uacpi is implement I will just give it one page and call it a day

fiery turtle
#

Basically

rustic compass
#

I haven't looked at the table api yet, so does it only allocate tables on demand or all found tables as soon as possible?

fiery turtle
#

the entire array is populated at init time

#

but it doesnt allocate tables, only these structs i sent earlier

rustic compass
#

One thing that can make the heapless phase easier would be giving a additional parameter to the page mapping function that indicates if it's a table map/nvs map/aml map... so that for example on limine table and nvs would be nop without having to check the memory map

fiery turtle
#

tables are only mapped during uacpi_initialize

#

the rest of the mappings are for AML

rustic compass
#

It would be nice if you could explicitly state that in the docs so that we don't have to rely on undocumented behavior

fiery turtle
#

Its about to change sooo

#

I might look into your idea

#

I need it for userspace emulator

vast kestrel
torpid ferry
#

it can also be a linked list of packet parts

kindred beacon
#

Userspace emulators are very nice but absolutely under-utilized

fiery turtle
#

I mean yeah

#

It already works pretty much flawlessly

#

And runs hundreds of blobs for ci

#

Its just that if I change this table subsystem it will have to be changed

hollow crescent
#

but how does it work?

#

do you emulate the devices themselves?

fiery turtle
#

They aren't needed to emulate, for mmio I just return all zeroes, for IO I return all 0xFF

#

Sometimes it hangs some blobs that spin until some value changes, but uacpi has while loop timeouts

#

So its not a problem nor an error

hollow crescent
#

ah

north holly
#

@fiery turtle there's a slight mistake in the uacpi wiki page.

#
uacpi_status ret = uacpi_get_current_resources(node, &kb_res);
if (uacpi_unlikely_error(ret)) {
  log_error("unable to retrieve PS2K resources: %s", uacpi_status_to_string(ret));
  return UACPI_NS_ITERATION_DECISION_NEXT_PEER;
}```
#

you used uacpi_unlikely_error, when you probably intended uacpi_likely_error

fiery turtle
#

Why

#

It is an unlikely error

north holly
#

or am I just understanding this all wrong

fiery turtle
#

Why do you expect an error here

north holly
#

because it logs an error

fiery turtle
#

In case of an error it does indeed log it lol

#

Im confused lmao

north holly
#

ok what does uacpi_unlikely_error do

fiery turtle
#

It checks ret ! = 0 wrapped in builtin expect

north holly
#

then what's uacpi_likely_error

fiery turtle
#

It tells the compiler the error is unlikely

north holly
#

ohhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh

fiery turtle
north holly
#

that confused me

fiery turtle
jaunty fox
#

did you know someone called Mintia is inventing a technology to use uacpi from rust?

fiery turtle
#

Yeah iirc we did talk about it here a little bit but I think its abandoned now

rustic compass
#

doesnt uacpi use cmake?

#

it does and rust has a cmake-rs crate that would have made the buildscript considerably smaller and easier to maintain on uacpi version bumps

fiery turtle
#

It doesn't use anything per se, cmake is one of the options, the one present simply accumulates all sources into a variable

#

There's also a meson file

rustic compass
#

true

#

if uacpi-rs is really abandoned i will probably ask mintia11 to take over once i need uacpi, as it looks like a solid foundation to work on

#

also how does the link to uacpi's github work there?

fiery turtle
rustic compass
fiery turtle
#

I know that feeling

rustic compass
rustic compass
fiery turtle
#

working on implementing this now

fiery turtle
#

hmm freeing the entire namespace is kind of not so trivial

#

i wonder if its possible without a node queue buffer

mortal yoke
#

in qacpi I just kept a linked list of all nodes and then I can just go through it to free everything (and also the potentially attached objects that the nodes might have)

fiery turtle
#

but i think i can reuse the same algorithm i used for depth-first walk

#

to do it non recursively

mortal yoke
#

ah you want to do it without an extra link?

fiery turtle
#

nah like

#

how do u even do it if u only have a next link?

#

how do u find children

mortal yoke
#

well you don't really need to find children while freeing and I have separate parent ptr + child array

#

unless you are talking about like freeing only one acpi scope and not everything

fiery turtle
#

so u have a separate list of every node and then each node also has the links to parent and children?

mortal yoke
#

yeah though the children are actually stored in an array of pointers

fiery turtle
#

interesting, i have a much simpler system

#

why do u need the list of all nodes?

mortal yoke
#

it was specifically for freeing them in case eg. some aml fails and it has created some temporary scope, though yeah ig it could be done using only the parent/child pointers

fiery turtle
#

ah

#

i have this algo

void uacpi_namespace_for_each_node_depth_first(
    uacpi_namespace_node *node,
    uacpi_iteration_callback callback,
    void *user
)
{
    uacpi_bool walking_up = UACPI_FALSE;
    uacpi_u32 depth = 1;

    if (node == UACPI_NULL)
        return;

    while (depth) {
        if (walking_up) {
            if (node->next) {
                node = node->next;
                walking_up = UACPI_FALSE;
                continue;
            }

            depth--;
            node = node->parent;
            continue;
        }

        switch (callback(user, node)) {
        case UACPI_NS_ITERATION_DECISION_CONTINUE:
            if (node->child) {
                node = node->child;
                depth++;
                continue;
            }
            UACPI_FALLTHROUGH;
        case UACPI_NS_ITERATION_DECISION_NEXT_PEER:
            walking_up = UACPI_TRUE;
            continue;

        case UACPI_NS_ITERATION_DECISION_BREAK:
        default:
            return;
        }
    }
}
#

for non recursive iteration

#

i can reuse it for non recursive deletion as well i think

mortal yoke
#

yeah probably

#

that's one of the nice things you can do with linked list of children, I don't think I could do that with the way I did it with arrays

fiery turtle
#

yeah

mortal yoke
#

well ofc you can do it using a stack but it uses extra mem

fiery turtle
#

wait so only the first node in a tree has the array of children?

#

or rather

mortal yoke
#

nah every node has

fiery turtle
#

how do u find peers?

mortal yoke
#

every node has NamespaceNode** children and NamespaceNode* parent

fiery turtle
#

but what about peer

#

like

#

parent -> child1 -> child2
|
peer1

#

can child1 find peer1?

#

oh they would have to scan the parent's childern array for themselves?

#

and then look for the next node

mortal yoke
#

yeah you'd have to do it like that

fiery turtle
#

i see

mortal yoke
#

in fact I kinda do it like that in the code that looks for nodes by name, if the node is not found in the current node's children it continues the search on the parent going through its array of children which includes the first searched node too (but it doesn't go down to any of the child nodes because that's not how the scoping works)

fiery turtle
#

yeah

fiery turtle
#

new addition to the insane real hardware AML collection

#

two identical tables with a slightly different name

#

bleeding edge hw too

#

uACPI worked fine btw meme

#

25 aml blobs on that laptop

fiery turtle
fiery turtle
#

And Fadanoid for the first kernel advanced enough to support all 3 platforms with acpi

deft canopy
fiery turtle
#

Big

#

So you have like a working kernel with it already?

deft canopy
#

partially, it's untested as of now

fiery turtle
#

Nice

#

Isnt there an ia64 qemu?

deft canopy
#

I'm not sure if it ever got to a functional enough state to test with

fiery turtle
#

Ah

deft canopy
#

@sterile egret has a fork, but idk how far he got it

fiery turtle
#

Is the source available anywhere?

deft canopy
#

It's on github

#

wait

#

my kernel or the ia64-qemu thing

fiery turtle
#

The former

deft canopy
#

my kernel is not public as of now, no
it's on a local git server

fiery turtle
#

Ah

#

Lemme know once its available

deft canopy
#

oki :3

deft canopy