#uACPI - a portable and easy-to-integrate ACPI implementation
1 messages · Page 43 of 1
It's fine
ill be swapping this to iterator api soon so sent a permalink lol
the descending/ascending is clearer and more like what most projects will use i think
Ill probably merge iterator api today
cool
I can try the iterator thing, I have no preference what to use
Especially if @north holly tests the new pr 
what i also might do is create a device object for specifically the _SB namespace and iterate under that
Nah its not needed in C
also not merged yet
its very good for working in zig and absolutely unnecessary in C
because callbacks through C cant propogate zig errors and error tracing
Haiku uses it for c++ for whatever reason
that's not happening, got my report card
The what
Yes.
Like school stuff?
yes
if i wasnt busy today id pull in the PR and test that
its one cli command to swap over and after that i just need to write binding externs
What do you need to test?
the new iterator api
Just normal operation
where you call next instead of giving a callback
but im stuck doing (thankfully paying) web dev work today 😭 so no testing new uacpi things
Good for you anyway
if I get the chance I will be testing the iterator api
and will be migrating my acpi driver detection to use that
If you just check that nothing in obos regressed that'd be great
Its worse than the old api
So dont do that
worse how
Requires dynamic memory or recursion
nvm
I will temporarily change it
but revert it after finding it works
or doesn't work
Fair
50/50 either today or not
yes
im literally maintaining a hack that breaks error stack traces rn because of not having an iterator style api so i appreciate this too lol
Yeah I didn't realize other languages needed it
zig L
yeah sadly no closures in zig
or anonymous functions (without weird syntax at least)
you can technically &struct { fn x() void {} }.x but 🤢
yeah no
the closures is intended because of implicit allocation potential there
which any memory management other than declaring a variable (local or global) has to be explicit
the lack of anon functions is kinda annoying but i was doing work with java before that lang got them so i easily get used to that
yeah
i dont find it too annoying tbh
its just that i cant return an error union from a function that returns uacpi_iteration_result or whatever the enum is called
yes but if you get namespace_node_info that function does that for you
oh, fun
the struct has bools for if things are present and then a field with the thing if it exists its real nice
its what i use
Yeah I guess I'll also do that...
Wth
6.1.3 _CLS (Class Code)
This object is used to supply OSPM with the PCI-defined base-class, sub-class and programming interface for a device.
This object is optional. However, it may be useful for loading generic drivers on hardware that is compatible with PCI
-defined device classes, but that is not implemented on the PCI bus (and is therefore enumerated by ACPI.)
yeah
i think my code might even handle that i dont remember
nope apparently i dont
astral has no memmove?
yup
pretty sure uacpi-linux doesn't have any of the mem* functions
anyway i just added UACPI_USE_BUILTIN_STRING
yeah we'll have to pass that define as well
Astral has fallen billions must die
uacpi-linux being uacpi in the linux kernel or uacpi running in userspace?
the latter ofc
this makes me wonder, shoudl i make it possible for uacpi to export its own impls of vsnprintf and even string as globally available without the uacpi_ prefix

true ture
because unlike haiku (apparently) linux uses acpica apis directly kernel wide so migration is a paaaain
uprintf when
i mean, most apis seem to translate pretty much 1:1
it must be doable and not that bad
"time to switch acpi libraries!!!"
"wait why is my printf not working"
most code could probably be converted with sed
lol
Load bearing uacpi
it's still like tens of thousands of changes to call sites, types, method names, parameter ordering, etc
true true, but it can be done with enough time and will power lmao
yeah
my main objection is that such a huge effort isn't really worth it unless it has a chance of getting mainlined, and that's not happening unless you add a config option to choose between acpica and uapci, so you essentially have to write your own independent abstraction layer that can be backed by either
basically yeah
maybe an abstraction later isnt that expensive
since so many osses have it
i mean i wanted to have a config switch for uacpi from the start tbh
expensive almost certainly not, I doubt acpi is in any kind of performance critical path anyway, but it is even more effort
but it might be a big project lol thats true
i mean coding time wise
u could just draw inspiration from NTs interface ig
I feel like no matter what you do the migration is gonna be the most time consuming part of it
like changing code to call into it?
yeah
yeah
yeah
Linux maintainers will never merge a compat layer
what is nt's interface like anyway? I'm curious
If you want to get uacpi into linux, the only reasonable path is probably reimplementing the acpica API on top of uacpi
which would probably be ugly af
thats probably the cheapest way
im not sure why you're so certain about that
you would be if you were up to date on linux happenings
nvm wrong link
Hardware abstraction layers regularly get rejected in linux
or no its correct i think(?)
uACPICA layer over uACPI :p
It's not too uncommon that some company wants to merge a driver that's portable across, say, freebsd and linux and it usually results in heated discussion
yeah im not necessarily talking about rust anything
hm yeah
i mean an acpica interface layer is also possible, most apis are translatable 1:1
I am talking about the amdgpus of the world being refused to be portable between the OSes so freebsd needs linux compat
For example drivers that wrap mem allocation or PCI into a compat layer regularly get NAKd
stupid
maybe it would be smart to reach out to a maintainer and see if it has a chance to pass?
idk
whatever you do, if you are serious about upstreaming it, you will need to talk it out anyways
@LinusTorvalds
so better start at that
yeah
looks like these arent intel employees at least
if you are also russian, so you want to clear that up first if you are employed by a russian company
unless you want to be in a phoronix article
lol
unrelated, this is my personal project lol
or at least a very polish sounding last name lol
i think i've talked to him before as well
when sending some patches for acpica fixes
to the linux mailing list
so how do you usually reach these people?
mail, yeah
like, literally send an email to one from above?
yup
thats how mailing lists work
fair lol
usually u Cc the mailing list as well, but for inqueries u dont have to
ah
full doxx in preparation of the talks
:^)
lol
gotta have the upper hand /s
true
I like to live dangerously and use sprintf which I wrote myself with uACPI 
more fake bug reports for me to figure out thanks 
yeah
just let everyone else (haiku, bsds, ros) switch to uacpi
then it's gonna be linux's problem that they're the only ones using acpica

freebsd would be cool as well
what is a ros
maybe after haiku(?)
ReactOS
freebsd mlibc would be cool
reactos exists? damn
reactos is getting better
freebsd uacpi would be cool
why
because freebsd is all into using their own stuff
i wonder if freebsd also calls into acpica directly
I think they've said that uACPI has fixed a bunch of issues for them
yeah
they only dont use their own stuff when they have absolutely no other chance, like, using the AMD drivers
(or acpi)
although there is a BSD that rolled their own acpi
who would have thought
idk how well that went
how's uDRM? 
.
it’s apparently not that big of a task

considering you did it solo and it’s better than acpica
but is it really that high of a bar :^)
and there's a lot of time and dedication that went into it
yeah ofc
it only took me 2 years 
but there are at least 18 operating systems that've been using/testing it
not trying to discredit infy or qwinci here, dont get me wrong
you could concievably have the acpi guy on a 10-15 people project
just working on that
if I had those resources in Ironclad, I would maybe do that
because C vs Ada
wdym by that
formally verified aml interpreter
and then aml just does while (1) ;
its not a thing id have a 1 person out of a 5 person team do
but 1 out of 15 seems fine use of resources
ah
u should advertise how much u pay for ironclad features
people assume its probably like 10 euro
yeah
I also got an announcement to do regarding that on some Ada events
to get some eyes on it
nice
thats also important tbh, i dont have that amount of resources or computes to constantly test it
and find rare bugs etc
Time to learn ada and put even more bugs in ironclad
So you can get even more payouts
Business grindset $$$$
C++ mindset
btw how did u discover ada
I was one day bored and say in quora that american boats use Ada
I like boats
so I learned Ada
i had a similar experience but with planes
where is your Ada uACPI then
apparently all autopilot/fmc software is ada
yeah pretty much
naah im a c guy
based
never
ill give it a try i swear lol, ive been wanting to
Write an os in lua because lua is brazilian tech so its the best
maybe ill contribute sometihng to your zig os eventually 
yooo that’d be sick
letsgo
someone needs to pull through with a c# os
i got a basic scheduler and dispatcher done yesterday :^) so maybe i will work on the io stack today
when new thread, when open source 
then a simple acpi and pci drivers for discovering devices
soon™️
i need a little reorganization of code
currently i call into hal for 90% of things that should be in ke lol
so it needs a little clean up
ill be waiting
oh thanks for reminding me i have to write the C api too
i want to be able to write drivers in C and C++
C++ :(
C :)
i mean i get C++ for free if i have a C api
The faces cancel each other so its just :
the c too
++ :
i should switch to meson so i can have native rust build support
I could probably write drivers in rust too, I bet there is some kind of wdk crate out there
though one bad thing is that there is no native seh support in rust so gl if you pass some garbage pointer to some kernel function and it raises an exception
truue
wdym
well actually most of the kernel functions don't generate any exceptions visible to the outside but you could have smth like ```rust
unsafe fn handle_device_control(device: *mut DEVICE_OBJECT, irp: *mut IRP) {
let slot = IoGetCurrentIrpStackLocation(irp);
if (*slot).RequestorMode == UserMode {
let addr = (*irp).AssociatedIrp.Systembuffer;
// generates STATUS_ACCESS_VIOLATION exception if a kernel mode address/unaligned address is passed
ProbeForRead(addr, 1, 0);
// can generate an exception too if the user address was unmapped/mprotected
(addr as *mut u8).write_volatile(1);
}
}
oh you mean in NT context
yes lol
just released uacpi 2.0
🎉
okay okay
we getting to chromium version numbers with this one
<3 semver
The year is 2057. It is the year of the managarm desktop. Uacpi 327492.0.2 is out
lol
that was fast
it's a breaking change technically so i have to bump the major number 
y'all know how some projects go like 1.6, 1.7 and then drop the 1 and release 8.0
imagine mlibc did that 🤯
is it possible to do the reverse
like add a new major-major
you do well
at least you do semver (based)
its better to have a 13.0.1 than having to change half of your code with a major release every 6 months
i thought mlibc followed semver but rarely made a release?
these people are haters
mlibc doesnt do releases, thats their brain worms
I wouldnt know how to do semver properly for a project like an os
SCI and stuff shouldn't be semver, just don't make any breaking changes
I use semver for Ironclad, I am pre 1.0 though so it didnt really kick in
:clueless:
when ironclad 1.0
Just call it alpha for all of infnity
what I plan on doing for my OS is pre-1.0 cargo-flavoured-semver
i mean at what point is a kernel really 1.0
until I can call a release 1.0 and then "ratified" interfaces are frozen but new interfaces will have an experiment stage or so
When you can play a full 100 hour run of factorio in it without it crashing once
whenever someone pays me 13 quintillion gazzidollars
is factorio portable
I honestly dont make releases because I am lazy
i mean the wine version should be
wine is
You can wine or do glibc shim like qwinci did
Managarm ran factorio
omega zased
I give you the factorio zip, instructions to enable syscall logging and you do it 
damn
I like that they give drm free versions if you own the game
I was trying to get wow64 working on astral but wine seems to not look in /lib/wine for the dlls for some fuckin reason
whats next on the list for astral atm
astral automated teller machine
steam
Versions are considered compatible if their left-most non-zero major/minor/patch component is the same. This is different from SemVer which considers all pre-1.0.0 packages to be incompatible.
cargo-flavoured semver is the best
Rework scheduler, rework irq system, rework drivers, fix wine, idk
imagine if i didn't have to fight tooth and nail to have every single reasonable change merged...
i personally like the last point
idk
ASTRAL stands for automated static teller real-mode advanced libre
ok it needs a noun
Time to shill astral for the higher ups and have it run on the atms
imagine when they see "address is not kernec"
this is how u know its top quality software
lol
ç
lol
leverage
What's the glibc shim?
the preloadable lib that I made that contains aliases for some functions and overwrites some others like a lot of the pthread functions to make them usable from both libraries compiled against mlibc and from an executable linked against glibc
yes
games probably
the thing that I like the most about that thing is the logic used to determine whether the caller was linked against glibc or not
it uses dladdr1 to get the dynamic section of the caller, gets the symbol versioning information from there and looks if any symbol begins with GLIBC_ (and then if it finds symbol like that and the caller uses pthread_mutex_init etc a special flag in the mutex is set to indicate that the mutex was created from a glibc expecting executable so the other code like pthread_mutex_lock knows to use a different struct layout)
you could contribute to my zig os instead 
true
ive not been doing irp functions until i need them so rn the only thing drivers can do is query properties but i do have a fully working driver stack complete with enumeration and even async completion support
How does it work? If it detects glibc, it provides alternative implementations for some functions?
well right now it just unconditionally overrides a lot of the pthread functions and the impl for them is basically copied from mlibc with some small differences to make it handle eg. the mutex created by glibc app but locked by some library case
anyway time to look at the uacpi 2.0 stuff and see what i can yeet and what changes i can make
so defining uacpi_use_builtin_string tells it to not assume builtins?
if my reading this is right?
basically tells it to use own impl for memcpy etc if you dont have your overrides
ok
weird name for the define but sure
the naming confusion between builtin (a thing what starts with __builtin and comes from compiler) and builtin (a thing what is built into uacpi) is confusing
I think I kinda have an ACPI bus discovery mechanism 
nice
(now I just need to implement deserialization in C++)
Also, why does _UID in info suspiciously looks like _MLS?
(This is C server publishing to Rust server
)
uid is context dependent i think?
but yeah tbh i can see why uid would be like the english version of mls for some things
only requirement for uid is it must be unique across the same HID/CIDs and must persist across reboots
But it's the same between multiple objects?
yeah thats weird
" The _UID must be unique across all devices with either a common _HID or _CID. This is because a device needs to be uniquely identified to the OSPM, which may match on either a _HID or a _CID to identify the device."
so idk
the pci interrupt link devices are incomprehensible to me and those are the ones im seeing have repeats though
so idk on there
(also MLS has multiple languages to it so it should be localizable. idk how to access that info though and my kernel doesnt do localization at this point anyway)
Yeah I know, dunno how to make it better and it doesnt matter because there's config.h that explains all options

the config.h had the same exact confusion to it and it took me multiple minutes to realise the docs werent wrong because of that
What part specifically?
"Makes uACPI use the builtin versions of mem{cpy,move,set,cmp} instead of relying on the host to provide them." implies it should be using the __builtin if the flag is set to me
because thats what the phrase "builtin versions" would be expected to mean, no?
and then the end of the docstring on that define says that the compiler might depend on them being available even if the thing is defined which feels like a contradiction
how that doc comment reads to me is saying if its defined then uacpi will use the __builtin_memxxx but be aware the compiler might generate dependencies on them even if you define it (which is implied to make uacpi depend on them explicitly so of course theres a dependency on the __builtin_memxxx)
That would make no sense, since it should really be detecting if those exist itself
Uacpi doesnt have any config options that are compiler dependent
i just dont see how that first sentence implies anything other than forcing the use of __builtin_memxxx
which is the opposite of what the define does
Built-in to uacpi, it doesnt say “compiler intrinsic” anywhere tho
Im open to suggestions for better wording tho
tbh if the intrinsic didnt have builtin in the name itd be less confusing
id call it "default implementation" or "uacpi-provided" or something like that personally
uacpi-provided is my instinct
at least for in the doc string
can keep the define name for version compat if the docs make it clear
Yeah thx
yay!!
is this rust?
ah, so that explains why the formatting looks like rust's Debug
it's deserialized in rust?
yes
I will update my uacpi one day
do it two day
How do you test uACPI? Do you have your own operating system kernel you use it with or do you use some common unix distribution
see tests/
i have a userspace port of uacpi
that i run against the test suite as well as real hardware blobs
I see, That’s dope
Does the user space port do all the same stuff just using system calls or how does that work
Dang bro I’ve been looking around the repo and I wanna say this is one of the most robust open source software projects I’ve seen in years, congratulations
thank you
What was your main motivation? Lack of non bullshit ACPI implementations?
i wanted a fully NIH OS, and ACPI was going to be a big part of that
when i started out i didnt know anything about ACPICA's quality
i thought it was good since everyone used it
ACPICA is actually a joke
But that’s fire bro keep it up
I’m gonna port it to mine soon
I’ve gotten almost all of the deps done
I’ll let you know when I do 💯💯💯
letsgo!

then you ping oberrow 
Then you die because you forgot to put a lock 
Yeah I just get the
Wel%co[*{%]*]e to FlqodidococcOS 1.02948293738;8.29382Segmentatjon fault at 0x02938382912728sjskxjdnxiekenjabcdefihatemlifeeucidnejxidodoeen
true
How is uacpi_kernel_reset_event() used, and is it guaranteed that there is no contention on the semaphore when it is called?
shit
that means I need to actually do stuff, then?
should I wake up waiters and tell them the acquire failed?
yeah, and it'd overcomplicate stuff
just looked at uacpi-linux
and what it does is much easier
what does it do?
basically this:
while (trylock (semaphore))
;
thats smart
for me, sema_lock_timeout (sema, 0) is equivalent to trylock
so I can just do that instead
yeah
I just discovered a bug in my acpi mutex implementation
almost makes me think reset should be implemented internally be uacpi
do you see the bug?
overflow?
ah right
ill get rid of uacpi_kernel_reset_event and just have a loop of uacpi_kernel_wait_for_event(event, 0)
how did i not think of that implementation
well i didnt because i basically stole acpica's api for events sort of
why? someone might have a faster sema_slurp or something which is basically
void
sema_slurp (struct semaphore *sema)
{
spin_lock (&sema->lock);
sema->count = 0;
spin_unlock (&sema->lock);
}
not sure it matters
yeah, it probably doesn't
anyway
why are the return types of uacpi_kernel_acquire_mutex and uacpi_kernel_wait_for_event inconsistent?
the former returns a uacpi_status and the latter returns a uacpi_bool indicating success
it just seems strange
good question
but tldr is there's nothing uacpi can currently do with an error for wait
since events are mostly used for aml
aborting is probably worse than just not entering the branch that does Wait(...) in aml
there's going to be like zero use of semaphores in my kernel besides ACPI that I can think of now
lol
but yeah it was a mistake not to convert events alongside mutexes
i might do it later for 3.0
i think same goes for linux
not many users of it
like everything is either plain mutex or rwmutex
I mean you can use them to implement mutexes
uacpi_status uacpi_kernel_acquire_mutex(uacpi_handle mutex, uacpi_u16 timeout) {
i64 timeout_value = static_cast<i64>(timeout * (NS_IN_MS / 100));
auto status = KeWaitForSingleObject(
mutex,
KWAIT_REASON::Executive,
KernelMode,
false,
timeout != 0xFFFF ? &timeout_value : nullptr);
return status == STATUS_TIMEOUT ? UACPI_STATUS_TIMEOUT : UACPI_STATUS_OK;
}
void uacpi_kernel_release_mutex(uacpi_handle mutex) {
auto semaphore = static_cast<KSEMAPHORE*>(mutex);
KeReleaseSemaphore(semaphore, 0, 1, false);
}
uacpi_bool uacpi_kernel_wait_for_event(uacpi_handle event, uacpi_u16 timeout) {
return uacpi_kernel_acquire_mutex(event, timeout) == UACPI_STATUS_OK;
}
void uacpi_kernel_signal_event(uacpi_handle event) {
auto semaphore = static_cast<KSEMAPHORE*>(event);
KeReleaseSemaphore(semaphore, 0, 1, false);
}
void uacpi_kernel_reset_event(uacpi_handle event) {
auto semaphore = static_cast<KSEMAPHORE*>(event);
KeInitializeSemaphore(semaphore, 0, INT32_MAX);
}
sure, but then you lose out on this fastpath:
initialising uacpi on a thread instead of before the scheduler results in a few hundred thousand points more on average
only on uefi though, on bios the performance is affected negatively

I'm getting 4.5 million consistently on my cpu
and your CPU is?
that doesnt make much sense ngl
since aml is the same
ryzen 5 pro 4650g
yeah I don't know what's happening
yeah maybe, though a semaphore acquire isn't that costly either as it can also just be a single cmpxchg
oh now it's almost the same
I'm really cursed
we really need a good automated test runner 
obos is basically an automated test runner
what does iloblix do again?
ukernel time
i mean a piece of hardware
Use a watchdog and any existing hardware
picokvm with it wired up to press the power and reset buttons
A test runner is not very hard to wire up
I have a bpi-f3 wired up as a test runner for RV
I just use a smart wall plug to turn power on/off
- tftp boot + uart wired to a different machine
We need a leaderboard for RISC-V 
risc-v qemu acpi is like 10 opcodes
lmao
The board doesn't have acpi
I use it to test managarm, not uacpi
But the same approach would also work for uacpi on x86
Do ARM and RISC-V have sleep states as well?
yes
RISC-V can sleep using SBI
I'm not sure how this is wired up to ACPI
it'd help if they released a proper acpi spec with risc-v support in it 
there are ECRs in github issues pointing to google drive links 
last time I checked the links were dead
this does not include RISC-V shit tho??????????????????????
bruh
waiting for 6.6 then
I have these
Should've saved the rest
Is it even worth supporting 64 bit wakeup vector memes?
based
Like they were not dead a year ago
nah
So like just having the 16 bit mode one is fine?
Does everyone folow this?
Platform runtime firmware restores the pre-sleep configuration or initial boot configuration of
each CPU (MSR, MTRR, firmware update, SMBase, and so on). Interrupts must be disabled (for IA-32 processors, disabled by CLI instruction).
Wait, initial boot
Still
I think someone was saving MTRRs here?
i wouldnt rely on it
idk what _TTS does
_WAK is handled by uacpi_prepare_for_wake_from_sleep_state
_PTS is from uacpi_prepare_for_sleep_state
_PRW is fnuy
let me go back to my suspend code to see what it did again
ok yeah so PRW basically tells you the power resources needed to be enabled for the device to wake u
and also tells the deepest state the device can wake you frame
as well as the gpe index that you should use uacpi_setup_gpe_for_wake on
btw it mentions something about gpe block devices, ignore that
infy said a while back they don't exist
btw before doing that you should evaluate _DSW if it exists, or _PSW if _DSW does not exist
if _PSW doesn't exist, obos ignores the error and continues
after doing that you can simply put the device into the deepest state supported for wake from _Sn
(there was a chart for that in the acpi spec)
Do I need them?
I just call _ON on each one
but technically they should all be enabled before suspend, unless manually disabled
but I enable them manually anyway
What do I do with TTS?
never heard of it
16.1.6 Transitioning from the Working to the Sleeping State
On a transition of the system from the working to the sleeping state, the following occurs:
- OSPM decides (through a policy scheme) to place the system into the sleeping state.
- OSPM invokes the _TTS method to indicate the deepest possible system state the system will transition to (1, 2,
3, or 4 representing S1, S2, S3, and S4)
Control method used to prepare to sleep and run once awakened
yes I see it
it probably means _SST, and yeah uacpi calls it
9.2.1 _SST (System Status)
This optional object is a control method that OSPM invokes to set the system status indicator as desired

Elixir Cross Referencer - source code of Linux v6.13.4: drivers/acpi/sleep.c
linux calls it on its own
oops
inb4 seabios bug was obos bug
that said obos did die on some real hw
said hardware doesn't have _TTS
out of 500 blobs only macbook pro 12/14 have it
So basically,
- I have to implement wakeup vector
- I have to call a bunch of ACPI methods
- Profit?
❯ grep -rn '_TTS'
Notebook/Apple/MacBookPro12/MacBookPro12,1/A236F4DD9072:9015: Method (_TTS, 1, NotSerialized) // _TTS: Transition To State
Notebook/Apple/MacBookPro12/MacBookPro12,1/A236F4DD9072.bin:2676: 79A0: 5F 12 08 03 0A 07 0A 07 0A 00 14 0C 5F 54 54 53 _..........._TTS
Notebook/Apple/MacBookPro14/MacBookPro14,3/91077C25D705:10177: Method (_TTS, 1, NotSerialized) // _TTS: Transition To State
oh btw you do all that for each wake capable device you wish to enable
wkaeup vector is literally just
smp trampoline
I think 12,1 is a model number
I don't have smp trampoline
ah well
And I need some system to park cores?
people raised by limine
and you do it before sleep, of course
L
L
smp trampolines are always fun to write
My pmm has memory zones though
idk what that does
So it shouldn't be hard to allocate memory below 1MB
I just hardcode the smp trampoline at 0x1000 
(btw doing it at phys. 0 will not work in any case)
((if you workaround the bios not letting you, it'll just cause you to triple fault because you'd have overwritten the IVT))
other than acpi stuff, you should probably get a way to tell your drivers that you are going into suspend
I can then just pagefault to success
also park other cores under cli;hlt
No, but then how do I wake them up
and vice versa
Like this needs to be a syscall
Because I will not do @ monkous memes and I will let uACPI enter S3 from userspace instead
and continue doing shit
1 stack per CPU should help with wakeup
So like the only thing I need from kernel is a syscall to flush caches and a wakeup vector?
btw here is a list of what you need to save before S3 (that you might forget about) on x86-64:
- HPET status
- LAPIC status
- IOAPIC status
- PCI status
- ACPI NVS ram regions (some devices don't need to / cannot do it, so add a kernel command line option to enable/disable this)
- and that should be it
pretty much
What's PCI status?
and also you will need to wake other CPUs again
literally anything in the PCI config space
nah
(it only resulted in a full PCI interface rewrite for me)
((nothing big))
btw unless you have my patched seabios, if you use PCIe, it will be broken
after wake from suspend
I will see
My kernel devicesd server already keeps the list of PCI devices
Apparently
I just add a few fields and then memcpy?
Also I can just let device drivers take care of it
(except that it would be a race condition)
Ok, I need to look how to implement SMP wakeup vector
/ACPI
(My hyper builds have no SMP for now)
(so that also needs to be taken care of (eventually))
And my grub memes were extremely cursed
🤮 intel syntax
kys (keep yourself safe)
yes
unfortunate...
wha
it is quite fortunate
because my pmm has zones
so I just tell it to allocate a 32-bit cr3 for the kernel
obos_status Arch_InitializeKernelPageTable()
{
obos_status status = OBOS_STATUS_SUCCESS;
uintptr_t newCR3 = Mm_AllocatePhysicalPages32(1,1, &status);
uintptr_t oldCR3 = getCR3();
// ...```
i should work on smp at some point tbh
I can't load 64 bit idt (except...) and I can't jump to 64 bit address (also except...)
Does jmp extend sign?
If the kernel is in -2GB
So I can pagefault to success
Or I need to jump to somewhere in -2GB
?
you can just have a structure at the end of the trampoline and fill in the jump address to there
you are not making sense go to sleep and come back
🥚sactly
yeah that's what I was saying
but I want my trampoline to be relocatable
(Which does not change anything)
you can do cs relative accesses
yeah
if you don't want to patch instructions that is
But still
jump to the jump address in long mode
so then you can use rip-relative accesses
just mov rax, addr jump rax
you first enter long mode to a label within your tramp
and after you are in long mode you do a normal jump to the actual dest
I want that label to be in higher half directly
why
its very likely not possible
exception thrown in my brain: e.what(): "what are you smoking?"
you need an identity mapping for enabling paging anyway
like you can't just be in a random lower half page that is not mapped when you enable paging (and you can't be in higher half either because paging is not active yet)
ChatGPT says this is possible 
Real mode doesn't have paging
So I enter long mode from real mode, the far jump would enable paging
If jmp does sign extension, I can jump directly to higher half address
Or am I too tired
i dont think so lol
afaik paging is activated immediately when you enable it in cr0 and not delayed like that
Ok I forgot how to x86
yeah
It enters compat mode
then 2, if idtr does sign extention, I could pagefault to the right address
bru
Ok fine I'll just map that page
But then I won't be able to detect kernel nullptr derefs
it doesn't have to be page 0
It can be page 0
wrong
My pmm can suddenly decide it's page 0
the acpi spec does not allow that for wake from suspend's
wake vector
yeah that too
That's anoying
its not
no not really
also the IVT
is at address zero
so you can't even put it at phys. zero if you tried
otherwise you'd overwrite the IVT
and cause the firmware to triple fault (which I have experienced on qemu!!)
also you could always only map the trampoline before needing it and unmap after you are done using it
this
Anyway, before the smp trampoline
I have to make sure that entering S3 from userspace (by which I mean writing whatever to SLP_TYPx in Ring 3) doesn't destroy kernel state
park all other CPUs
and you're fine
*if you also make sure the current CPU doesn't get rescheduled until the wake
I need to make sure I don't get a timer interrupt or whatever and uACPI doesn't get preempted unexpectedly
and also that the kernel is able to schedule uACPI server after wakeup
the hardest part is timers (?)
Can I have problems if I don't enter S3 from bsp?
hopefully not
although I don't depend on that
and make sure the suspend helper frame is pinned to the BSP
Do I get NVS regions from limine?
yes
Ok, entering S3 was trivial
Now I just need to wake up 
(my testing PC is very confused
)
It showed 03 POST code, then a bunch of stuff, then went to sleep
i wish i could make limine give me the mp info without bootstrapping the APs tbh, im gonna need a trampoline anyway for possible suspend/wake so like what would be the point in having limine do it
uacpi tables only mode when lol
(so i can make a bootloader that does what i want)
how about making a pr to limine to do exactly that? :^)
adding a simple flag to the mp request would be simple enough
limine source code is very approachable
atp just diy
but why
tbh it doesnt matter that limine starts them up for you
I honestly don't get the point
you can just ipi them and start them up again yourself
wait you can ipi an already running processor? didnt know that, assumed it wasnt allowed
of course you can
ye ofc
ok but its C and i wont want to write C lmao
ok in that case im good
the ziggyness is why i like zig over c lol
lenovo x270 aquired 
now i need a os to test uacpi on it and dump the tables
how is the policy for adding table structs to uACPI?
esp for non-standard (as in, not part of the ACPI spec) tables like DMAR
@fiery turtle
any new tables are welcome
surprising but nice
i mean it already has hpet and mcfg
fair
lmao things that essential are not in the ACPI spec?
Is fadt preserved between sleeps?
Or do I need to be setting wakeup vector every time?
what if there's some insane firmware which overwrites it, idk
Perhaps
then that isn't your problem, perhaps
print a big ass warning with bios interrupts
YOUR FIRMWARE IS STUPID
PLEASE BUY A NEW COMPUTER
and halt in a loop
easy
Well technically one is an unrelated device, and the other is part of the pcie specification which costs 2 thousand dollars
but realistically just see what linux does 
i will now port uACPI to Vinix
Letsgo
finally 🙏
i will do that until i am eepy to go to sleep
Good way to fall asleep
fr
it's building llvm
i need to wait for it to finish now
i don't wanna interrupt it
Might as well sleep
ok i'll interrupt it
Lol
How good is v to c integration
True
Convert the entire types.h and resources.h 
Also me when there's like 3 or 4 kernels written in zig that use uACPI but no official bindings 
I also saw one on github recently
imaginarium has some bindings in tree
but i havent looked at them
learn zig and write official bindings
Does zig have like a package manager where you would put them or how does that work
sort of
how it works is you just fetch tarball or other form of sources
like uhhh
one sec
there's thie build.zig.zon file you can put your dependencies in
and build.zig fetches them for you
.{
.name = "zigux",
.version = "0.0.0",
.dependencies = .{
.@"freestnd-c-hdrs" = .{
.url = "https://github.com/osdev0/freestnd-c-hdrs/archive/21b59ecd6ef67bb32f893da8288ce08a324d1986.tar.gz",
.hash = "1220a5942e368a8780187b9138b5db8c24f098533d6084c58d1122378bb4a31dcfd5",
},
.limine = .{
.url = "https://github.com/48cf/limine-zig/archive/7b29b6e6f6d35052f01ed3831085a39aae131705.tar.gz",
.hash = "1220f946f839eab2ec49dca1c805ce72ac3e3ef9c47b3afcdecd1c05a7b35f66d277",
},
.uacpi = .{
.url = "https://github.com/uACPI/uACPI/archive/757dcece1a9f1c069355b23f7feaf21656728f94.tar.gz",
.hash = "12200468fb671c04225f04d87e0fe1131e49ccd153e870be6e858dc80e39cb4e18df",
},
},
.paths = .{"."},
}
Interesting
you can grab them in build.zig, either treat them as zig modules (if they have a build.zig) or just use the include directories or source files directly
Also os name leak
const freestnd_c_hdrs = b.dependency("freestnd-c-hdrs", .{});
this is how you refer to them in build.zig
kernel.addIncludePath(
freestnd_c_hdrs.path(b.fmt("{s}/include", .{@tagName(arch)})),
);```
Makes sense
and here i add the include path for the freestanding headers to the kernel executable
so it ends up being ${source_dir}/${arch}/include
the source dir for the dependencies usually points somewhere inside the zig cache
there's 2 zig caches though, one in your home directory and one in the project root
~/.cache/zig and ./.zig-cache
Whats the global cache for?
honestly idk what its used for but i think caching dependencies
so the same tarballs can be reused across multiple projects
they are identified by the hash so
if it sees the same hash in the global cache it can just get it instead of downloading it again
thats why its important to change the hash when updating the url in the build.zig.zon file
or dont do it manually and just use zig fetch :^)
hacker@raptor:~$ zig fetch --help
Usage: zig fetch [options] <url>
Usage: zig fetch [options] <path>
Copy a package into the global cache and print its hash.
Options:
-h, --help Print this help and exit
--global-cache-dir [path] Override path to global Zig cache directory
--debug-hash Print verbose hash information to stdout
--save Add the fetched package to build.zig.zon
--save=[name] Add the fetched package to build.zig.zon as name
--save-exact Add the fetched package to build.zig.zon, storing the URL verbatim
--save-exact=[name] Add the fetched package to build.zig.zon as name, storing the URL verbatim```
how do I wake qemu up? 
Ah
I've put a while 1 loop in assembly at my wakeup vector, and gdb doesn't reach it
Press key
ah even better, didnt know
It won't wake up if u didnt do any wake gpe configuration
are you using break or hbreak
break can be a bit finicky during cpu init
just ctrl+c whatever?
ah
nevermind then
U sure u suspended?
It said "QEMU paused"
Also that same code (without complications) did suspend my test PC
you can also git+https://github.com/osdev0/freestnd-c-hdrs#21b59ecd6ef67bb32f893da8288ce08a324d1986
instead of the archive url
why would you choose to bypass the CDN like that
and if you give it a tag/ref on the command line itll figure out what commit to use
or well
not bypass
but still git clones are significantly slower than regular tarball downloads in my experience
(it's supposed to be 0x9E000)
its more about being able to tell it a ref and have it resolve it
Yeah idk only oberrow knows how any of this works
And he won't write a wiki article
This seems like a triple fault with -no-reboot -no-shutdown
gatekeeping the suspend to ram knowledge smh
I could use bochs, but I need to fix my PCI functions
Ikr
I don't pass those
also worth noting on the zig dependency things, the dependency you fetch doesnt have to have any zig build support - the dependency object you get has a path method to get a dependency-relative path you can give to things in your main build. i use that to get both uacpi and limine binaries
Oh, hmm
Like before I was setting wakeup vector, it was properly tripple faulting
So does it wake or not
yeah, no, you don't even need zig code to use build.zig lol, that's the great part about it
Since I only support ecam
Idk I think it does? But it doesn't reach my assembly
Also make sure you're not trashing bios state with your low mem allocator
it shouldn't be
Yeah ecam will be broken on qemu after resume as well
Because of a bios bug
anyway, I don't care about PCI for now
oh and last zig uacpi bindings note: you dont technically need them at all

but native zig bindings would be much nicer
can just
const uacpi = @cImport({
@cInclude("uacpi.h");
// repeat for other headers
});
but yeah native bindings are better
I need to printf
i thought you dont need one? ah nvm
seems like a wrong resume vector
ive got a whole bunch of stuff already bound and ill probably throw a license exception thing for the bindings in imaginarium allowing uacpi to adopt them officially
Is imaginarium gpl?
mpl-2 yeah
i dont use the incompatible with secondary licenses thing but ill still probably add a note for uacpi adoption for clarity anyway
Letsgo
Wtf
Hm yes lettuce wake up in real mode

I need more printfs
Looks correct?
well... yes?
he said it was supposed to be 9e000 earlier
Ohh
lmao I learn more about how little I know every day
I thought it woke up in long mode
_S3 throws you in real mode on wake
I mean yeah CPU is reset
So it starts in real mode
that's only _S2/_S1

