#uACPI - a portable and easy-to-integrate ACPI implementation
1 messages ยท Page 20 of 1
ive got intrusive singly and doubly linked lists in zig in my kernel under bsd 0-clause btw, separate license from the rest of the project
yeah its great
you cant put decls on types at comptime only fields but its still great
Are there macros
nope
no macros only comptime
What does this mean
no new functions on types
decls are type-scoped things that arent fields
Hm
you cant create a type with reflection that has decls is the only major limit
and if you do you can somewhat easily work around that
and yeah ive never needed it either
Is that like a compiler limitation or on purpose
if i had to guess i'd say both
technically a not implemented but it looks like itll be made on purpose yeah
theres an open gh issue with a debate on whether to implement it or make it actually illegal
i can't think of a way to create functions at compile time
Interesting
and functions are decls so
theres a proposed builtin called unrollArgumentTuple that would take a function with a tuple argument and return a function with one argument per tuple element
Ill definitely try writing something in zig tomorrow just to see how it feels
and you can use a comptime switch to implement it yourself
day 0 of asking for an ultra rewrite in zig
Its like a barenones kernel that prints one message to e9 ๐
the other thing to note with zig is that varargs only exist for c binding compat - to make a varargs zig function you take a tuple and use anytype to let it specialize per tuple combination
that's a good start
now implement everything else
day 0 of asking for ultra
and make it run wayland
Bash before obos
the downside of that tuples for varargs bit is that std fmt generates generic specializations for every combination of argument types which can cause some binary size bloat - theres an open issue there too iirc
let's make it happen ๐ฅ
So like c++ templates
lmao
a bit yeah
it's still probably better than std::format lmao
assuming ttys aren't too confusing, I should get bash by the new year
Lfg 2026 
and iostream
iostream is a disgrace to humanity
this
for reference on the linked list question btw, https://github.com/Khitiara/imaginarium/blob/main/src/util/queue.zig heres my impl that i use basically everywhere in my kernel lol
Iostream is truly disgusting
it really is lol
petition to the c++ committee to remove iostream in c++29 or whatever
no
what dumbass in the C++ committee decided to add it in the first place
Is ? Like Optional
and what dumbass(es) decided to accept it
they arent that bad
Why do you want both ? And a pointer
its even called optional
.? is like rust unwrap
are you talking about ttys or smth else
an optional pointer automatically uses 0 as null
you can have ?T which is a nullable T
Ah so there's no hidden fields there?
so ?* is more like a nullable pointer than it is an optional-of-pointer
tty.c in astral is 550 lines ~~if you ignore the 611 lines signal.c and 430 lines of jobctl.c
~~
an optional not-pointer requires one extra hidden field but optional pointers dont
and you can also have !T which is an error union, basically T with an addiitonal error value passed together
Makes sense
that's what i do
good luck doing anything other than simple programs
technically SomeErrorSet!T is an error union, !T by itself infers the error set
Are errors standardized
and E!T is a T with an explicit error union type
they are user defined
you can return error.MyError
and it adds MyError to the global error set, which is the default
yeah but it's a global enum sort of
Wait u can do that
an error set is a subset of the global error set which is every error in the program
What if I make a typo and add a new bogus error
every type that doesnt use an explicit error set uses the global error set anyerror
use an explicit error set :^)
const MyErrorSet = error { A, B, C };
Interesting
and the global error set gets mapped onto a 16-bit int internally but the mapping isnt reliable
anyerror is more of a convenience i'd say
Can u store extra info in there?
sadly not
if you return an error not in the explicit set you have then its a compile error
nope, its errors in the same way a status enum is
if you want extra info do it the C way and have a function to get extra info
which you store in a threadlocal global or something
you can get a stack trace for the error with a builtin though which is usually enough to debug things, or also catch errors and return more specific ones in intermediate stages
as long as you stay below 2^16 error names total its fine
U can get an original backtrace of the error when itโs propagated down?
yeah
Damn
Why does it matter?
the compiler bakes the global error set into a u16-backed enum basically. i think you can change the size though somewhere
any function that returns an error takes a hidden parameter of type *StackTrace and appends its current rip to the trace before calling an error-returning function or returning its own error
65k errors ought to be enough for anybody
and then you can get that trace with @errorReturnTrace
Ohh
also defer and errdefer are beautiful
though the builtin returns an optional trace because that whole thing gets elided if you run optimized modes with error tracing turned off
gods yeah defer and errdefer rule
errdefer is defer which runs if the function returns an error
block not function
Really nice yeah
defer statements run in reverse order when the block theyre in is exited by any means
zig has been successfully shilled
lol
What about errdefer
same thing but only if the block returns by returning an error. useful for stuff that allocates something and then initializes and returns it - if the init code errors you can free the partially-initialized object with errdefer
I mean this makes sense, same as c++ destructors
Yeah I can appreciate that
my favorite use for defer is for locks and for frees - put the free with the alloc or the unlock with the lock in the source and guarantee itll still go in the right order and everything
yeah it's amazing
i think what actually convinced me to try zig was still the bit-packed structs though tbh
i think C has those now too but idk
Yeah
Hm?
Like bitfields?
yeah
also arbitrarily sized integers
Yeah C has that but in broken ways
u5 is a thing
zig technically has every signed and unsigned int size from 0 bits to 65536 bits (idk why that big) and inside a packed struct any of those things take up exactly that many bits
instead of rounding up to bytes
also inside a packed struct a bool becomes 1 bit
I remember that breaking llvm in some way
zig is probably a big fucking benchmark and test case for llvm lmao
idk if it actually works for big int, i remember some crashing issues for ints bigger than whatever your biggest register can support
and yeah lol zig runs on llvm atm
outside a packed struct, a u5 is a u8 but in safe modes it gets its overflow checks for 5 bits of size. inside a packed struct u5 is a 5-bit-wide bitfield
packed structs are backed by integers to and you can cast both ways there
basically means my page table entry struct looks like this and just works
you really should give zig a go, not even for osdev :)
Very cool
Yeah
packed unions are untagged unions of packed things, and in this case Pfi and PtePfiPad are int types determined by comptime from the physical addr width and page size
but a new osdev project that has a chance of getting off would be cool
if you do decide to do zig osdev i have fully working uacpi integration in zig already you can steal lmao
if you do decide to do zig osdev there's my https://github.com/48cf/limine-zig-template and https://github.com/48cf/limine-zig you can use as reference
i might try to make a hyper-template too
never looked at it but it might be fun
i still might grab limine-zig someday if i decide to switch off of bootelf
Lol thanks, ill definitely be taking a look
if you find anything missing or wrong just lmk i will fix it as fast as i can
i dont really keep it up to date because i dont do much osdev, especially in zig
Nice
Good to hear
yeah
im running nightlies and have had nearly zero issues with zig itself
plenty of issues with my kernel being bad but thats separate lol
Lol
bro is looking for a dtb on x86
Well that's kinda what happens in the early stages of adding AMD64 support to a RISC-V kernel.
Anyway, I'll make sure to run the uACPI benchmark thingy as well ;)
i was bored lol, here it is https://github.com/48cf/hyper-zig-template
no proper hyper bindings but cimport did well :^)
even the ULTRA_NEXT_ATTRIBUTE macro was translated which is pretty cool
if i was i would make proper hyper bindings
(i will at some point tomorrow)
(yes i want to see ultra-zig
)
also i have no idea how to actually do all that hyper stuff, i just kind of freestyled it hoping it would work which it did :^)
I mean lgtm

Lol, thats pretty cool
Btw the protocol is called ultra 
Yeah looks pretty good to me
Ideally it should be higher half exclusive I guess
billions must rename repos
what a coincidence, i currently happen to be working on implementing realloc efficiently
it's not going to be that much faster than just normal kalloc+kfree, because of some of the general constraints of my allocator
(each heap page needs to have the same power-of-two size for each object, so shrinking/expanding an object beyond its current power-of-two size requires kalloc+memcpy+kfree)
but for ranges that end up using vmalloc_large, it should have a good impact
@fiery turtle just by making dynamic arrays use realloc, proxima's score went from 5.1M to 5.6M
did you hack uacpi's dynamic array to use them?
yeah
damn
it also grows only by one element each time, i wonder if making this constant configurable could improve perf
oh definitely
if a dynamic array doubles its capacity when growing instead of just adding space for one element, its insert performance is amortized to O(1) iirc
hmm
right, that, and a million other lies
here's the patch i used for getting dynamic array to use realloc btw https://hst.sh/piroloyahu.php
makes sense
wdym
if i make it do this (combined with realloc) proxima's score goes to 5.9M
nice, I guess an optional realloc is useful to have
the combined patch: https://hst.sh/ojofuluhit.php
nothing dw just me being salty at zig's lack of stability
did u find it unstable?
i did not use it but i was at the receiving end of many reports when the limine-zig-template was part of the limine organisation
which is the main reason why i transferred it to czapek
ah
nah its true afaik
it used to be that the language is cool but the compiler is buggy
and now they have a working compiler and a shitty language
basically
In rust you get that automatically when implementing the allocator trait
you also actually have to implement it
not really, you get a default impl that does alloc+memcpy+free
Nope mandatory is only alloc and free
well yeah but you donโt just โget oneโ is what iโm trying to say ๐
@gentle peak btw for those measurements, did you look into the hit/miss rate of how many allocations were able to get resized, and where they came from etc?
Yea the allocator has to actually implement it to be usefull but when you change yours to be able to do so you don't have to recheck all allocation sites
i didn't
for the former i assume not that many because all of them were getting routed to kalloc which has very strict requirements for actually resizing vs copying+freeing
interesting
also, most complaints about limine-zig not working were because of the big changes to the build api at the time, the rest were probably me not updating the thing lol
some basic measurements:
vmrealloc: 301 calls, 271 with orig == NULL (routed to vmalloc), 30 routed to krealloc
krealloc: 30 calls, 0 successfully resized
i really have no idea where the speedup came from considering all of them were alloc+copy+free anyway
lmao
actually maybe that's because this is with both realloc and dynamic array doubling
i wonder what it'd be like if it expanded by one at a time
yeah the x2 growth probably allocates way too much
so u get way less allocations and hence the perf improves
not just that
2x growth guarantees that the new allocation won't fit in the same power-of-two bucket
and that yeah
so krealloc can never resize the allocation
ok disabled the 2x growth
vmrealloc: 1823 calls, 271 with orig == NULL (routed to vmalloc), 1552 routed to krealloc
krealloc: 1552 calls, 980 successfully resized, 572 kalloc+memcpy+kfree
yeah
on the other hand
i just tested with only dynamic array doubling and not realloc
it's still 5.9M
lmao
dynamic array doubling + realloc was also 5.9M, and just realloc was 5.6M
well realloc is basically a no-op for x2 growth as we've found out
id imagine for most implemetations, at least slab-like allocators
anyway this should be a pretty good universal performance improvement ```patch
diff --git a/include/uacpi/internal/dynamic_array.h b/include/uacpi/internal/dynamic_array.h
index 8135d7e..a68c1d6 100644
--- a/include/uacpi/internal/dynamic_array.h
+++ b/include/uacpi/internal/dynamic_array.h
@@ -65,8 +65,8 @@
void *new_buf;
type_size = sizeof(*arr->dynamic_storage); \
-
bytes = arr->dynamic_capacity * type_size; \ -
bytes += type_size; \
-
bytes = arr->dynamic_capacity * type_size * 2; \ -
if (bytes == 0) bytes = type_size * 8; \ \ new_buf = uacpi_kernel_alloc(bytes); \ if (!new_buf) \
might need per-instance tuning, some of those are pretty huge structs
especially call_stack
or call_frame sorry
yup
maybe add a parameter to the dynamic array macro that specifies the initial capacity?
i was also thinking of caching execution_context and reusing them for further eval's, since that thing is 2 pages almost
or even a parameter that enables/disables the doubling growth
yeah thats what i was thinking
yup
or like that takes in a growth "functor"
oh wait you already have that effectively because it first uses inline storage
yup
i wonder if the call frame dynamic array ever even starts using dynamic storage
depends how deep qemu's AML nests
probably never
i fine tuned these to have inline storage that should cover hopefully at least 80% of real life aml
so first 4 function calls are free
(nested that is)
yeah i overlooked that
then the initial capacity for the dynamic storage should probably not be 8 lmao
maybe the size of inline storage
oh yeah that'd effectively continue the doubling
basically yeah
and from there it could be any other algo
maybe += initial_capacity / 2
iirc the O(1) amortization applies as long as the new capacity is a factor of the previous one
yeah
yes because it would be a 10k byte allocation for some of them right away
i cant just blindly 2x
also you should move uacpi_shareable_unref_and_delete_if_last, uacpi_shareable_unref and uacpi_shareable_ref into a header
yes you can
thats the only way to get O(1) performance in fact
also the uacpi_bugged_shareable checks should just be an assertion
i think
for some of them i can and should probably yeah, for huge strucuts i definitely dont want that, especially since exceeding inline capacity is rather rare there
it produces hilariously bad codegen
to get O(1) amortized cost, it's enough to grow exponentially
the factor doesn't matter
well yeah true
whether it's 2 or 1.000001
ofc
๐
and it never gets inlined
(ofc 0.000001 would be stupid)
maybe i should try getting lto working
well its in a C file
i was thinking half of base inline storage size each time
but could be a more sophisticated formula
never! this does not result in a trap
you need it to be a factor of the previous size
oh discord cleared the message i was replying to
anyway the call frame array never gets into dynamic storage
gets significantly better if you turn on LTO btw
yaeh makes sense
i guess i should move those into the header yeah
also if i make the initial dynamic capacity the inline capacity the score becomes 5.7-5.8M instead of 5.9M
isn't that 2x as well
i mean the numbers shouldnt change from 2x unless it grows even further?
yeah
but the 5.9M is when the initial dynamic capacity is a constant 8
for a lot of things, that's effectively multiple doublings at once
ah
thats probably the item array id guess
although it has a base cap of 8
idk actually
^ pitust is right here, if you grow linearly, the total cost becomes quadratic in some cases
should definitely use a factor of the current size
with initial_dynamic_cap == inline_cap it's still O(1) amortized but a worse O(1)
it has a worse constant
yeah
the current cost is definitely quadratic
its interesting because u hardcoded 8, which happens to be the inline_cap of most used arrays
oh 8 just happens to be my go-to for initial cap of dynamic arrays
completely arbitrary
8 or 16 is a pretty good choice i think
no like, i dont get where we lost 200k
if its the same constant

all interpreter arrays are base 8, call frame (which is never resized as we've found out is 4)
when i say 5.9M btw it's more like 5.85-5.95M
i might've just gotten a bad run with inline_cap
probably
what if u grow by prev_size / 2?
thats not amortized either i think
wait
no it is
it's a factor
its just growing by 1.5 times
it's just a factor below 1
thats fine
below 1 would be shrinking lol
yes lol
tbh the += 1 there was probably left from a very long time ago when i was debugging it lmao
and then never reverted to x2
still 5.8-5.9M but the mean seems to be closer to 5.83M
thats not too bad considering its way less memory used
bytes = arr->dynamic_capacity * type_size; \
bytes += arr->dynamic_capacity / 2 * type_size; \
if (bytes == 0) bytes = type_size * inline_cap; \
``` this is what i'm using for that btw
it's also with -O3 and LTO
feasible ig, the buffers are immutable size
most common allocations for the benchmark thing
what are the hex numbers
the top 4
assign, control method, package, buffer
the small 0x5 byte allocs are probably ssoable?
what's that?
assign is basically object copying
small string optimization
storing strings in the pointer
ahh
the number 1 spot is when src->type is 2 or 3
string & buffer
and when behavior != UACPI_ASSIGN_BEHAVIOR_SHALLOW_COPY
this is by size
so, 769 allocs of 5 byte buffers
lol
you can fit that in sso no problem
yeah SSO could really help here
u would overwrite it to a completely different string object
like python basically
is the null term removable? because if you're gonna use sso for this, making it 4 bytes would be helpful for kernels that support i386
this does a deep copy of the string at X and stores it at label Y, the Z = X is a memcpy
or other 32 bit platforms for that matter, though i don't think any of them other than i386 use acpi
ah
wait
so you can't overwrite a string by reference?
u can only change the characters, but not resize it
ah
so memcpy basically
or memcpy_zerout rather as uacpi calls it lol
if the thing being assigned is bigger, the rest of it is zeroed
i could just reuse one byte of the size field
there are smart ways to get 6-7 bytes of storage out of ptr + size
iirc
you can even get more
on 32 bit
because aml names (which are the common case anyway) are super common
so you can constrain to an alphabet of \_ and A-Z
and 0-9
that's 38 symbols
no like, obviously object names are stored as inline data, i dont heap allocate them, these are probably package fields or something, which are just normal string objects, but they store the aml name to look it up later
assuming lengths are less than 2^31, you can fit 12 whole characters
well yeah
but still
if u add like an AML_NAME bit or something?
perhaps yeah
apple did this kind of meme in objc :^)
lol
yeah thats definitely an optimization you could do
would shave a lot of those allocs
yeah
i wonder how far that'd push the numbers lol
also if i cache execution contexts and have a small pool of them
although the benchmark is the first invocation of the interpreter so doenst matter
they're always allocated at the beginning of execute_control_method
and are 7k bytes lol
how do you compile all the test stuff?
a single large alloc isnt that bad
the important thing is avoiding tons of small allocations
cd tests/runner && mkdir build && cd build && cmake .. && make
ah
or ./run_tests.py
btw you know that cmake .. -G Ninja && ninja can make builds go faster for free?
yeye, my build times are shit because they're done over 9P anyway
ah lol
since im using wsl
io is ridiculously slow
well i could do it on the ext partition but whatever
but uacpi is small enough its not noticable
fair enough
I can add you to Co-authored-by or something if u would like, once i make the commit with this stuff
nah dw
i remember this question being asked but i don't remember the answer, for uacpi_kernel_wait_for_event if the timeout is 0 should it be non-blocking just like with uacpi_kernel_acquire_mutex? because right now i only implement that for mutexes
yeah it should be, since you're not the first to ask that I should probably add a comment
since it's only used by AML it probably won't notice if u block it for a tiny bit, but yeah it shouldnt be
yeah right now it'd try to sleep for 0 tsc ticks, aka it'd be timed out immediately after blocking if the initial try was unsuccessful, but still
out of my 500 blobs there isnt a single invocation of Wait with anything less than 0x05
in case u were wondering as well:
โฏ grep -rni 'Wait (' -l | wc -l
114
about 20% use Event
huh that's more than i thought it'd be
from what i've seen its used on wake, aml waits for some sort of event from firmware
maybe some initialization to finish
that'd make sense ig
but there could be other use cases as well, you never know with these people
every blob is strange and unique in its own way
yeah... unique... While ((GP50 || (GP51 || (GP52 || (GP53 || (GP54 || ( GP55 || (GP56 || (GP57 || (GP60 || (GP61 || (GP62 || (GP63 || (GP66 || (GP67 || (GP70 || (GP71 || (GP93 || (GP94 || ( GPAP || (GPBP || (GPCP || (GPDP || (GPEP || (GPFP || (GPGP || (GPHP || (FCDP || (FTVP || (FQSP || (GP96 || (GP97 || ( GPD0 || (GPD1 || (GPD2 || (GPD3 || (GPD4 || (BPFE || (TPBP || (ECDS || (B1ST || B2ST)))))))))))))))))))))))))))))))))))))))))
lmao
@fiery turtle do_make_empty_object seems to leak memory?
you set buf->text to a pointer that points to 1 byte of memory
without setting the size
which is invalid
Check the corresponding free
But anyway its a hack that im not sure is needed, I might take a look at it at some point
Im sure there are no leaks because I run with asan on at all times
Its special cased there basically
I dont remember, probably not needed now
I think it was because the Mid operator is the only legal way to produce an empty buffer and I didnt want to add special handling for null buffers everywhere
But I dont think I actually rely on that anywhere
also seems like handle_concatenate leaks memory?
if arg0 is UACPI_OBJECT_STRING and arg1 is UACPI_OBJECT_BUFFER
you allocate an on-stack buffer then never free it
(im trying to hack up sso into uacpi as an experiment)
ah wait nvm
i didnt see the free
ye
nice, im not sure about the complexity of that, but there have to be some pitfalls lmao
aight
on my experimental branch for now but will merge along with some api changes later
i think this breaks if inline_cap is 1
it will always grow by 0
ye, ill fix it
was just making sure
if (arr->dynamic_capacity == 0) {
bytes = type_size * inline_cap;
} else {
bytes = (arr->dynamic_capacity / 2) * type_size;
if (bytes == 0)
bytes += type_size;
bytes += arr->dynamic_capacity * type_size;
}
I think this should work
looks right yeah
how did u implement sso so fast
lmao
how many tests we talking
btw --large-tests 
tbh its probably all of them
and dont forget to test 32 bits as well, there's a switch in ./run_tests
cant really do that on my m1 though
ah, this is resource conversion tests
its not aml methods
You can have 32 bit kernel running on them
lol yeah
fair, CI will do all of that anyway
I would imagine some people could want to do that on some embedded shit or something like that where memory is limited
embedded doesnt have acpi
it might not even support 32 bits at EL1 or wahtever
No, it runs 32 bit kernels
ah ok
btw how much storage did u squeeze out of that
Like an official raspbian up to Raspberry Pi 4 was 32 bit
not sure
also i figured it out
Even though raspberry pi 3 was 64 bit
i probably forgot to zero out a buffer
And newer revisions of raspberry pi 2
you're not sure what your SSO buffer size is? 
ACPI has a lot of strings which are 5 characters ยฟ
truly 5 chars or 4 chars+null?
because from what i've seen of acpi dumps it's mostly 4c+0
Like method names
4 + 0
well in the byte stream its litrally 4 ascii chars
there are no zeroes anywhere
yeah
it has a StringOp which is zero terminated tho
and it doesnt tell u the length
so u have to strlen it
They save memory though
yeah no aml encoding is pretty good
if you're that desperate for mem they're fine yeah
but having the length speeds up a lot of string ops
So many bugs in all sorts of software could have been avoided if C didn't have them
aml has a ByteOp + <byte> to encode bytes, but Zero, Ones or One are separate op codes which are exactly 1 byte long
Does it that much?
a lot of string ops are O(1) if you have the length already
The're so common they must be optimized very well by the compilers and whatnot
strlen can be optimized a lot with simd and such but it's still O(n) by nature
there's a reason people use string_view etc
also stuff like strcmp could have early return if the length of both strings are known
yeah
using slices instead of zero-terminated strings also makes syscall param validation easier, not that it wasn't easy to begin with
strlen_from_user 
My syscalls only take slices
hence the "not that it wasn't easy to begin with"
yeah same
or well they did in my previous rewrite and they will when i implement them in this one
honestly syscalls should always take slices
You can just strlen in userspace if you need it that much
And it's like how strings function everywhere that's not C anyways
(I kinda don't like C)
ill have to take raw strings because im going for full linux compat tho (in my kernel)
like binary compat?
yeah
damn
Can you not do that in vdso?
Like have native API not take them
also this allows me to reuse linux stuff for validation
And then give a shim for syscalls
syzkaller, fio, etc
i mean it's fairly simple to be linux-compatible on the source level (as long as you have all the same capabilities as linux), and once you have that porting stuff is just recompiling it
and programs that work on linux in one way i can instantly spot a mismatch e.g. in strace
true, still kinda dont wanna go there
Programs that do that are stupid (?)
i just want cp ./bash ./myimage
What if Linux adds a new syscall
programs wont randomly start using it
glibc or something might
and thankfully the amount of raw syscalls programs do is not that much
it does that based on the kernel version or some other property
that i can just not expose
I'd imagine
just return-ENOSYS and glibc will fuck off
Idk, personally I just find making Linux clones kinda uninspiring
a posix clone is somehow more inspiring? 
Posix is just a bunch of functions
im mostly doing it to learn about linux internals while also focusing on drivers (the thing im interested in)
so i spend as little time as possible on userspace
My kernel doesn't have a single POSIX system call
I implement all of them in userspace
well u still have a posix server
I have a process server, a vfs server and pipes server
this wasnt directed at you tbh, u have a pretty unique kernel
i just dont care about uniqueness, im just doing my thing
i want 3d accel with my drivers etc
Yeah I'm not criticizing you
not interested in innovating userspace
if i can run e.g. wine + some cool windows game fully 3d accelerated on my kernel that would be an achievement for me
at least on an older igpu, like 2015 or soemthing
although there isnt that much of a difference between generations
Is new Arc memes very different from their older iGPUs?
nah
although linux is using a new driver for it
they got rid of backward compat and made a new driver that uses only new things
There was a lot of drama with Windows drivers when the first gen launched
its the exact same igpu, just with more command streamer engines lmao
one nice thing about them might be that as they are dedicated things you can probably pass through them to qemu I'd imagine unlike some other newer igpus
At least in 8th gen CPUs
Since that's what I had
for development u should just run linux headless and pass through to qemu entirely
just ssh into it instead
No but in theory you should full on be able to pass the GPU to Windows
While linux is not left headless
Get a second GPU 
I couldn't get that to work either, the south bridge registers always returned zeros on my alder lake igpu
Yeh that's what I'm talking about
i have two gpus but one wide enough pcie slot unfortunately
motherboard skill issue
But it's only on server GPUs on nvidia and amd afaik
Me too
mATX case
2.5 slot GPU
PCIe connector in second slot
i have a 4060ti so no such problems 
I could put a second gpu with a pcie riser cable
though I think it would have to partially be outside the case
Free slot is occupied by serial lead, as in the stone age 
wouldnt that result in increased latencies and stuff
I don't think this would make a difference
I mean maybe but I don't think its that much, I used to use a gpu like that when I had even smaller case than I do now
There's also Thunderbolt/USB 4 memes
i mean there's a reason u put your gpu to the pcie slot closer to the cpu
It has more PCIe lanes
And on nower motherboards it's the slot which is wired to PCIe 4/5
ah maybe idk
fun fact, igpus are mandated by the spec to be located at 0000:00:02:00
It's for that forum person who refuses to use ACPI
you wouldn't even need ACPI to detect it in places other than that
Windows 98 compat?
just brute force detect all possible devices on every addressable bus
I don't have experience in computer industry so I don't know if that's true, but I would imagine there must be some embedded shit which uses some cursed OS to control machine tools and that stuff would have it hardcoded
doesn't that kinda stuff use 386 and 486 CPUs
igpus are pretty tightly intergrated with acpi as well, they usually have a separate SSDT dedicated for them, a custom opregion, and various notification things
if you're lucky there is even a method to do modesetting via acpi
The ASUS laptop which I've dumped yesterday was turning screen on and off with the keyboard buttons in pmOS
With no GPU driver
Really?
And spamming a bunch of ACPI events
So could have that been done by ACPI?
yeah, by the corresponding query handler
Does uDRM have plans for Nvidia? 
uKernel soon
Ye
maybe you're expected to call this after resume from suspend
your blob has this method
Hmm
this might restore graphical output
Which one
_DOS
Which blob
the laptop one
I'll try that
I assume it is under the GFX0 object?
yeah
in an ssdt
SSDT1 has tons of stuff for graphics-related things
probably some combination of those methods can restore the screen
just read the entire spec chapter on that, its pretty small
so u need to detect which screen u want to activate, then activate it ig
idk
Does yesterday's laptop have this?
It also has 6000 series AMD iGPU
Which has datasheet
yeah
Btw, I don't think it has Windows keys
your laptop has 2
โฏ grep _DOS *.dsl
dsdt.dsl: Method (_DOS, 1, NotSerialized) // _DOS: Disable Output Switching
dsdt.dsl: Method (_DOS, 1, NotSerialized) // _DOS: Disable Output Switching
How do you remove them?
if you could PR it that would be great
the dump is an ascii file
On my Lenovo laptop, I could only get touchscreen version with Windows license so I don't want that on github
just remove the windows license table from the table dump
I wanna fuck around and find out what happens if I call _SPD (set post device) for my graphics card
Elixir Cross Referencer - source code of Linux v6.12.6: drivers/acpi/scan.c
because after all what could possibly go wrong
k
i guess by posting they mean this
maybe they post it somehow after restore
need to find code
Elixir Cross Referencer - source code of Linux v6.12.6: drivers/acpi/acpi_video.c
all video logic is here
you might be saved from having to write every driver
they even set notify handlers for brightness control etc
pretty interesting
so it seems like I need to do the following:
on suspend:
foreach graphics device
save_brightness
on resume (after _WAK):
foreach saved graphics device
restore_brightness```
(pseudocode of course)
something like that i guess
that's what linux seems to be doing in the thing you sent me
Do PCs with descrete GPUs have that?
yes
no i didnt understand what you meant
Now that I'm dumping all the tables
ah
are you sure?
that dump contains a hex view
oh right it might be on a column boundary
acpixtract -a dump.txt && iasl *.dat
nope
nah like actually look at whats inside
is there a GFX0?
oh wait is this only for pcs with an igpu?
because mine doesn't have an igpu
and no there's no gfx0
also no
is that a laptop or
desktop pc
My new-ish b550 PC
which cpu/gpu?
ryzen 5800x, rx 6500 xt
and my other test pc
can u ls that dir?
although this one doesn't have s3 suspend
$ ls
apic.dat cdit.dat dsdt.dat facp.dsl fidt.dsl hpet.dsl mcfg.dsl ssdt1.dsl ssdt11.dsl ssdt3.dsl ssdt5.dsl ssdt7.dsl ssdt9.dsl vfct.dsl
apic.dsl cdit.dsl dsdt.dsl facs.dat fpdt.dat ivrs.dat pcct.dat ssdt10.dat ssdt2.dat ssdt4.dat ssdt6.dat ssdt8.dat tpm2.dat wsmt.dat
bgrt.dat crat.dat dump.txt facs.dsl fpdt.dsl ivrs.dsl pcct.dsl ssdt10.dsl ssdt2.dsl ssdt4.dsl ssdt6.dsl ssdt8.dsl tpm2.dsl wsmt.dsl
bgrt.dsl crat.dsl facp.dat fidt.dat hpet.dat mcfg.dat ssdt1.dat ssdt11.dat ssdt3.dat ssdt5.dat ssdt7.dat ssdt9.dat vfct.dat```
hmm ok maybe new amds dont do that or sometihng
@gentle peak any of these?
barring _ADR
no
ah ok
mkdir -p acpidumps && cd acpidumps && acpidump > dump.txt && acpixtract -a dump.txt && iasl *.dat
thx
Wth is Component Distance Information Table
open the dsl maybe it will tell u
My PC has no BCL
F
5900X + 5700 XT
apparently discrete amd gpus dont have those
doesn't that output many files in the current directory
I should've gotten 5700X 
it does
I have 7850, I can also check there
probably should add a notice then
ill add a mkdir step
I was skill issued enough to do it in my home dir once
lol
just rm *.dat *.dsl
and make sure you don't have anything important with those extensions in your home dir ofc
rm -rf / to be sure
That need a flag to work
downgrade rm to some old version
do you want a b650e dump
rm -rf --no-preserve-root /
find /dev -type f -exec dd if=/dev/urandom of={} \;
if you're willing to PR it in a proper format ill gladly accept :^)
remove the French rm -fr
wdym PR
the link it generates has a hwid column
it'd be cool if i could figure out how to generate that without having to upload all the hw info to that website but whatever
maybe i should make a script to PR a local dump quickly
so that its easier for people
i got this now
for the sake of the PR we only need the .txt renamed to <ID>.bin
and what's ID
is <ID> really that important?
either this or come up with a random one
maybe it can just be dump.bin
im cargo culting it at this point
also how should it be handled if different firmware versions have different acpi tables/aml
that would probably produce a different id
fair
@north holly btw if that works we can PR a _BCL for QEMU's bochs device as well
unless there's one already
and that reminds me that u have abandoned your SeaBIOS series
no local file tho
the website now has an id
u can take that and rename your file i guess
(is that what monkuous did?)
yeah
just tested it, id didn't change
who me?
Yes
I guess their tools aren't that good

until they return to their senses and fix the bug themselves, I will be using my patched seabios
what's the bug
ECAM restored using ECAM on wake from S3
the fix is literally:
+make_bios_writable();
+mmconfig = 0;```
in pci_resume
I can pick it up if u want
yea sure
infy
if I do this:
uacpi_eval_simple_typed(node, "_BQC", UACPI_OBJECT_INTEGER_BIT, &dev->current_brightness);```
do I need to `uacpi_object_ref(dev->current_brightness);` manually?
Why would u ever need to ref manually
idk
Tldr no
k
@north holly could u test a faster uacpi + new kapi real quick?
sure
u should be getting more points now
just let me test suspend with the gfx things
I'll try
maybe u also need to enable switching and stuff
that could be handled by linux native drivers or something
btw is it valid to do something like:
uacpi_object_array arr = {.objects=&dev->current_brightness, 1};
to pass to uacpi_eval
ofc
pretty sure it wouldve segfaulted otherwise lol
I mean who knows, maybe it did, as that's done after wake from suspend (therefore I have no way of knowing about the crash)
lol
what I find interesting is that the function key to disable the display works despite me not handling it
u dont have to handle it even for firmware to do wahtever it wants in the query handler
if u have a keyboard driver u can actually try to increase/decrease brightness for different keypresses just to see if it does anything
or hook up a notify handler on LCD
what the hell's the problem with just doing Return(Zero)
probably workaround for some windows xp aml interpreter bug
yeah but why would it do this here
but this here
brain rot
I swear I'd rather have shrek write AML
maybe he did
I'll test the uacpi updates
whats up with bcl stuff?
canโt wait to see proxima results with sso
1B
I think I might need to also call _DOS
probably
uacpi_object* brightness = uacpi_object_create_integer(0);
uacpi_object_array arr = {.objects=&brightness, 1};
uacpi_eval(node, "_BCM", &arr, nullptr);
although doing this has no visible change in brightness, but maybe I'm just doing it wrong
Zero is the third element of _BCL
i mean
whats the default level
and whats the current
u should've increased it and have like a sleep() loop
good idea
also dump the entire thing
uacpi_object_assign
I can't stop laughing
nyaux
?????
i will make a header that converts ASL to C
Eat, sleep, repeat
proxima on uacpi's api-changes branch (a932364e16a8bb7e59007fad1bbf564eede5e1d8, qemu-system-x86_64 -accel kvm -cpu host,migratable=off -no-reboot -debugcon stdio -device isa-debug-exit,iobase=0xf4,iosize=0x04 -M q35,smm=off -cdrom proxima.iso):
uacpi: info: successfully loaded 1 AML blob, 1705 ops in 0ms (avg 6123797/s)
huh, faster than we did locally?
apparently
omitting migratable=off has a negative impact on the performance now for some reason
like if i just do qemu-system-x86_64 -accel kvm -cpu host -M q35,smm=off -cdrom proxima.iso i get 5975411
whereas with qemu-system-x86_64 -accel kvm -cpu host,migratable=off -M q35,smm=off -cdrom proxima.iso i get 6113455/s
i can feel the speedup even locally with the base test cases, perhaps my shitty memcpy being used less at O0 helps
I decided to add a handler for the brightness FN keys
and change the brightness there
to see how that goes
oh cool
it's only temporary though
why not keep it
because of how I register it
uacpi_namespace_node* node = nullptr;
uacpi_namespace_node_find(uacpi_namespace_get_predefined(UACPI_PREDEFINED_NAMESPACE_SB), "PCI0.GFX0.DD1F", &node);
if (node)
uacpi_install_notify_handler(node, gfx0_handler, nullptr);```
also when asked to increase u should probably use items from that package right?
they range from 0->100
๐
pmOS on the latest commit and with pthread_mutex fixes, on a faster PC
(haven't changed uACPI stuff to builtins)
what does it return for current level? @north holly
So like 0 optimization work
big
tryna figure that out rn
inb4 obos gets highest score when ran with the new branch
i suspect this is because my tsc calibration code usually gets a frequency that's a bit lower than it actually is, so with migratable=off the same number of tsc ticks is assumed to take longer.
with migratable=off time: tsc is 3792.871000 MHz
without time: tsc is 3792.733814 MHz
latest commit is api-changes branch or master?
master
interesting
so i guess the speed up is only because better pc
And because pthread_mutex doesn't yield on unlock anymore
ah
But like faster CPU is 5900X
vs 7480S in my laptop
Which should still be fast on single core
I suppose
Soon I will get 1 bil aml ops per sec trust
i would need to jit aml for that
uACPI 2.0
Imagine people switching from python to aml one day for quick compute stuff 
Does TSC run at CPU frequency?
I've just noticed that my CPU reports itself as 3.7 GHz in Windows, and that is more or less my TSC clock
python has an experimental jit now as well
usually it runs at one of the cpu frequency levels
I have discovered that _BCM doesn't do shit
But it boosts to 4.5GHz or so all the time
not entirely if you have invariant tsc
