#OBOS (not vibecoded)
1 messages · Page 29 of 1
or should I just save the timers I use
ignore
Nyaux suspend support when
if that happens
I will be muting that thread
😭 💀
Jkjk
okay
implementing suspend is going into the wild west of acpi
the actual power management part
it's no longer fun and games when you implement suspend
it will def be pain but yk ill pull through\
you won't
i will because ill do something u wont
I already have it..?
work on other aspects of the kernel while suspend isnt working

then like keep debugging suspend
but still working on other things
Advanced Configuration and Power Interface
yes will be very scary
do you know what a power resource is?
that's what I thought, no
💀
Technically these last two words are on the east side
_ON, _OFF, _PSW, _S3W, _S3D, _PRW, _DSW
those are the methods I remember having to evaluate to setup wake gpes
also _PSn, _PRn with n being a D state
then I needed an entire smp trampoline just to wake up to a bare minimum long mode state
along with some 50 lines of x86_64-specific wake code
to get stuff running again
which will be increasing since I'm adding HPET restore code
as well as another ~50 lines of x86_64 specific code to wake the other CPUs again
for restoring the hpet do u just need to enable the main counter again?
no
okay then what do u need to do
ah okay
at least everything you need
ig you can skip init of some timers
since it has multiple comparators
then PCI stuff needs to be restored
which needed a REVAMP of my pci interface
I also needed to add suspend/wake callbacks to drivers
just for it to still be partially incomplete
because I have no framebuffer
if that hasn't scared you off, idk what will
wait
how would I restore const HPET fields

maybe I just don't
Yes
so I need to restore:
- HPET.generalConfig
- HPET.mainCounterValue
- HPET.timer0
- any other HPET comparators I use
I also don't restore IOAPIC state
silly me
Who needs that 
me 
Does it work with hpet restoration?
nah
I need IOAPIC for GPEs
so I will add restore code for that soon™️
and you should probably go to sleep
it still hangs
yup
can't believe I'm going to sleep at the same time as infy (he's 8 hours ahead of my timezone)
infy challenge: have sleep schedule, challenge level: impossible
Lol
but hey who needs sleep when you have osdev
Thought u were in Europe
no I'm in canada
Did you move recently?

Vacation
fair
when I was on vacation in uae, I would go to sleep at 3 am
in saudi I had a normal-ish sleep schedule
mainly in mecca since I think I wanted to be able to get up for the dawn prayer at the sacred mosque
but alas, I was only able to make it once
another time I woke while the prayer was happening
so I used my phone to record the reciter
Oh well
Yup
I would send it here, but the file size is too big for discord
Hai
soon will be now
time to add I/O APIC restoration code
suspend/wake-up on osdev wiki when
soon™️
how much do you have left?
which is the deadlock infy and I were debugging yesterday
TODO: Rewrite I/O APIC code to not use bitfields
as well as ACPI NVS saving code
nvm, that's for S4 (hibernate) only
no
ok
Elixir Cross Referencer - source code of Linux v6.13-rc3: drivers/acpi/sleep.c
/*
* The ACPI specification wants us to save NVS memory regions during hibernation
* and to restore them during the subsequent resume. Windows does that also for
* suspend to RAM. However, it is known that this mechanism does not work on
* all machines, so we allow the user to disable it with the help of the
* 'acpi_sleep=nonvs' kernel command line option.
*/
static bool nvs_nosave;
void __init acpi_nvs_nosave(void)
{
nvs_nosave = true;
}
/*
* The ACPI specification wants us to save NVS memory regions during hibernation
* but says nothing about saving NVS during S3. Not all versions of Windows
* save NVS on S3 suspend either, and it is clear that not all systems need
* NVS to be saved at S3 time. To improve suspend/resume time, allow the
* user to disable saving NVS on S3 if their system does not require it, but
* continue to save/restore NVS for S4 as specified.
*/
static bool nvs_nosave_s3;
kinda annoying
but thats suspend for u
yeah
I'll add a command line option because linux does
no-nvs-save-suspend
or something like that
ye
linux calls it nvs-nosave-s3
so I'm copying that into obos
and I might as well also add a config option for it
option (OBOS_NVS_SAVE_S3 "Enable compile-time support for saving NVS before S3" ON)
nice
struct acpi_nvs {
void* saved_region;
uintptr_t phys;
size_t size;
};
struct acpi_nvs* saved_nvs;```
@real pecan ULTRA_MEMORY_TYPE_NVS is acpi nvs right? not some weird uefi thing
it seems like it, but I'm just making sure
ye
kthx
are there any PCs where there are multiple NVS regions?
surely there are, right?
probably
i believe so but i may be wrong
rip
well I always got github
infy if u were a black hole like ur pfp what would u do
linux treats NVS ram as IO memory
calls acpi_os_get_iomem on it
to get its address
then memcpy's that in the buffer it allocated
for each nvs region
and restore does the same thing, backwards
@real pecan what kernel api does uacpi use to timeout loops, get_nanoseconds_since_boot?
like aml loops
i mean what other api could it even use
idk
I will return zero from that in case the hpet is still dead somehow
and a loop isn't timing out
during _WAK
/*
* Calculate the expiration point for this loop.
* If a loop is executed past this point, it will get aborted.
*/
block->expiration_point = uacpi_kernel_get_nanoseconds_since_boot();
block->expiration_point +=
g_uacpi_rt_ctx.loop_timeout_seconds * UACPI_NANOSECONDS_PER_SEC;
no, because UINT64_MAX+any number would overflow
and
why would the loop timeout
max + any number is some number
if u do this calculation again u get the same number
or wait
yeah ur right
[uACPI][INFO]: successfully loaded 1 AML blob, 1726 ops in 0ms (avg 1726000000000/s)
woo
but this will make it so any while that must run at least twice will not run at all
take that mammogram
I only set the loop timeout before calling wake_from_sleep
or whatever the function was called
uacpi_context_set_loop_timeout(3);
uacpi_wake_from_sleep_state(UACPI_SLEEP_STATE_S3);```
I assume the default is zero?
no it's 30
yes
if (!OBOS_GetOPTF("nvs-nosave-s3"))
{
// Save ACPI NVS regions.
// Why? Some versions of windows do, so I guess we have to :)
// Read the memory map.
uintptr_t index = 0;
for (obos_pmem_map_entry* entry = MmS_GetFirstPMemMapEntry(&index); entry; )
{
if (entry->type == ULTRA_MEMORY_TYPE_NVS)
saved_nvs_count++;
entry = MmS_GetNextPMemMapEntry(entry, &index);
}
saved_nvs = OBOS_NonPagedPoolAllocator->ZeroAllocate(OBOS_NonPagedPoolAllocator, saved_nvs_count, sizeof(struct acpi_nvs), nullptr);
index = 0;
size_t nvs_index = 0;
for (obos_pmem_map_entry* entry = MmS_GetFirstPMemMapEntry(&index); entry; )
{
if (entry->type == ULTRA_MEMORY_TYPE_NVS)
{
saved_nvs[nvs_index].region_address = Arch_MapToHHDM(entry->physical_address);
saved_nvs[nvs_index].size = entry->size;
saved_nvs[nvs_index].saved_region = OBOS_NonPagedPoolAllocator->Allocate(OBOS_NonPagedPoolAllocator,
saved_nvs[nvs_index].size,
nullptr);
memcpy(saved_nvs[nvs_index].saved_region, saved_nvs[nvs_index].region_address, saved_nvs[nvs_index].size);
nvs_index++;
}
entry = MmS_GetNextPMemMapEntry(entry, &index);
}
}```
that's to save
have u tested this on real hw?
Yes, I have no idea if it works
wdym
but i guess it doesnt help with hangs?
nope
its probably nothing complex like that
some simple bug
maybe obos using ecam to restore ecam type of bug
that was seabios
MTRRs are restored at this point right?
yes
I said type of bug not literal bug lol
what I have restored at that point:
- tss/gdt/idt
- LAPIC
- caching stuff (MTTRs/PAT)
- IOAPIC
- NVS
- HPET
- SMP is restored
- scheduler is alive
- LAPIC timer is alive
maybe there is some obscure device I forgot about
that I need to restore
stores to regions should never do anything but write to memory/io, right?
e.g., \_SB.PCI0.GFX0.CLID = 0x80000000
that would only ever translate to uacpi writing to that memory/ioport, right?
is this on obos3
or i mean
dump 3
OperationRegion (IGDM, SystemMemory, ASLB, 0x2000)
Field (IGDM, AnyAcc, NoLock, Preserve)
Its a non-locked SystemMemory opregion
so its literally a volatile r/w
anyway, I'm going to send my uacpi version back in time
yeah
oh btw
ye
k
cok 
your ec also has queries
sounds cool
Method (_Q27, 0, NotSerialized) // _Qxx: EC Query, xx=0x00-0xFF
{
P80H = 0x27
Notify (ACAD, 0x80) // Status Change
Notify (BAT1, 0x80) // Status Change
}
u should get events for power plug/unplug
u support events right?
never register any
void onECQuery(uacpi_handle hnd)
{
// Evaluate whatever the EC wants us to evaluate.
uint8_t idx = (uint8_t)(uintptr_t)hnd;
char method[] = { '_', 'Q', 0,0,0 };
snprintf(method+2, 3, "%02x", idx);
uacpi_eval_simple(ec_node, method, nullptr);
uacpi_finish_handling_gpe(ec_gpe_node, ec_gpe_idx);
}```
yes
idk maybe
its 02X not x
thx
probably not
because u would see it in logs
so yeah fix your ec
static uint8_t ec_read_reg(struct acpi_gas* reg)
{
uint64_t val = 0;
// Wait until OBF goes to one.
do {
uacpi_gas_read(&ec_control_register, &val);
} while (!(val & EC_OBF));
// Read the register.
uacpi_gas_read(reg, &val);
return val;
}
static void ec_write_reg(struct acpi_gas* reg, uint8_t what)
{
uint64_t val = 0;
// Wait until IBF goes to zero.
do {
uacpi_gas_read(&ec_control_register, &val);
} while (val & EC_IBF);
// Write the register.
uacpi_gas_write(reg, what);
}
static uint8_t ec_read(uint8_t offset)
{
ec_write_reg(&ec_control_register, BD_EC);
ec_write_reg(&ec_data_register, offset);
return ec_read_reg(&ec_data_register);
}
static uacpi_status ec_write(uint8_t offset, uint8_t value)
{
ec_write_reg(&ec_control_register, BD_EC);
ec_write_reg(&ec_data_register, offset);
ec_write_reg(&ec_data_register, value);
return UACPI_STATUS_OK;
}```
this looks sane to me
no idea
this part
oops
I write burst disable to command
instead of ec read/ec write
silly me
@real pecan what does UACPI_InternalOpUnresolvedNameString_L do
because obos hangs on it during EC init
at least taht's the last thing logged before a hang

probably read from a field that starts with an L
hmm
yeah
LDS0
Method (_REG, 2, NotSerialized) // _REG: Region Availability
{
If (((Arg0 == 0x03) && (Arg1 == One)))
{
ECOK = One
If (ECOK)
{
If (LDS0)
{
this is where u hang
infy has cameras in my house confirmed
it hung in INVOKE_HANDLER
invoke handler just calls into your ec_read
im busy
in my walls?
understandable
nyaux code be liek
it hangs waiting for EC_OBF
uint64_t?
yeah what about it
Registers are 8 bits
yeah
but gas_read takes a uint64_t*
also I just found the bug
I was doing reg = uacpi_gas_read(reg, &val)
whoops
ec driver still hangs on wake from suspend
lol maybe fix the driver instead
I do everything I need to do for a burst, so idk
could be broke firmware
sure
do u get events now at least
no
unless
these look like lid events
at one point I get an ec event
which fails for reasons
fuck
why isn't my laptop booting
nvm
was spurious
according to my logs
linux' ec driver makes no sense
at least you are not getting 5 random power button ec querys when you start your kernel like I do on my laptop 
at least you don't get an ec query every second on your laptop
after fixing a deadlock bug with ec events
(me right now)
idk whats up with that, I didn't find any quirks within linux for that laptop but what I ended up doing anyway was just flushing ec events to the void at the start until it no longer gives anything to get rid of the spurious power button presses
I mean its possible that you get them in every few seconds but yeah every second sounds a lot
and each time it
is spurious
i.e., index=0
hmm
oopsie
still not fixed
but I did find a bug
unless...
does that happen with uacpi as well?
I am not sure, I haven't booted any uacpi kernel on it enough to be able to tell as it only happens sometimes

I can try to boot managarm on it for a few tens of times sometime to see
damn the EC
or pmos
fnuy field name
maybe it was first named COUNT
but preprocessed to CUNT
automod flagged a message sent by oberrow
preprocessor that removes the 2nd letter of a name until it becomes four letters
@short mortar did your ec driver not give events?
and if so what wsa the problem
Or we can just assume it was intentional
maybe it's the same problem for me
Idk some of the stuff was wrong
the only events I am getting are spurious
But it was hanging so that's why
And then it worked fine

I'll add framebuffer to kernel
ok
sorry
np
can u tell me what i did wrong so i know not to do in future
you did nothing wrong
oh okay 😭
(if it were a problem, I'd say so)
I HATE ACPI
I HATE ACPI
I HATE ACPI
I HATE ACPI
I HATE ACPI
Possible spam detected for user: oberrow. Please contact a moderator to be unmuted.
thanks
np
wth
why is the ec driver giving me 0x00 after enabling burst
seems pretty fishy
OSPM driver writes the Burst Enable Embedded Controller, BE_EC (0x82) command byte and then the Embedded Controller will prepare to enter the Burst mode. This includes processing any routine activities such that it should be able to remain dedicated to OSPM interface for ~ 1 microsecond.
poll_ibf(device);
write_reg(&device->control, BE_EC);
poll_obf(device);
uint8_t status = read_reg(&device->data);
if (status != BURST_ACK)
printf("Failed to enable EC burst mode. Out: %hhx\n", status);
pmOS' code
ec_write_reg(&ec_control_register, BE_EC);
uint8_t response = ec_read_reg(&ec_data_register);
if (response != BURST_ACK)
{
OBOS_Warning("ACPI: Burst not acknoledged by EC, ignoring. Expected: 0x%02x, got 0x%02x\n", BURST_ACK, response);
return false;
}
return true;```
obos' code
ec_write_reg/ec_read_reg poll ibf/obf
You need to poll obf before reading anything
Oh
@real pecan when uacpi reads from a gas, the raw io port read returns 0x801a56a0, among other values, yet the actual gas read returns 0x00, do you have any idea how this could be?
not sure what that means
so basically
my ec driver reads from the gas
when uacpi actually reads the io port, the value returned is 0x801a56a0
and some other values occasionally
but the value given to me by uacpi is 0x00
the gas format is:
register bit offset: 0
register bit width: 8
access size: 0
address: 0x62
how can this be the value returned if port width is 1 byte
the ec status register
i meant the fact that its a 4 byte value
it isn't, I was printing a pointer by accident
💀
show code
static uint8_t ec_read_reg(struct acpi_gas* reg)
{
uint64_t val = 0;
// Wait until OBF goes to one.
ec_wait_for_bit(&ec_control_register, EC_OBF, EC_OBF);
// Read the register.
uacpi_gas_read(reg, &val);
return val;
}```
reg = ec control register
check the return status as well
with this format
good idea
it sounds like its not even initialized
what isn't?
val
it fails
lmao
not found
if (!gas->address)
return UACPI_STATUS_NOT_FOUND;
weird
omg I am stupid
I was incrementing a variable called current_index in the resource iterate callback
to figure out if this is the control register's resource or data register's
resource
I incremented it
before
switch (*current_index)
upon fixing this bug
suspend breaks
it hangs before going into S3
and
I stop getting all those spurious events
linux disables ec interrupts prior to going into s3
i think
maybe ur hanging in that
well it hangs polling IBF
k
it logs shit quickly
then the screen goes blank
with a cursor
at the last line
Can you record what it logs?
If the screen goes blank then it enters userspace
My EC driver might also be hanging...
I know what I can try
@flint idol
Sure
there goes pmos stability 
The kernel did boot it seems
jkjk
oberrow laptop's fault 
linux doesnt seem to have any quirks for ecs that hang on poll or dont respond with acks
whats that laptops model
pmos might hang because of spinlocks skill issue
ur terminal is fucked
Does it turn off with power button?
no
BUT
it does seem to "enter userspace/idle"
oh shi
it does
it takes like 5 seconds
Yeah it waits for 3 seconds
So EC potentially works? lol
And framebuffer is fucked
I need logs from pmOS to help me debug, but alas
It also logs to serial
..which I don't have
yeah
does it log to xhci 
Your power button is through EC, right?
think so
I can implement that 
maybe it also has fixed event
wait seriously
Idk what's going on with my framebuffer
Could this be wrong?
lgtm
If bpp is less than 8
it isn't
wtf why would it not work
microkernel skill issue
No

How do you log onto that?
USB serial controllers?
I guess
I've removed kernel framebuffer...
Could it be because of how I map framebuffer?
No cache
no
What does it print
cpu x entering userspace/idle
three times
then a bunch of tasks exit
then it stops
Which tasks exit
It's normal
wait why is my mmap 282 loc
+65 loc to find an avaliable address
I wonder if it could help (for profiling purposes) to store how long locks are held in stuff like spinlocks and mutexes
and pushlocks
obos surprisingly doesn't have too much spinlocks
29 spinlocks in total
18 mutexes
or well 16
or well
maybe a bit less than these numbers because uacpi kernel api
2 semaphores
2 rw locks
and like three event objects
I added uint64_t lastLockTimeNS; fields to spinlocks/mutexes
this field has the time in nanoseconds of how long the lock was last taken
as in, the time between acquire and release, in nanoseconds
and it's configurable the config option OBOS_ENABLE_LOCK_PROFILING
which configures if it is enabled or not, since it has a big perf hit
which is visible
Another day, another gruesome obos debug session
I have this crippling fear that I'm gonna remove some wait by accident in the EC driver then accidentally corrupt some proprietary bios state causing the system to hang in the firmware
#1217009725711847465 message
yeah its easy to corrupt firmware with a bad ec driver
but it fixes itself after power loss
almost
because u might get an event at the same time as opregion access
i had to fix that for managarm
lol
so the read completes then
it hangs reading from a gas
or well
hangs waiting for OBF to become one
I might know the problem
I wait for OBF trying to read the status register
in the control register
meaning there isn't any data for me to read
from any pending commands
I think you read the control whenever you want
No
ok
it probably does
No but if the control register isn't buffered the ibf won't be set
or obf
whichever is host to ec
But as I understood it, there are 2 registers
Host to EC and EC to host
When you write to EC, the register is written to and the bit is set
untill it is processed
its actually 4 registers
Internal registers that is
its 2 but virtually split into 4
Like length 1 buffer
because reading and writing do completely unrelated things
Anyway
fuck
There is buffer for host to device stuff and there is buffer for device to host stuff
why didn't my laptop boot
all is fine now
💀
Ill buy your bricked laptop for 1 dollar
when I plug in and plug out my laptop I get EC evetns/!111!11!
what about suspend
it wakes successfully
damn congrats
and no longer hangs in the ec driver
big work
that's cool
indeed
third
good enough for me
even your nvs restore works i guess
are u going to make an article about suspend to s3?
Yes
nice
whoa
I get events when I close/open the lid
I get occasional Notifys abouts some device with the HID "VPC2004"
and even one from an "Ambient Light Sensor"
when I remove the battery, I get a Notify
@real pecan is there a way to get uacpi to stop spamming Notify warnings without raising the log level > UACPI_LOG_WARN
install a notify handler to root
thx
time to update uacpi
test
then push
bruh why is SMP so slow in obos
probably because of my TLB shootdowns
I need to make cancellable syscalls soon
TODO™️
theoretically, it is as shrimple as lowering the IRQL to PASSIVE
instead of DISPATCH
then also adding a way to cancel waits
which I have half of
the half I have is signalling the waiting threads
the half I need is getting it to notice that it needs to abort what it's doing
when it's awaken
maybe that's not related
yeah why did I raise the irql to dispatch in my syscall handlers
surely there was a good reason to that?
if it don't crash when I remove it
then it's fine
@real pecan I was trying to see if would get the framebuffer restored by firmware after wake from suspend if I set back my OSI to windows XP, but instead it deadlocks before suspend
in uacpi, ofc
at least I think in uacpi
uacpi_bulk_configure_interfaces(UACPI_INTERFACE_ACTION_DISABLE, UACPI_INTERFACE_KIND_VENDOR);
uacpi_install_interface("Windows 2001", UACPI_INTERFACE_KIND_VENDOR);```
where does it deadlock
well i've looked at those two functions and there's no way they can deadlock
u do this before namespace_initialize right
after having done that
before load
ah ok
first it acquires two locks in a row on the same thread
then another thread deadlocks while trying to acquire the first mutex acquired
tid 2: waiting for tid 8 to release mutex x
tid 2: waiting for tid 8 to release mutex y
tid 9: waiting for tid 2 to release mutex x
DEADLOCK
but the weird thing is, tid 2 is CPU 0's idle thread
what you've written out here is not a deadlock
your per_cpu->tid bug?
hmm weird
a reboot causes it to PF
another reboot causes it to work as normal
but unfotunately, no framebuffer
no framebuffer after reboot that pfs?
nope
how do u know it pfs
it PFed before suspend
what if I become windows 2000
no framebuffer after suspend :(
anyway
once uDRM comes out, this problem will be solved
I guess it's time for me to make interruptible I/O
where
lol
my I/O system is kinda terrible
I think NT has something called an IRP which is basically an I/O request packet
and I like that idea
my current I/O system is:
- io requested
- forward to driver, this action is synchronous
- you wanted async I/O? oh let me just start a worker thread for you and you give me an
eventobject
- wait you wanted progress on that async I/O? too bad so sad.
- you wanted to abort an I/O operation, uhh sorry we don't do that here
which, imo, is quite shit
luckily, I don't have much I/O
in the kernel
most of it is abstracted behind the VFS
#polls message
pls vote
in the meantime while I wait for the poll
I will be implementing elf loading
which I do have
but that's for loading drivers
/// <summary>
/// Allocates space on a thread's stack. Calling this after the thread has started running can be catastrophic.
/// </summary>
/// <param name="ctx">The thread's context.</param>
/// <param name="size">The of the stack region.</param>
/// <param name="status">The status of the function.</param>
/// <returns>A pointer to the region..</returns>
OBOS_WEAK void* CoreS_ThreadAlloca(const thread_ctx* ctx, size_t size, obos_status *status);
I have made this amazing api for pushing stuff to the stack
there aren't any platforms where the stack grows upward, right?
Defining a variable:
no
this is meant for stuff like process loading where I need to push auxillary values
before the process starts
void* CoreS_ThreadAlloca(const thread_ctx* ctx, size_t size, obos_status *status)
{
void* ret = (void*)(ctx->sp -= size);
return ret;
}```
That should be how it's implemented when the stack grows downward
void* CoreS_ThreadAlloca(const thread_ctx* ctx, size_t size, obos_status *status)
{
void* ret = (void*)ctx->sp;
ctx->sp += size;
return ret;
}```
and that's for when it grows upward
If I ever need that for future reference
these functions are just pseudocode, as I need error checking
I theoretically have an elf loader now
except it uses an unimplemented function: Mm_MapViewOfUserMemory
which I will implement rn
lmao
which will be a problem
if I need to implement a new vmm function
SO what I'll do is copy and paste code
so this is supposed to be mapping a private user memory region ubase->ubase+size from user_ctx into the kernel's context as shared memory
at kbase
with prot flags protection
possibly locking the user pages, depending on lock_pages
// File page.
page_info info = {};
MmS_QueryPageInfo(ctx->pt, (uintptr_t)reg->owner->data+currFileOff, &info, nullptr);
if (flags & VMA_FLAGS_PRIVATE)
{
// Private.
// Moooo (CoW)
cow = true;
}
isPresent = info.prot.present;
page what = {.phys=info.phys};
phys = isPresent ? RB_FIND(phys_page_tree, &Mm_PhysicalPages, &what) : nullptr;
if (phys)
MmH_RefPage(phys);
rng->cow = cow;
if (cow)
{
rng->un.cow_type = COW_SYMMETRIC;
pc_range->cow = true;
pc_range->un.cow_type = COW_SYMMETRIC;
pc_range->prot.rw = false;
info.prot.rw = false;
}
MmS_SetPageMapping(ctx->pt, &info, info.phys, false);```
this is what I do for mmap'ing files
and reading this I discover a possible bug
lmaooo
but idk if it's ever going to happen given my current page cache setup
do u want my pizza btw
my dad bought me pizza even tho i told him im not hungry
my address is 123 seasme street
I live at the senate of canada

lovely
cc @astral mason
is it broken?
no.
no
then ur fine
right after I complete this function
I will be redoing TLB shootdowns
obos thread at 40 stars
nah nvm
I can only work so much on obos in a day before getting bored

obores
Let me see
kk
also
which branch is the right one
Clone userspace-work
found it
Wha
I'll find you a TODO
oki
ive never done pci let alone pcie before
I'll find something else then..
okay
grep -nR ";;" .
you can implement interruptible waits
oh
interruptible waits?
so you know when you block a thread for a specific purpose
you're usually blocked
until that thing is fulfilled
yea?
I want you to make that interruptible from external sources
obos
the intended behaviour is that CoreS_WaitOnObject reports OBOS_STATUS_ABORTED
do you want multiple bugs introduced in your kernel
I am testing his code extensively
dw
can u point me to the file in which i probs need to edit?
You dont even test yours extensively 
exactly my point
locks/wait.h
under src/oboskrnl
okay
you might also need to make changes to mutexes, semaphores, and events
contribute to my kernel
which are also under locks/*
okay
yea im so confused
so
when u want to wait on an object
or thread*
u add it to some kind of threadlist
am i understanding this
yup
hint: CoreH_SignalWaitingThreads
obosman I suggest you put some empty lines in your code
between different parts
I'm trying to in new code I write
and I do occasionally go around the codebase adding newlines
Are you sleeping with dispagch irql
most of the infrastructure is already there, it's just that if you interrupt most waits, it falsely reports SUCCESS
where?
so CoreH_SignalWaitingThreads is happening in an interrupt?
The one right before the thread block
is this correct
oh shit you're right
thanks mathew
nd
it happens on release of a lock, or to signal event objects
and iirc, it has to be called at <= IRQL_DISPATCH
or yells at your face
i dont know what IRQL_DISPATCH is supposed to mean
sorry im asking a ton of stupid questions
nah it's fine
this is stranger code to you
IRQL_DISPATCH is where all scheduler IRQs are masked out
as well as timer IRQs
an IRQL is basically a level where certain IRQs are not executed
highest is 15 on x86-64, which means masked
i see
lowest is PASSIVE (0) which means unmasked
enum
{
IRQL_PASSIVE,
IRQL_DISPATCH = 2,
IRQL_TIMER = 2,
#if OBOS_ARCHITECTURE_HAS_ACPI
IRQL_GPE = 8,
#endif
IRQL_MASKED = 0xf,
}
this is the enum simplified
i get you
and at a higher IRQL, lower IRQL interrupts are also masked
why is it falsely reporting success
because it doesn't expect to be interrupted except when it succeeds in getting what it wants
because signalling an object really just means waking an arbitrary thread in it
how does obos know if its wait is getting interrupted exactly
*signalled
how it knows is because it's in a list of threads in the object
and signalling an object just chooses an arbitrary thread to wake
so it's like:
waitforobject:
append(obj->waiting_threads, curr)
block(curr)
return success
signalobject:
thread towake = obj->waiting_threads.head
remove(obj->waiting_threads, towake)
ready(towake)
return```
mm okay i see
now signal object in the actual kernel can also signal all objects at once
as you'll able to see from the signature
I think you're missing * after thread

it's pseudocode
ik
so what we need to do exactly is in waitforobject somehow check if we got signalled, then stop blocking the current thread and return an obos failure
am i understanding the problem correct
yup
or does this sound like complete gibbberish
okay
is there like a function you already have that can check if the current thread is getting signalled?
like some callback or smthin
set a variable if cancelled and check for it
you specifically need to check if you got signalled and the object is still not ready
yea
because you know you've been signalled as soon as you leave the CoreH_ThreadBlock
you need to make it figure out why, instead of it assuming blindly it was because it was signalled successfully
and then return the "why" as the status
so it's rather it returns OBOS_STATUS_SUCCESS because our wait was successful
or it returns OBOS_STATUS_ABORTED because our wait was aborted
that less so
you might need to add a new function
void abort_wait(struct waitable_header* obj);```
something like that
well to add interruptible waits to the kernel, you first need a way to interrupt a wait
brb
okay


