#uACPI - a portable and easy-to-integrate ACPI implementation
1 messages · Page 58 of 1
yea i saw that
this is mtune znver4
when the clocksource is tsc or kvmclock there is no syscall involved in getting the time
what does that even look like
how dare u disrespect hpet
same score
/j
I always syscall
instead of having something like jiffies that you use when precision isn't as important as access time, whenever you want to get the time it does a full read from hw
okay nyaux might also be handicapped by HPET
i could implement kvm clock and see how it is
i think nyaux is much more handicapped by its allocator
I use tsc
ah and jiffies are supposed to be cached?
jiffies is just a counter of a periodic irq
how so 
yeah but that's because in reality you are compiling twenty big projects, not one.
i wonder how it updates jiffies in tickless mode
i should really figure out how i want to do architect timekeeping in general tbh
oh and there's a bunch of places where i read the time only to read it again 4 lines later in a leaf function with no locks taken in between or anything
aka i don't bother reusing the last read value even if it's still pretty much valid
its probably fine to rely on time reads to be fast
if you target relatively modern hw
hitting the wall of i want my code to pick a time source (and calibrate tsc) as early as possible for stuff like logging but also half the time source options rely on some level of device discovery
like modern software in general spams gettimeofday all the time etc
i just need to figure out how to check if im running under kvm
id check the hypervisor bit but
what if im running on tcg
or
what if im running on hyperv
wrote a quick test and it turns out my pit clock source does in fact work correctly
there's a bit which tells you that you have kvm clock I think
where?
how does your pit clocksource convert time to ticks
do u just bump a counter in an irq handler
so in qemu+kvm, taking a spinlock and doing 1 isa io port read + 2 isa io port writes is faster than reading from the hpet main counter
when an irq happens i increment a counter, and when reading i read the current count from the pit and and add that
how tf is HPET so slow even emulated
so basically reading is num_irqs * TICKS_PER_IRQ + (TICKS_PER_IRQ - remaining_ticks())
what would happen if i cpuid this on real hardware KVM_FEATURE_CLOCKSOURCE
damn, HPET read is just ndelay(3000)
it's emulated accurately 
with some extra stuff to avoid off-by-ones, race conditions, clock going backwards if the irq went pending after taking the spinlock, etc
was gonna say, systemd-detect-virt exists so there has to be a way somehow
cpuid 1 ecx bit 31 is set if in a hypervisor
it wouldn't be set
then cpuid 0x40000000 has a kvm signature
makes sense
kvmclock looks piss easy
lets cook
this is how i determine kvmclock presence
i believe we use the same cpuid function lol? perhaps i stole it from you??
i mean
yea no timer makes no noticeable difference at all
i don't think there can be that many differences between cpuid functions
at the end of the day it's a wrapper around inline asm
yes but whats ur license 
its important still
i always explcity declare if code isnt written by me
with comments
or if its obvious
holy shit my laptop is a space heater
its 90C
???
anyway, features.hypervisor is the value of cpuid 1 bit 31, features.hyp_vendor is this union initialized from cpuid 0x40000000, features.cpuid_hyp is eax from cpuid 0x40000000
damn your code is really educational
MIT, but i really don't think this is enough to warrant attribution (and i also doubt you took it from me since this is relatively new code compared to nyaux)
like its a fully correct thing but at an understandable scale
for some parts i'm not sure it's fully correct lmao especially the vfs
that's what i'm saying
i'm still not convinced there aren't thousands of deadlocks waiting to happen in my vfs
what is this about btw hydrogen_ret_t irq = x86_64_isa_controller.ops->open(&x86_64_isa_controller, 0, 0, handle_pit_irq, NULL);
especially in rename/link
still gonna credit you idc

oh also just noticed u use uacpi barebones in hydrogen? I thought u were gonna roll your own parsing
acer-wmi kernel module is fucking trolling me
x86_64_isa_controller is an instance of the irq_controller_t class
open(controller, n, flags, func, ctx) opens a handle to irq n of controller with flags (active low/high, edge/level triggered, shareable/not shareable), and sets it up to be masked and to invoke func(ctx) when triggered.
u should repaste it
that was for the abandoned "full microkernel" rewrite of hydrogen
ah
ngl it could use some enum values
dirt cheap
ah
makes sense
there's not really anything to turn into an enum there, the first constant is a device-and-controller-dependent irq number and the second constant is only zero because there aren't any flags to pass
i guess i could #define PIT_IRQ 0
but that's about it
ah yeah if no polarity/triggering flags are passed it's active high/edge triggered
i dont have enough money 
i guess i could define those flags as 0
thats what i would do
i love ringing nvme doorbells
yep
coretemp-isa-0000
Adapter: ISA adapter
Package id 0: +77.0°C (high = +100.0°C, crit = +100.0°C)
Core 0: +70.0°C (high = +100.0°C, crit = +100.0°C)
Core 4: +72.0°C (high = +100.0°C, crit = +100.0°C)
Core 8: +70.0°C (high = +100.0°C, crit = +100.0°C)
Core 12: +72.0°C (high = +100.0°C, crit = +100.0°C)
Core 16: +72.0°C (high = +100.0°C, crit = +100.0°C)
Core 20: +74.0°C (high = +100.0°C, crit = +100.0°C)
Core 24: +75.0°C (high = +100.0°C, crit = +100.0°C)
Core 25: +75.0°C (high = +100.0°C, crit = +100.0°C)
Core 26: +75.0°C (high = +100.0°C, crit = +100.0°C)
Core 27: +75.0°C (high = +100.0°C, crit = +100.0°C)
Core 28: +72.0°C (high = +100.0°C, crit = +100.0°C)
Core 29: +72.0°C (high = +100.0°C, crit = +100.0°C)
Core 30: +72.0°C (high = +100.0°C, crit = +100.0°C)
Core 31: +73.0°C (high = +100.0°C, crit = +100.0°C)
thats rlly fucking bad
Nice
whoever gave these cores their IDs needs to get fired
Luckily repasting takes 10 minutes
they should
but it's probably a big.little arch
it is
so big cores get 4 ids?
ill have to get it my dad gives me my money 
blud has my 950 euro
Arctic 4 costs like a few euro
one issue i should fix in hydrogen is that rn if the only available clock sources are pit and 32-bit hpet the kernel will panic (if 32-bit hpet is going to be used as final clocksource instead of just calibration source it'll panic since i don't feel like dealing with overflow, and if the hpet is present it will unconditionally override pit (the logic here is that if any clock sources can be enumerated the pit will never be touched))
dealing with overflow is easy
brb reboot
@fiery turtle could you test this iso?
qemu-system-x86_64 -serial stdio -cpu host,migratable=off -M q35 -accel kvm -cdrom image-x86_64.iso
I get very different results between runs so pick out the highest one :P
8.7M
huh??
yep
[00:00:00.014335] [info] uacpi: successfully loaded 1 AML blob, 1705 ops in 0ms (avg 8703286/s)
💀
wait a sec, I must have something commented out or idk
that's too much
or wait proxima is 11M
try this one
same
bruh
very good kernel ig
I doubt that but I'm still happy lol
yeah may as well take it lol
finally got it working
the generic interface
had to rewrite the fucking stall polling and that was pain because i suck at math
anyways time to get kvm clock
lol was looking through some old files and found my old mesa igpu triangle dumps
LD_PRELOAD="/home/infy/tests/mesa/build/src/glx/libGL.so" LIBGL_DRIVERS_PATH="/home/infy/tests/mesa/build/src/gallium/targets/dri/" INTEL_DEBUG="bat, submit" ./a.out 2> dump.txt
thats apparently how i tested it
when the next leaderboard update 
black on white??? theme?? my eyes!!!
yay boot allocator seems to work
just need to test dynamic growth and top down allocations now
Project thread when? 
after log ring 
lol
vulkan?? holy shit nie
semver, any breaking change no matter how small increments major
based
one day I will go back to doing osdev and write the world's greatest operating system that has ever operating system'd
I just wait till my boyfriend has a C class and then I make him do osdev with me its that simple
thats crazy
nah but fr one day I will actually start working on an os and try to make it actually like. not crap
maybe winter break
systemd reference
Are you saying astral is bad
I mean it kinda is
Why
bad style and questionable design
I'm still thinking of rewriting some stuff tho maybe I will do that instead of doing it from scratch
just havent had the time
maybe once I finish some uni stuff I have to do I can leave astral doing a clean build
listen mathew
if uve seen bad
look at nyaux
or boykisseros by ofluffydev
(real thing btw)
I should daily drive that
read the code for yourself 😭 this cannot be real
humanity is cooked 😭 🙏
astrole?
casserole
yes
i want astral to be back 
daang
by the time boron gets a uacpi port it will probably be 4.0
you can do both at the same time
The update was breaking for me
nyaux update: uacpi: successfully loaded 1 AML blob, 1705 ops in 0ms (avg 1966580/s) on 13700k
@dusky glade
yes
@fiery turtle i was playing around with the irq numbers and uacpi complained about this:
uACPI: unable to install SCI interrupt handler: already exists
which irq does uacpi use for SCI?
sci is always 9
oh ok
uacpi doesn't change anything
that's why sci uses it
i mean technically theres a field in i think the fadt that says what irq it is
but its basically always 9
(on imaginarium that ends up being ioapic mapped to vector 22, not sure what i have the targeting set to but it doesnt matter yet since i dont have AP startup yet)
I mean uacpi doesn't pull that error out of its ass, you return that yourself lol
yeah ik
Why do you return that?
I mean you did return it from install irq handler
how i can get pci configuration when i using uacpi_find_devices
You're supposed to enumerate PCI devices yourself
😭
Wdym by configuration
ACPI gives you root buses, then you enumerate each root bus, discovering devices and possibly more downstream buses, which AFAIK don't have to be present in AML.
yup
technically root bridges and its the downstream buses of those that you then enumerate but same idea
i like how everyone is super aware about aml and acpi now
i dont even have to answer questions 
no but you are expected to respond within three seconds of uACPI breaking because of bad kernel API implementations.
is that really worth it?
how do i acpi?
real
the uACPI SLA
just do the thing
I call uacpi_initialize, why doesn't my krenel work on real hardware?

trueee
ACPI is a Real Hardware Thing so you are now cursed to be the Real Hardware Person and people will ping you about the most random of Real Hardware Quirks and expect you to know.
I call uacpi_initialize, why doesn't that magically do everything a kernel is supposed to do?

uACPI pma, vma and heap when 
UACPI_USE_BUILTIN_OS
lol
finally, os crate
uos when @fiery turtle
I believe it's being worked on
Yep
when uacpi motherboard
with sane aml
it's not hard at all don't worry 👍
scan all buses devices and functions
static void probe_function(uint16_t seg, uint8_t bus, uint8_t slot, uint8_t func) {
/* Match some drivers or add the device to the list */
}
static void probe_slot(uint16_t seg, uint8_t bus, uint8_t slot) {
uint16_t vendor = pci_read16(seg, bus, slot, 0);
if (vendor == 0xFFFF)
return; /* No function present */
probe_function(seg, bus, slot, 0);
/* Check if the device has multiple functions */
uint8_t header_type = pci_read8(seg, bus, slot, 0);
if ((header_type & 0x80) == 0)
return;
for (uint8_t func = 0; func < 8; func++) {
uint16_t vendor = pci_read16(seg, bus, slot, func);
if (vendor == 0xFFFF)
continue; /* No function present */
probe_function(seg, bus, slot, func);
}
}
static void probe_bus(uint16_t seg, uint8_t bus) {
for (uint8_t slot = 0; slot < 32; slot++) {
probe_slot(seg, bus, slot);
}
}
void pci_init(void) {
for (/* for each root bus */) {
probe_bus(bus->seg, bus->bus_num);
}
}
shrimple
it seriously is yeah
isn't there some stuff you have to do with PCI to PCI bridges?
yes but that's going to be part of probe_function
or is it
idk, can oyu have a pci-pci bridge at function != 0?
probably safe to do it in probe_function anyway
a pci-pci bridge requires you to read the secondary bus number and scan there
Wait are you supposed to do that? BadgerOS just iterates all 256 busses lol
Oh I think I may be doing PCI discovery very wrong then lol
i believe what they are saying is they scan all busses instead of actually properly following the pci-pci bridge
you don't have to scan all 256 busses, right?
I group all functions into one device node
i mean yeah brute forcing all 256 buses works too ig
that i don't think is correct though :^)
consider a gpu which has the actual gpu function and an intel hda function for audio
oh
is it better to scan bus 0 + follow pci-pci bridges properly? or can there be a non-zero bus that isn't discoverable from bus 0 or acpi?
you'd use 2 different drivers for them
yeah that's a bit of a thing isn't it
Well in my case the DTB says bus-range is [0,255] anyway
i guess that works if you create sub-device nodes for each function
That would be incorrect interrupt-wise in my model.
Because of automatically inherited interrupt-parents, which are implicit if not specified.
I guess I'll just make one node per function then.
yeah 100%
That was also the only reason my device system supports multiple addresses so I might as well just make that exactly one again.
But that's a future thing. For now, I'm going to be doing some SATA funny business and hopefully query drive parameters like block size and count.
do you have actual ahci hardware you want to support?
I'm going to target the generic AHCI controller and I have a NVME-to-sata thingimajig that doesn't require special drivers on my testbench.
i would honestly just go for nvme lol
I don't have spare drives of that kind right now
I'm going to support AHCI, NVMe and USB MSC
Requires USB first though
minus it being wrapped scsi
xhci is also a nice spec to work with
at least my driver worked on most hardware it tested it on.
following the topology is definitely the right way
Damn the physical memory allocation for an AHCI driver is going to be a bit of a PITA.
Just look at all this indirection
there are no busses that are unreachable from the roots (that'd be a bug in the acpi tables or the DT)
How do y'all implement the memory allocation for all this? Do you have static command tables to be filled out and then dispatched, or do you allocate them as needed, use them, and release the memory later?
probably the sane thing is to allocate the command ring buffer at setup time
and the response ringbuffer too
i think i read somewhere that reading or interacting with buses that dont exist can cause problems. reading the relevant byte to determine if a device exists is fine as long as the bus is real though. (also a root bridge can list a _BBN acpi method that gets you its root bus number but its almost always 0)
i could be wrong tho
that's what my pseudocode basically does, assuming you get the segment and bus number by evaluating _SEG and _BBN
i didn't know about the non-existing bus thing tho
i dont remember where i saw it and it might be something else im confusing tbf
people have said it in here before
i'm not sure if reading their config space can be problematic but you can definitely run into devices that are behind bridges with mmio/pio decoding disabled etc
so if you do naive brute force, you'd think that these devices are usable while they are actually not usable until you reprogram their bridges (or until ACPI does that through AML, not sure if that's a thing though)
Nah
To this
I allocate two memory regions per controller I think
Like fixed size command list I think?
the situation probably is something like this: on most hardware it is fine and just returns 0xffffffff, but on some hardware it hangs or raises MCEs
goddamn family interrupting me for half an hour when I'm in the middle of writing multiple messages
they raised NMI
on the pi4 instead of yielding 0xffffffff it hangs the core for like 8s and then raises an SError :^)
although this happens for all nonexistent devices, so in addition to not doing a brute force scan you also need a different optimization
I think this is infy approved?
oh wtf
uint32_t nSlots = 32;
// A PCIe downstream port has only one device (slot 0) attached.
// In theory, this is only an optimization, in practice however omitting
// this causes a SError on the BCM2711 when trying to access the vendor ID
// of a non-existant device.
if (bridge && bridge->isPcie && bridge->isDownstreamPort)
nSlots = 1;
for(uint32_t slot = 0; slot < nSlots; slot++)
checkPciDevice(bus, slot, enumerateDownstream);
(except the raspberry pi thing)
Because Broadcom's PCI controller is funny, and they do weirdness with ACPI
this is not even acpi-related, it's just a bug (?) in their pcie rc
there is no proper ACPI for the pi4
they fixed it for the pi5
the community EDK2 fork is not compliant
did you get this optimization from linux?
most x86 acpi isn't spec compliant either, sounds like it fits right in
Not really a bug 
Wasn't it even worse?
yes, and conversely if you turn it off on linux (with pci=pcie_scan_all) then you get a kernel panic on linux too
ah
yeah but the pi community fork's ACPI doesn't even expose the pcie controller
that's because of the weird config access mechanism right?
yeah
the pi4/5 pcie rc exposes a single 4K config space window you slide around between functions
instead of ecam
why do they do this??
(and for 00:00.0 you use the pcie rc's mmio directly)
of course there are damn exceptions, why wouldn't there be!
I'm guessing it's a remnant of when they had a 32 bit physical address space since proper ecam has huge mmio regions
that seems likely
yeah their pcie ip is descended from their mips socs
didn't raspberry pi 4 also have some weirdness with 8gb versions or something?
pcie dma is limited to the first 3GB of ram iirc?
because 32-bit?
no it was a bug in the pcie controller integration with the memory controller in early pi4 chips
the pi4 also has 3 (?) possible physical memory layouts
because of backwards compat shenanigans
it's lovely
yeah there are 3 phys address spaces, the legacy 32-bit addr one which some dma devices see, the full 35-bit addr bus one, and a low-peripheral 35-bit addr bus which moves a bunch of peripherals under 4G
this is actually so cursed wtf
iirc the gpu is always using the normal 35-bit one, and the cpu can be toggled by applying a dtb overlay in config.txt
and as i mentioned some peripheral dma (for stuff like i2c etc ig) uses the legacy 32-bit phys addresses
but yeah you can clearly tell that the broadcom socs have a long heritage :^)
all the way to the mips ones :^)
the x86 of chipsets.
How did it work on raspberry pi 3? 
pi3 has no pcie
impossible
No way! ||Isn't testing usually done using google test or some other programs that feed program test binaries and check outputs xd||
Things may appear working but it doesn't mean it will always work
And that decides if program works?
Yes, uacpi already has a test suite but it cannot simulate hardware
Aw that's sad
uacpi hardware simulator
i believe they are testing and expecting known behavior
oh sorry discord didn't scroll all the way down 
thats always so annoying
The pcie spec mandates that all reads from non existing device has to return something like all 1s and writes to be discarded
And whatever pi4,5 do is not spec compliant
Where does it say that?
Also, that doesn't contradict what i said
Wasn't intended to
the complaining at the start about the OS requiring the smbus hc driver is a bit stupid and just means he doesn't understand acpi, but the second part is funny nevertheless
Yeah SMBus is a mess
I wanted to implement it
okay spent some time studying how linux handles pgd/p4d/pud/pmd/pte and page faults, I think i get it enough to implement something like that
once i have that ill start building the sparse struct page array
ill try to use less stupid names for page table level abstractions
infy speed running re-writing linux from scratch
more like slow running
tbf you have like 20 years of work to catch up :^)
but yeah i guess this is a mini-linux project tbh
i wanna research all subsystems in depth
what's wrong with just having a loop?
reusing the same code on all arches and on all runtime configurations
an arch just needs to provide some basic defines and helpers
yea i have a generic paging impl with a loop
plus very easy to make that stuff handle huge pages etc
that can do an arbirary amount of levels (as long as the arch supports it)
well how do u handle 5 vs 4 levels
in linux level 4 is just folded transparently if the cpu doesnt support it
if there's 5 levels then i start at 5, otherwise at 4 :P
there are obviously some arch dependent bits to determine the flags for each level
do u do stuff like arch_flags_for_level(i)?
i do this
like this linux stuff is basically a loop just unrolled and optimized at compile time
makes sense
you're going to have a blast with DRM actually
linux drm is one of the best documented subsystems IME
yeah im kinda ridiculously far from that atm, but ill have to devise some shitty impl to have a dumbfb over the vesa/gop thing
not quite
there's helper functions that can translate fbdev stuff into drm
that's what i used to translate the s3fb driver to drm
but you can still have a raw fbdev backed driver
ah ok ill have to look into that
i do want to do the kernel text mode thing
so i can at least run shit without drm
kernel text mode?
yeah like /dev/ttyX
just kernel vt i guess
the thing u get when u press ctrl+alt+a number or wahtever
yea kernel vt
tty
that
i think thats the default mode and then a drm master can switch it into graphical
roughly the kernel is the drm master, but it's like a weak ref because the second a user process requests to be the master it hands it over
multiple people already started doing that
really?
yea
would it possible to do a gui in vga text mode, if you loaded a 8x16 font that had 128 characters with each having a single pixel occupied at different position
then you could draw basically anything
(including me)
no
why not?
is it public
because i wanted to do some drm userland programming
i've done very little drm programming
i have a flanterm buffer but i do want a simpledrm fb
how do you plan to handle the sparse array accesses? assuming by sparse you mean what I think you do, how do you control what is in the array and check for if a page is in the array?
im not sure what u mean exactly, by sparse i mean that the struct page array has a fixed base, but only present physical memory will have an associated struct page mapped at the corresponding offset
- some fake struct pages for the buddy allocator max order alignment
PFN database?
i think thats what they call it in NT land yeah
not usable memory = indices aren't mapped
easy as
yes but how do you actually guard against that, and also how do you handle when a not usable page has a struct page in the same page as a usable page
you pretty much never need to test if there is a page at phys addr X
then you map it
if you got phys addr X from someone, that means there is a page there
(or it is device memory and you're not going to use struct pages for it anyway*)
my map for mmio stuff is the same function as to make an temporary extra kernel-mode mapping of existing memory so i need to do that check in there for page refcounting
ah
so you need some kind of pfn_is_ram() or something?
by the nature of page tables, it is actually possible to implement this with another "virtual" array, where pfn_is_page is just
extern uint64_t *pfn_bitmap;
static inline bool pfn_is_ram(pfn_t pfn)
{
return pfn_bitmap[pfn/64] & (pfn%64);
}
this can be done by aliasing portions of the array with identical contents
and this aliasing can possibly even be done at higher page table levels too (so e.g. pml4[foo] = pml4[bar] = a pml3, with all entries pointing to the same pml2, with all entries pointing to the same pml1, with all entries pointing to a zero page
IMO this is a little too much fun to have with page tables
why does the temporary extra kernel-mode mapping need refcounting on the pages?
to prevent them getting paged out
ok yeah using a bitmap is what im doing, was just curious if there was a different method i was missing
but presumably the caller holds a reference to the page already
and will unmap before dropping that reference
or, by refcount do you mean something like mlock?
the main case im running into is io buffers from usermode
so a usermode thing passes a usermode buffer to the kernel io stuff
and the kernel wants to access that buffer from another context e.g. DPC or some other callback somewhere (when it might be running in a different address space)?
yep, so the problem case is:
- usermode gives buffer to kernel io stuff
- user process isnt running on processor that runs the io callback
- user process phys page gets swapped out to disk
could have the refcount not part of the map function but i prefer it in there so i cant forget
yup, makes sense
i ended up using a bitmap after looking into how reactos does it since my kernel is very NT-inspired so react is a good reference for some general stuff like that
or you could have a
page *get_user_page(uintptr_t addr)
{
// increase mlock_count
}
void put_user_page(page *pg)
{
// decrease mlock_count
}
yeah ig
and i still might end up changing this idk
hell i dont even have usermode yet so it doesnt matter lmao
lol
well
it's good to plan ahead
anyway so before you've mapped a page into the kernel address space, do you hold some lock or something which prevents it from being swapped concurrently?
also there's a tricky case to be aware of: another thread can be performing a simultaneous mmap(MAP_FIXED) that is replacing the portion of the address space you are doing IO on. this means that you can pin the page, dispatch IO, some other thread unmaps the page, IO callback writes to the page, kaboom unless you are careful
IMO: for synchronous IO it is best to have a copy_to_user that runs in the context of the calling process.
and then the page fault handler can fault in pages or make copy_to_user return EFAULT
asynchronous IO is tricky, but since you're doing NT-like you may want to be aware of the existence of something called the APC (iirc) which runs in the context of the enqueueing process (iirc).
someone will probably dispatch a serial killer to me for butchering NT terminology lmao
context of a thread even but yeah
the whole thing is that theres a separate kernel mode temp mapping so changing out the virtual mapping of the buffer page doesnt break anything
yeah theres a one-bit spinlock in the page struct
anyway ig if this is going to turn into rambling about my kernel it should be done in #1312232715193683988 instead lol
well that's not going to happen since I'm a human being who needs sleep 
What's strange is Linuxes PAE support seems to be compile time
Like it cant dynamically disable it if the CPU doesnt have it
Like it can for 5 level paging for example
pae is much more invasive than adding an extra level
the new level is a different size than other levels, it behaves differently, and most importantly the page table entry size (and number of entries per table) changes
i think the most important one is the entry size change, their model cant easily adapt to that
yeah
both that and the number of entries per table (and thus the vaddr index encoding change) are really annoying to deal with at runtime
especially if your model hasn't been made with it in mind
number of entries they can handle dynamically, they pretend the p4d has 1 entry if 5 lvl paging is not supported
is that not just a special case for folding?
well im not sure what u mean, but folding works by just unconditionally returning true to pgd_present() and reusing the pgd offset in p4d_offset
im not sure exactly what code relies on number of entries per thing
the problem with number of entries per table actually changing, and not just pretending X amount of top-level tables are 1 entry, is that it completely changes the layout of the vaddr bitfield
with pae you go from 10:10:12 to 2:9:9:12
technically all that is hidden behind thing_offset, but some code might be using publically available "constants", not sure
fair enough
i think some code in ASAN or hugetlbfs are places i've seen referencing these
but not sure how much of a problem this is
arch/x86/boot/cpu.c-75- if (err_flags) {
arch/x86/boot/cpu.c:76: puts("This kernel requires the following features "
arch/x86/boot/cpu.c-77- "not present on the CPU:\n");
Yeah it just dies on boot if u dont have PAE
i guess pae is old enough so whatever
this is also interesting
/*
* Checks whether a page fault on the given mm is still reliable.
* This is no longer true if the oom reaper started to reap the
* address space which is reflected by MMF_UNSTABLE flag set in
* the mm. At that moment any !shared mapping would lose the content
* and could cause a memory corruption (zero pages instead of the
* original content).
*
* User should call this before establishing a page table entry for
* a !shared mapping and under the proper page table lock.
*
* Return 0 when the PF is safe VM_FAULT_SIGBUS otherwise.
*/
static inline vm_fault_t check_stable_address_space(struct mm_struct *mm)
{
if (unlikely(test_bit(MMF_UNSTABLE, &mm->flags)))
return VM_FAULT_SIGBUS;
return 0;
}
while a process is being reaped by the oom killer its considered to have an unstable address space
there are some ifs in the pf handler to not cause recursion i guess
does the oom reaper free the mm before terminating the threads or something?
yeah
if the process being killed is the one that caused the OOM it gets to satisfy the allocation that caused the OOM by killing itself
so __alloc_pages spins until the OOM killer reclaims enough memory to satisfy the allocation
which could be in the context of the process being killed
ah makes sense ig
im confused about this math lol
static inline int page_level_shift(enum pg_level level)
{
return (PAGE_SHIFT - PTE_SHIFT) + level * PTE_SHIFT;
}
why the hell does it subtract pte shift from page shift
shouldn't it be just PAGE_SHIFT + level * PTE_SHIFT?
maybe it's one-indexed?
so it basically does 3 + level * 9
yeah nevermind my guess for what PTE_SHIFT was was incorrect
it's basically the number of bits covered by one level
in this case the bottom most table
yeah i was guessing it was the number of bits in a hardware page (to support software page size > hardware page size)
im gonna assume this function is just bullshit
because it doesnt math
Author: Dave Hansen <[email protected]>
Date: Tue Jan 22 13:24:31 2013 -0800
x86, mm: Pagetable level size/shift/mask helpers
I plan to use lookup_address() to walk the kernel pagetables
in a later patch. It returns a "pte" and the level in the
pagetables where the "pte" was found. The level is just an
enum and needs to be converted to a useful value in order to
do address calculations with it. These helpers will be used
in at least two places.
This also gives the anonymous enum a real name so that no one
gets confused about what they should be passing in to these
helpers.
"PTE_SHIFT" was chosen for naming consistency with the other
pagetable levels (PGD/PUD/PMD_SHIFT).
Cc: H. Peter Anvin <[email protected]>
Signed-off-by: Dave Hansen <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: H. Peter Anvin <[email protected]>
yeah
PG_LEVEL_4K is 1, so (12 - 9) + 1 * 9 = 3 + 9 = 12
what is that number tho?
it's the number of bits to shift the vaddr by before masking to get the index for the given level
jesus lol
page_level_size is then the size of 1 entry in the given level
least convoluted way to write this
yeah i can't help but feel that PAGE_SHIFT + (level - 1) * PTE_SHIFT would've been clearer lol
yes
some peoples brains are just built different idk lmao
for whatever reason i spent a few hours studying how rseq(2) works
which is fine ig because its one of the first syscalls used by glibc
also me when set_robust_list
Also if anyone has updated scores they want to submit for the uacpi leaderboard now is a good time
i think you already have my latest
nice
i have too much temporary shit in my head, I need to implement it quickly before i forget everything lmao
(not on the readme mind you, but you tested mine at some point past)
can u send a link if u have it?
#1217009725711847465 message found the message
ah
infy cooking with ukernel
new mod colour
Rseq is cool
rseq is about the least important syscall 
it's quite invasive which is interesting
like various code paths must check for rseq_cs presence explicitly every time
in the core scheduling and signal delivery etc
but its pretty simple anyway
also i learned about mm_cid, which is a relatively new thing
aka concurrency id
basically it allows u to cheaply index per-cpu data in userspace using the cid instead of the cpu id
e.g. if u have 256 cpus and e.g. 4 threads in your process and your thread 4 is scheduled on cpu 255 the cpu_id will be 255 but cid will be only 3
basically allowing you to have smaller arrays
i think I have most x86-specific page table code done, one thing left is huge page support and implementing ptX_populate()/prot bits
no one needs huge pages anyways, outside of mapping the HHDM, right?
basically yeah, atm im only gonna use them for HHDM
(note: I am aware of the usecases of hugepages, this is just me memeing, no need to lecture me about database uses for it and such)
im definitely not gonna support THP or hugetlbfs any time soon
its too much adhoc code everywhere
THP is a mess
yep
you know, there are languages with proper support for things like that

Never heard of em
@fiery turtle shame that uacpi doesn't have madt helpers
the madt is annoying to parse so those would've been nice
i mean it's not a big big deal
just something that'd be nice
U mean like an iterator for it? It was suggested earlier by someone else as well
it's really just two functions that would need to be implemented:
acpi_entry_hdr *uacpi_subtable_first(acpi_sdt_hdr *hdr, size_t hdr_len)
{
uintptr_t end = (uintptr_t) hdr + hdr->length;
uintptr_t addr = (uintptr_t) hdr + hdr_len;
return (addr < end) ? (acpi_entry_hdr *) addr : nullptr;
}
acpi_entry_hdr *uacpi_subtable_next (acpi_sdt_hdr *hdr, acpi_entry_hdr *entry)
{
uintptr_t end = (uintptr_t) hdr + hdr->length;
uintptr_t addr = (uintptr_t) entry + entry->length;
return (addr < end) ? (acpi_entry_hdr *) addr : nullptr;
}
this should give a nice iterator interface to any such table with subtables in that same format
acpi_entry_hdr *uacpi_madt_first(acpi_madt *madt)
{
return uacpi_subtable_first(&madt->hdr, sizeof(*madt));
}
acpi_entry_hdr *uacpi_madt_next(acpi_madt *madt, acpi_entry_hdr *entry)
{
return uacpi_subtable_next(&madt->hdr, entry);
}
Yeah something like that ig
I might have both a macro version and a function version
Similar to resource iteration
yeah, like a function to parse it handily or so
do I need to call any of the init before using uacpi to discover tables
just uacpi_setup_early_table_access
ah
thanks
so should I just pass like a page of memory to the early access
realistically I need access to maybe three tables lol
it doesnt matter how many tables u want to access, the array will store all existing ones so yeah
it has a very large doc string above the function btw
yeah
or if u have heap available at this stage u can just uacpi_initialize
and not worry about static buffers
yeah
wait how tf is this still not handled by acpica lmao
rewrite acpica in rust 
I believe the real problem is that ACPICA is architectured in a way where it blindly trusts a machine's AML. This is not from a security perspective (i.e. prevent malicious AML from pwning you and stealing all of your cookies) but rather a fault-tolerance one, AKA firmware devs should be able to ship sloppy firmware and its effect on us should be limited in scope.
Fortunately, uACPI is good at that
But of course, making Linux use uACPI is probably never gonna happen
true
Someone should reply with "I think this is another example of the need to move to a modern ACPI implementation, one that luckily enough already exists: <uACPI link here>"

well, somebody would need to put in the work to replace all the acpica calls by uacpi
We need a crowdstrike style Blackout for Linux systems caused by a firmware update, that might help get uacpi support 
What about BSDs?

depending on their level of abstraction for the acpi driver
My guess is zero :^)
i mentioned this before but if you want to get uacpi into linux, you need a acpica API compat
otherwise it's not going to happen
Or someone with suspiciously insane amounts of free time and autistic level focus rewriting all call sites to uacpi
yeah, which is gonna be extremely annoying because they have global variables as public api, they have unsafe practices like allocating aml objects on the stack as part of user api, no opaque objects etc
but if anyone wants to do it unironically ill gladly merge an optional compat layer
wait, I thought the only way to parse aml was to lookup the function to see how many argument it expected... been a while, I'm probably misremembering.
it's possible that the caller frame just ends at two arguments so theres nothing to parse after, so acpica just continues the call
they didnt attach a dump so its impossible to say
i wanted to make a test case for this but u have to use a hex editor unfortunately
ah nvm managed to make it work
yeah lol acpica just jumps to the function anyway
Method (TEST, 3) {
Printf("Arg0 %o Arg1 %o Arg2 %o", Arg0, Arg1, Arg2)
}
TEST(123, 321)
Table [DSDT: Local ] (id 01) - 0 Objects with 0 Devices, 0 Regions, 0 Methods (0/0/0 Serial/Non/Cvt)
ACPI Error: Uninitialized Arg[2] at node 0x5977751aed78 (20230628/dsmthdat-471)
ACPI Error: AE_AML_UNINITIALIZED_ARG, While resolving operands for [Concatenate] (20230628/dswexec-505)
Failed at AML Offset 00001, Opcode 0073: Concatenate (-Return Value- (), Arg2)
No Local Variables are initialized for Method [TEST]
Initialized Arguments for Method [TEST]: (3 arguments defined for method invocation)
Arg0: 0x5977751aebc0 <Obj> Integer 000000000000007B
Arg1: 0x5977751ae910 <Obj> Integer 0000000000000141
ACPI Error: Aborting method \TEST due to previous error (AE_AML_UNINITIALIZED_ARG) (20230628/psparse-580)
ACPI Error: Aborting method \ due to previous error (AE_AML_UNINITIALIZED_ARG) (20230628/psparse-580)
ACPI Error: Invalid zero thread count in method (20230628/dsmethod-869)
ACPI Error: Invalid OwnerId: 0x000 (20230628/utownerid-210)
ACPI Error: AE_AML_UNINITIALIZED_ARG, (SSDT:RUNRIDTB) while loading table (20230628/tbxfload-244)
idk if it actually corrupted some memory with this or not
uacpi just skips this call, it's never invoked because it doesnt parse enough arguments
[uACPI][TRACE] load of 'DSDT' (OEM ID 'uTEST' OEM Table ID 'RUNRIDTB')
[uACPI][DEBUG] BEGIN OP 'MethodOp' (0x0014)
[uACPI][DEBUG] pOP: TRACKED_PKGLEN (0x0F)
[uACPI][DEBUG] pOP: CREATE_NAMESTRING_OR_NULL_IF_LOAD (0x11)
[uACPI][DEBUG] pOP: LOAD_IMM (0x1F)
[uACPI][DEBUG] pOP: SKIP_WITH_WARN_IF_NULL (0x01)
[uACPI][DEBUG] END OP 'MethodOp' (0x0014)
[uACPI][DEBUG] pOP: RECORD_AML_PC (0x1B)
[uACPI][DEBUG] pOP: OBJECT_ALLOC_TYPED (0x1A)
[uACPI][DEBUG] pOP: INVOKE_HANDLER (0x15)
[uACPI][DEBUG] pOP: INSTALL_NAMESPACE_NODE (0x25)
[uACPI][DEBUG] pOP: <END-OF-OP> (0x00)
[uACPI][DEBUG] END OP 'MethodOp' (0x0014)
[uACPI][DEBUG] BEGIN OP 'UACPI_InternalOpUnresolvedNameString_T' (0x0054)
[uACPI][DEBUG] pOP: AML_PC_DECREMENT (0x2C)
[uACPI][DEBUG] pOP: EXISTING_NAMESTRING_OR_NULL (0x13)
[uACPI][DEBUG] pOP: CONVERT_NAMESTRING (0x31)
[uACPI][DEBUG] pOP: LOAD_INLINE_IMM (0x1D)
[uACPI][DEBUG] pOP: IF_NOT_NULL (0x35)
[uACPI][DEBUG] pOP: TERM_ARG_UNWRAP_INTERNAL (0x07)
[uACPI][DEBUG] BEGIN OP 'BytePrefix' (0x000A)
[uACPI][DEBUG] pOP: LOAD_IMM_AS_OBJECT (0x20)
[uACPI][DEBUG] pOP: OBJECT_TRANSFER_TO_PREV (0x26)
[uACPI][DEBUG] pOP: <END-OF-OP> (0x00)
[uACPI][DEBUG] END OP 'BytePrefix' (0x000A)
[uACPI][DEBUG] RESUME OP 'InternalOpMethodCall3Args' (0x00FA)
[uACPI][DEBUG] pOP: OBJECT_CONVERT_TO_SHALLOW_COPY (0x18)
[uACPI][DEBUG] pOP: IMM_DECREMENT (0x2D)
[uACPI][DEBUG] pOP: JMP (0x3C)
[uACPI][DEBUG] pOP: IF_NOT_NULL (0x35)
[uACPI][DEBUG] pOP: TERM_ARG_UNWRAP_INTERNAL (0x07)
[uACPI][DEBUG] BEGIN OP 'WordPrefix' (0x000B)
[uACPI][DEBUG] pOP: LOAD_IMM_AS_OBJECT (0x20)
[uACPI][DEBUG] pOP: OBJECT_TRANSFER_TO_PREV (0x26)
[uACPI][DEBUG] pOP: <END-OF-OP> (0x00)
[uACPI][DEBUG] END OP 'WordPrefix' (0x000B)
[uACPI][DEBUG] RESUME OP 'InternalOpMethodCall3Args' (0x00FA)
[uACPI][DEBUG] pOP: OBJECT_CONVERT_TO_SHALLOW_COPY (0x18)
[uACPI][DEBUG] pOP: IMM_DECREMENT (0x2D)
[uACPI][DEBUG] pOP: JMP (0x3C)
[uACPI][DEBUG] pOP: IF_NOT_NULL (0x35)
[uACPI][DEBUG] pOP: TERM_ARG_UNWRAP_INTERNAL (0x07)
[uACPI][INFO] successfully loaded 1 AML blob, 4 ops in 2ms (avg 1887/s)
What if there is a termarg after the the bad call to test ? Like just a math op or a literal...
in the byte stream it would be parsed as an argument to the function invocation, simply because there's no way to tell if its a standalone op or an argument
well up to the number of arguments the function has
the rest of standalone ops would be skipped
Like if u have TEST(123, 321, 123, 321, 123 , 321)
it would parse the first 3
the rest would be skipped since it's basically an rvalue that just dies without side effects
Aml really bad. Maybe not much you can do to mitigate a corrupt stream...
well best u can do is just make it so u dont care if its a corrupted stream
but yeah it was a really stupid decision to not have a MethodCall opcode
By doing this they also left it to the implementation to decide when a named method should be invoked and when it simply produces a reference to the method
so whether u invoke a method is context dependant
which is insane
for example Package { METHOD } here u just store a ref, but Add (123, METHOD) here u call the method
but both just have the method name there, no other opcodes
Yeah, I remember having headaches dealing with refs
yeah especially since refs work entirely different on acpica vs nt
That bug report above is also bogus... an external doesn't specify the number of args. (I think, right ?)
NT!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! >:(((((((((((((((((((((( NT!!!!!!!!!! >:((((
D:<<<< NT!!!
external is generated by the iasl diasssembler, it doesnt even exist in the original dump
ExternalOp is always a no-op anyway
Exactly
@fiery turtle to disengage uACPI wholly what does one need to do? is calling uacpi_state_reset() enough?
Yes
asking because even after doing that you need to long press the power button to turn the system off
Tbf I am not sure how many bioses properly support disabling acpi mode
leaderboard :(
Csmwrap doesn't even enter acpi mode to begin with
Iirc
So that shouldn't matter
multiply astral score by 10 billion
real
Astral ops/s = NaNeInf
balatro ref
alright uh
time to release uacpi 3.0 and do leaderboard updates
i also have 10 billion ultra changes not commited
how are ultra changes different from normal ones? 
uACPI jit when? 
lol
added some comments to resources.h
since its a very very common thing to fuck up
I kinda want to try making a speed benchmark comparison for ACPICA vs uacpi to add to the readme
like im almost 100% sure uacpi is at least 2-3 times faster, but i cant prove it without a lot of effort
both uacpi's test runner and acpica's acpiexec have a ton of extra crap that they do as part of init just to test that stuff works
so id have to modify both
ah fuck it ill give it a try anyway
ok i have acpiexec built with -flto and -O3 and with some extra init stripped out
ill make one for uacpi as well
infy@DESKTOP-IGT40G0:/mnt/d/uACPI/tests$ /mnt/e/Projects/acpica/generate/unix/bin/acpiexec -to 100 x.aml
Intel ACPI Component Architecture
AML Execution/Debug Utility version 20250404
Copyright (c) 2000 - 2025 Intel Corporation
Automatic loop timeout after 100 seconds
Input file x.aml, Length 0x62 (98) bytes
ACPI: RSDP 0x00006111189D3A80 000024 (v02 Intel )
ACPI: XSDT 0x000061112F6FB4E0 00003C (v00 Intel AcpiExec 00001001 INTL 20250404)
ACPI: FACP 0x00006111189D3B40 000114 (v05 Intel AcpiExec 00001001 INTL 20250404)
ACPI: DSDT 0x00006111189D2100 000024 (v02 Intel Local 00000001 INTL 20090730)
ACPI: FACS 0x00006111189D3A40 000040
ACPI: SSDT 0x000061112F6FC4F0 000062 (v02 uTEST RUNRIDTB F0F0F0F0 INTL 20230628)
ACPI table initialization:
Table [DSDT: Local ] (id 01) - 0 Objects with 0 Devices, 0 Regions, 0 Methods (0/0/0 Serial/Non/Cvt)
ACPI Debug: "10,000,000 additions: 00005AF31112D680"
Table [SSDT: RUNRIDTB] (id 02) - 1 Objects with 0 Devices, 0 Regions, 1 Methods (0/1/0 Serial/Non/Cvt)
ACPI: 2 ACPI AML tables successfully acquired and loaded
Final data object initialization: Namespace contains 10 (0xA) objects
elapsed nanoseconds 19443959481 (19443 ms)
Initializing General Purpose Events (GPEs):
Initialized GPE 00 to 7F [_GPE] 16 regs on interrupt 0x0 (SCI)
Initialized GPE 80 to FF [_GPE] 16 regs on interrupt 0x0 (SCI)
Initializing Device/Processor/Thermal objects and executing _INI/_STA methods:
Executed 0 _INI methods requiring 0 _STA executions (examined 2 objects)
- q
ACPI: No outstanding allocations
infy@DESKTOP-IGT40G0:/mnt/d/uACPI/tests$ runner/build-linux-64bits/test-runner x.aml --while-loop-timeout 100
[uACPI][INFO] starting uACPI, version 2.1.1
[uACPI][INFO] RSDP 0x00007FFE288BF200 00000024 v02 (uOEMID)
[uACPI][INFO] XSDT 0x000058F0A492D5C0 0000002C v02 ( uTEST uTESTTBL)
[uACPI][INFO] DSDT 0x000058F0A492E5D0 00000062 v02 ( uTEST RUNRIDTB)
[uACPI][INFO] FACP 0x000058F0A492D600 00000114 v06 (uOEMID uTESTTBL)
[uACPI][INFO] FACS 0x000058F0A492D720 00000040
[uACPI][TRACE] load of 'DSDT' (OEM ID 'uTEST' OEM Table ID 'RUNRIDTB')
[uACPI][TRACE] [AML DEBUG] String => "10,000,000 additions: 5af31112d680"
[uACPI][INFO] elapsed nanoseconds 6275607129 (6275 ms)
[uACPI][INFO] successfully loaded 1 AML blob, 110000015 ops in 6275ms (avg 17528186/s)
[uACPI][TRACE] initialized GPE block _GPE[0->128], 0 AML handlers (IRQ 0)
[uACPI][TRACE] initialized GPE block _GPE[128->256], 0 AML handlers (IRQ 0)
[uACPI][TRACE] fixed event 0 enabled successfully
[uACPI][TRACE] activated all 'EmbeddedControl' opregions controlled by '\', 0 _REG() calls (0 errors)
[uACPI][TRACE] activated all 'PCI_Config' opregions controlled by '\', 0 _REG() calls (0 errors)
[uACPI][INFO] namespace initialization done in 0ms: 0 devices, 0 thermal zones
[uACPI][TRACE] _STA calls: 0 (0 errors), _INI calls: 0 (0 errors)
[uACPI][TRACE] fixed event 0 disabled successfully
uACPI is 3 times faster 
this is just 10M additions
Method (ADDM, 1, NotSerialized) {
Local0 = 0
While (Arg0) {
Local0 += Arg0 + Arg0
Arg0--
}
Return (Local0)
}
Printf("10,000,000 additions: %o", ADDM(10000000))
les fuckin go
[uACPI][INFO] elapsed nanoseconds 6275607129 (6275 ms) vs elapsed nanoseconds 19443959481 (19443 ms)
aml has a printof method??
its a macro that makes a series of ConcatOp
ah okay i see
this is a completely fair test, both runners built with O3 and i put the exact same function to calculate time in the exact same places
when uacpi 3.0 gets commited, ill see the ops for it on nyaux so u can update it
ah actually i can use the Timer operator
it's already commited
just not formally
wait really?
yes
epic
nothing actually changed lol
just some minor things that caused backward compat breakage
ah okay
does acpica have sized frees?
dont think so
probably not
fuck
why?
acpica is a dumpster fire
tbf i didnt expect a 3x difference on a simple math test lmao
i thought it would mostly be cpu bound
as in not interpreter logic
trying to implement it it in proxima to see an actual OS comparison with uacpi
ah damn
all that this really tests is the decode loop
yeah that would be cool if u did that
but you can only make it faster than that
considering add is the simplest op there is
yeah i guess simple math test basically tests how fast the interpreter loop is
but i think thats kinda what matters no
guess i'll just have to do something like this
lmao
exactly
so while this is only 3x faster, in reality it's probably even faster
depending on how shit the implementation is
which i dont have high hopes for
ill try other test cases as well
rn i want to convert it to use the TimerOp from AML so that the test is entirely self contained
holy shit
and still cant handle incorrect number of function arguments
Method (ADDM, 1, NotSerialized) {
Local0 = 0
While (Arg0) {
Local0 += Arg0 + Arg0
Arg0--
}
Return (Local0)
}
Method (TOMS, 2, NotSerialized) {
Return ((Arg1 - Arg0) / 10000)
}
Local0 = Timer
Local1 = ADDM(10000000)
if (Local1 != 0x5AF31112D680) {
Printf("Unexpected test result %o", Local1)
Return (1)
}
Local2 = Timer
Printf("10,000,000 additions took %o ms",
ToDecimalString(TOMS(Local0, Local2)))
There you go
yooo iretq morning
you should add libgccjit
to uacpi
unironically though would be neat for userspace 
[uACPI][TRACE] [AML DEBUG] String => "10,000,000 additions took 6444 ms" vs ACPI Debug: "10,000,000 additions took 17094 ms"
there u go
super fair self contained test
bro is also pro gamer, bro also uses sized frees
same cpu, same compiler options
that is fair
i did not sleep either
until like 2 hours ago
yeah but i wanna get out of uacpi hell
ive been working on it for two years
fair
watch me add libgccjit to uacpi on my os only so it obliterates everyone on the leaderboard
aml jit sounds like a project at least as big as the interpreter itself
real
Yeah its a huge project
would it even be feasible with the amount of weird shit aml does implicitly?
i mean, there's javascript jit
so why not lmao
well depends on how u do it, if u do a pass over the aml and convert it to jit calling into native interpreter handlers that would probably already be an order of magnitude speed up
and its not that hard
famous last words
especially for math test like this we could be looking at 100x even
huh?
what I was thinking of was more like
just aml to machine code converter
instead of interpreting it all you JIT it
so e.g. AddOp would be call uacpi_handle_add
that'd be doable
would you do it as a stack machine and have handlers operate on that or do proper regalloc? 
depending on how much time you have on your hands 
just generate x86 directly
last time i checked x86 did not contain the capability to operate on arbitrary data types other than numbers
https://gcc.gnu.org/onlinedocs/gcc-14.3.0/jit/cp/intro/tutorial04.html idk much about AML, but that doesnt seem so bad to do
so you can't really "generate x86" without a bunch of runtime support
well yeah first step of jitting something is always just transforming stuff into calls into C
next step is hand optimizing each thing so it can be handled inline
etc
why do the acpica docs say AcpiOsReadPciConfiguration can have a Width parameter of 64??
wtf is a 64 bit pci read
who knows lol
lmao
its also strange it gives u the number of bits
i'm just returning AE_BAD_PARAMETER for that
like can u do a 13 bit read
i sure hope you can
is this like "the parameter format allows passing it" or "this will be passed and you have to deal with it"
i can add this math test case results as well as proxima's result if u get that done, would be cool to have both
i hope it aligns them up to next byte boundary
but idk lol
well according to this
it's always aligned
because 
yeah doesnt look that bad
how fun
Lol
wait I was testing uacpi with sized frees with every allocation recorded in a hash table
that might've slowed it down a bit 
I will unironically try it once I get it running in userspace
just to beat you all
that would be cool
- I'm in userspace so I can abuse a lot more stuff
yeah, that shaves off another second [uACPI][TRACE] [AML DEBUG] String => "10,000,000 additions took 5124 ms"
like simd and I can port mimalloc
yeah true
this will be the theoretical limit of uacpi speeds
yep
I can test on my cpu as well since i have avx512 it should be faster
[uACPI][INFO] successfully loaded 1 AML blob, 110000046 ops in 5125ms (avg 21463362/s)
So i guess ATM the maximum speeed uACPI can run at is 21M ops/s
i wonder what happens if i tune for my cpu
@gentle peak what were the compiler options u used for tuning
(for my cpu)
-march=znver5 -mtune=znver5 i think
thanks
whats the record again
ah fuck my clang is too old did you mean ‘znver1’?
probably
did you try uacpi linux on it
like
userspace uacpi
on it
i'm getting ACPI Error: AE_NO_ACPI_TABLES, While loading namespace from ACPI tables (20250404/tbxfload-110) but it isn't even calling AcpiOsGetRootPointer ???
lmfao
no I meant like
iirc the score on first run (with cold caches and memory not being paged) is ~7M
infy is currently running uacpi vs acpica
this repo is uacpi running in userspace linux
it would be pointless to try qemu's blob in my current set up since it does IO accesses etc, so I would be testing the speed of the test harness
which is kinda useless
yes
up until the point where it tries to install an irq handler anyway since that's impossible in pure userspace linux
but that's enough to get the score
i did at one point but this was last touched 4 months ago
so with CPU tuning uacpi gets about 23M/s and ACPICA gets 6.5M/s
creaking noise on laptop, hello kitty lamp, insane cheering
this is truly a 10/10 video
lol true
So basically 3.5x diff vs acpica is what i can get on a stable basis
ill use that for the readme
and im using the best result i managed to get on acpica
it's znver4 because my clang is too old
I'd expect that the difference is higher on a math test than on real world AML code
yeah ofc, this is purely an interpreter benchmark
since real world AML code will spent a large fraction of the time talking to the HW
yes
monkuous is currently implementing acpica in their os
we'll see what that generates
especially interesting to see real hw diff
yo at least u have signals 😭
but ill mention in the readme that this speed is interepreter only and doesnt matter that much irl
its literally like
write shit into stack frame
or kill if no handler
signals can get messy tho
from some ppl
well u have to implement sigreturn as well etc
fun
signals are way worse on the userspace side than on the kernel side
well u have checkpoints at which syscalls check if current thread has a signal pending
its not that bad
you see
and if it does u just return -EAGAIN
the thing is i designed nyaux's syscall shit without it being interruptable in mind
so
fucking pain is near
EINTR
but u still need to handle signal shit for syscalls right?
its not required to make stuff work

