#uACPI - a portable and easy-to-integrate ACPI implementation
1 messages · Page 36 of 1
popcount was only used in one place in code
and its not triggered by proxima
the toshiba laptop right?
yes
btw do u get notifies for charger and stuff?
can't test, threw away the laptop battery a while ago due to expansion
ah right
You can try testing pmOS 
searched in my message history a bit and it seems like on dec 26 i did still get lid events
so i'm downloading an image from ci from that day and testing with that
god bless continuous integration
yeah there should be a lid notify
for GPE 02
the one with this
holy hell
whats interesting is i didnt really change much since dec 26
maybe i downloaded the wrong build but i'm not getting lid events on this either
oh wait nevermind i am
i apparently just wasn't patient enough?
uhh
maybe that was the issue with the newer build too lol
can you retry the newer one lmao
like i didn't keep the lid closed long enough
nopunintended
i guess it makes sense for them to have a slight timeout
or maybe a polling interval of some sort
yeah i'm getting LID_(0x80), VALZ(0x8F), LID_(0x80) on latest proxima (with uacpi master)
testing 1.0-rc now
getting them on 1.0-rc too
yeah
ok nice
least broken laptop firmware
btw do u have the power button hooked up?
yes
does it work?
it does
and shuts down fine and stuff
yeah perfectly fine
no problem
alright, I guess thats it, im adding davix to the leaderboard and merging this PR
then pushing the 1.0 tag
testing pmos too for the fun of it
because this laptop had broken fb before on there
still broken unfortunately
power button works fine regardless though
most stable microkernel
The framebuffer driver is in userspace, so technically the kernel is indeed stable 
it did shutdown so i guess
yeah this is basically textbook example of why u dont make a recursive aml interpreter
Still, needing to press enter in VMs is weird
Does QEMU use keyboard controller for shutting down?
no
The new 32 bit build...
It works in all vms (including bochs) and tripple faults on my laptop
uACPI 1.0 is finally LIVE 

the 1.0 leaderboard
Congrats on the big 1
thanks for believing in the project!
Shouldn't you, to fairly compare kernels, run them all on the same type of CPU?
So e.g. they'd send you ISOs and you run it.
that needs a volunteer with a good cpu
i have a shitty cpu that doesnt perform well, plus people want to track progress relative to their cpu and not the cpu that i have
The CPU doesn't need to be "good", it needs to not be abhorrently slow.
the top1 score is definitely not the best cpu on the list either lol
i'm really curious what the difference between proxima and the rest is
I'd say that the volunteer part is the most important
No worries, you have certainly established yourself as an authority on acpi
insane allocator
i dunno it feels super weird
I would be willing to run benchmarks, my CPU isn't the most recent but it's decent. It's a Ryzen 5 5600.
its. a very large margin
A fast path allocator does wonders
what can i say monkuous is really good at what they do
No smp
this score is with smp support
the allocator actually is really that fast
ikr
Like, I think we saw that with a lock in the alloc path it dropped dramatically
monkuous profiled every function call and micro optimized it
lmao nice
Congrats on the 1.0 🎉
thanks a lot!
keyronex is still not on the list which makes me sad
But either way, let me know if you guys want to take me up on my offer. I think it'd be cool if the leaderboard is all run on the same CPU.
I have figures in this thread somewhere
May you never go crazy and smash up an expensive sports car 
those are probably severely outdated
I agree that there should be a clearinghouse for scores so we can compare them fairly
infy, are you also updating the Managarm bindings?
i agree
It should be someone with decent statistical skill
no disk space to build managarm 
wtf lol
its like 30gb
Hydrogen (Proxima's kernel) is always built with -O3 LTO (it relies on it to keep performance that would otherwise be sacrificed for code cleanliness)
no, it's 3 gb
is it
So there's a lot of inlining
you don't need to build every package ;D
maybe ill give it a try
Lto, that'll be helping no doubt
by now we also have automatic pulling of deps, so you only need to do xbstrap install --rebuild managarm-kernel in an empty build dir (after setting up xbstrap correctly ofc)
I don't use 03 they say it makes hash out of good code
oh cool
yeah inlining the entirety of the kernel into kmain certainly helps 
yeah lto is insane
With LTO the allocator's fast path is a few instructions that are inlined basically everywhere
What sort of allocator is it?
Slab
building Managarm with LTO doesn't make a huge difference
With magazines?
but Managarm doesn't have a lock free allocator fast path
No magazines, but it doesn't matter because the benchmark is done with -smp 1
They do at least let locking be elided
With magazines you can replace 2*cmpxchg with pushf+cli+sti
It'd probably improve perf a bit but I doubt it's that much
pushf/cli/sti also affects the score decently if you do it in alloc fast path
yeah
pmOS is -O3 lto
cli/sti isn't that expensive right? Iirc they don't cause vmexits at least (unlike cr8)
putting another pushf cli sti in the managarm syscall path gives a measurable performance drop in glxgears
Mutex acquire is actually the major performance bottleneck of the allocator currently
Not because of the acquire itself but because of the memory ordering requirements
ah
my bet is that it would be the pushf/popf but I haven't verified whether that's the case
how does your schedule_work work if it needs to allocate a task that is called from an irq handler?
no, the cli sti are expensive
that might sleep on the mutex
IRQ handlers are not allowed to allocate
yeah cli/sti is pretty pricey
yeah so how does it work currently
An ACPI IRQ simply signals a semaphore which a softirq task is waiting on
ah ok
If you don't use the allocator from interrupt handler you can replace cli/sti with a preempt count
Good point
interesting, is it related to the fact how they have the delay and whatever? because aren't they fundamentally just setting a bit in a register?
what is that? like block preemption until the counter drops?
(while still keeping the per core semantics obviously)
Before I switched to a softirq task I just statically allocated enough to have 256 things in flight at a time
Yeah basically, if you get a preemption with the counter being non zero toy just return
And preempt manually at zero
i see
The cost is basically a per cpu count and an if at the decrement
like call yield after it drops? wouldnt that steal your entire slice potentially
Your slice is already up if it preempted in the middle
but u dont know that
You keep a mark
the problem with preemption locks is that you probably don't want to acquire a spinlock while they are active though
You increase the count, if a preemption interrupt happens toy mark it, and when decrementing and it's marked for preempt you preempt manually
Yeah
Preemption locks are obviously only for the per-cpu path
What I do for {enable,disable}_preempt:
- Separate TASK_RUNNING and TASK_READY
- On yield always set state to TASK_READY, even if preemption is disabled
- When counter reaches 0 and state isn't TASK_RUNNING, yield
ah
according to uica it looks like its specifically the sti that's expensive, 4x more than cli so maybe its indeed the effects and whatever (and popf is almost 5x more than cli)
Popf isn't used though
Pushf is, but it's popped into a regular register
At least usually
In keyronex can do an ipl raise instead
Unless you do lazy IPL that has to write to cr8 which causes a vmexit
thats a cr8 write tho right
It won't be reflected with a cr8 write unless an interrupt arrives while ipl raised
That's even worse
Cr8 is a bit more expensive than cli/sti iirc
not a bit
Oh ok lazy ipl helps a lot with that yeah
like a ton
Ignoring vmexit
in vms
On real hardware probably a bit, but in VMs it's incredibly expensive
ah yeah
If one does, cr8 is written and interrupt left unhandled for later
why write it in the irq handler? cant u just keep it at what it was
then you are going to get the irq again
hmm
Level triggered IRQs + IRQs are already so expensive you might as well write cr8 and avoid further IRQs
who would unset it tho
Then you can't receive higher priority interrupts
and that yeah
I wonder why wouldn't they use the vmx tpr virtualization if its supported tho
you'd unset it when exiting the critical section
that would avoid vm exits on cr8 writes/reads afaik
i wonder why that needs a vmexit in the first place
why cant that be emulated by the virtual irq chip
It shouldn't with vTPR or whatever Iots called now but unfortunately it seems that's not exploited
i guess because its not a priority for kvm
since linux or bsds dont use cr8
and nt has lazy cr8 probably
it's not clear that these strategies are worth it though
which
I doubt lazy IF update is worth it
sure, they will improve the uacpi benchmark but they pessimize workloads that actually use interrupts
its just a different system
CR8 probably because the only reason to use cr8 is because you want interrupt priority for other reasons
lazy IF update is strictly superior to lazy CR8 update in terms of throughput
Yeah but lazy IF update doesn't preserve the priority stuff
From what I've seen the interrupt priority stuff is rarely done for performance reasons
and masking of some interrupts at some ipls
yup
and cli/sti is better for uacpi benchmark too
Honestly the best part of uacpi 1.0 is that i can finally remove __popcountdi2.S
ikr
I'm aware that there are other uses of CR8
i'm only talking about the optimization here
nah its not a superior approach for perf
Oh yeah for optimization it's definitely not worth it over just plain cli/sti
i dont think there was an argument for that
well, it is definitely faster in the uacpi benchmark
because cli / sti have a real (and non-negligible) cost while lazy IF=0 has no extra cost if there is no interrupt
and there are no (or very little) interrupts during namespace initialization
I just stubbed out save_disable_irq and restore_irq (so no cli/sti at all during uACPI benchmark), performance is still ~within the same range
why does cli / sti have a cost? is it that "sti doesn't apply until the next instruction is done executing" thing?
that's surprising
Eh, not that surprising, almost none of my kernel APIs disable IRQs
Except the ones that are absolutely required to
So it's not called particularly often
for example, just inserting an irq lock + unlock into Managarm's syscall path is way more impactful than disabling LTO
not for the uacpi benchmark ofc but for performance in userspace benchmarks
I haven't used the profiler in a while but the last time I did, during the entire uacpi benchmark, save_disable_irq and restore_irq were called a grand total of 4 times each
Compared to for example mutex_lock (17k) and kalloc (10k)
how do you protect against IRQs that interrupt a spinlock?
Spinlocks always disable IRQs, I just don't use spinlocks if I can avoid them
no code paths that need spinlocks are touched by the benchmark i guess
how does the 17k mutex_lock operations match with 4 cli then?
Mutexes don't disable IRQs unless they're contended
In the uncontended path lock and unlock are both just one cmpxchg
And given how early uacpi is initialized, if they're contended at all it's a bug and deadlock
so what happens if CPU1 does mutex_lock (uncontended), then CPU2 locks (contended) and CPU1 receives an IRQ?
congrats on the 1.0 lol
thx!
Eventually CPU1 will get back into the critical section and unlock it
Same way userspace mutexes work at all
Ryurjr7dkryd
so the task on CPU2 will sleep in this case?

Yeah
1.0 released
ah
If mutex_lock is called while contended, the mutex state is updated to reflect that, and the thread sleeps on the mutex
Then in mutex_unlock it tries to cmpxchg the locked-uncontended state to unlocked, and if that fails it must be contended and it wakes up one of the sleeping threads
yeah i get how the mechanism works i didn't think of this though
yeah pretty smart
also because we do quite a bit of work in contexts where we can't sleep
monkuous is just huge brained
you can only do this operation if all work happens on threads though
i.e., you need one stack per concurrent unit of work
which doesn't apply to us
yeah with fibers this wont work
Ah you have stackless coroutines in kernel?
yes
That'd make this more complicated yeah
yeah managarm does all uacpi work in fibers too
get_thread_id is implemented as currentFiber() iirc
fibers in the kernel do have their own stack though
but some stuff is done on work queues that don't have their own stack
but even on your kernel, this approach has the same performance characteristics than locking a spinlock with preempt disabled (but IRQs on), right?
in particular, CPU2 in my example will pay at least the latency of the IRQ on CPU1
in reality, it will pay more since a task switch is more expensive than spinning
It does
But the same performance characteristics apply to mutexes and spinlocks in userspace
Or well I suppose the spinlocks are a bit better in kernel because you can avoid the IRQ latency
Hm
I should test this once I've got a more active userspace
Anyway the general consensus for userspace mutex vs spinlocks is that it's not worth optimizing for the heavily contended case
your strategy is probably good for workloads where you always have enough tasks to run on all cpus
Yeah I tend not to consider multi-CPU workloads beyond "does it work"
Hydrogen is intended to be a single-CPU kernel with multi-CPU functional but not super great
why is that
If you want to have a good multi-CPU kernel your scheduler will get very complicated very quickly due to hyperthreading and heterogenous CPUs
I didn't want to deal with that, and I decided that if I was gonna half-ass multi-CPU support in the scheduler I wasn't gonna focus on good multi-CPU support in other areas either
hm
how does hyperthreading make it more complicated
If you have two CPU-intensive threads you have to take care not to schedule them on the same physical CPU
Otherwise you will have terrible performance
it used to afaik but iirc nt doesn't have lazy cr8
or at least the wdk headers I have irql as macros that set cr8 directly
cli/sti doesn't work for ring 3
(which is how I use cr8)
breaks how?
gpf
how 💀
idk
the current one just switches between pf and inv opcode
which opcode even

x/10i $rip
yeah I'm not in the mood for debugging
why do I even do this
I'll go play factorio
lol
congrats on v1 btw
uacpi in linux 2025 
thanks!
is v1 out yet?
LETS GO 
we shall be implementing
@fiery turtle I have upstreamed support if you want to add Ironclad now
actually dont add it, the ops/s are too slow for now and its going to look like shit
ill optimize it and give them to you
I have self respect
Its an Ada kernel so I think its fair
Reactos is also in that neighbourhood I think
I can speed it up a lot ill just do so
Sure
context?
did ironclad have acpi before this
(0000000007) unable to attach (PCI_Config) operation region \_SB_.PC00.THC0.TH
(0000000007) CR: not found
(0000000007) aborting table load due to previous error: not found
(0000000007) #0 in \()
oh no the new line is expected
sorry I forgot that I am splitting them
yeah its THCR not found
this means you returned NOT_FOUND from your pci_device_open
is this qemu?
nah this is real hardware
ah ok
its a decently new intel board
thats the only error though so thats encouraging
well considering it aborted the entire table load due to it
or maybe it was one of the SSDTs, since u didnt paste the entire log idk
nah its the DSDT
i mean
+ function PCI_Device_Open
+ (Address : PCI_Address;
+ Handle : out System.Address) return Status
+ is
+ Ret : constant uACPI_PCI_Acc := new uACPI_PCI;
+ Success : Boolean;
+ begin
+ Arch.PCI.Search_Device
+ (Bus => Address.Bus,
+ Slot => Address.Device,
+ Func => Address.Func,
+ Result => Ret.Dev,
+ Success => Success);
+ if Success then
+ Handle := C3.To_Address (C3.Object_Pointer (Ret));
+ return Status_OK;
+ else
+ Handle := System.Null_Address;
+ return Status_Not_Found;
+ end if;
+ end PCI_Device_Open;
u do return not found here
yeah I do, it is not coming from nowhere
can u send the dump btw?
ill do when I can
sure
I gotta sort some other stuff right now that should let me debug it easier
btw your github mirror is severely outdated
yeah it is, thank you
Did you figure it out?
I was fixing another thing, ill let you know when I get around debugging that
does uacpi support acpi 1.1? asking for a friend
i'm thinking about buying a am2 board with an athlon 64X2
and i would like to test uacpi sometime in the future on that
uacpi should work on any piece of hw
and id be curious to see some of the old more fucked up aml
I do have an HP Mini 100e (made in 2009-2010) if you think it's old enough to be worth testing uACPI on it. I'm not sure what you'd define as "old AML"
Damn
Old is pre vista
But yeah 2009 is pretty old
I have a feeling that's gonna be saner than modern aml
is there any image (OS) that I can test uACPI with on that notebook? I haven't ported uACPI to my kernel and even if I did, I'd have to write some proper tests...
I mean there are a bunch but like a non-cursed one
managarm, pmOS, proxima, astral
obos 
Is it 64 bit?
only crashes on about 82.74% of real hardware that I have tested
non-cursed
wait a sec I'm not sure
this is a semi-recent build
yeah it's 64-bit
give me a few minutes and I'll test
for whatever reason it just shows a black screen - no Limine menu
I've previously booted Limine with no issues on this laptop so idk what's up
also on my PC it boots fine so it isn't an issue with the bootable media
the ISO supports legacy BIOS, right?
weird
From USB drive
I've just changed my build system to generate a hard disk image instead
for what it's worth this iso didn't do anything on my laptop while it was in bios mode
i had to put it in uefi mode to even get to limine
I can upload it when I come home
check how you build it and see if it is like the template
worth noting that a bunch of legacy BIOS systems won't boot GPT partitioned devices in legacy CSM mode but that's usually only if they know what a GPT is
it doesn't have UEFI or CSM support, it's a BIOS system, so most likely it's an issue with the ISO
managarm does a thor panic related to AHCI or sth, so I couldn't test uACPI 
but Limine does boot, no issues on that
Gn
ty
It's xorriso'es image
I'm too dumb for this, how do I install limine onto the image?
where do i get limine?
either v8.x-branch or compile it yourself
binary branch i think
sorry
v8.x-binary is the branch name
if you get that you can run make to build the host limine tool
I was running xorriso -as mkisofs -b boot/limine/limine-bios-cd.bin -no-emul-boot -boot-load-size 4 -boot-info-table --efi-boot boot/limine/limine-uefi-cd.bin -efi-boot-part --efi-boot-image --protective-msdos-label isodir -o $(ISO)
if you only do that, the iso's only bootable on bios if you're actually booting from a cd (or if you have a weird bios)
limine bios-install is necessary to make it bootable from a usb as well
Does this look right?
limine/limine bios-install pmos.img
Physical block size of 512 bytes.
Installing to GPT. Logical block size of 512 bytes.
Secondary header at LBA 0x3ffff.
Secondary header valid.
GPT partition NOT specified. Attempting GPT embedding.
New maximum count of partition entries: 44.
Stage 2 to be located at 0x1a00 and 0x7ffd600.
Reminder: Remember to copy the limine-bios.sys file in either
the root, /boot, /limine, or /boot/limine directories of
one of the partitions on the device, or boot will fail!
Limine BIOS stages installed successfully!
(I mean I can just try it...)
seems fine yeah
i mean assuming pmos.img is the previously created iso, yes
It seems to have created a bunch of GPT entries...
GPT partition NOT specified. Attempting GPT embedding.
limine embeds itself in the GPT
you need to respect the size of the partition table
you're likely reading past the end of it
I've just wrote this code so idk how it works
lol
it's probably wrong*
I am supposedly respecting the size
Anyway, this is the new hdd image
Which booted in QEMU with bios
bruh my wifi is so bad it can't push the commit over ssh
I'm doing this ```C++
struct GPTHeader {
uint8_t signature[8];
uint32_t revision;
uint32_t header_size;
uint32_t header_crc32;
uint32_t reserved;
uint64_t current_lba;
uint64_t backup_lba;
uint64_t first_usable_lba;
uint64_t last_usable_lba;
uint8_t disk_guid[16];
uint64_t partition_entry_lba;
uint32_t num_partition_entries;
uint32_t partition_entry_size;
uint32_t partition_entry_array_crc32;
};
// ... read gpt
auto gpt_entry_size = gpt->partition_entry_size;
auto gpt_entry_count = gpt->num_partition_entries;
auto gpt_partition_array_size = gpt_entry_size * gpt_entry_count;
// ... read gpt array
std::vectorDisk::Partition partitions;
for (size_t offset = 0; offset < gpt_partition_array_size; offset += gpt_entry_size) {
auto *entry = reinterpret_cast<GPTPartitionEntry *>(reinterpret_cast<char *>(gpt_ptr) + offset);
if (guid_zero(entry->type_guid))
continue;
std::string guid = guid_to_string(entry->type_guid);
printf("GPT partition: type %s, start %" PRIu64 ", end %" PRIu64 "\n", guid.c_str(),
entry->first_lba, entry->last_lba);
partitions.push_back({entry->first_lba, entry->last_lba});
}
@slow drift
./partitions.hh:42:15: error: static assertion failed due to requirement 'sizeof(GPTHeader) == 92'
42 | static_assert(sizeof(GPTHeader) == 92);
| ^~~~~~~~~~~~~~~~~~~~~~~
num_partition_entries
It's 44
yeah
why should it be 2?
it's the number of partition entries the table holds
free or non-free
44 means there are 44 available slots
why am I reading past the table though
idk, i am just assuming you are if you're reading garbage data
GPT isn't hard
you can easily figure it out with wikipedia alone, really
it's way more than enough
I'm reading that stuff from entries 0, 1, 2, 3, 4, 8, 9
Maybe my AHCI driver is reading bogus data
And entries 8 and 9 contain the right data....
Which are lba_size * 2 
(my theory is that my driver is ignoring the start sector and reading from 0)
uacpi feature request (not a huge deal but might be nice): let me have (by a define probably) a separate alloc function for smallish object allocations compared to larger or variable size allocations
ig
i was thinking more for possibly pooling some of the structs vs variable sized stuff
but that would probably take a lot more work to add
maybe im just used to zig and passing around allocators lol
like it also might be cool to have support for an arena for if theres a lot of short-lived allocations during init or whatever
just do it in ur alloc function
yeah ig
Even EC works, nice
yep
I might have a 1999 PC with acpi now that I'm thinking about it
daamn
maybe at least try to get a dump from it
I can try porting pmOS real quick 
fastest port in the west??
So far all I have found out is that uacpi is asking to find a device going by (segment, bus, device, func) (0. 0. 0x10, 0x6), both Ironclad and Linux do not find such device
you will have my acpi dump on your dms shortly
Some hw checks non existent devices and then checks if VDID == FFFF
but ill take a look
So tldr you must support that
so what should I return in my bindings for those cases, should I check that, and if it is true, report a fake device?
Make a fake device object that just reads at the correct place where that device would've been
thats very stupid
Stupid hardware
That's aml for you
Or you could unconditionally return FF on reads from it
But Linux just does what I suggested first
Aka it uses the raw pci helpers
@strong heath lol i was right
Device (THC0)
{
Name (_ADR, 0x00100006) // _ADR: Address
Name (RSTL, Zero)
OperationRegion (THCR, PCI_Config, Zero, 0x0100)
Field (THCR, ByteAcc, NoLock, Preserve)
{
VDID, 32
}
If ((VDID != 0xFFFFFFFF))
{
it basically creates the body of the device only if its actually present
otherwise the body is skipped
amazing
nice
how old are these
oh wait damn this is itanium
daamn GPE blocks live in system memory on it
its not hardware reduced acpi
[0ACh 0172 00Ch] PM1A Control Block : [Generic Address Structure]
[0ACh 0172 001h] Space ID : 00 [SystemMemory]
[0ADh 0173 001h] Bit Width : 10
[0AEh 0174 001h] Bit Offset : 00
[0AFh 0175 001h] Encoded Access Width : 00 [Undefined/Legacy]
[0B0h 0176 008h] Address : 00000000FF5C100C
Method (_PTS, 1, NotSerialized) // _PTS: Prepare To Sleep
{
Debug = Arg0
}
lol
Huh
[094h 0148 00Ch] PM1A Event Block : [Generic Address Structure]
[094h 0148 001h] Space ID : 01 [SystemIO]
[095h 0149 001h] Bit Width : 10
[096h 0150 001h] Bit Offset : 00
[097h 0151 001h] Encoded Access Width : 00 [Undefined/Legacy]
[098h 0152 008h] Address : 0000000000000400
SystemIO on itanium?
thats the only mention of SystemIO
❯ grep -rni 'SystemIO'
rx2800-i2/dbgp.dsl:27:[028h 0040 001h] Space ID : 01 [SystemIO]
rx2800-i2/facp.dsl:106:[094h 0148 001h] Space ID : 01 [SystemIO]
rx2800-i2/facp.dsl:120:[0ACh 0172 001h] Space ID : 01 [SystemIO]
rx2800-i2/facp.dsl:141:[0D0h 0208 001h] Space ID : 01 [SystemIO]
rx2800-i2/facp.dsl:148:[0DCh 0220 001h] Space ID : 01 [SystemIO]
rx2800-i2/spcr.dsl:27:[028h 0040 001h] Space ID : 01 [SystemIO]
Debug = "Dumping OpReg Info..."
Debug = " DSIX is: "
Debug = DSIX /* \DRBL.SET_.DSIX */
Debug = " DCIX is: "
Debug = DCIX /* \DRBL.SET_.DCIX */
Debug = " SVNP is: "
Debug = SVNP /* \DRBL.SET_.SVNP */
Debug = " DBLL is: "
Debug = DBLL /* \DRBL.SET_.DBLL */
Debug = "Storing DSIX"
DCIX = DSIX /* \DRBL.SET_.DSIX */
Debug = "Storing SVNP"
SVNP = One
Debug = "Storing DBLL"
DBLL = One
most production ready aml
lol take a look at this
its hilarious
Pastebin.com is the number one paste tool since 2002. Pastebin is a website where you can store text online for a set period of time.
[uACPI][TRACE] [AML DEBUG] String => "Init of scratch RAM complete!"
[uACPI][TRACE] [AML DEBUG] String => "Fatal Error: "
[uACPI][TRACE] [AML DEBUG] String => "_SB_._INI"
[uACPI][TRACE] [AML DEBUG] String => "SCRAM Data struct access init failed."
[uACPI][TRACE] [AML DEBUG] Integer => 0x00000003
Fatal firmware error: type: 1 code: 1 arg: 1
[uACPI][ERROR] loop time out after running for 3 seconds
[uACPI][ERROR] aborting method invocation due to previous error: hanging AML while loop
[uACPI][ERROR] #0 in \CLIB.ERRR()
[uACPI][ERROR] #1 in \_SB_.SBA0._INI()
it literally
calls Fatal
then hangs
While (Ones)
{
Sleep (0x03E8)
}
are u insane
very cool to see anyway
server hw is built differently
I can tell 
0x3e8 = 1000
Wasn't able to export the dump, but it does have a bit of funny stuff
It has a method named strc that compares two strings
It has a mutex object it uses for protecting some communication buffer
It has a power button device and an acpi power source device (whatever that is)
I might be able to export it, not sure
Thats a classic
USB?
It's complex cause its a work machine
I can def test something on it, not sure I can bring stuff out of it
so I was looking through uACPI sources, and I found this:
Some kernels may want to use an in-kernel implementation of the rwmutex.
so... feature request (can make an issue on GitHub if you want me to): the ability to define a macro somewhere that tells uACPI to use an additional kernel API for rwmutexes.
i mean sure that could be added ig, not sure how common that is tho
I will be having an rwlock in kernel idk about others
I have full posix api in userspace so...
barely anyone bothers reading about other existing uacpi options so im not sure its worth it
but ill think about it
truly the best AML ever, isnt it? :P
not many people even replace libc stuff
yeah pretty funny, thanks for the dumps!
I mean, is the rwlock used that much and is implemented that differently
basically yeah, its used once in uacpi for ns walks
and if your kernel has it, is it like much faster or
Big brain, instead of mutex and event just take a futex like api :^)
It would really only replace (up to) two mutex acquisitions with one rwmutex acquisition (which can potentially be faster on high reader contention). It may in fact pessimise the writer (I find it hard to imagine an rwmutex writer acquisition being faster than a normal mutex acquisition).
That's because we're lazy (and for me, because I speedran uACPI --- currently working on IOAPIC stuff so I can actually handle events)
true
However an in-kernel rwmutex would allow e.g. preventing writer starvation by making readers block even if the rwmutex is held by readers, if there is a writer waiting.
btw does itanium actually have io ports?
sorta, only for systems with x86 compat I believe
interesting
if you need to access the IO ports from outside of x86 mode then you need to map them into a 64KiB region of the address space or smth
but idk if you can map them if the x86 compat mode isn't implemented on the processor
another reason why uacpi should have map api for ports
I suspect you probably cant, but presumably they'd be wired to nothing even if you could
If it's needed then uacpi can implement itself
NICE

I have funni rwlock
bru 😭
does anyone have any insight into how uacpi uses memcpy/memset/memmove? i wonder if small copies are more dominant than bigger copies (>64 bytes)
i "wrote" (not exactly, with a little help of llvm
) some very optimized memory operation routines and i wonder if uacpi will make good use of that
not sure how fast they are in practice, but on paper (according to IACA 3.0) they should be able to process roughly 5-7x more data than a naive memcpy/memmove imlpementation, so i hope my work is not gonna go to waste
i think most of the impact is from clang recognizing memcpy/memset as an intrinsic
and not from it being extra fasts
most should be tiny
i hope this will at least speed up my allocator
when i have to copy/zero out big blocks of memory
but honestly this doesn't happen very often, so idk
maybe i am just overengineering it 😭
could be usefull on process creation when copying elf segments around
yeah i am quite far from that
but it will maybe slightly speed up my prekernel, since i am loading the kernel and modules manually :^)
could you share the algorithm?
i am basically doing 64, 32, then single byte copies
unrolling those loops apparently produces very fast code
it's like 200 lines of assembly compared to 10-20 but yeah
i also addiitonally prefetch the next 64 byte blocks using prefetcht1, idk if that has any significance but it's there for both 64- and 32-byte cases
and the bytewise copy is done using a jump table where each case falls through, so basically a duff's device
could be significant as the cpu can copy stuff around in cache and at the same time fetch from ram
hopefully, the IACA analyzer shows significant throughput increase for my optimized version
also my naive versions were backend bound where this one is frontend bound
though tbf it was tested against skylake uarch so idk how well it compares to modern uarches
uICA (https://uica.uops.info/) doesn't seem to support anything newer and i cant be bothered to set up the tools myself
my memmove (as i said, i helped myself a little bit with LLVM) was actually unrolled into a 128 byte loop so there's a little discrepancy between that and the memcpy, and i was too lazy to go back and unroll my memcpy too lol
tbh its somewhat annoying that cpus dont feature buildin memcpy/set engines like programming a vector register and the cpu does it in the background
like a simd extension just for memcpy/set
just stop making up words
last commit yesterday
Uacpi thread dea
and more like complete 
d
Signed-off-by: Daniil Tatianin [email protected]
Very big commit
I'll try and test uACPI on my friend's Asus EEE 700 in a few days
nice
I think the AML on my laptop is cursed
I get a good few errors with uacpi and acpica on linux too
where is the post for uDRM or the gpu thing
It's a 2007 Intel Atom netbook
what are they
I'll take a picture in a little bit
thanks
5 years
After UltraOS gets Mesa? 
nah ill use one of the osses from here as the test bed
obos 
By then I would definitely have a mesa port
100%
nah by 5 years i mean a usable library
uacpi 1.0 out, can't wait for the ukernel :^)
uLibc when? 
petition to rename mlibc to ulibc
already exists
there's uclibc but i'm not aware of ulibc
oh i probably mean that then
\\\\\
\\<
miaow
unsuccessful = timed out
oh and if the timeout is 0 you're supposed to do it without blocking at all
thats fine
wait so am I waiting for the counter to go to zero
and if it goes to zero before timeout its successfull
you're waiting for the counter to be non-zero
ah
if that happens before timeout, decrement it and return success
it's just a semaphore
least fucked firmware
there's even some more that wraps the fb
lol
ran into an issue finalizing my new MM stuff and hooking it into uacpi
that being that uacpi doesnt support sized unmap
hey im thinking on using uACPI on my project
does it need an allocator or specific stuff?
theres a header, kernel_api.h. you need to define the things in there
oh ok
i already have an allocator so i guess im done
it uses a page allocator right?
or its byte based
it needs more or less malloc/free
well shi, my allocator is page based
i guess its fixing time
i could make a suballocator
that allocates more pages if there are not enough bytes
thats the normal way to do that yeah
yeah
i still need to make a new allocator
the bitmap allocator is kinda bad for efi memory maps
does uacpi need to do mallocs bigger than a 2M large page?
if so then fuck that but if not then my new mm can at least handle every allocation it needs
Wdym? It does tho
What the fuck
Does your linux dmesg look similar?
Although acpica would abort the entire table on first duplicate method
Its not that simple, for example it uses dynamic arrays to store a lot of things, so in theory it depends on the aml being executed, if it has an insane deeply nested expression for example
Not sure what you mean but unmap takes a length parameter
fairly
it throws less errors
but yes
its absolutely cooked
yeah thats because acpica cant handle graceful skipping of some ops and aborts right away
idk what your firmware developers were smoking
do they not test at all
did u update your bios?
then again ive seen a person here who has multiple copies of the same SSDT in their pc
lmao'
thats how they fix aml yeah
ill give that a shot
considering this is the main thing I use for testing
I'd like not to get blasted with errors every boot
lol
ah of course they ship bios updates as fucking windows executables
fuck
here is a snippet from dmesg
💀
I was browsing around in the coreboot docs as a girl does on a random friday
it looks like coreboot people have their own DSL for device trees that compiles to AML?
probably also compiles to FDT?
very interesting
device pci 15.0 on
chip drivers/i2c/generic
register "hid" = ""ELAN0000""
register "desc" = ""ELAN Touchpad""
register "irq" = "ACPI_IRQ_LEVEL_LOW(GPP_A21_IRQ)"
register "detect" = "1"
register "wake" = "GPE0_DW0_21"
device i2c 15 on end
end
end # I2C #0
Scope (\_SB.PCI0.I2C0)
{
Device (D015)
{
Name (_HID, "ELAN0000") // _HID: Hardware ID
Name (_UID, Zero) // _UID: Unique ID
Name (_DDN, "ELAN Touchpad") // _DDN: DOS Device Name
Method (_STA, 0, NotSerialized) // _STA: Status
{
Return (0x0F)
}
Name (_CRS, ResourceTemplate () // _CRS: Current Resource Settings
{
I2cSerialBusV2 (0x0015, ControllerInitiated, 400000,
AddressingMode7Bit, "\\_SB.PCI0.I2C0",
0x00, ResourceConsumer, , Exclusive, )
Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive, ,, )
{
0x0000002D,
}
})
Name (_S0W, ACPI_DEVICE_SLEEP_D3_HOT) // _S0W: S0 Device Wake State
Name (_PRW, Package (0x02) // _PRW: Power Resources for Wake
{
0x15, // GPE #21
0x03 // Sleep state S3
})
}
}
for acpidumps we could probably compile all mainline device trees in coreboot to AML
that would be lots of chromebooks
so this is a great source of production arm AML
probably pretty much all chromebooks out there
damn i thought this was gonna be a unique feature for shkwve
wait what? I'll have to double check then because my impl never has lol
ok yeah im just stupid apparently
Lol
non-sized unmap would be horrible to deal with
yeah for whatever reason the zig export for it that ive got has never had a length param and ig last night i wasnt thinking enough to double check the header
i still gotta figure out why my new map thing does a safety-checked index out of bounds (which panics because im on a safe build mode) but thats a thing for later today
i tested Ironclad on my laptop and trying to shutdown made it turn off the fans only but the laptop stayed on
and i had to force turn it off
i was scared it would overheat lol
i wonder if it's an Ironclad or uACPI issue
maybe missing EC handling or some crap?
Test a different OS to find out
Pmos/obos/managarm
Could be yeah
Or proxima as well
Anything in logs BTW
The fact that it stayed on tells me prepare to sleep probably failed
i see
Does ironclad log anything to the fb?
no
alright
don't use the latest one from github actions, that one's using a just-started kernel rewrite
Wait
doesn't have uacpi yet
this?
A rewrite AGAIN?
yeah well the rewrite was kinda necessary considering i'm completely changing what i want the kernel/userspace boundary to look like
it was going so well 
Whats the new idea?
microkernel
i love how it's always like "yeah just go dig in logs and determine which of the many arbitrarily thrown around ISOs from days ago is safe to test with"
wanted to be able to write drivers in funny languages like java and python
that's really the main reason
Interesting
this is the latest pre-rewrite image
Although proxima might not shutdown because your laptop probably routes the power button via ec so it just won't get the notif
Is it a pc or a laptop
no
Then its not routed via gpio at least
you never know
True
speaking of which, i wonder how uacpi would perform if the kernel api was written in javascript
💀
yeah probably
but then what if the mmap regions for libuacpi.so are backed by an ahci driver written in python
this is the kinda stuff i wanna experiment with
i thought of that but the old plan for proxima was Yet Another Monolithic Unix Clone and i realized that i would lose motivation to work on that extremely quickly
i booted it, it says uncompressing init, then it doesn't say anything after that, then i press the power button, it says shutting down in 3/2/1, and it shuts down (i assume successfully)
Does the laptop shutdown?
yes
Ironclad bug ig
you mean executing init followed by hello world? because if nothing's printed after uncompressing init it shouldn't have even init'd uacpi yet
yeah
Lol
because the hello world is at the top
i guess it could wrap around if your laptop has a very large number of acpi tables
I mean if it says shutdown in 3 it did init successfully
it has a bunch of ACPI tables
this is the qemu output for that iso fwiw
I'm gonna miss this kernel
btw for the curious it does 1.2M
This is 1.0 correct?
also side note i have no idea what happened because i changed literally nothing in the kernel (i've mostly been working on userspace) but a few days ago the uacpi performance spiked up from 7.0-7.2M to 7.5-7.6M
let me check
Damn
it's uacpi 1bd2930030ef819519de32dd1f7a8f999440308f
which is the first commit of 1.0
Ok nice
ok time to start adding printfs to uacpi i guess, this is looking like a use-after-free of map/unmap stuff in early table access rn and i cant get my interrupt handler to give me the last few stack frames correctly sadly
...it also might help if i set the log level so my printfs actually get executed
Your issue confused me since I read it right as I woke up and I was like wait it doesnt have a length?
next time proxima's benchmark score gets updated it probably won't be at the top anymore
Indeed
gonna miss that
That's why I want this ukernel to be a separate project
well it's not like i'm deleting the repo or something, right now the rewrite's a separate git branch and once it's mature enough i'll just rename main to pre-rewrite
Is it gonna have full smp support btw
Oh well
sort of? i'm planning to fully take smp into account where i can but i'm probably never gonna get around to making a proper smp scheduler
yeah that was just me being tired and missing it in the header lol
yet another microkernel unix clone is more interesting and you can do your funny stuff later
Lol
Drivers in go or python could be fun ig
have your cake and eat it too (have your C/rust/c++ drivers and have your JavaScript ones too
oh ok cool it isnt a bug in uacpi that im getting rn at least
its my own problem that i dont know where its coming from 
but at least i managed to confirm it isnt trying to unmap the address it then page faults on
so back to my own thread for debugging hell ig
if i comment this one line out and it fixes it im gonna be mad ngl
the line in question being the unmap-the-ptes line
it didnt \o/

oh i bet i know it
ok so dump prints fine and debug prints fine and memcpy page faults accessing the header and i dont know why
tables.c L563
well the header is the virtual address you have mapped right
whats the value of cr2
fffffc001ffff324 which is the thing that map returned
does your memcpy return dst?
my memcpy is builtin_memcpy
throwback to a bug I had while integrating ACPICA into a previous kernel of mine. it failed because my (then nonconformant) memcpy impl didn't return dst
that calls into normal mecmpy
did and it isnt mapped anymore and that has me very confused
and no compile error because the impl was in asm and C land used the builtin
which is zig's @memcpy in zig compiler_rt here
what if u disable your libc overrides entirely and let uacpi run with builtins
thats good ig
fwiw my zig kernel used builtins and it worked fine
unless this is some compiler nonsense
so that shouldn't be the problem here
i think it cached wrong gimme a sec
idk why it wouldnt have invalidated build cache on changing the headers tho
ok yeah same error using uacpi's version
https://gist.github.com/Khitiara/c7fce93c47de7474563d39c21241dfa2 heres my log btw, ffffffff8013365c is tables.c L184 and ffffffff80133922 is in uacpi_memcpy
in case anyone sees something im missing
ig ill put a debug after the memcpy call just in case its a different one somewhere idk
alright no i was wrong its a different memcpy call
ok it turns out it was this one on line 105
btw why cant u just use gdb
i cant figure out how to get it to breakpoint in my code booting from limine
disable kaslr
it isnt on gdb just refuses to let me put in the breakpoint
gdb + qemu is in general just goddamn awful to setup lol. been there, tried that, gave up and did hcf debugging instead
you need hbreak with kvm
with tcg it should work flawlessly
ig i can try again at some point
also with qemu+gdb being annoying i find printf stuff easier
oh GOD if this is the problem im gonna feel so dumb
2025 microkernels Renaissance
it was the problem
turns out using max instead of min is a problem sometimes
i needed it to clear up to the first two of a thing with given length. put in max instead of min so it was overrunning when length was 1 and nuking the next pte along which was the rxsdt
bruh
and it took me a while to find the issue because the table load was recursing to get the dsdt and that made me think the problem was later than it was
anyway now its getting past all the uacpi things and then i think dying in my code later
yep dying in my code now
so all good here
nice
same tbh, though I already have two osdev projects so I think I will not at least for now lol
I could theoretically still turn the nt thing to a microkernel because its that early but eh I don't think I want to do that
yeah the reason i didn't make the new proxima iteration a separate project is because it'd have been my 3rd one lmao
I haven't really understood what would make microkernels easier to develop than monolithic kernels.
like, sure, the 'kernel' is much smaller and doesn't have to contain IO or filesystem drivers, but you've still got to do that work somewhere, except now it is in userspace and your kernel needs an appropriate form of IPC.
also kinda forces you to have a decent driver interface lol
obos rewrite 6 will be an astral fork 
yeah splitting everything into smaller pieces doesn't make development easier but it does at the same time
it forces you to have good abstraction layers
with microkernels you can't make a quick hack that bypasses a bunch of abstraction and oops 100k loc later it's very tightly integrated
but with a microkernel if you want some piece of information you need an api to get it out of the kernel
except 'this shiy' is in a different userspace process and the kernel doesn't even know it exists or how to find it
currently I am writing a monolithic kernel, and I will continue with that until it is self-hosting and has actually good userspace. but there might come a day when I decide to rewrite (or atleast redesign core subsystems). I believe that I learn things about everything that I implement in every iteration that gives me the ability to make the next iteration better. and I believe this is mostly true regardless of whether you're writing a monolithic or a microkernel.
microkernels are harder
oh crap i forgot i set it to debug level to find that bug earlier
You can just have everything in userspace
or that, yeah
you usually need some sort of protocol so processes can talk to each other
so i guess that's the abstraction
the thing with that is, you're still going to have to implement everything that you'd need to implement in a monolithic kernel.
tradeoffs
the kernel just needs to have a good IPC interface
and some other things
i think minix does pmm and vmm in userspace
yeah, all the kernel really needs is a way to create a thread, start executing user code and manipulate virtual memory
oh
interesting
nah
IPC
i prefer memory management in kernel though
yeah that is extreme
yeah but like... you don't have to write device drivers inside of the kernel... but if you want an OS, you're still going to have to write device drivers
but you can write drivers in userspace
yeah but the abstractions needed to write them wont write themselves
which implies you can do cursed things
and that generally determines the quality of everything
and how enjoyable writing new drivers is
a microkernel system is more complex and slower
what, you just need to map memory and have a good strategy for interrupts management
you can have a perfectly fine driver interface in the kernel
not (slower) by much
and doesn't matter probably
with modern CPUs it doesn't matter tbh
complexity can be fun if it isn't due to bad design, and if you want maximum performance writing your own os isn't the best option in the first place
from what i have looked at microkernels they are largely behind the times when it comes to modern scalability measures
they don't have to be
Is it slow if the vast majority of CPU time is spent in userspace normally anyway?
as we saw in #ipc message microkernels (or microkernel-like systems) were looking at these issues historically
that is not the problem
the problem is constant context switches
and cache invalidation
but microkernels have suffered probably from their unfortunate relegation to mostly embedded applications
and embedded people do not look at scalability
I think they're talking about general cache invalidation, afaik the main issue with microkernels for that is that what would be syscalls on monolithic kernels often get processed by daemon threads running on different CPUs
if a microkernel achieves the same end result as a monolithic kernel, are they not one and the same thing? 
no
so the inputs and outputs of those 'syscalls' aren't in the cache for the server and the client
you can spawn per cpu threads for servers
I don't see it as an issue
yeah but most microkernels don't bother making sure that the server thread that accepts the message is running on the same cpu as the sender
most microkernel problems are implementation issues yeah
but is that always best? see #ipc message for a counterpoint

