#OBOS (not vibecoded)

1 messages · Page 23 of 1

flint idol
#

but now I use DPCs

real pecan
#

E.g. Managarm and astral just shutdown by doing uacp_kernel_schedule_work

real pecan
#

Although dpcs aren't good for this

white mulch
#

but if the registers don't get saved then it might cause issues when you want to resume that thread after the wake?

flint idol
#

I can just suspend in a throwaway thread

#

actually no

#

I think when I wake up from sleep

flint idol
real pecan
#

I think Linux invokes the actual sleep from an asm stub to preserve the regs?

flint idol
#

and I enforce that thread to run on the bsp

#

then when I wake up from sleep

#

I can just exit the thread

#

to continue from somewhere else

real pecan
#

Idk I haven't looked at it in depth

white mulch
#

a throwaway thread was just the first idea that I had so I went with that (and its nicer with all the c++ stuff that I have)

real pecan
#

Do it on the thread that requested shutdown, preserve regs, do actual enter_sleep

#

Also

#

Dont forget to quiesce other CPUs

#

Its probably ub not to

flint idol
#

how'd I do that

#

just stop them

#

by teling them to stop with an IPI

real pecan
#

Just ipi and make it cli hlt in the handler

flint idol
#

yeah ok

real pecan
#

U should do it on panic anyway

#

And on shutdown

flint idol
#

I do it on panic and shutdown

real pecan
#

Oh

flint idol
#

and reboot

white mulch
#

what does doing it on shutdown or reboot gain tho

#

if the cpu is going to be reset anyway

flint idol
#
void Sys_Reboot()
{
    OBOSS_HaltCPUs();
    uacpi_reboot();
    while(1)
        asm volatile("");
}
void Sys_Shutdown()
{
    OBOS_Log("oboskrnl: Shutdown requested.\n");
    OBOSS_HaltCPUs();
    // We're at IRQL_DISPATCH which should probably be enough for prepare for sleep state.
    uacpi_prepare_for_sleep_state(UACPI_SLEEP_STATE_S5);
    UACPI_ARCH_DISABLE_INTERRUPTS();
    uacpi_enter_sleep_state(UACPI_SLEEP_STATE_S5);
    while(1)
        asm volatile("");
}```
#

the forever loops are because it might take a bit for the shutdown/reboot to actually happen

#

past whatever uacpi's timeout is

#

(I have observed that on real hw)

real pecan
flint idol
#

interesting....

white mulch
#

ah

white mulch
flint idol
#

my computer sometimes hangs on shutdown

real pecan
#

And how do u even shutdown if your other CPUs still do interrupts and talk to hw lol

#

It would explode

white mulch
#

I just do that lol

flint idol
real pecan
#

Yes

flint idol
#

it would happen on windows and linux

#

idr if obos had that problem

#

if not then obos > windows and linux

real pecan
#

Well they probably also shutdown individual devices and run other aml

flint idol
#

yeah

#

but anyway

#

I have made a small change to the smp trampoline

#

so that the kernel tells it where to jump to after cpu initialization

real pecan
#

Inb4 it thinks its a resume from suspend when first booting

#

Causing obos to shit itself

flint idol
#

lol

#

nah it worked fine

#
diff --git a/src/oboskrnl/arch/x86_64/smp.asm b/src/oboskrnl/arch/x86_64/smp.asm
index 24cb3e4..0053f09 100644
--- a/src/oboskrnl/arch/x86_64/smp.asm
+++ b/src/oboskrnl/arch/x86_64/smp.asm
@@ -12,6 +12,10 @@ global Arch_SMPTrampolineCPULocalPtr:data hidden
 
 section .pageable.data
 
+extern Arch_APEntry
+global Arch_SMPTrampolineWakeLocation
+Arch_SMPTrampolineWakeLocation: dq Arch_APEntry
+
 Arch_SMPTrampolineStart:
 bits 16
 real_mode:
@@ -84,12 +88,9 @@ reload_cs_addr: equ $-Arch_SMPTrampolineStart
 ; Load RSP.
        mov rsp, [Arch_SMPTrampolineRSP-Arch_SMPTrampolineStart]
 
-extern Arch_APEntry
-
 ; Call AP initialization code.
        mov rdi, [Arch_SMPTrampolineCPULocalPtr-Arch_SMPTrampolineStart]
-       mov rax, Arch_APEntry
-       call rax
+       call [Arch_SMPTrampolineWakeLocation]
 Arch_SMPTrampolineEnd:
 section .text
 ; All of these CPUID bits are in CPUID.07H.0H:EBX```
#

that's all it was

#
obos_status OBOS_Suspend();

extern uint32_t OBOSS_WakeVector32;
extern uint64_t OBOSS_WakeVector64;

extern OBOS_WEAK obos_status OBOSS_PrepareWakeVector();```
#

nvm

real pecan
#

Will you also supply a 64 bit vector

flint idol
#

I changed that

#
obos_status OBOS_Suspend();

#define NO_WAKEVECTOR UINT32_MAX
extern uint32_t OBOSS_WakeVector;

extern OBOS_WEAK obos_status OBOSS_PrepareWakeVector();```
real pecan
flint idol
#

idk what a protecte mode entry is

#
 * 'addr64' is the protected mode entry-point address
real pecan
#

Just have 0 be no entry

#

Why 0xfffff

flint idol
real pecan
#

What the fuck

flint idol
#

and I don't feel like changing that and seeing what happens

flint idol
#

I have the barebones for suspend implemented

#

but no wake related things are called yet

real pecan
#

is the wake code called

flint idol
#

I do something slightly cursed

#

and by slightly I mean very cursed

real pecan
#

i mean its obos so i trust u

flint idol
#
bool OBOS_WokeFromSuspend;
static void suspend_impl()
{
    if (OBOS_WokeFromSuspend)
    {
        uacpi_prepare_for_wake_from_sleep_state(UACPI_SLEEP_STATE_S3);
        UACPI_ARCH_ENABLE_INTERRUPTS();
        uacpi_wake_from_sleep_state(UACPI_SLEEP_STATE_S3);
        OBOS_WokeFromSuspend = false;
        CoreH_ThreadReady(suspended_thread);
        Core_ExitCurrentThread();
    }
    uacpi_prepare_for_sleep_state(UACPI_SLEEP_STATE_S3);
    UACPI_ARCH_DISABLE_INTERRUPTS();
    // good night computer.
    uacpi_enter_sleep_state(UACPI_SLEEP_STATE_S3);
    OBOS_UNREACHABLE;
}```
suspend_impl is the entry of the suspend worker thread
#

it's entered at IRQL 2

#

(Dispatch)

#

so it cannot yield

#

so the idea is that

real pecan
#

i mean this aint even cursed

flint idol
#

will just switch to that thread

#

but the scheduler's structs still think that

#

it is at the entry

flint idol
#

so it wakes from suspend

#

kinda cursed

real pecan
#

nah not cursed

flint idol
#

hmm

#

anyway I'm now gonna implement the arch side of suspend

#

wake.c under arch/x86_64

real pecan
#

maybe its cursed in the sense that this is some other random thread

flint idol
#

oh yeah I forgot to set any wake GPEs

#

I'll do that after the wake trampoline code

flint idol
#

@real pecan the gpe-related functions in uacpi take in an index, can this be anything unique per gpe device, or do I need to find it some way

real pecan
#

wdym

#

gpe is literally an index

flint idol
#
UACPI_ALWAYS_ERROR_FOR_REDUCED_HARDWARE(
uacpi_status uacpi_gpe_enable_for_wake(
    uacpi_namespace_node *gpe_device, uacpi_u16 idx
))
UACPI_ALWAYS_ERROR_FOR_REDUCED_HARDWARE(
uacpi_status uacpi_gpe_disable_for_wake(
    uacpi_namespace_node *gpe_device, uacpi_u16 idx
))```
#

idx

#

what do I pass

real pecan
#

oh just null

flint idol
#
UACPI_ALWAYS_ERROR_FOR_REDUCED_HARDWARE(
uacpi_status uacpi_gpe_setup_for_wake(
    uacpi_namespace_node *gpe_device, uacpi_u16 idx,
    uacpi_namespace_node *wake_device
))```
real pecan
#

either null or just the _GPE node

flint idol
#

then uacpi_gpe_enable_for_wake

flint idol
#

oh wait I get it now

#
static void set_wake_vectors()
{
    uacpi_gpe_setup_for_wake(nullptr, 0, nullptr);
    uacpi_gpe_enable_for_wake(nullptr, UACPI_FIXED_EVENT_POWER_BUTTON);
}```
#

I think I would do that to make the power button wake me

real pecan
flint idol
real pecan
#

no

flint idol
#
static void set_wake_vectors()
{
    uacpi_gpe_setup_for_wake(nullptr, 0, nullptr);
    uacpi_gpe_enable_for_wake(nullptr, 0);
}```
#

what about this

real pecan
#

wtf

flint idol
#

well you said idx can be null

#
 * NOTE: 'gpe_device' may be null for GPEs managed by \_GPE
#

and you also said that

real pecan
#

i never said anything about the index

flint idol
real pecan
#

i didnt mean the idx

#

because that would make no sense

flint idol
#

what do I pass to idx

#
/home/oberrow/Code/obos/src/oboskrnl/power/suspend.c:57:(.text+0x10f): undefined reference to `uacpi_gpe_setup_for_wake'```
#

uhhhh

real pecan
flint idol
#

hmm what do we have here

real pecan
#

ur supposed to figure out the gpe index of the device u want to enable for wake

#

then set it up for wake

#

thats it pretty much

flint idol
#

ok

real pecan
#

lmao

flint idol
#
/home/oberrow/x86_64-elf-tools/bin/../lib/gcc/x86_64-elf/13.2.0/../../../../x86_64-elf/bin/ld: src/oboskrnl/CMakeFiles/oboskrnl.dir/power/suspend.c.obj: in function `set_wake_vectors':
/home/oberrow/Code/obos/src/oboskrnl/power/suspend.c:57:(.text+0x10f): undefined reference to `uacpi_gpe_setup_for_wake'
/home/oberrow/x86_64-elf-tools/bin/../lib/gcc/x86_64-elf/13.2.0/../../../../x86_64-elf/bin/ld: /home/oberrow/Code/obos/src/oboskrnl/power/suspend.c:58:(.text+0x118): undefined reference to `uacpi_gpe_enable_for_wake'
real pecan
#

i think its

#

it should be uacpi_setup_gpe_for_wake

#

the header is bogus

flint idol
#

how do you just

#

mess that up

#

lmfao

real pecan
#

thats why i need a test kernel like i said lmao

#

this is untested api

flint idol
#

yeah it's uacpi_setup_gpe_for_wake

#

along with gpe_enable_disable_for_wake

real pecan
#

nope

#

u dont need to enable anything yourself

flint idol
#

oh

flint idol
real pecan
#

it will be enabled automatically when u prepare to sleep

#

u just tell it u want it enabled via setup_for_wake

flint idol
#

yeah ok

#
// thanks infy
UACPI_ALWAYS_ERROR_FOR_REDUCED_HARDWARE(
    uacpi_status uacpi_setup_gpe_for_wake(
        uacpi_namespace_node *gpe_device, uacpi_u16 idx,
        uacpi_namespace_node *wake_device
    ))
static void set_wake_vectors()
{
    // uacpi_gpe_setup_for_wake
    uacpi_setup_gpe_for_wake(/* TODO */);
}```
real pecan
#

i have a pr open with fixes anyways ill get that in

flint idol
#

@real pecan how do I find if a namespace node has a method in uacpi

#

linux seems to have acpi_has_method

#

I want something similar

#
if (!acpi_has_method(device->handle, "_PRW"))
    return;```
real pecan
#

literally

#

see how its implemented

#

just node find _PRW

flint idol
#

uacpi_namespace_node_find

#

on PRW

#

yeah

real pecan
#

yes

flint idol
#

the object returned isn't refcounted or anything right

real pecan
#

the node?

#

no

flint idol
#

ok

#

reading linux source to find out the thing I need

#

instead of pinging infy for the 11th time today

#

my brain hurts

real pecan
#

yes

#

its generally more useful to consult the source than me since ive never even implemented suspend

flint idol
#

it seems to do something like

package = (union acpi_object *)buffer.pointer;```
#

buffer is an acpi_buffer

#

so I tried to replicate that in uacpi by evaluating the PRW object as linux did

real pecan
#

in uacpi its just obj->package

#

acpi_buffer is what ACPICA uses to return anything from methods

#

its just an opaque data buffer

flint idol
#

ok if I understood this right

#

if the first element is an integer

#

that's the gpe number

#

and the wakeup device is null

#

otherwise if it is a package

#

and that package's first element isn't a local reference

#

wait nvm

#

ignore that

#
if ((element->package.count < 2) ||
            (element->package.elements[0].type !=
             ACPI_TYPE_LOCAL_REFERENCE)
            || (element->package.elements[1].type != ACPI_TYPE_INTEGER))
            goto out;```
flint idol
real pecan
#

why cant u just read the acpi spec

flint idol
flint idol
#

oh wow that doesn't give me brain damage

#

from reading linux src

real pecan
#

in uacpi ACPI_TYPE_LOCAL_REFERENCE would just be a string that u would uacpi_namespace_node_resolve_from_aml_namepath

flint idol
#
if (pkg->objects[0]->type == UACPI_OBJECT_INTEGER)
{
    gpe_idx = pkg->objects[0]->integer;
    gpe_dev = nullptr;
} 
else if (pkg->objects[0]->type == UACPI_OBJECT_PACKAGE)
{
    uacpi_package* pkg2 = pkg->objects[0]->package;
    gpe_dev = ;
    gpe_idx = pkg2->objects[1]->integer;
}```
in the 2nd branch, I must set gpe_dev, which is a namespace node, to the pkg2->objects[0]
#

but idk how because that is a uacpi_object

real pecan
#

what

flint idol
#

well

real pecan
#

u mean this case DeviceName // Reference?

flint idol
#

yes

real pecan
#

did u just ignore what i sent above

flint idol
#

uacpi_namespace_node_resolve_from_aml_namepath

real pecan
#

yes

#

package[0] would be a string object

#

that u resolve against that device

flint idol
#

oh

#

thanks infy

real pecan
#

np

flint idol
#

and I assume a string behind the scenes is a uacpi_buffer

real pecan
#

yes

#

and that has a .text

flint idol
#
if (pkg->objects[0]->type == UACPI_OBJECT_INTEGER)
{
    gpe_idx = pkg->objects[0]->integer;
    gpe_dev = nullptr;
}
else if (pkg->objects[0]->type == UACPI_OBJECT_PACKAGE)
{
    uacpi_package* pkg2 = pkg->objects[0]->package;
    gpe_dev = uacpi_namespace_node_resolve_from_aml_namepath(node, pkg2->objects[0]->buffer->text);
    gpe_idx = pkg2->objects[1]->integer;
}
else
{
    OBOS_UNREACHABLE;
}```
#

before that I also make sure that device can wake me in S3

real pecan
#

besically yes if u dont do any error checking at all

flint idol
#

using the 2nd object of the first package

#

who needed error checking anyway

real pecan
#

this is going to be the new interface btw #1217009725711847465 message

#

you wont be able to access shit like that anymore

flint idol
#

well that is in the future

real pecan
#

yes

flint idol
#

rn I need something down

real pecan
#

btw

#

the second branch is only relevant for non x86

#

or well

#

probably some very very niche x86

flint idol
#

well I do eventually plan on aarch64

#

or riscv

#

oh cool it's suspended rn

real pecan
#

did u suspend qemu

flint idol
#

and it triple faults

flint idol
flint idol
#

lmao

real pecan
#

lol

#

did it have any wake devices

flint idol
#

probably

real pecan
#

how did u wake it up

flint idol
#

sendkey a

real pecan
#

interesting

flint idol
#

in qemu

#

weird

#

I added a log to see if it finds any wake gpes

#

and I never get one

real pecan
#

lol

flint idol
#

yet sendkey triple faults it

real pecan
#

how do u uh

#

even look for it

flint idol
#

namespace iterate

#

then I make sure I see a device

#

otherwise I go on

white mulch
#

does any of the wake code ever get executed?

flint idol
#

good question

white mulch
#

also did you put the wake vector at a non zero address? because the facs doesn't allow zero as the wake address because it means invalid

flint idol
#

my trampoline is at phys 0

white mulch
#

well yeah that's probably why lol

real pecan
#

i mean

#

what does -d int say

flint idol
#

good question

#

nothing

#

*of interest

#

the last exception is normal

real pecan
#

normal exception?

flint idol
#

one that is expected

#

it was a page fault because the kernel needed to page something in

real pecan
#

so uh

#

how do u even know it triple faults

flint idol
#

it reboots

#

so I assumed triple fault

white mulch
#
void VISIBLE32FLAT
handle_resume32(int status)
{
    ASSERT32FLAT();
    dprintf(1, "In 32bit resume\n");

    if (status == 0xfe)
        s3_resume();

    // Must be a soft reboot - invoke a hard reboot.
    tryReboot();
}
``` s3_resume returns early if the facs waking vector is zero and then it gets to tryReboot (this is on seabios)
real pecan
#

oh cool

flint idol
#

soo ummm

#

I need a non-zero vector

real pecan
#

placing anything at 0 is a terrible idea ngl

flint idol
#

now since it'd be too much work to make my smp trampoline be relocatable

#

I will just have some temp page

#

that jumps to address zero

#

hacky, but whatever

real pecan
#

bruh

flint idol
#

the smp trampoline assumes addresses off zero in many places

white mulch
#

its not that hard to make a relocatable trampoline, you can use cs relative addressing and put the boot info at the end of the trampoline or whatever

flint idol
#

doesn't change the fact that

#

I don't wanna

#

ok now it triple faults

#

which is better

real pecan
#

lmao

flint idol
#

it's a GPF

#

nvm

#

it's a bad instruction

flint idol
#

werid stuff

#

I think the bios uses phys. zero as a scratch space

#

because when I am actually in the trampoline it's corrupted

#

but before I go to sleep it's not

real pecan
#

phys zero is bios ivt

flint idol
#

oh yeahhhhhhh

#

since I still don't feel like making my smp trampoline relocatable

#

what I'll do now is

#

keep a copy of the trampoline after the reset vector

#

and copy it to phys. 0

real pecan
#

this guy will do anything but move his goddamn trampoline

white mulch
#

at this point you would have already made it relocatable lol

flint idol
#
Arch_ACPIWakeTrampoline:
bits 16
    call $
    pop ax
    mov es, ax
    mov si, es:.data-Arch_ACPIWakeTrampoline
    mov di, 0
    mov cx, Arch_SMPTrampolineEnd-Arch_SMPTrampolineStart
    rep movsb
    jmp 0x00:0x0000
Arch_ACPIWakeTrampoline_data:
times Arch_SMPTrampolineEnd-Arch_SMPTrampolineStart db 0```
#

bam

white mulch
#

cursed

flint idol
#

then I just copy the smp trampoline into Arch_ACPIWakeTrampoline_data

#

and I'm good

flint idol
flint idol
#

this code is cursed

#

but I will not look past at it past today

#

ok now it crashes in a different way

#

instead of it triple faulting because of an invalid opcode

#

nvm

#

bro wtf is up with the cpu

#

how is it at

#

long mode

#

where is the gdt????

#
GDT=     0000000000000000 00000000```
real pecan
#

did u expect registers to survive

flint idol
#

no

#

which is why I load a gdt

#

the first thing in the smp trampoline

thick jolt
#

hi infy hi oberrow

#

my favourite peopple

flint idol
#

hi nyauxmaster

thick jolt
#

hi

flint idol
#

is your day good

thick jolt
#

yes

#

😎

flint idol
#

good to hear

#

nyaux is returning to greatness it seems

thick jolt
#

yes indeed

#

im eta'ing scheduling in maybe 3-5 days depending on what memes ill encounter :)

flint idol
#

W

thick jolt
#

indeed

flint idol
#

I'm tryna setup bochs

thick jolt
#

ooo

#

does obos run in bochs

flint idol
#

I'm tryna get it running

#

so idk

real pecan
#

yeah just boot it in bochs

#

bochs will tell u what u did wrong

thick jolt
#

exactly

flint idol
#

bruh how do I use bochs

#

Message: ROM: couldn't open ROM image file '/usr/share/bochs/BIOS-bochs-latest'.

real pecan
#

u need a config

flint idol
#

yuh huh

thick jolt
#

good luck on this oberrow!

#

ima take a nap

flint idol
#

thanks

thick jolt
#

np

flint idol
#

gn

thick jolt
#

gn

real pecan
#

nyaux nap%

flint idol
#

wtf

#

why don't I have any BIOS rom

#

but I do have a vga bios

#

it is in the bochsbios package

#

life without apt-file

#

would be bad

short mortar
#

Bochs build in Debian'/Ubuntu's repos is ... weird

real pecan
#

U mean GNU/Linux/Debian/Ubuntu?

short mortar
#

Lol yes

#

Is there bochs for Debian GNU/Hurd? thonk

flint idol
#

idk what I did wrong

#

but I don't even get to my kernel in bochs

real pecan
#

bochs debugger time

short mortar
#

I just compiled mine from source on Ubuntu

real pecan
#

as you should tbh

short mortar
#

Fedora's repos were really nice

flint idol
flint idol
#
uacpi_namespace_node* prw = uacpi_namespace_node_find(node, "_PRW");
if (prw)
    goto end;
#

lmao\

#

I was wondering where all the devices

#

that could wake the system were

#

why does qemu have no devices with PRW

#

and why can't bochs get past "Booting from hard disk"

#

without triple faulting

flint idol
#
KVM internal error. Suberror: 1```
white mulch
real pecan
#

obos try not to triple fault challenge

flint idol
#

ok it stopped triple faulting

#

I think

#

now it's doing something different

#

unless

#

I think it's just executing zeroes

#

or the ivt

flint idol
#

@real pecan I think I accidentally found a workaround to not being able to set the FACS reset vector to zero

#

if you set it to 0x800

#

it seems to actually throw me at address 0x0

flint idol
#

wait wtf

real pecan
#

implementation details of a specific bios

flint idol
#

it's always going to 0x0

flint idol
#

I wasn't trying to do that

#

I found out by accident

real pecan
flint idol
#

at least if gdb isn't lying to me

#

I have two bps

#

one at 0x0

#

and one at the reset vector

#

the latter never gets hit

real pecan
#

i mean print the value in facs

flint idol
#

yeah

#

that's what I'm doing

real pecan
#

p g_uacpi_rt_ctx.facs->whatever

flint idol
#

I printed it in uacpi_set_waking_vector

#

and it's what I expected

real pecan
#

print in gdb as well

flint idol
#

yeah I am

#

it's 0x1000

real pecan
#

u could of course

#

compile the bios

#

and add printfs there

flint idol
#

Bah

flint idol
#

weird

#

it doesn't like hyper

#

@real pecan helppppppppp

#

seabios no working

real pecan
#

idk figure it out

flint idol
#

now it's not even building

#

on the 1.12-stable branch

#

finally

#

it booted

#
In resume (status=254)
In 32bit resume
table(50434146)=0x3ffe21f3 (via rsdt)
Found 4 cpu(s) max supported 4 cpu(s)
PCIe: using q35 mmconfig at 0xb0000000
Running option rom at c000:0003
Start SeaVGABIOS (version 1.16.3-debian-1.16.3-2)
VGABUILD: gcc: (Debian 13.2.0-7) 13.2.0 binutils: (GNU Binutils for Debian) 2.41
enter vga_post:
   a=00000000  b=0000ffff  c=00000000  d=0000ffff ds=0000 es=f000 ss=0000
  si=00000000 di=000060c0 bp=00000000 sp=00000f36 cs=f000 ip=d004  f=0000
Jump to resume vector (1000)
real pecan
#

There u go

flint idol
#

well 0x1000 is the vector I wanted....

real pecan
#

Does it not actually jump there

flint idol
#

let me add an artifical breakpoint

#

it does

real pecan
#

Sooo how are u not seeing it via grub

flint idol
#

grub?

real pecan
#

Lmao

#

Sorry

#

Gdb

flint idol
#

idk, it's quite weird

real pecan
#

Probably some skill issue

flint idol
#

bruh

#

I put b *0x1000

real pecan
#

Maybe its waiting on virtual 0x1000

flint idol
#

perhaps

#

yay it triple faults now

#

or maybe not yay

#

probaby yay!

real pecan
#

Wdym yay

flint idol
#

I now know I'm not jumping to arbitrary code

real pecan
#

Big

flint idol
#

now I just need to find out the reason for the triple fault

#

which I will do after a tiny bit

#

it's a gpe

#

bruh

#
 53176: v=0d e=0012 i=0 cpl=0 IP=0008:00000000000fd089 pc=00000000000fd089 SP=0010:0000000000000000 env->regs[R_EAX]=0000000000000000
#

that ain't my code

torpid wigeon
#

i stole it

flint idol
#

yeah it's because of my smp trampoline isn't it

#

indirectly

#

time to give in and write a relocatable smp trampoline

real pecan
flint idol
#

I was triple faulting because I was getting an irq in an AP when it was it was still in bios code

#

and the IVT was overwritten

real pecan
#

Ah

#

Oberrow finds out that fucking with bios structures is not good

flint idol
#

lol

flint idol
#

I'll just assume it's at 0x1000 instead

#

@real pecan

#

IT WORKS

#

defgdsfudrhesfw\

#

I woke up from S3

#
static void on_wake()
{
    for (volatile bool b = true; b; );
}```
#

I was able to get the state to the bare minimum to get something to print

#

gdb is being stoobid

flint idol
#

idk why but my tss is broken

#

fixed

#

idk why but I must reinitialize the tss' segment on wake

flint idol
#

I do now properly restart the cpu

#

but it's still not in a preferable state to yield to another thread

#

I am now gonna wake the other CPUs

#

bruh

#

I triple fault

#
check_exception old: 0xffffffff new 0xd
 56719: v=0d e=0012 i=0 cpl=0 IP=0008:00000000000fd089 pc=00000000000fd089 SP=0010:0000000000000000 env->regs[R_EAX]=0000000000000000```
#

fixed

#

I now restart all CPUs

#

what's next is restarting the LAPIC timer

#

then I can finally switch back to whatever that thread was doing behind

#
check_exception old: 0xffffffff new 0xd
 44433: v=0d e=0012 i=0 cpl=0 IP=0008:00000000000fd089 pc=00000000000fd089 SP=0010:0000000000000000 env->regs[R_EAX]=0000000000000000```
#

sigh

#

I tried restarting the lapic timer

#

for this to happen again

flint idol
#

after syncing all CPUs to initialize their timers at the same time

#

it no longer triple faults

#

but now it crashes (best word to describe what just happened) when trying to switch to a new thread

#

@real pecan your wake from sleep state might be broken

#

I'll see once I actually fix this code

real pecan
flint idol
real pecan
#

debug it at school

flint idol
#

I just can't get caught

real pecan
#

suspend school pc

flint idol
#

Also a good idea

real pecan
#

lol

flint idol
#

So what I will do is bring debian livecd

#

Or just a debian installer

#

So that I can dd the iso

#

And I'll just debug at school

#

I need to push my code first thiugh

#

*though

real pecan
#

win32 imager or fuse

flint idol
#

Those need admin access, no?

real pecan
#

not sure

flint idol
#

Forgot to commit n'stuff

flint idol
#

time to debug

#

what I know now is that:

  • it hangs after all CPUs get a halt NMI
real pecan
#

halt all cpus
everything hangs
meme

flint idol
#

no but it's unintentional

#

idk why it's happening

#

hm

#

it panics

#

but where are all the log sources?

#

oh

#

wait

#

it hangs while waiting for all CPUs to stop

#

which I think I know why

#

yeah

#

I also noticed that there is a slight (big) bug

#

the other CPUs restart fine

#

but they jump to some previous point of the thread they were running

#

since the thread contexts are not saved

#

so I'll need to do that

real pecan
#

btw u can cherry-pick the fix for the event header if u want

#

its not in master yet

flint idol
#

nah I'll just wait for the PR to be merged

white mulch
# flint idol since the thread contexts are not saved

I were thinking about this, one way could be that you save the rsp after the irq frame + current thread to somewhere within eg. the cpu struct and then when the ap wakes up after you have done all the lapic init and whatever you would set rsp to the saved rsp + pop regs + possibly swapgs + iretq (after first setting your current thread to the old thread)

#

and wait for all the cpus to have done that before actually proceeding with the sleep ofc

flint idol
#

@real pecan

#

I fixed the bug

#

I can now restart the scheduler

#

damn it

#

it doesn't work well when it tries to run the uacpi code (but that's because of me)

real pecan
#

why is that

flint idol
#

some sorta irql bug

#

brb though

#

wait

#

it might actually have ran the uacpi code

#

@real pecan your uacpi code actually seemed to have not crashed

real pecan
#

who would have thought meme

white mulch
#

also on an unrelated note would be funny if the acpi global lock would be contended and the wake aml would try to acquire it when the io-apic is reset (so no sci's) meme

real pecan
#

probably would crash windows as well

#

so they wouldnt do that

flint idol
#

bro fuck this shit

#

HOWWWWWWWWWWWw

#

fixed

#

@real pecan something interesting is happening

#

after wake from suspend, the framebuffer stops working

white mulch
#

I also observed that though I didn't look into it yet because all of the other annoying bugs that I have

flint idol
#

anyway, first log message is before the suspend

#

and the rest are after I wake from suspend

white mulch
#

probably the vga card is also reset or something

flint idol
#

that's gonna be hard to tackle...

white mulch
#

well on qemu it isn't that bad but on real hw however...

#

if that happens on real hw that is

flint idol
#

yeah S3 leaves like everything dead

real pecan
#

ur supposed to reinit everything

flint idol
#

when uGPU so I can reinit the GPU

real pecan
#

i think u dont even need a gpu driver

#

to post the gpu

flint idol
#

well then what do I do?

real pecan
#

linux/seabios code

flint idol
#

I don't feel like brain damage

real pecan
#

well on real hw _WAK might post the gpu

#

qemu doesnt have that

white mulch
#

though it would make sense to use some more portable mechanism if there is one

real pecan
#

anyway yeah idk

flint idol
#

I can just put a warning before suspend

real pecan
#

its uncharted territory for me

flint idol
#
OBOS_Warning("Note: Framebuffer might die\n");```
real pecan
#

u should try on real hw

flint idol
#

good idea

real pecan
#

althought very large chance u will see a blank screen

flint idol
#

I'll make it shutdown after wake from suspend

real pecan
#

lol

flint idol
#

so I can know if it worked

real pecan
#

thats my stupid pc when it wakes for no reason

flint idol
#

well does your PC use obos?

real pecan
#

worse

#

its nt

flint idol
#

no way

#

LET THE SHITTY NT KERNEL DIE!!!!

#

REPLACE IT ALL WITH NYAYX~!!!!!!!!!!!

#

ummm

#

shutdown broke

real pecan
#

f

torpid wigeon
flint idol
real pecan
#

??

flint idol
#

well

real pecan
#

literally nothing changed

flint idol
#

let me log stuff from wake from suspend

torpid wigeon
#

oberrow try not to deflect blame challenge

flint idol
#

well it gets to uacpi code

real pecan
#

oberrow try not to blame uacpi for every bug in his kernel insane challenge

flint idol
#

it's always uacpi

#

/j

torpid wigeon
#

i dont use uacpi yet and im still having kernel bugs

#

must be infys fault

real pecan
#

it is

white mulch
#

meanwhile I only have myself to blame

real pecan
#

techinically u copied some stuff from uacpi right

#

so u can blame it as well

flint idol
#

uhh wtf

#

why is my user program getting SIGTRAP

torpid wigeon
#

if you steal all your code from other projects you can blame the people that wrote it galaxybrain

white mulch
real pecan
#

lmao

flint idol
#

kinda sounds like the entirety of uacpi

torpid wigeon
#

copying inline asm

real pecan
#

well his stuff is c++

flint idol
#

idk why but when running my kernel

flint idol
#

in qemu

#

kde froze

torpid wigeon
#

use xfce like a real linux user

flint idol
#

when ur kernel is so bad that when in a vm it causes the host system to die

flint idol
torpid wigeon
white mulch
#

and I didn't ctrl c v any code because it wouldn't work ofc, I rewrote it in c++

flint idol
#

🗣️

#

ok uacpi copier

torpid wigeon
#

#1230349543623757845 message

flint idol
#

shit

#

I forgor to put the license

#

actually

#

if the license is in the file

#

would that count

#

oh infy!

#

it hangs in uacpi_enter_sleep_state(UACPI_SLEEP_STATE_S5);

#

wtf

real pecan
#

i mean that doesnt tell me anything

flint idol
#

why is it in idle task

#

HOW

real pecan
#

lol

flint idol
#

IRQS ARE DISABLED

#

AHHHHHHHH

#

HOWWWWWWW

white mulch
#

idk if this works on all gpus tho because at least newer intel igpus don't advertise themself as vga compatible

flint idol
#

for now at least

real pecan
#

who needs a framebuffer

flint idol
#

exactly

#

it's not like I'll ever use obos

#

and if I do I can just shutdown

real pecan
#

lol

flint idol
flint idol
#

I am somehow killing kvm

#

BRO HOW THE FUCK

#

IS THISS FUCKING HAPPENING

flint idol
#

well luckily (or perhaps unluckily)

#

it doesn't happen when I don't suspend

#

omg

#

uacpi_kernel_stall

#

yields

#

well

#

something is utterly fucked

flint idol
#

@real pecan uacpi_kernel_stall might not be able to be used in uacpi_enter_sleep_state. if someone ever uses the hpet (or any external timer source for that matter) for stall/sleep, then it probably will break if PTS shutdown the timer source.

#

also shutdown does not work after waking from S5

#

it times out

#

it could be that I am missing something in my wake code

#

which is weird since I

uacpi_prepare_for_wake_from_sleep_state(UACPI_SLEEP_STATE_S3);
UACPI_ARCH_ENABLE_INTERRUPTS();
uacpi_wake_from_sleep_state(UACPI_SLEEP_STATE_S3);```
#

could be my skill issue though

#

since I do not put any devices to sleep

#

nor wake any devices up

#

but like

#

if you wrote the shit needed to the ports needed

#

then it should shutdown

#

and like this is qemu seabios

#

the most basic environment

#

weird

#

on ovmf it works

#

firmware fuckiness

thick jolt
#

oh trust me

flint idol
#

KVM Internal Error 3

thick jolt
#

oh nvm not that worse

#

😭

flint idol
#

so I'm playing chess against some bot right

#

wtf did I get myself into 😭

thick jolt
#

bro is cooked

#

😭 🙏

#

i got suspeneded in valorant for 7 hours

#

thats insane

flint idol
#

bru

thick jolt
#

how

#

i didnt even

#

do anything wrong 😭

#

i only yelled at my teammates

#

everyone does that in this game

flint idol
#

probs had baby teammates

thick jolt
#

yea maybe one of my teammates reported me

flint idol
#

FUCK

thick jolt
#

rip bro

flint idol
#

yeah I'm not very good at chess

thick jolt
#

same

flint idol
#

oop

#

just stalemated

flint idol
#

tomorrow I hope on implementing the driver interface part of suspending

#

as now I shall sleep

#

and maybe working around this bug with shutdown

#

but before I sleep

#

I will test obos on one of my test subjects

flint idol
#

wake from suspend, not so much

#
Notify (PWRB, 0x02) // Device Wake
#

is ignored according to uacpi

#

twice, actually

#
Method (SIOH, 0, NotSerialized)
{
    If (((WKRS == 0x02) && (WKRS != 0xFF))) {}
    Else
    {
        If ((^SIO1.PMS1 & 0x08))
        {
            Notify (PS2K, 0x02) // Device Wake
            Notify (PWRB, 0x02) // Device Wake
        }

        If ((^SIO1.PMS1 & 0x10))
        {
            Notify (PS2M, 0x02) // Device Wake
            Notify (PWRB, 0x02) // Device Wake
        }
    }
}```
#
Method (PS2K._PRW, 0, NotSerialized)  // _PRW: Power Resources for Wake
{
    Return (GPRW (0x1B, 0x03))
}```
#
Name (PRWP, Package (0x02)
{
    Zero, 
    Zero
})
Method (GPRW, 2, NotSerialized)
{
    PRWP [Zero] = Arg0
    Local0 = (SS1 << One)
    Local0 |= (SS2 << 0x02)
    Local0 |= (SS3 << 0x03)
    Local0 |= (SS4 << 0x04)
    If (((One << Arg1) & Local0))
    {
        PRWP [One] = Arg1
    }
    Else
    {
        Local0 >>= One
        FindSetLeftBit (Local0, PRWP [One])
    }
    
    Return (PRWP) /* \PRWP */
}```
#
Name (SS1, Zero)
Name (SS2, Zero)
Name (SS3, Zero)
Name (SS4, One)```
#

wait

#

_S3 doesn't look like it exists on this PC

#
If (SS3)
{
    Name (_S3, Package (0x04)  // _S3_: S3 System State
    {
        0x05, 
        Zero, 
        Zero, 
        Zero
    })
}```
#
acpi_namespace_node* s3 = uacpi_namespace_node_find(uacpi_namespace_root(), "_S3_");
if (!s3)
{
    OBOS_Error("Firmware does not have the _S3 (suspend) sleep state\n");
    return OBOS_STATUS_UNIMPLEMENTED; // bios does NOT support suspend.
}```
#

I will do that

#

this is quite weird

real pecan
real pecan
#

Notify is basically a syscall from aml to kernel

flint idol
#

I apparently need to implement D state shit for wake to work properly

#

#1217009725711847465 message

thick jolt
#

i might implement this stuff too into my kernel

#

to be honest

#

im unsure about much of what it does but

#

seems interesting

#

when i fix my page tables being fucked up and when i reach userland and have a bunch of unix programs running

#

that might be something id look into

real pecan
flint idol
#

but it's hard to implement

short mortar
#

May be I'll try to implement it as well (after finishing with exams, and implementing working set...)

flint idol
#

Since I'm going to be "done" soon enough

#

You guys will probably able to take my kernel as a reference when you do it

weak kestrel
#

what did you have to do?

flint idol
#

At the moment, it is the only kernel using uacpi that has some sort of suspend

#

Find sleep capable acpi namespace nodes

#

Put them into the required D state

#

Mark then as a wake GPE

#

*them

#

Then stop all CPUs

#

Then enter S3

#

On wake

flint idol
flint idol
#

On the wake vector

#

In real mode

#

On the bsp

weak kestrel
#

so you have to do all the initialisations again

flint idol
#

Move any device back to the old D state

#

After entering long mode

#

Also you probably want to have driver specific wake and sleep functions which you call at respective times

#

You will need to restart the LAPIC timer

real pecan
real pecan
#

well given oberrow actually gets it to work properly

flint idol
real pecan
#

if u get it right fb should get restored on real hw as well

#

especially if u disable modern windows support via osi

#

uacpi_bulk_configure_interfaces(UACPI_INTERFACE_ACTION_DISABLE, UACPI_INTERFACE_KIND_VENDOR)

#

then re-enable only some shit like very old xp

#

aml will assume u dont have any drivers and do most stuff for u

#

or well, try to at least

flint idol
#

Uncommon AML W

real pecan
#

idk if qemu checks for it, probably not

flint idol
#

Would be one of the first times that something in obos worked as intended on real hw but not qemu

white mulch
#

also the bochs vbe stuff that I were thinking about didn't work for restoring the fb, idk what exactly qemu wants you to do to it

real pecan
#

could just look at qemu source

white mulch
#

actually I think I might know at least one possible reason, the pci bars get reset

real pecan
#

lool

flint idol
#

Oh ye

#

I could make some sort of hack

#

That looks for the fb in PCI bars

#

And just saves all BARS for them

real pecan
#

just do info pci after resume

flint idol
#

Then replace it later

real pecan
#

and see what it says

white mulch
real pecan
#

yup

#

ideally what u should do in your drivers is when initing a pci bus, walk all devices, and look at their bars: if it'a non-zero bar, try to "claim" it aka allocate it out of unused memory. if that fails, allocate a new addres. Record the allocated/claimed address somewhere in a struct.

#

Then on resume just walk again and re-assign

#

thats how linux does it anyway

white mulch
#

the irq fields aren't right either, ig you have to restore those too

real pecan
#

if u use them, yeah

#

and bus mastering and stuff

#

its basically pci at reset state

flint idol
#

Yeah I need to make some more pci helpers

#

For the driver interface

real pecan
#

->resource is an array of BARs

#

it tries to use whatever the bios put there

real pecan
weary hound
#

and the pin is hardwired in the device iirc

white mulch
#

ah yeah

#

so its basically only the bars + the usual stuff that you do when you setup a device anyway like enabling bus master

flint idol
#

yeah rn the only sort of unified API for PCI devices is finding them

#

and interrupts

flint idol
flint idol
#

before suspend

#

after wake

#

so yeah

#

one of the vga BARs had the framebuffer

#

which is probably why the framebuffer died

#

what I'm thinking to do is why was suggested to me yesterday

#

but own most PCI devices by default

#

then drivers claim them later

#

I wonder what the difference between ovmf and seabios is

#

because with ovmf, qemu shutdowns after suspend

#

but seabios does not

#

with seabios it doesn't even log it with -d trace:qemu_system_shutdown_request

#

before suspend (on ovmf)

weak kestrel
#

are you going to write an osdev.wiki article once you finish it? meme

flint idol
#

that might not even be a bad idea

weak kestrel
#

I'm mostly interested in what needs to be done for pci devices

#

I gather everything else is the same

flint idol
#

you save BARs and other config registers in teh PCi thing

#

probably includes MSI config

#

and other capabilities

#

you throw the device into some D state

#

you go onto the next device

#

on wake you restore everything and move the devices back to D0

#

also

#

there probably should be some driver-specific way to suspend a device

#

and vice versa

flint idol
#

sorry

#

when I make it shutdown

#

after wake from suspend

#

I worded that terribly KEKW

real pecan
#

so your resume is broken on seabios?

flint idol
#

pretty much

#

qemu doesn't even log the shutdown attempt

real pecan
#

lol

white mulch
#

also about the pci thing I am not sure what else do you need to do because I tried writing the bars back after suspend but it didn't change them at all (and -trace pci*) showed no writes at all

#

tldr: sleep is a huge pain lol

flint idol
#

well you do call the _WAK stuff

#

and prepare for wake

#

might be needed

#

at this point I might as well import seabios

flint idol
#

see 1.3

white mulch
#

yeah I did that and then back to d0 after suspend for the wake capable devices (idk if you should do it for all devices tho)

#

also apparently my resume is broken on ovmf but not seabios meme

flint idol
#

rather the acpi spec is outright wrong here

#

or my computer's firmware made an oopsie

#

because _PRW > 3, so I think that just means 3 in this table

#

_S3D is 2

#

so I should enter D2

#

this device has no D2 state

#

rather that or I misunderstood the spec somewhere else

#

yeah no

#

there's no _PS2 method

white mulch
#

_PRW is the deepest system state that it supports waking from

flint idol
#

ye

#

that evaluated to

0xD, 0x4```
#
Method (_PRW, 0, NotSerialized)  // _PRW: Power Resources for Wake
{
    Return (GPRW (0x0D, 0x04))
}```
white mulch
#

does it have a _S3W

flint idol
#

nop

#
Method (GPRW, 2, NotSerialized)
{
    PRWP [Zero] = Arg0
    Local0 = (SS1 << One)
    Local0 |= (SS2 << 0x02)
    Local0 |= (SS3 << 0x03)
    Local0 |= (SS4 << 0x04)
    If (((One << Arg1) & Local0))
    {
        PRWP [One] = Arg1
    }
    Else
    {
        Local0 >>= One
        FindSetLeftBit (Local0, PRWP [One])
    }
    
    Return (PRWP) /* \PRWP */
}```
white mulch
#

then you can enter D2 or D3

flint idol
#

then enter D2

#

unless I missed something

#

in the spec

white mulch
#

oh yeah nvm

flint idol
#

fucked firmware

#

but all other devices are the same

#

that support wake

#

and have _S3D

#

I hate acpi

#

I hate acpi

#

I hate acpi

#

I hate acpi

#

I hate acpi

quaint rivetBOT
#
Anti-spam Message

Possible spam detected for user: oberrow. Please contact a moderator to be unmuted.

torpid wigeon
#

i hate acpi

#

i hate acpi

flint idol
#

maybe if the D state just doesn't exist

#

I ignore it and move on to calling _PSW

#

or DSW

white mulch
#

does the device have a _PS0/_PR0 method?

flint idol
#

yes

#

it has _PS0

#

and _PS3

#

but not the required _PS2

#

and I just found another unrelated blob doing the same thing

#

actually the other blob isn't even for a computer that has S3

white mulch
#

is there a _PR2? because there is the thing where if there is no explicit _PSx method then you are supposed to use the power resources to do the transition

flint idol
#

no _PR2

#

or _PS2

flint idol
#

and where do I find said power resources

#

_PRW?

white mulch
#

_PRW contains the resources needed for the device to be able to wake the system

#

ah yeah ig you can do it using that + _PR0

flint idol
#

but isn't PR0 for D state 0

#

and also I have no PR0 in that object

#

*device

#

only for fans

white mulch
white mulch
#

so like if there would be some resources needed in d0 but not in the wake state (or whatever state you explicitly put the device to) you'd turn those off if I understood it correctly

flint idol
#

makes sense

white mulch
#

but yeah idk what are you supposed to do in the case of your firmware

flint idol
#

maybe

#

journalctl will have something in the logs to guide me

white mulch
#

or add debug prints to linux code meme though that would be kinda annoying

flint idol
#

I don't feel like compiling the linux kernel

#

journalctl has nothin for me

#

thanks infy for making uacpi_object opaque /s

real pecan
#

lmao

flint idol
#

thank god it doesn't affect my pnp thing

#

bruh

#

I can't even use packages

real pecan
#

uacpi_object_get_package

flint idol
#

use of undeclared identifier uacpi_package

real pecan
#

read

flint idol
#

an object array

#

is what it gives me

#

ok

#

bruh

#

uacpi_object_get_integer returns a status

#

and takes a pointer to the integer

real pecan
#

yes??

flint idol
#

yeah

#

just kinda annoying

real pecan
#

safety ™️

flint idol
#

but who am I to complain

#

it's a free acpi library

real pecan
#

what is it supposed to do if u give it a different type or a null pointer

real pecan
#

uacpi is built onto the idea that all errors are propagated to the client and it on its own doesnt have the right to decide what to do with them

flint idol
#

just made it use the new object api

real pecan
#

so it doesnt have bullshit like uacpi_kernel_abort etc

flint idol
#

good thing I noticed that you merged the PR before I wrote the D state code

#

otherwise I would've went to play minecraft for 43 days

#

and come back

real pecan
#

lol

flint idol
#

the 2nd value in _PRW is irrelevant for finding out the d state to put the device in when entering a sleep state

#

only snd/snw matter

#

with n being the sleep state

#

that you wanna enter

#

which basically makes the tables in the acpi spec for each

#

_SnD object

#

the same

#

since some parts of the table say I can enter one of two sleep states

#

I will by default choose the deepest

#

if that does not exist

#

I go a bit shallower

#

etc.

#
typedef enum d_state {
    DSTATE_INVALID = -1,
    DSTATE_0,
    DSTATE_1,
    DSTATE_2,
    DSTATE_3HOT,
    DSTATE_3COLD,
    DSTATE_MAX = DSTATE_3COLD,
} d_state;

// if dry_run is true, then the function does not actually put the device into the state,
// but only checks if it would be able to and returns an apprioriate status.

obos_status OBOS_DeviceSleep(uacpi_namespace_node* dev, d_state new_state, bool dry_run);
obos_status OBOS_DeviceWake(uacpi_namespace_node* dev, d_state new_state, bool dry_run);
d_state OBOS_DeviceGetDStateForWake(uacpi_namespace_node* dev, uacpi_sleep_state state, obos_status* status);```
#
if (snw >= snd)
{
    if (status)
        *status = OBOS_STATUS_MISMATCH;
    return DSTATE_INVALID;
}```
#

I wonder if it makes sense to have a check like this

#

because surely the deepest D state that the device can wake itself in

#

in sleep state n

#

is always deeper or equal than the shallowest state that the device can be in in sleep state n

#

if (snw <= DSTATE_2 && snd == UINT64_MAX)
{
    nStates = 3;
    avaliableStates[0] = DSTATE_2;
    avaliableStates[1] = DSTATE_1;
    avaliableStates[2] = DSTATE_0;
}

if (snd <= DSTATE_2 && snw == UINT64_MAX)
{
    nStates = 1;
    avaliableStates[0] = DSTATE_2;
}

if (snd == DSTATE_2 && (snw >= DSTATE_3HOT && snw != UINT64_MAX))
{
    nStates = 3;
    avaliableStates[0] = DSTATE_3COLD;
    avaliableStates[1] = DSTATE_3HOT;
    avaliableStates[2] = DSTATE_2;
}```
#

idk if I like this logic

#

I mean it probably works

#

but I wanna make it unreadable use less redundant checks

#
typedef enum d_state {
    DSTATE_INVALID = -1,
    DSTATE_0,
    DSTATE_1,
    DSTATE_2,
    DSTATE_3HOT,
    DSTATE_3COLD,
    DSTATE_MAX = DSTATE_3COLD,
} d_state;

// if dry_run is true, then the function does not actually put the device into the state,
// but only checks if it would be able to and returns an apprioriate status.

OBOS_EXPORT obos_status OBOS_DeviceSetDState(uacpi_namespace_node* dev, d_state new_state, bool dry_run);
OBOS_EXPORT obos_status OBOS_DeviceHasDState(uacpi_namespace_node* dev, d_state state);
// Returns DSTATE_INVALID on error, or if the device does not need to be moved in another
// D state to wake us.
// Always check status to make sure.
OBOS_EXPORT d_state     OBOS_DeviceGetDStateForWake(uacpi_namespace_node* dev, uacpi_sleep_state state, obos_status* status);```