#tabula imaginarium: osdev experiments in zig

1 messages · Page 4 of 1

haughty cipher
#

general order of operations plan is that the dpc interrupt will be set up during smp init

#

and all processor-local interrupts (like the timer, or other PPIs and SGIs on aarch64) will be configured by scheduling a DPC to all targets after the smp is initialized

#

and/or ill make a list of them somewhere and hardcode this tbh

#

id like to keep this generic-ish though

#

if i dont do the list thing then DPC irq init (and tbh maybe also timers) will definitely be hardcoded during smp startup because dpcs will be how to have more added later if needed by devices

#

what do yall think on that front actually?

#

may as well take advice if anyone has it

placid swallow
#

I dont know if this is useful advice for you but I do DPCs entirely in software

#

I have an ipl for dpcs, and they're executed whenever a cpu lowers from/past that ipl

haughty cipher
#

that could work and I considered it but I didn't want to do that route

haughty cipher
#

mostly because thatd be yet more shit i have to cram into my post-context switch handler

#

which is already getting painfully complex lmao

haughty cipher
#

had a somewhat obvious and simple idea to solve half of this tbh

#

which is to just give my percpu modules an "init on AP" function

haughty cipher
#

im actually very happy with how i did percpu storage btw

#

my hal/smp.zig PCR (processor control region) struct gets padded to page-length and then instantiated once on each cpu.

#

it has, besides the smp-general support stuff, a field called module, which points to a struct defined in my root krnl.zig file

#

each field of the modules struct has to either define a default value or a .init function and can optionally define other functions for other points in init

#

i had late_init for after the mm is fully up already (used for allocating the idle thread stacks for instance)

#

now adding ap_init which is called during ap startup, for setting up anything that needs to happen on a target processor

haughty cipher
#

and confirmed i can now receive a DPC on other cores

#

on x86_64 anyway lmao

#

i uh dont have smp set up for aarch64 yet lol

#

tbh it looks easier than the x86_64 version overall, just because im not fiddling with getting perfect codes onto the apic

#

or dealing with real mode lmao

#

starting up a cpu on aarch64:

  1. put 0xC4000003 in w0
  2. put the MPIDR of the processor in x1
  3. put the ap startup function pointer in x2
  4. put the first argument of the ap startup function in x3
  5. run either smc or hvc depending on the value of a flag in the acpi tables/devicetree
#

it does have to be a physaddr function pointer

#

and the mmu will be disabled

#

but this still slaps compared to having to figure out real mode segmentation bullshit for the trampoline on x86

#

i wont even have to relocate it to lowmem or anything

#

shit fuckin slaps

#

anyway not sure if ill get anything else done today but im glad i did that before i forgot how i was going to do it

haughty cipher
#

found a weird maybe bug I'll need to investigate

#

where it looks like my gic priority code has an off by one but when I fixed that it suddenly didn't work at all even though in theory everything is using this same function for priority stuff

#

(I need to remap 0-f to f0-00 with that reverse in there, and was subtracting from 16 instead of 15)

haughty cipher
#

yup

#

sure enough

#

now I don't know why it works anyway when the math is wrong

#

because dispatch is irql 2

#

so the bad math is turning that into 0xE0 when it should be 0xD0, but that should still be masking it?

#

unless the pmr has an undefined reset value?

#

can't check rn I'm in a car lmao (not driving)

haughty cipher
#

got home and checked and it seems its architecturally defined for warm reset but i see nothing about other resets

haughty cipher
#

o h im stupid lmao

#

turns out my set_group function for gic irqs was accessing the wrong registers 😅

#

so the call to set_group was just. disabling the interupt instead of changing the group

#

ok fixed that and one other off-by-one and now we good

haughty cipher
#

ok ive got a docs site now

#

not published or anythin yet

#

but ive got a semblance of one in progress

#

thanks xq of the ashet project for the css theme lol

#

even got autodoc for the kernel on it

#

not sure how ill host it yet, dunno if codeberg has a gh pages like thing but if not ill cram it on a subdomain of my site probably

#

i honestly might do autodocs my own way instead of using the zig buildin setup

haughty cipher
#

another pic of the docs before i get back to work on the actual kernel

#

though idk what part of this i actually wanna work on next

haughty cipher
#
pub const TimerDivisor = enum(u32) {
    @"2" = 0,
    @"4" = 1,
    @"8" = 2,
    @"16" = 3,
    @"32" = 8,
    @"64" = 9,
    @"128" = 10,
    @"1" = 11,
};

ok the apic timer divide config is fucked up actually

haughty cipher
#

ugh i dont want to write fuckin calibration code

#

hate timer calibration shit

haughty cipher
#

tick tick tick :D

#

what to do with it? dunno wasnt trying to actually do anything interesting yet just wanted it ticking lol

#

(just figured out how to get the frequencies from WHPX and stubbed out manual calibration with a panic for now on x86. aarch64 will be easier, theres a fuckin cntfrq register i can just read lmao)

#

next up when im not feeling just really sleepy for no reason is the arm generic timer

#

and then after that we back in acpi land with device enumeration

#

(technically we'll be in acpi land for the generic timer too, im using an acpi table to get the interrupt number, but whatever dont worry about that lol)

haughty cipher
#

alright we tickin on arm too now

haughty cipher
#

copied a bunch of my driver registration stuff in and now to see if it works on the new kernel lmao

#

once i test this im going to bed tho lmao

#

(well test and fix some of the stupider bugs)

#

yknow idk why i wasnt expecting this known working code to still work in the new context but after a few quick compile error fixes it does seem to be

#

albeit shockingly slowly

#

esp in context of what uacpi is doing up above

#

def going to try and profile this shit at some point but whatever the baseline works i can start copying in actual drivers soon

haughty cipher
#

oh also forgot to mention but we got hypervisor msrs working for getting tsc and apic frequencies now

#

which means i can keep putting off apic timer calibration

last pebble
haughty cipher
#

(msrs is for hyperv. can use cpuid to get the frequency under kvm, at least with qemu. not sure if raw kvm does the cpuid leaf)

haughty cipher
#

also did do some tweaks to how devices and irps are structured thatll hopefully help make this slightly more sane lmao

#

its a lot closer to the NT kernel device model now actually, albeit with the benefit of not overloading terms like they do

#

the new scheme is:

  • theres a global tree of struct Device
  • each Device has one root Function and zero or more leaf Functions
  • the root Function of the Device is installed by the bus driver which discovered the device
  • all other Functions have a Driver and a parent Function, which chain must eventually terminate at the root Function
  • a Driver has an attach function which takes a Device and returns bool. if attach returns true, the Driver has installed Function(s) in the device's function tree
  • a Driver has a dispatch function which takes an Irp
  • an Irp has a stack of Entries, and each Entry has an associated Function and Operation (a bigass union of different methods and parameters a device can have)
  • a Driver's dispatch function peeks the top Entry of the Irp and attempts to perform the specified Operation on the attached device Function, possibly pushing a new Entry to the Irp to dispatch to a lower level device
  • when dispatch returns, the caller can peek the top Entry to check its status
  • if/when an Entry is completed, the caller or callback can pop the Entry to get the result and do whatever with it
#

as an example chain, a filesystem function would be on top of a volume io function, which could either be virtual (for spanning multiple disks) or on top of a disk partition function, and the disk partition would be on a device having the actual disk as a parent etc

#

or as a lower level example, a device on the pci bus with acpi provided methods additionally would have a root acpi or pci function with the other on top of it, and the actual driver would be on top of that. the top driver could ask to enumerate some generic property of the device and whichever of the pci and acpi drivers can provide that property then answers

#

each function can be containerof'd to get a driver-specific structure with bonus stuff on it also

#

(also while what i described is the theory, in practice i expect to keep the leaf functions and the bus functions on separate lists where each leaf gets a singly linked list and if it has no parent then the function to get parent will return the head of the bus list)

#

i learned about containerof/@fieldParentPtr in may 2024 and just fuckin never looked back lmao

#

im also considering giving each device node an attached buffer to allocate Functions from, make freeing the whole mess easier

#

(also open to alternative names to Function, but i didnt want to call them devices because NT does that and it makes it so confusing when device nodes also exist at the same time)

haughty cipher
#

out here implementing the for_each_node myself in zig because roundtripping through a callback nukes zig's error tracing etc but i dont want to use a ton of stack with recursion lmao

#

anyway

#

wonder how badly this will die if i try to do it on aarch64 without changing anything lmao

#

not. the answer is it does not die

#

fuckin hell yeah

#

I do NOT recognize most of these device ids lmao

#

do recognize ACPI0007 though, thats the processor object

#

and im going to guess ADMH0011 is a PL011 uart based on the id and name being COM0

#

apparently LNRO0005 is virtio-iommu

haughty cipher
#

anyway next up is to figure out how im going to do generic pnp property storage and then once thats done ill be able to cram the last few bits i need from acpi enumeration into this and get started on pci enumeration

#

and then ill add a noop driver for processor objects/acpi processor devices and then ill be fully caught up to pre-rewrite imaginarium

#

never know what to do when the code just works first try lmao

#

the old version had a processor driver and a pci enumerator/bus driver; the new version has timer interrupts, a real slab, aarch64 support, and uefi runtime services

#

everything else both have

haughty cipher
#
fn recurse(drv: *Driver, root: *Device, gpa: std.mem.Allocator, root_node: *ns.NamespaceNode) !void {
    var iter: ?*ns.NamespaceNode = null;
    var parent = root;
    var parent_node: *ns.NamespaceNode = root_node;
    var depth: u32 = 1;
    while (depth > 0) {
        if (try ns.node_next_typed(parent_node, &iter, .initMany(&.{ .device, .processor }))) |node| {
            parent = try descend(drv, parent, gpa, node);
            depth += 1;
            parent_node = node;
            iter = null;
        } else {
            iter = parent_node;
            parent_node = parent_node.get_parent() orelse break;
            depth -= 1;
        }
    }
}

yknow maybe i shouldnt call it recurse anymore, given its no longer recursive

#

though there is an (easily fixed) bug here actually that i just noticed

#

i think ill also make a function to print out the devie tree at some point

last pebble
peak oriole
haughty cipher
haughty cipher
#

idk how much dev ill do today but the plan if i do is to:
a) fix the bug i found late last night after id already shut down
b) maybe print the device tree to console

haughty cipher
#

i really got to make hashing the kernel not the default or at least make a way to turn it off, it takes longer than all other build steps combined using my shitty tool lmao

haughty cipher
#

ok for acpi-only enumeration this looks fairly reasonable to me

#

also looks reasonable on aarch64

#

ignore that integer overflow idk why thats happening though it is happening on both arches at least?

haughty cipher
#

set virtio-mmio-transports to 0 and this is so nice

#

im using none of them and doing device discovery i dont need them yet lmao

last pebble
#

Not bad

haughty cipher
#

with PCI

#

(it stores all HIDs and CIDs, just only prints the "primary" one)

#

think ill change which pci cid is picks though, this one isnt useful

#

yeah thats better

#

final output for aarch64 too

#

with this we are tantalizingly close to having full parity with the pre-rewrite version

haughty cipher
#

alright added one more file and we're not officially caught up to pre-rewrite imaginarium 🎉

#

up next: idk

#

maybe ill start fiddling with thread quanta so i can actually make use of the timer interrupt idk

#

maybe resource enumeration for devices and then work on storage or serial? idk

#

other thing coming soon will have to be docs for the io system, because that def needs it

#

(i also might work on my object manager setup too, undecided)

haughty cipher
#

me: yknow i should look into codeberg pages so i can put up the imaginarium docs somewhere
codeberg: gets DDOSd outta nowhere

#

will work on that tomorrow™ sometime

haughty cipher
#

basically only the stuff under docs works rn, apart from source being a link to the repo

haughty cipher
#

i think i found the bug

#

PR'd a one-liner change up to zig and now the api docs are actually fully working

haughty cipher
haughty cipher
#

ok im completely redoing how my device properties are handled lmao

#

didnt actually speed anything up but now property-getting doesnt require going through a full driver chain and allocating an irp and the whole thing lmao

#

instead it requires a lookup in a hashmap which idk if thats better or worse but it feels better structured at least

#

fascinating that q35 is out here giving me a screen, keyboard, mouse, etc but no network by default and ahci 1.0 storage
and virt-acpi for aarch64 is giving no screen keyboard or mouse but a scsi storage controller and an ethernet controller

haughty cipher
#

ok cool the autodocs fix i figured out got merged

haughty cipher
#

me rn about my os

#

btw @last pebble does #1312232715193683988 message look logically correct? id use the callback thing but i lose a lot of zig ergonomics doing that

last pebble
#

I was never good at these recursive things

#

If it works it works I suppose

haughty cipher
#

i basically tried to copy how your for each device method works

#

and it seems to be working?

last pebble
#

Makes sense

haughty cipher
#

well i swapped to doing apic base properly (aka ignore madt use msr) and also made it enable x2apic

#

and now im gp faulting in yield somehow

#

oh nvm

#

its on the EOI in my irq dispatcher

#

apparently either qemu or whpx enforces that you write 0 for eoi but only on x2apic

#

so thats funky

haughty cipher
#

yknow i think something might be incorrect here lmao

#

ok this looks more like it lmao

haughty cipher
#

ok yeah this shouldve been expected lol, but now i know whats making enumeration take as long as it is

#

the numbers are very inconsistent though so im not touching it atm

haughty cipher
#

decided on a whim to configure qemu for an nvme controller behind a pcie-pci bridge and forgot that acpi will enumerate the empty slots lol

haughty cipher
#

(also moved the nvme controller to addr 1 instead of 0 so aarch64 qemu doesnt get mad about it, but this is working there too)

#

(funny enough aarch64 isnt giving all those empty nodes from acpi, dunno why x86_64 is doing it tbh)

haughty cipher
#

woke up today and decided to fix my memory caching shit

#

so now i got mair and pat set up

#

or will have once i finish fixing all the compiler errors my renaming things has introduced and test everything lol

haughty cipher
#

simple thing i did that im quite happy with is i gave each device object an arena

#

used to manage the device's string table, property bag, and functions

haughty cipher
#

was lookin through my ioapic code thanks to talk in #1385970208631427173 and now realised theres an error in my implementation lmao

#

one that ill fix later as part of some refactoring around the same code

haughty cipher
#

so my future self doesnt forget, im currently only adding the 0x10 for the actual redirection table base when the GSI is one of the bottom 32 with possible isa irq redirection applications

haughty cipher
#

gods im sleepy today lmao

haughty cipher
#

anyway fixed that but idk if ive got it in me to actually do the refactor i was considering today

haughty cipher
#

did it anyway

#

ioapics now have methods and also get stored instead of it re-iterating to find them literally every time

haughty cipher
#

not sure how i want to handle empty pci slots tbh

#

like do i want to make acpi not create device objects for ADR-only devices and instead just do some form of lookup table for them so it can attach later above the pci driver?

#

@outer pawn if youre willing to share since i had a hard time figuring this part of the code out, how does reactos's acpi stuff handle that case? where acpi enumerates first and finds a device with just an ADR which then gets filled out by pci later?

outer pawn
#

It ignores it

#

Windows has a table of IDs that make actual PDOs out of. It doesn’t just make PDOs out of everything

haughty cipher
#

so then how does the pci driver attach the acpi functions afterwards for the ones that do exist?

outer pawn
#

Through a private dispatch interface.

It pretty much manually retriggers the parse

#

that’s what windows 11 does right now

haughty cipher
#

ah ok, good to know

outer pawn
#

reactos I cache it right now

#

Mostly because I’m lazy

haughty cipher
#

mood

#

I may do some sort of private dispatch for it tbh

#

thanks for the info

outer pawn
#

yup, I wouldn’t bother mimicking the windows one though, it changes everyday few updates

haughty cipher
#

yeah im not mimicking exactly more looking for the general ideas as inspo

#

not trying to be nt-compatible here just nt-inspired

outer pawn
#

Sounds good, you got it then good luck YoshiThumbsUp

haughty cipher
#

thanks!

#

im going to literally make one of my irp payloads just pass a GUID and an opaque pointer and then return an optional opaque pointer or error, and then drivers can use that for private dispatch extensions

haughty cipher
#

initial version of that typed up so time to test

#

and it panicked

#

to the shock of noone probably

#

fixed the panic and now its page faulting KEKW

haughty cipher
#

and now its sorta but not quite working

#

oh fuck

#

yknow it might help if i actually appending this thing i make to the list it goes in

#

and now it works perfectly

#

lmao

haughty cipher
#

need to double check this is still working on aarch64

#

yup

#

still good

#

this is a nice looking device tree for x86_64

#

and aarch64

haughty cipher
#

next up probably resources but I'm really not sure how I want to handle those

#

probably going to take a bit of a break and ruminate on that

haughty cipher
#

ok so the initial thoughts:

  • device provides EITHER fixed resources or sets of alternatives for possible resources
    • todo look into how acpi PRS works because i dont understand it yet
  • if its mixed fixed and possible then the fixed ones are just a set with only one alternative
  • io manager picks from alternatives to assign resources without conflicts, ideally prefer the default setup in PRS if applicable
  • we only use consumer resources from acpi? im still not 100% on how producer/consumer resources work in acpi
  • PCI BARs and MSIs count as resources
  • because of the way i changed the ADR stuff earlier, the order of acpi vs pci resources is always fixed
    • therefore, device drivers can rely on resources always being in a fixed order
haughty cipher
#

@last pebble so you happen to understand how PRS works as compared to CRS? because i struggle to understand how its setting alternatives with the same abi

last pebble
#

didnt get the last part

#

but _PRS is just a list of possible alternatives

#

whereas _CRS is the currently set resources

haughty cipher
#

yeah that i get

last pebble
#

are you asking who generates the correct data?

haughty cipher
#

the thing i dont get is e.g. if a device has two irq resources how does it specify two different sets of alternatives there

#

because it cant just do more than two irq resources

last pebble
#

can u show an example of what u mean

#

i still dont get it KEKW

#

an irq resource can accept up to 65k different irqs

#

so it would be one resources with multiple irqs

#

if thats what u mean

haughty cipher
#

i dont have one in ASL which is part of the confusion tbh
but the idea is: my device of whatever kind has two interrupts. in CRS itd put an irq resource for the first one with, say, GSI 36, and an irq resource for the second interrupt with GSI 37. if it wants to say that the first one can be any of GSIs 32-36 and the second can be anything 37-42 how would it do that

#

(in PRS)

last pebble
#

resources are delimited with a different resource type

haughty cipher
#

so itd put something else in between the two interrupts then?

last pebble
#

lemme find an example

#

describes a group of resources which must be selected together

haughty cipher
#

so at the root level of PRS each entry is an alternative and start/end dependent make groups of resources interpreted as a unit then?

last pebble
#

yep

haughty cipher
#

is the interrupt list in the irq resource a list of options or a list of separate interrupts?

#

because if each in the list is an option for that interrupt then suddenly this is making more sense lol

last pebble
#

Some examples from real hw:

last pebble
#

if it wanted to specify exactly what you mentioned it would have to generate every combination

#

at least if i understand it correctly

#

could be wrong

haughty cipher
last pebble
#

guess so

haughty cipher
#

that sounds so wrong but ig lol

#

we're wrong there

#

"To specify multiple interrupt numbers, this descriptor allows vendors to list an array of possible interrupt numbers, any one of which can be used." .... "Interrupt Table Length: Indicates the number of interrupt numbers that follow. When this descriptor is returned from _CRS, or when OSPM passes this descriptor to _SRS, this field must be set to 1."

last pebble
#

oh cool then

haughty cipher
#

the basic irq descriptor is way more vague about it

last pebble
#

cant find the place in linux source where it checks that but w/e

#

cant be assed

haughty cipher
#

mood

last pebble
#

but yeah thats the only option that makes remote sense

haughty cipher
#

yeah

last pebble
#

heres an example

#

link->irq.possible_count++;

#

i guess yes

haughty cipher
#

cool

#

ok now that i understand this time to actually figure out some dang data structures for my kernel side lmao

haughty cipher
#

well pulled in my avl tree from the pre-rewrite because ill need it if i plan to actually check resource collisions

#

and surprisingly after fixing the compiler errors resulting from the breaking changes to zig since i wrote it it still passes tests

haughty cipher
#

here goes nothin

#

and by nothin i mean waiting five years for llvm to emit it

polar pilot
#

come on, it's not taking THAT long

#

did it work?

haughty cipher
polar pilot
haughty cipher
polar pilot
#

i kinda want to do something similar to what you're doing now lol

#

the nt like driver/io model seems really nice

haughty cipher
#

it slaps

#

i do have some nits but the overall design is excellent

#

um you drunk mate

polar pilot
#

lmfao

#

how did that even happen

haughty cipher
#

i was forgetting to initialize the union

#

but idk why it output like that lmao

#

pci root port acpi resources, we poppin off now

polar pilot
#

that is awesome

haughty cipher
#

its actually slightly wrong because i dont really want to enumerate produced resources like the bus numbers there

#

in general tho

#

and now that thats fixed

#

one of my favorite functions in zig continues to be ArrayList.shrinkRetainingCapacity

#

its great for printing shit to an arraylist buffer and then freeing the space without resizing the list if the followup to the print fails

#

did forget somethin though that i gotta fix rq

#

which is that its not enumerating properly for stuff that doesnt get accepted by a high level driver

#

oh welp

#

did that change and now its gp faulting lmao

#

well theres youre problem

polar pilot
#

yeah that could cause some problems

haughty cipher
#

ok the freeing of the setup resources is causing memory corruption of some sort

#

and i dont know why

#

i hate diagnosing memory corruption 😭

haughty cipher
#

ok i think this is an uncaught use-after-free

#

this is going to destroy me

#

gonna give up for the night shortly lol

#

one last attempt

#

going to swap this function to use the debug allocator in std and see if that complains

#

oh fuck

#

i think i found it

#

nope

#

fuckin bedge time

#

i aint looking at it until tomorrow earliest and honestly even then idk givne im coming down with a cold lmao

#

and i know it isnt the allocator because im currently bypassing the allocator to use the debug one in the zig std

haughty cipher
#

yup definitely got a cold

haughty cipher
#

oh god the memory corruption bug was so fuckin stupid lmao

#

and i still dont entirely understand it tbqh

#

but it is fixed now

#

the pattern wasnt what i thought it was which really didnt help

#

i thought it was that it was failing for things with resources that had no driver to attach to

#

in reality, it was failing on things enumerated from the nested private dispatch from the pci enumeration

#

and the first device with no driver yet that had resources was one from the nested dispatch

#

theres some confusion still because the thing that finally fixed it was making it pass the allocator through IRPs but the irp was hardcoding to the same allocator as the other side was using before so that should only have been an issue with using the debug one and shouldnt have fixed anything by changing

#

but it somehow did

#

either that or that different-allocators error was masking my accidentally fixing the original issue? idk

#

anyway now that its working im quite happy with it lmaoooo

#

(i was already happy with the design it was just broken af earlier)

haughty cipher
#

ok lets see if aarch64 kills it

#

nope! it actually still works on aarch64!

haughty cipher
#

continue to be shocked every time i get something working on one arch and it suddenly works on the other one lmao

#

anyone happen to know how either windows or linux handle pci interrupt link devices?

#

im really not sure what i want to do with them

last pebble
#

I sent u code with srs for it yesterday I think

haughty cipher
#

oh lmao i was so focused on the irq resource bit i didnt notice what device it was

#

tbh im generally more curious about how nt does it atm because my driver/device model is much more similar to theirs, but still good to have the linux version

haughty cipher
#

should probably redo some of the docs for io stuff since ive made a bunch of changes but too much feeling sick rn to do that

haughty cipher
#

other next thing fwiw is pci BARs

#

and then maybe eventually ill get actual resource assignment instead of just using whatever the firmware gives me

haughty cipher
#

qemu out here being weird with its aml again

#

instead of using the 0-for-namepath version for the PRT in apic mode, it uses a whole second pci interrupt link device instead

haughty cipher
#

ok i think i know how i want to handle PRT stuff but not 100% sure

haughty cipher
#

anyway first BAR time

haughty cipher
#

bar enumeration done, forgot to post somethin here about it earlier lol

haughty cipher
#

part of me isnt sure whether i want to leave the pci/acpi backchannel as a private backchannel or make it public. gonna document it either way though because this is an open source to try and learn with not undocumented enterprise hell lmao

haughty cipher
#

more sick today than yesterday but still might get some osdev work done

haughty cipher
#

also updated docs

#

wild that im too sick to do osdev so i fall back on fuckin webdev of all things as something im capable of still

polar pilot
#

did you mean to type –? :^)

haughty cipher
polar pilot
#

although i don't see why you'd place a dash there

#

also capitalize Zig programming language maybe, idk 🙏

#

very cool that you've set up a blog, i like reading stuff like that

haughty cipher
#

ye me too, thats why i made it lol

haughty cipher
haughty cipher
polar pilot
#

ah no sorry, it makes sense now

#

i was confused by the semicolon after the html entity

haughty cipher
#

yeah it makes more sense when its actually a dash lol

#

ah yeah the semi always throws me off reading them too

#

(except the actual autodocs wasm/js which is part of zig and output by the compiler because of a flag ive set, along with a tarball of the sources)

#

also worth noting that home and about have nothing on them yet so theyre just the contents of the template for the ssg im using, but devlog and docs are fully set up (apart from sparse content in the former case) and the source link works

haughty cipher
#

its automatically set up so the devlog link at the top goes to the newest quarterly page and newer posts are put up top, with the left side nav sorted by date newest to oldest

#

unrelated, i love StringIndexContext/StringIndexAdapter in zig

#

its two types that i think are mainly for use for the compiler but are in the std so i can use em too

#

what they do is provide functionality to make a hashset/hashmap with u32 keys act like a set/map of strings, where the strings are stored in an arraylist

#

so i can call getOrPutContextAdapted on the hashmap with a string key and itll tell me if that string is already in the table but its only actually storing indices into the arraylist in the map

#

lets you just store 4 bytes to refer to a string while having O(1) access to the actual string bytes and it keeps the strings contiguous in memory and allows resizing the string byte array without invalidating all the u32s

haughty cipher
#

i may rework the device properties stuff to have a single string table instead of 2.5

#

one think i definitely need to figure out and write is an RWLock

#

or whatever variant name you wanna use for it

#

a threaded one that is, not an rwspinlock i already got one of those

#

that and condition variables would be good to have i think

haughty cipher
#

yeah i think ill do the string table change

haughty cipher
#

im still so happy just to be seeing this output lol

last pebble
#

looks pretty good

#

would u like uacpi to automatically strip trailing _?

haughty cipher
#

nope, dont really mind it tbh

last pebble
#

i was thinking of doing that since its considered redundant technically

haughty cipher
#

i wouldnt mind either way tbh

#

the path is here purely as an informative thing, not to actually be used for anything too too important - the acpi driver keeps a pointer to the namespace_node with each kernel device object

last pebble
#

fair

haughty cipher
#

oh for completeness, aarch64 output

last pebble
#

find() already accepts either option but generate does the full thing

haughty cipher
#

cool

last pebble
#

lol qemu gives _SB some sort of a hid?

#

never seen that before

haughty cipher
#

no

#

thats manual

last pebble
#

oh

#

what is that hid?

haughty cipher
#

same one NT hardcodes for it

last pebble
#

oh

#

interesting

haughty cipher
#

though idk if NT actually associates it with the _SB namespace object but i figured that makes sense

last pebble
#

where did u see that id then?

haughty cipher
last pebble
#

oh interesting

#

theres probably a way to find out which node its talking about

haughty cipher
#

my tree is almost identical to the NT one if you go to device manager on any nt-based system and do view->devices by connection

last pebble
#

is there a chance your aml actually has that id somewhere?

haughty cipher
#

if i go to the PCI root complex the path is there for it

last pebble
#

hm

haughty cipher
#

theres actually a bunch of devices under PCI0 on this system that are hardcoded to return 0 for STA but do have that HID lmao

#

but no hid on the root _SB

#

afaik this HID is hardcoded

last pebble
#

i dont have the same thing as u

haughty cipher
#

the default view groups by kind

last pebble
#

oh yeah

#

i see it

haughty cipher
#

the one labeled "ACPI x64-based PC" corresponds to me ACPI_HAL device, the one labeled "Microsoft ACPI-Compliant System" corresponds to my PNP0C08 and you can confirm that yours matches that HID

last pebble
#

yeah it does

haughty cipher
#

my ACPI_HAL also matches the HID of the corresponding one on NT fwiw

last pebble
#

but i also have an amd pc so its not a good test KEKW

haughty cipher
#

lol

#

hang on my laptop is intel ill check there

#

well the HIDs all match i know that

#

but idk if the node path is in the system board device on it

last pebble
#

is your mobo asus?

haughty cipher
#

my desktop is MSI mobo, my laptop is dell all the way

last pebble
#

ah

#

TIL SBRG is the isa bus

#

ive seen it so many times

haughty cipher
#

mhm

#

that devices by connection menu is like 99% of why i ended up taking inspo from NT's device model for this kernel lmao

#

because that view is so clear and also exactly how id intuitively want to structure things

#

i might give uefi runtime services a driver which would match that uefi-compliant system thing but idk

#

undecided

last pebble
#

a lot of hw actually has it

haughty cipher
#

my desktop has 9 of these

haughty cipher
last pebble
#

yeah i found the same pattern

#

_STA always returning 0

#

wtf are they doing there

haughty cipher
#

no goddamn clue lmao

last pebble
#

are they stealing bs code from each other

haughty cipher
#

lmao probably

last pebble
#

like its literally dead weight

#

since its just sta 0

haughty cipher
#

yep

last pebble
#
$ git grep PNP0C08 | sort -u | wc -l
163
#

like one third

#

or actually wait, this is a crappy query

#
infy@DESKTOP-IGT40G0:/mnt/d/uACPI/tests/acpi-dumps$ git grep -l PNP0C08 | sort -u | wc -l
163
infy@DESKTOP-IGT40G0:/mnt/d/uACPI/tests/acpi-dumps$ git grep -l DefinitionBlock | sort -u | wc -l
783

Yeah this is more like it

#

163/783

haughty cipher
#

mhm

last pebble
#

so its relatively common I guess, although usually just weird dead code

haughty cipher
#

yeah

haughty cipher
#

wrote an extremely tentative rwlock but dont have time or energy to make code actually use it lmao

#

its upgradable and reentrant too, which are nice for an rwlock

haughty cipher
#

(it stores the state of being either a reader or a writer and has two queues. reader state stores the number of readers and writer state stores the writer's threadid and a depth. if the lock is taken for writing and the thread matches than any lock or upgrade increases depth. upgrade when the lock is shared succeeds if theres one reader and otherwise drops the read and enters the write queue. downgrade and unlock for writing decrease depth but downgrade sets share count to 1 if depth hits 0 whereas unlock sets share count to 0, and both then free everything in the read queue. if unlock would set depth or share count to 0 it tries to signal a writer before releasing the readers. lock for writing succeeds if share count is 0 and lock for reading succeeds if its in reading state at all)

#

the downside with that rwlock setup is that the sequence read() read() upgrade() will deadlock

#

but e.g. read() upgrade() read() is fine and uses the write reentrancy

haughty cipher
#

might keep working on non-coding os projects today if anything

#

still sick

#

i kinda wanna make a logo for the project

#

somethin i can put on the website and also use a splash screen in the far future when i get the os doin graphical stuff

haughty cipher
#

and officially got a logo now, based on editing some clipart lmao

haughty cipher
#

not really been as productive on the actual os last few days as id like because of being sick (but also simultaneously more productive on that than expected tbh) but at least i got some periphery stuff like the site going at this point

placid swallow
#

and the blog is cool

#

I just realized the logo isnt meant to be a computer with a face

haughty cipher
haughty cipher
#

updated my dep versions today and then spent all day trying to debug them instead of actually working on my kernel lmao

#

otoh the newest qemu published version no longer needs my whpx workaround

#

so im gonna swap that to be default not used

haughty cipher
#

yknow what

#

i might work on vfs next

#

been trying to avoid it for a hot minute now

#

but maybe i should actualy work on it sometime lmao

#

i do already have sorta a plan for layout at least

#

which is that im using nt-style object paths internally, therell be a root file system using some complex fs (probably something custom tbh), and a boot partition using fat (not necessarily the ESP)

#

kernel will get told by the bootloader the partition uuid it booted from

#

and then it can load an fstab from the boot partition, and maybe some other stuff too

#

(could also do a tar initramfs since zigs got a tar reader that works in-memory but idk i lean a bit away from using that)

#

the boot partition and root partition will be put at some fixed object paths as volume objects

#

and also the boot partition will generally be mounted at /boot on the root partition, but that isnt actually a requirement

#

actually to be extra specific: all volumes have a uuid derived from the filesystem and/or the raw disk(s) the volume encompasses. they are then put at /?/volumes/{uuid}. the root and boot partitions get named symlinks to those volume objects. volume objects are able to override object resolution, where they get given a subpath and create a file object with the joined path as its name

#

normal filesystem syscalls will take file paths which are then converted into object paths by prepending the root filesystem name

#

file paths are a null terminated byte array with some reasonably large but fixed maximum length and the only restriction is that a path must not start with /?/ (using the basic unicode values for those characters)

#

though tbh i probably dont even need that restriction

#

oh yeah no dont need that one

#

so file paths are just 0-terminated sequences of non-0 bytes

#

as are object paths

#

with one extra feature: a non-absolute object path evaluated with no explicit parent is evaluated relative to the object /?. this allows creating global shortname aliases for things

#

its like the PATH env var but for objects and hardcoded

#

if this sounds familiar it probably should, this is by far the most nt-inspired part of the os

toxic iris
#

How are there 3.5k messages here if you're basically the only one talking

#

💀

haughty cipher
#

i ramble a lot

toxic iris
haughty cipher
#

accurate

haughty cipher
#

(well ok its more involved than that but there is an object /GLOBAL??/C: (note the trailing colon) that is a symlink to the os partition)

kindred isle
#

hey i have a few questions about zig osdev hmmCat

#

ive always been a bit inrerested in the language

haughty cipher
#

go ahead and ask em

kindred isle
#

how does the stdlib get used in freestanding?

#

i know in rust osdev you can get things ported there?

#

eg like btrees etc if you get an allocator etc

haughty cipher
#

zig has two big things going for it on that front

#
  1. allocator is a type you can make one and pass it around
  2. the compiler is so lazy about compiling shit in that if you never call a function that uses the os it literally wont be compiled lmao
#

legit the only part of std i cant use rn is the IO part and theres literally an open pr to allow overriding the like 3 types id need to do to get even the working

kindred isle
#

would IO be printf etc?

haughty cipher
#

file io

kindred isle
#

ahh

haughty cipher
#

i mean the stdin/out/err counts for that too but the print function is a function on writer not a global so i just make my own writer implementation and use it there

kindred isle
#

this part of me reading the samples intrested me alot

kindred isle
#

and i presume i can just import say flanterm and implement that right there etc?

haughty cipher
#

yeah you can import c libraries, thats how i use uacpi

#

and the less c headers they need the better, zig doesnt import any libc

kindred isle
#

so it shouldnt be too bad to get to started?

haughty cipher
#

theres also a build system step that translates c headers into a zig module with externs thats basically bindgen

kindred isle
#

how does using zig in userspace work for poirting to a kernel

haughty cipher
#

yeah i didnt find it hard at all to start

kindred isle
#

like eg if i wanted my full stack to be in zig

#

would it just need a libc?

haughty cipher
kindred isle
#

wait so you get a free heap with a PMM?

#

(and VMM/VMA for >4kb)

haughty cipher
# kindred isle would it just need a libc?

you could go with a libc for it, or you could write your own zig os layer too, the pr i mentioned that will let you use the std file io stuff but even without that you can just have people call your functions instead (thats what @hoary aurora is doing with ashet - sorry for the ping mate - but hes got userspace programs in zig for his zig os working)

haughty cipher
#

thats how the first version of imaginarium worked, i wrote a buddy allocator and then plugged it in the backend of the DebugAllocator and got free allocation for literally all object sizes with leak, double free, invalid free, etc protection

#

(well i started with a stack of free lists that could allocate like a buddy but not merge, and then i decided fuck that i dont want it to fragment and wrote a buddy allocator)

#

when i was having memory corruption on my current kernel i swapped the functions causing issues over to use a debugallocator and it caught the problem (even if it took me like two days to understand what it was telling me because i had made a wrong assumption)

#

oh also because zig has no libc dependency (unless you want to link libc), it has full dwarf cfi unwinding in the std, so if you override like three files you get stack traces with source locations and symbol names on freestanding

kindred isle
#

or yeah an os layer

haughty cipher
#

yeah

kindred isle
#

i honestly should consider doing a kernel in zig. i want to make a buddy allocator and getting a free heap is nice

haughty cipher
#

if you link libc then i think most io stuff would call into that but not 100% sure, but yeah even without that you can just write your own layer because if you dont call the std stuff it doesnt get compiled

kindred isle
#

honestly zig looks pretty damn cool

haughty cipher
#

ye its great

kindred isle
#

im gonna try and fix up my kernel still. if SMP ends up messing me up or other things i may switch

#

how does zig handle with smp btw? and other things like macros etc

haughty cipher
#

(when i say override, zig has a thing where if you @import("root") that points to the main root file of the compilation, so a bunch of places in std do checks of if root has this thing as a declaration use that otherwise use the default std version)

haughty cipher
#

comptime is basically certain things (default values of globals are the big one but you can mark a block as comptime to force it other places) are interpreted by the compiler as if its an interpreted language with a branch limit (to prevent infinite looping)

#

and then the result is used for the actual compiling the rest of it

#

so instead of macros you get shit that looks like normal code

kindred isle
haughty cipher
#

but runs at compile time

kindred isle
haughty cipher
#

one of the big uses of comptime though is to replace the #if on target stuff in std, which is part of why some of the os-independence of it works

kindred isle
#

hmm neat

kindred isle
#

and snprintf was a horrible monstreisty

haughty cipher
#

so in that case in your dbgstub if you made it an inline function in zig, the width would get inlined and then the branch on it would get chosen ahead of time

kindred isle
haughty cipher
haughty cipher
#

tho that one is little endian

kindred isle
#

is there a bultin hex to int?

kindred isle
#

and to do the reverse on recv

haughty cipher
#

parseInt or parseUnsigned (if you want to ignore the sign) in that namespace. for the little endian recv you probably want to do hexToBytes in that namespace and then call std.mem.readInt (or you can actually @bitCast the returned array from hexToBytes into an integer if youre on an LE system)

kindred isle
haughty cipher
#

that too

kindred isle
#

how does zig handle compiler inteinics btw?

haughty cipher
#

we got builtins, anything that starts with an @ is a builtin

kindred isle
#

do they have less stuff where i need to make manual things with outb/inb?

haughty cipher
#

so for byteswap youd use @byteswap

haughty cipher
kindred isle
#

ahh darn

#

i did hear the inline asm was good

#

you shill that alot

haughty cipher
#

the inline asm is just normal c inline asm, but the asterisk is that the string it accepts is a comptime known string rather than a literal string

#

so you can use comptime to generate the asm string

kindred isle
#

yo what

#

like huh

kindred isle
#

what the lol

#

ih wait

haughty cipher
#

the first bit is a block at comptime that iterates the fields of the interrupt frame GPRs sub-struct and generates two strings from it, one pushes the register and one pops it

kindred isle
#

is this like macros?

haughty cipher
#

but in the right orders automatically for whatever gpr fields i put in the type

#

kinda yeah

#

but written like normal code

kindred isle
#

also why save these if i may ask?

#

also your missing CR8 /hj

haughty cipher
#

debug printing lmao

kindred isle
#

ah

#

💀

#

my panic just grabs within its self instead of pushing it onto the frame

haughty cipher
#

i dont need em for 99% of things but when something goes wrong i want to see the values in my unhandled interrupt panic

#

yeah i could do that tbh

#

and may someday

#

i was basing what i had on what qemu's -d int output prints lmao

kindred isle
#

my talk is cheap and il send patches tro

#

this is what my panic screen looks like

#

i get alot of stuff dumped with a normal stack frame lol

#

even nornal panic() calls get some stuff dumped

haughty cipher
#

my panic handler (theres a @panic builtin but it goes through a set panic handler that also has functions for a bunch of different kinds of safe-mode assertions like out of bounds etc, theres a premade default with messages that all get sent to a regular panic handler that you provide that i use) actually does a stack unwind and prints the panic stack too

#

as does yours

kindred isle
#

oh nice nice

#

@panic seems nice lol

#

i need to do DWARF at some point

#

or atleast generate my symboles better 💀

#

my make debug compiles the entire thing twice

#

once forn symbols

#

the second to cimpile them in

haughty cipher
#

theres also std.debug.panic which is like @panic but it takes a format string and args instead of a comptime string so you can format your panics

#

provide extra info like the faulting address for example using your case there

#

for debug symbols in zig i just had to set strip=false in the build system

#

and then limine (or now my bootloader since i swapped) gives me the kernel file as a blob, and i use std's dwarf parsing to load it from there

#

the part i had to override for debug was the part that tries to load the bin file from the file system which would compile error on freestanding, but because i dont touch that filesystem stuff now it works

#

does allocate a fuckton of memory though, the std debug info is not memory efficient lmao

#

had to up the max block size in my page allocator to make it happy on full debug -O0 builds

#

and it was borderline on my normal releasesafe

#

in any case if you ever got more zig osdev questions feel free to ask lol

#

ill do my best to answer

kindred isle
#

possibly more general for zig lmfao

#

but thats if i start such a rewrite

#

I do wonder

haughty cipher
#

i can also try to help answer those

kindred isle
#

Could I mix and match it

#

And just use zig for dwarf

haughty cipher
#

maybe? id copy @last pebble's cfi unwinding if youre already in mostly C land though

#

from #1385970208631427173

kindred isle
#

true

#

but i could infect more of it with zig etc

#

and like ease it in etc

#

for some stuff i may not be compfy to make in zig etc etc

kindred isle
#

💀

#

that CR8

#

it shows a bitfield

#

it should never have a total value of 1

hoary aurora
#

@kindred isle on your question regarding printf:

zig has a really good print and logginh that doesn't need io at all

haughty cipher
#

yep

#

just declare a logfn

#

and whatever uses std log will call that

kindred isle
haughty cipher
#

yep

kindred isle
#

Huh neat

#

Yeah maybe I should replace some of my kernel with zig

#

I quite hate making stdlib shit

kindred isle
#

Wow that looks pretty simple lol

haughty cipher
kindred isle
haughty cipher
#

and the log fn just uses that

kindred isle
#

It’s that it got set to 1

haughty cipher
#

yeah uh a TPR of 1 aint right

#

a tpr of 0x10 is more right

kindred isle
#

Or 2

haughty cipher
#

iirc how it works anyway i think its that second nibble that matters

kindred isle
#

TPR on x86 is in chunks of 16

#

An TPR of 2 means nothing from 0x20 to 0x2F

#

3 is 0x20 to 0x3f masked

#

Etc etc

haughty cipher
#

yep

#

aarch64 is sorta the same except you can have anywhere from 4 to 7 bits of it

#

and its backwards

#

so 00 is all masked and FF is all unmasked

#

the shift is the same though, the extra bits is just which lower ones are allowed to be nonzero

kindred isle
#

oh dang

#

thats neat

#

i wonder hiw riscv is

haughty cipher
#

(and technically if youre in secure mode instead of nonsecure mode its 5-8 bits, with the nonsecure version mapped to one bit lower, so secure mode interrupts get higher priority with their own half of the range)

hoary aurora
#

@haughty cipher i wonder how convinced @kindred isle is when she sees the packed struct.

haughty cipher
#

so you know bitfields in c?

#

zig has those as a first-class language feature with packed structs

#

and theyre a lot better defined than c bitfields

kindred isle
#

Yes. I use them. I say fuck it we ball I don’t care if the compiler fucks it up lmao

haughty cipher
#

yeah with zig they have very well-defined semantics so that isnt a worry generally

kindred isle
#

Oh I deal with it by ignoring it mmLol

haughty cipher
#

lmao

kindred isle
#

I use clangs over loadable functions anyways

#

So you kind of have to use clang to even build my kernel

#

So it works out in the end mmLol

haughty cipher
#

...whats an over loadable function?

kindred isle
haughty cipher
#

oh overloading

#

im so not used to seeing that as two words lmao

kindred isle
#

i love it for stuff like this

#

to provide defaults etc

haughty cipher
#

heres my idt packed struct for a decent example of em

#

and then selector itself is a packed struct too

hoary aurora
# kindred isle 👀
const What = packed struct (u23) {
  lsb: bool,
  mode: enum(u2) {yes, no, cancel, retry  },
  payload: i19,
  msb: u1,
};
kindred isle
#

Wait

#

How does that enum work

#

👀

haughty cipher
#

bitint-backed enums in em is my favorite thing tbh

#

you get to pick what the backing integer is for an enum

#

and it can be a bitint

kindred isle
#

That could make certain semantics fucking clean

haughty cipher
#

and then you can use em in packed structs like that

#

i love em for u1s even, when theres two options but neither one really fits onto true or false

#

stuff like gdt vs idt in a segment selector, or edge vs level in ioapic stuff

#

my memory cache typing is an enum backed by u3

hoary aurora
kindred isle
#

:O

haughty cipher
#

oh lemme go find my good packed unions

kindred isle
#

pakced union

haughty cipher
#

heres one

#

small in there

#

but its either a u36 or that other packed struct with the pat flag for large pages

#

im currently rebuilding zig itself in debug mode to try and track down something i noticed when i did that on a different platform the other day that alex (of the zig compiler team) couldnt reproduce because my build system didnt work on linux at the time lmao so i got plenty of time to find neat codebase things lmao

hoary aurora
haughty cipher
#

ok this one doesnt fit onto a full shot becuase of all the functions but at the top it says packed union

#

for the PCI BARs

#

in this case

kindred isle
#

what the

haughty cipher
#

heres how i define cr3

#

which is probably the best example for making it clear how packed unions work

kindred isle
#

what does packing a union do?

#

basicaly removes standard padding?

haughty cipher
#

packed in zig means bitfields/bitints

#

theres a proposal to rename it to bitpacked that got accepted but hasnt been implemented yet afaik

kindred isle
#

so i dont think id have that under CR3

haughty cipher
#

so a packed union(u12) is a union but 12 bits long, and you can use it like any other bit thing

kindred isle
haughty cipher
haughty cipher
kindred isle
#

so the bottom or top bits get cut off?

#

or wait

#

mind hurt

#

😭

haughty cipher
#

well no you assign a u51 bit int to it

#

so theres no extra bits

kindred isle
#

this is why id just CR3 |= PCID

kindred isle
haughty cipher
#

one of my most common uses for packed unions is actually to have one union field be the raw int and the other be a packed struct so i can use masking instead for efficiency™ though tbh the compiler might handle that case for me anyway

kindred isle
haughty cipher
#

oh heres another packed union that i use for the abstracted version of PTEs

haughty cipher
kindred isle
#

makes sense

haughty cipher
#

validpte being an alias for the arch-specific pte type

#

the only union fields for this packed union i actually use so far are valid and list though

haughty cipher
# kindred isle makes sense

i think the compiler will optimize cr3.base = phys >> 12 into a mask off and or but im not 100% certain lmao; also just out of frame below that shot of the cr3 packed struct are these functions lmaoo

#

i dont think i actually use them anymore tho

haughty cipher
#

i will someday™

#

i dont have any uses of that sorta thing in the hot path atm

#

oh heres a fun packed union from my bootloader i forgot about

toxic iris
haughty cipher
#

thats llvm not clang but yeah

toxic iris
haughty cipher
#

clang is just the frontend

kindred isle
#

well compared to GCC you know what i mean

toxic iris
#

rust llvm is pretty crappy tbh

kindred isle
toxic iris
#

There's none trl

#

I think so

haughty cipher
#

zigs got ok llvm output but also zig does have a completely self-hosted x86 backend that does the codegen itself

kindred isle
toxic iris
#

The problem with llvm and rust is fucking stack usage

kindred isle
toxic iris
#

Rust overuses the stack

haughty cipher
#

its just that the zig self-hosted x86 backend doesnt fully handle linker scripts yet and dies horribly if you try to make it use soft floats so its not suitable for osdev yet (it is in early beta)

haughty cipher
kindred isle
haughty cipher
#

but im also a known confirmed rust-hater

kindred isle
#

better than rust tro

#

you should make a guide on a howto for zig osdev when things are more stable

haughty cipher
kindred isle
#

like a mini wiki / yrabslation guide for C kernels

haughty cipher
toxic iris
# kindred isle 500 megabyte stacks

You joke about it but afaik some kernel here had to blow the stack into the megabytes to get rust working because like 128Kb wasn't enough

#

Like what the fuck

haughty cipher
#

if i make zig sound unstable its because im tracking zig master instead of release tags

#

so things break

kindred isle
#

not that its unstable

#

that there is upcoming cool features

haughty cipher
#

oh stable as in not getting breaking changes

#

gotcha

#

yeah zig is still fairly young as a language and getting a decent amount of breaking changes still as things get refined

toxic iris
#

Zig in like 5-10 years will be a decent language

#

For now they're in the feature craze phase

haughty cipher
#

like if you pull a tagged zig version rn the packed struct(u36) is a compile error and if you get zig master rn the packed struct { is a compiler error in some cases

#

yeah zig shows a lotta promise for osdev

#

im just in this for the learning and dont mind chasing breaking changes to try it out

#

theyre going to remove an entire builtin from the language after the next proper version gets tagged apparently lmao

#

(the @cImport builtin is getting nuked in favor of using a build step to do that translation so you get more control over it)

haughty cipher
#

the syntax for cimport was stupid anyway lmao

haughty cipher
#

anyway today might be object manager day if i get enough energy to actually work on shit

kindred isle
haughty cipher
#

ok heres a question for how to do the object manager

#

should the object header be a field of the object

#

or should it be prepended in the allocation

#

former is way easier, latter lets me drop parts of the object header that arent needed

#

to save memory

#

im on 64 bit though

#

so do i need to save that much memory?

#

esp since the objects therell generally be the most of are the ones that need the extra header bits

#

(latter is what windows does)

haughty cipher
#

(please someone give feedback im stumped here)

polar pilot
#

i think the intrusive object header approach is easier to implement as well

#

does the other one have any other advantages?

haughty cipher
#

you can just not allocate the extra memory for e.g. the name if an object wont have one

#

or the memory for the pointer that makes up a handle table, if it isnt accessible in user mode

polar pilot
#

gotcha, i don't think it's that important to save those couple bytes per object

#

unless you really care about memory efficiency down to that level

haughty cipher
#

yeah thats how ive been leaning too, just wasnt ever sure

#

tbh i think windows only does that because it has been since NT 3.51

#

from 1995

polar pilot
#

if you ever run out of things to do you can always revisit that area of the kernel and optimize it :p

haughty cipher
#

true

#

ok intrusive object header it is

#

(oh yeah the other benefit to not using intrusive header is its slightly less convenient for other code to access things about the header it shouldnt. which sounds like a why dont you trust your devs issue to me)

polar pilot
#

true tbh

haughty cipher
#

anyway instead of going too far with that now im currently doing something absolutely insane just to proactively turn a function pointer call into a switch and regular calls lmao

haughty cipher
#

ok time to find out if my bullshit compiles

haughty cipher
#

it compiles im scared

#

its probably ignoring all the bullshit that im not using yet

kindred isle
#

Maybe?

#

Well does it work?

haughty cipher
#

idk yet

#

i need something that implements this function first

kindred isle
#

Also I should ask. How is the LSP support for zig in stuff like KATE?

haughty cipher
#

i think its standard lsp protocol, thats how im using it just not with kate

kindred isle
#

Kate works with clangd so it should be fineee™

haughty cipher
#

if theyd just add @unrollArgumentTuple like ive been wanting then i could get this nonsense to be even more cursed but also kinda cleaner lmao

polar pilot
#

what would that do?

haughty cipher
#

it takes a comptime reference to a function whose last argument is a tuple. and returns a function body object that takes the elements of the tuple and wraps them up to call the function

#

so if i had fn foo(a: A, rest: .{ b: B, c: C, d: D }) R

#

then @unrollArgumentTuple(foo) would be

fn bar(a: A, b: B, c: C, d: D) R {
  return foo(a, .{ b, c, d });
}
#

but without having to type all that out

#

the main use is as an inverse to the existing @call builtin

#

which takes a tuple of arguments and calls the function

#

so you can make a generic wrapper with a generic argument tuple type that calls your inner thing with some processing, and then convert it into a wrapper with a normal function type

haughty cipher
#

zig hashmaps winning again

#

just make a context that uses the object names to hash them and make the object directory a hashset

#

and then i can make a key adapter context and use the xxxAdapted versions of all the functions and pass a fuckin string in

hoary aurora
haughty cipher
#

and it JUST WORKS

haughty cipher
haughty cipher
#

index out of bounds errors all over in the entirely normal boring code lmao

#

alright its working now

#

which is like, invisible mostly

#

but hey

#

something

#

infrastructure moment

#

and its all because of how goated the hash_map impl is in the zig std

haughty cipher
#

ive been informed that theres a number of cases in the zig compiler of AutoArrayHashMap(void, void)

#

which is cursed af but actually pretty useful somehow

#

in that case you use a key adapter context and hold onto the index in the arrayhashmap that you get

#

without ever actually storing anything in the map

haughty cipher
#

randomly decided to make setting BARs work

#

so thats done now

#

kinda boring code tbh

#

and doesnt do anything yet because i dont do proper resource reallocation lmao

#

so rn the resource "allocator" just sets everything to the initial value given and trusts the firmware

haughty cipher
#

added device categorization

#

ill need that for filesystem stuff

haughty cipher
#

sad but unsurprised to find out that qemu apci doesnt use DDN

#

tho actually hang on

#

i mightve made an error here and forgot to do this code somewhere

#

ive gotta refactor this shit

#

nope still nothin

#

oh nvm on aarch64 this is now triggering a panic

#

huh

#

this is weird

#

oh lmao

#

ok thats dumb but funny

haughty cipher
#

its a use-after free when a driver errors during init of a device, should be fixable but for now i just fixed the actual error that was happening instead

#

anyway now i get _DDN and _STR copied into device properties which is nice

#

even if across both of my qemu setups theres exactly one thing that has either (the pci root complex on aarch64 qemu virt-acpi has _STR set)

haughty cipher
#

idk if ive shared this yet but the device categorization stuff i mentioned (also names but theres currently no drivers setting names so only the root dev has one. considered using acpi name but the pci stuff has duplicates there)

kindred isle
haughty cipher
kindred isle
#

and if it ends with a number add a dash

#

and always add a zero even if no duplicated

haughty cipher
#

might just always add the dash KEKW

#

went one further and instead of deduplicating properly i just use a global monotonic value for it

#

and also probably didnt need to but decided to not bother with items that dont have a proper hid/cid anyway

last pebble
#

ACPI also has _UID for things that may appear multiple times

haughty cipher
#

does it use those for nested pci bridges?

#

or pci devices in general?

last pebble
#

Think so

#

For PCI links it should

haughty cipher
#

ie will \_SB_.PCI0.S18_.S00_ have a UID if \_SB_.PCI0.S00_ also exists?

last pebble
#

No its for multiple devices of the same type, not same nameseg

haughty cipher
#

yeah

#

the issue here is dedup by nameseg not by type

last pebble
#

Right

kindred isle
haughty cipher
#

this dash is already bothering me with the _s so im changing it to .

kindred isle
#

it cant be a zig function right

haughty cipher
kindred isle
#

damn

#

would of been cool tho lmfao

haughty cipher
#

i mean zig does have a function for this but its for the specific case of the progress reporting api the build system uses

#

i copied the ideas

#

its actually fairly shrimple

#

well it would be if i didnt decide to manually unrecurse it

#

the idea is to build a prefix in a buffer so you dont need to keep track of all the parents' sibling statuses

haughty cipher
#

anyway did a bunch of fiddling and also pushed up an update to the docs site

#

now i gotta go take my inhaler so i can breathe again and then gonna hang out with my brother since hes over today

kindred isle
#

Btw have you ever heard of 16 byte atomics?

haughty cipher
#

yup

#

I've got a thing that even uses them though I'm not actually using that thing for anything atm

kindred isle
#

I’ve always wanted to do some lockless algorithms with them but never got around with them

#

IIRC you can do a buddy allocator with them

haughty cipher
#

I've got a lockless singly linked list (prepends and pops only so basically a stack) that uses 128 bit cmpxchg

#

fun fact that exact lockless singly linked list is why windows 8 and newer hard requires 128 bit atomics to function

kindred isle
#

Oh dang lol

#

My plan was to use 16 byte atomic

#

And as a fallback use the extra space for a normal lock

haughty cipher
#

mhm

#

the thing with the list is it doesn't actually need 16 byte nodes, just the list itself needs to be 16 byte (nodes do need to be 16 byte aligned though)

#

id share a link to my code but on mobile rn and can't be assed

#

it's called a sequencedlist or slist though if you wanna look it up

#

and if you figure out a lockless buddy allocator using 16 byte atomics I'd love to see that

kindred isle
#

Esp with 16b CAs

#

I think somgody here has already implemented such

#

CC: @round robin

#

You could also get away with tagged pointers given it’s all 4kb aligned? Though I’m not sure how ABA resistant that is on the buddy allocator usage

haughty cipher
#

mhm

#

I wouldn't know how to start actually figuring this out lmao

#

I look at atomic ordering and my brain short circuits

kindred isle
haughty cipher
#

lmao

kindred isle
haughty cipher
#

yeah there's very little difference on x86

#

I'm also targeting aarch64 though and there there is a decent difference

kindred isle
#

Ahhh yeah true

#

x86 port planned?

haughty cipher
#

I'm doing both lmao

kindred isle
#

Oh lmfao

haughty cipher
#

multiple arches forces me to keep the code cleaner and more organized

round robin
round robin
round robin
haughty cipher
#

got links (and licenses) for them? im def interested in seeing how that works

kindred isle
round robin
kindred isle
#

Ahhh

haughty cipher
#

my buddy isnt truly a PMM atm, though i plan to rework that soonish since ill need physically contiguous stuff for the GIC ITS on aarch64

round robin
# kindred isle Ahhh

like comparing heap pointers where equality doesnt mean its really the same object

haughty cipher
#

yep

haughty cipher
round robin
haughty cipher
#

rip

round robin
#

i try to write it down in the next few days

haughty cipher
#

👍 no rush or worries, was more curious than anything

#

im currently only startup on aps on one of the arches i support and dont really have the scheduling infrastructure yet to make full use of aps anyway so making my alloc lockless isnt a priority

#

now as often the case im running into the issue of idk what to work on next on this os

#

anyone got any suggestions?

#

(so far i got acpi tables, an acpi device enumeration driver, timer interrupts, DPCs, a basic-ass round robin scheduler with no preempting yet, a pci bus/bridge driver, an object manager system, and ap startup on x86_64 but not aarch64)

last pebble
#

isnt ap startup on arm just unparking the cores?

round robin
haughty cipher
last pebble
#

ah

haughty cipher
# last pebble ah

theres the super-old no longer supported acpi unpark, a basical mailbox unpark ala how limine does it, and the PSCI SMC/HVC method thats the most common

#

that last one you get told whether to use hypercall or secure-monitor call and theres a predefined hyper/sm-call function that starts a given ap in a defined state at a specific address, with a given value in x0

last pebble
#

no init/startup ipi shitty design nooo

haughty cipher
#

and it returns a status code