#pmOS - microkernel OS for RISC-V, x86, and LoongArch
1 messages · Page 7 of 1
okay but having a pointer itself is fine
yeah
so its also not UB if you do it via C++
its also not ub via rust aiui
still UB to use though
getting a misaligned pointer via casting another pointer in c is also undefined behavior so C++ is a bit looser there
but interesting
huh i have found something even more cursed
The wording in the C standard only applies to object ptr to object ptr casts
int x(int* p, int* q) { return (p+100)-q; }
int z() { int a[4]; return x(a, a); }
``` this is UB in C and rust (in rust if you use a normal add() or offset() but not wrapping_add()) but not in C++
int to object is allowed regardless of alignment
afaict
i found this:
An object pointer can be explicitly converted to an object pointer of a different type.64 When a prvalue v of
object pointer type is converted to the object pointer type “pointer to cv T”, the result is static_cast<cv
T*>(static_cast<cv void*>(v)). [Note: Converting a prvalue of type “pointer to T1” to the type “pointer
to T2” (where T1 and T2 are object types and where the alignment requirements of T2 are no stricter than
those of T1) and back to its original type yields the original pointer value. — end note]
this doesn't explicitly mention it, but the note seems to imply that if T2 is more strictly aligned than T1 the round-trip is not preserved, which would only make sense if getting a misaligned pointer this way is UB/ID
i wonder if it's more explicitly mentioned anywhere
The note is non-normative
It refers to this part of static_cast
If the original pointer value represents the address A of a byte in memory and A does not satisfy the alignment requirement of T, then the resulting pointer value ([basic.compound]) is unspecified.
The wording in the note is more strict than required by static_cast: it is enough that the object is properly aligned, not that the type's alignment is stricter (though the latter implies the former)
ah ok
But it is correct that non-aligned casts between object pointers are not guaranteed to preserve round trips afaict
A compiler would be allowed to zero the alignment bits, for example
only if the type is not a struct, i think
ah maybe not, maybe always
it can't do that for incomplete types, though
hmm
actually what are the semantics on that
No idea
I guess what's more realistic is that if you turn a word ptr into a char ptr and read from it, the compiler is still allowed to generate word sized loads
due to this provision
That's probably the intention
I think llvm is confused again with my assembly...
movl %eax, %eax
Is this not correct?
inline uint32_t io_readl(uint32_t *ptr)
{
uint32_t data;
asm volatile ("movl %1, %k0" : "=a"(data) : "o"(*ptr) : "memory");
return data;
}
inline void io_writel(uint32_t *ptr, uint32_t data)
{
asm volatile("movl %k0, %1" :: "a"(data), "o"(*ptr) : "memory");
}
Nevermind, it does look correct...
what about it
I get a pagefault in this
check ptr for null 
The thing is it's not null
Ok I'm dumb
I'm blaming uACPI's vibes-based types 
I was returning wrong thing in uacpi_kernel_pci_device_open
⚡⚡⚡ vibe driven typing ⚡⚡⚡

wdym
I've registered it to 0x9e000
(which is whatever my PMM decided)
(I'm in a lecture)
This is what I do (there is a lot of stuff missing)
https://gitlab.com/mishakov/pmos/-/blob/dev/devicesd/generic/acpi/acpi.c?ref_type=heads#L318
https://gitlab.com/mishakov/pmos/-/blob/dev/kernel/arch/x86_64/wakeup_vec.S?ref_type=heads
It reaches jmp _64bitst
@hoary moat
(like I'm missing all the stuff to save/restore state of things)
you do know that you need to register wake gpes, right
?
Run a bunch of aml you mean?
Probably...
I need to get back to userspace first
no
before sleeping you need to register GPEs for wake
I haven't done that I think
I'll get to it
Initializing TSS... FAIL
But it makes no sense
Wtf
It just doesn't work
It must be something dumb
Like I just copy-pasted my smp init code, it can't be broken
And tss descriptor is FFFF8000208B018E000068
Initializing TSS... SUCCESS
Now I just need to restore (or rather save it correctly) userspace context (since I'm entering S3 from Ring 3), think about SMP bringup (idk how to expose it to userspace, I think I won't? But cpuidle would be nice to support, though idk if that depends on userspace, but I also wanted to have userspace schedulers...), save/restore ACPI NVS (?) memory (this should be another syscall), and write an interface for drivers to suspend/resume (above all I want ns16550 server for logs)
But like in theory, the kernel should be fully working with one core already
If I remove the panic
The difficulty with SMP bring up is my TLB shootdown code, which is just a bit unsound
Though I should probably also save and restore TSC?
And lapic timer
(though it shouldn't matter)
Yeah, lapic should already be fully working
For IOAPICs I've decided to add a variable which mirrors them, so it should also be trivial
Tsc ticks when in S3 (sometimes
)

If it's invariant?
if it's marked invariant in cpuid it's guaranteed i believe
S is when CPU is off
These are only S0
I'm sure I've heard of some separate TSC_CONSTANT or something. maybe that has something to do with it
The ACPI spec explicitly says (iirc) that S1-5 are different to those 3
$$P, C, T \in S0$$?
david
$$P, C, T \in S0$$?
why are there so many states lol? like there are P substates and the S1...5 states, which ought to be enough™️
P, C, T are for changing CPU frequency while the system is on
S1-5 is when the CPU clock is not on
Idk I've read a nice article about it
Also there are D states 
yeah lol
imo we should make a clearer distinction between the machine state (G0, G1[S1...S5] etc.) and CPU power state (C0...Cn)
I think P is for turbo boost, T is for throttling with PWM, and C is various states of CPU sleeping
Like how much cache is maintained on hlt
What if I ported pmOS to aarch64?
does suspend/resume work reliably?
zased
Ok, I've entered userspace/devicesd server (which runs uACPI) but I now have an issue that the stack is destroyed (kinda as expected) and I need something which could do longjmp in kernel
Explicitly
And at this point I might just implement callbacks in kernel istead of doing it by userspace thread
(basically making a good API for it)
why is the stack destroyed?
memory content is preserved when you wake up from sleep
isn't it?
so the stack should still be there, as long as you know where it is
because the cpu stops working in the middle of a function call
does it matter? if you just free the stack and take off from a different execution point?
should the "sleep" function return back to the caller once the system wakes up?
i guess it depends on the design lol
yeah this seems like a weird problem
just use a different stack when writing to the sleep vector
or that
i guess you could have something like
void sleep() {
event_t wake_event;
create_thread([](void *arg) {
event_t *wake_event = (event_t *)arg;
uacpi_enter_sleep(...);
// ...
}, &wake_event);
wait_for_event(&wake_event);
// we woke up from sleep !!!
}```
that's also how Managarm's idle task works
something liek that would be fun
[[noreturn]] void invoke() override {
runOnStack([] (Continuation) {
if(logIdle)
infoLogger() << "System is idle" << frg::endlog;
suspendSelf();
__builtin_trap();
}, getCpuData()->idleStack.base());
__builtin_trap();
}
but idk how you'd get from waking up back to after uacpi_enter_sleep
you'd switch to a new stack + record the old stack
then program the reset vector to essentially return to the old stack
then write to the sleep register
I'd still advise against doing the reset vector in usermode
that seems incredibly broken
especially since it'll be woken up in kernel mode
waking up in kernel mode and then resuming the thread that initiated the sleep seems like the best idea
with my "event" approach you could also just signal the event from kernel mode
and basically forget about the thread you spun off
assuming you can properly clean up the resources allocated to it
https://gitlab.com/mishakov/pmos/-/blob/dev/devicesd/generic/acpi/acpi.c?ref_type=heads#L332
This syscall is when the registers are saved, I walked it with a debugger, it returns correctly to after syscall instruction, and rets to 0, probably because of other function calls
Surprisingly, I had no problems with kernel stacks
Since I don't store anything on them
I just enter the kernel as normal, and return to userspace
I guess I could wrap it into asm so return address is saved elsewhere
(I'm talking about ret in here https://gitlab.com/mishakov/pmos/-/blob/dev/lib/libc/src/arch/x86_64/syscalls_asm.S?ref_type=heads#L49)
My idle task is just like userspace task, but runnning in ring 0
Sounds cursed
In a bad way?
But yea my main point is that it's possible to handle the situation that you can get killed at any time (e.g. by suspend or exiting the idle task) even in C (no assembly required)
well yes, but make sure it runs on a stack that you can just discard
I think I'll just do longjmp meme
Again, the problem is with userspace stack
Not the kernel
I don't like killing threads
I think the easiest solution would be to do a raw syscall and save the return address to thread-local variables
if you're writing the registers from the kernel, I don't see how the suspend syscalls differs from any other syscall from userspace's perspective
.text
.globl syscall_prepare_sleep
.type syscall_prepare_sleep, @function
syscall_prepare_sleep:
popq %fs:return_addr@tpoff
shlq $8, %rdx
orq $14, %rdx
xchgq %rdx, %rdi
xchgq %rsi, %rdx
movq %rcx, %r10
syscall
jmpq *%fs:return_addr@tpoff
.section .tdata,"awT",@progbits # TLS data section for initialized thread-local data
.align 8 # Ensure proper alignment for a 64-bit variable
return_addr:
.quad 0
it doesn't
Ok, something is trolling me an making syscalls
(My first uneducated guess would be uACPI)

(this is getpid basically)
get_thread_id
Appartently I've been calling it on mutex lock

Big time 
why
Which also means slower uACPI score
I forgor about it
you should cache getpid/gettid/getppid results
and of course clear/re-cache them on fork
I can just use pthread_self
just use mlibc
Does mlibc support library threads?
I have a library thread for signals and process management
So every process has at least two threads
I guess...
Ok, this has been ratified. Now I have a problem of pagefaults 
(almost as if I actually need a proper abstraction)
Wellll
Does it tho 
I think I have a (terrible) plan
nah i was there
it was epic
afaik KDE apps work
we did try gnome
we got to the screen which says that gnome encountered an error
not sure if it was gnome session or not
It needs all the session and systemd stuff
Nice
why didn't you merge this though?
How was that worked around again
does somebody still have that code?
we had this
dennis, maybe 
Lol
it was a while back
it was really hacky
like most stuff, but most stuff is also upstreamable
this absolutely wasn't
also, hijacking pmos thread lfgg
How does Gnome work on Hurd?
same way as glibc will work on ironclad (🙏)
lol no
It can get by without
That's how freebsd etc have the latest gnome and kde
no idea about gnome but kde itself has a significant upstream effort for running on BSDs iirc
For gnome it's as easy as this
gobject-inteospection is a bitch though, still
Very not nice thing about Rust: it's difficult to compile while on a train
can't xbstrap not do this
yeah
it can
this is more of a cargo thing than anything
me liking something from jinx doesnt mean xbstrap cannot do it too
xbstrap and jinx are more or less the same thing
true
This is why I hate carGo
Not everyone has the privilege of always on broadband
cargo does have an offline mode
i haven't used it so i don't know how effective it is though
car go?
car stop
yeah cargo seems to make the common case easy while not caring about advanced use cases at all
try to make it apply a patch to a transitive dependency that is imported by your Rust package
if you want to have some "fun"
Ok, qemu is really trolling me (totally not because my code is broken)
But luckily I'm arriving to a PC which supports S3 and has a COM port (so it's actually 2 PCs
) in 20 minutes...
It wakes up but still says paused, and doesn't want to sleep again...
isn't that pretty easy? just add a [patch] section to the global cargo.toml
Pointing to the patched repo/source
or even just passing it with --config
I don't remember the exact issues but IIRC it was not possible to do this reliably within Managarm without overwriting $CARGO_HOME
is there a reason overwriting CARGO_HOME would be undesirable?
ah there was also this issue reported by vinc: https://github.com/rust-lang/cargo/issues/9470
still not fixed after 4 years 
Fun, the physical PC bootloops..?
Time for while 1 debugging 
binary search time
This PC decided to place init vector at 0x7000
It also can't turn on...
like until i unplug it from wall
Ok, while 1 says that it gets to real mode
btw this shit is fun 
what does the manual say for E3?
Idk
This will be the best thing ever if It works
Like for debugging

lmaooo that's amazing
and incredibly useful
a polling driver (that would work in real mode :^)) is quite simple though
yep, you can just poke into 0x3f8 and poll tx ready or whatever
its like 5-6 lines of code
(assembly)
serial may not be particularly hard to implement in asm but it's not really suitable as just "insert these one or two easily memorable instructions wherever you want and you now have one byte of output"
imo
fine i'll implement serial
the problem with this is that it's too fast
Bruh this PC's PSU is making really scary noises
don't worry
And it's shitty
It can
These PSUs have a history of doing that
I think I'll just stick to while 1 binary search
For some reason it gets to line 29 and then tripple faults
i'm having a hard time figuring out why this worked on qemu and bochs in the first place
you're converting segments to their actual linear addresses in 16 bit registers
that's gonna overflow immediately
also when enabling protected mode, the far jump is supposed to be the very first instruction after the write to cr0
AMD CPU?
Why
Segment's values are >> 4
They're 16 bit registers
the segment registers themselves yes
but you're converting them into their linear addresses, which are 20-bit values
you're essentially discarding the top 4 bits of the seg regs
And bochs?
bochs too
Like I've walked over it and it was how that worked
if they're emulating correctly, this will essentially discard the top 4 bits of cs, leaving the truncated linear address in cx
same for what you're doing further down
they did not
I don't get it
what would be discarded
That's why I'm doing two stores
let's say cs=0x9e00 (aka wakeup vec is at 0x9e000)
bx = cs # bx = 0x9e00
cx = bx # cx = 0x9e00
cx <<= 4 # cx = 0xe000
yes
oh wait you're working around it in a weird way slightly further down
you aren't actually in pm until you do a far jump
wait a second
but it tripple faults
I need to read AMD manual
It must be that
fyi having any instructions between mov-to-cr0 and ljmp is UB
ok, firmware in combination with limine is trolling me
Limine because it refuses to boot randomly and firmware because it refuses to output image randomly
Wtf, it doesn't enter ACPI mode now?
nvm, this PC just enters S3 too quickly
I'm thinking about moving this mess to C++ eventually
like relocating the trampoline in c++ before using it?
that seems like a good idea
i think i'm in pmode
pmos - protected mode Operating System
Time for a reddit post
anyway
(i really need a pxe server)
like I've already got openwrt router which can host it...
(I'm digressing)
This seems promissing
(but suboptimal)
(I really need SMP trampoline)
It could've been really nice if limine had an option for disabling smp...
(anyway)
Yeah this is failing because it's not bsp
more fun stuff
I think my PMM is destroyed
(i'm blaming cache stuff)
I've no idea what's going on but something is allocating like a million pages
wdym?
No but so I can quickly test without smp without recompiling kernel
ah
ok, ignoring pmm, it looks like i'm waking up but getting no interrupts
This is weird...
I've added volatile to asm (wbinvd) and now it's failing in a different place
which should never fail
Ok, I think I'll work on an SMP trampoline
Which could also apply to 32 bits
And maybe I'll support Hyper on AMD64 builds as well...
Ok, I have CPU parking...
I have an idea
What if I make drivers explicitly unregister interrupt handlers before sleeping?

What is that going to achieve?
It's lapic id 3
No missed interrupts
Idk
I seem to have no interrupts after waking up, for some reason
is this the 32-bit destination from the icr?
looks like 3<<24
which would make sense actually
Don't you need to reinitialize devices anyway?
yes
Because I just store it as 32 bit int for x2apic compat
You do, but like I keep ioapics and stuff
I don't know why, but I've moved relocations to C++ and now my wakeup vector throws #GP when entering protected mode
I don't know what I'm missing...
check_exception old: 0xffffffff new 0xd
1300: v=0d e=0018 i=0 cpl=0 IP=9e00:000000000000002a pc=000000000009e02a SP=0000:0000000000000f70 env->regs[R_EAX]=0000000000000000
EAX=00000000 EBX=00009e00 ECX=00000009 EDX=00000001
ESI=00000000 EDI=00000000 EBP=00000000 ESP=00000f70
EIP=0000002a EFL=00000007 [-----PC] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0000 00000000 ffffffff 008f9300 DPL=0 DS16 [-WA]
CS =9e00 0009e000 ffffffff 008f9b00 DPL=0 CS16 [-RA]
SS =0000 00000000 ffffffff 008f9300 DPL=0 DS16 [-WA]
DS =0000 00000000 ffffffff 008f9300 DPL=0 DS16 [-WA]
FS =0000 00000000 ffffffff 008f9300 DPL=0 DS16 [-WA]
GS =0000 00000000 ffffffff 008f9300 DPL=0 DS16 [-WA]
LDT=0000 00000000 0000ffff 00008200 DPL=0 LDT
TR =0000 00000000 0000ffff 00008b00 DPL=0 TSS32-busy
GDT= 0009e0b0 0000001f
IDT= 00000000 000003ff
CR0=00000011 CR2=00000000 CR3=00000000 CR4=00000000
DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 DR3=0000000000000000
DR6=00000000ffff0ff0 DR7=0000000000000400
CCS=00000005 CCD=00000009 CCO=EFLAGS
EFER=0000000000000000
On the far jump intstruction
It looks sane
well, apparently the gdt is not so sane
I've no idea what was happening
I undid everything and did it again and now it works...
You do
but then a missed irq should be irrelevant anyway, right?
you're supposed to shut down + re-init all devices anyway
Ok, it's kinda maybe semi-reliable
I think I'll fix interrupts
Then fix the 32 bit build
Then fix RISC-V
Then get fix AHCI
Then merge to main
Ok, I'm getting tired of S3 stuff
It semi-works
So I think I'll implement it in i686 build (among with adding SMP support, which it doesn't have now)
(Since I think I should kinda be able to just translate it from x86_64 build/trampoline)
And then I'll work on adding "handles" to IPC
And fixing timers maybe
(before writing a proper driver interface for suspend/resume)
Also, I still need to fix fork() on RISC-V...
(too many things to do)
Which should help with drivers
It seems to wake up properly (including SMP), but it's kinda difficult to know since screen nor serial work and other drivers are also broken
Hence this
And I'm undermotivated to write this now
Bochs does show picture though and the userspace seems to continue to initialize though
It's not arch-specific, but I have an issue where processes call exit (which is syscall id 0) immediately after forking, and I think I'm messing up the registers somehow
on risc-v specifically
And I'm using a0 for both passing the syscall id and returning the result
serial should work after resume just fine
It does, but my userspace driver is broken and only works in QEMU for some reason
lol
Average ia32 assembly
Ok I need vdso...
(What if I implemented dynamic linking?)
(ok, I'm getting distracted)
Bruh I broke something in i686 builds
(ok, I urgently need the symbol table memes
)
(what the fuck)
(the best way to debug asserts is to add more asserts
)
XD
Ok, my userspace was dumb and my kernel wasn't cheking it
ia32 build works
And also Rust just worked
(Or did it?)
Nevermind, Rust is broken
It just failed silently
On the other hand PS/2 had suddenly decided to work...
Ok, I'm dumb
It's trying to load x86_64 executable on i386 for some reason
Wtf
How did that even compile?
lol what
My Makefiles are trolling me
Oh yeah, I forgot I rm -rf *'ed over it
This is better
Ugh
why are you putting an arch triple in your toolchain name lol
you can just name it pmos-dev or smth
cuz you know toolchains can have multiple targets
but no idea if rustup will let you do that
i don't see why it couldn't, toolchain name is just the name of a directory afaik
Idk I copied it from osdev wiki
oki
It does
Like dev-x86_64-unknown-pmos compiler x86_64, i686 and riscv64gc
It's like clang/llvm
Which is nice
yep that's the entire idea
Somehow this is what's failing https://gitlab.com/mishakov/pmos/-/blob/dev/rust/pmos/src/ipc.rs?ref_type=heads#L81
Which makes no sense
Oof
Ok, it's severely broken
This is very sus
I'm blaming this
why?
It just returns int64_t
And it's passing it as implicit argument
I needed repr transparent
Yeah, repr(transparent) worked
Ok, time for SMP on i686
Ok, smp kinda almost works in i686 port...
(By kinda almost I mean that I have garbage in cr3, and it pagefaults)
Initcheck_exception old: 0xffffffff new 0xe
0: v=0e e=0000 i=0 cpl=0 IP=0008:0000606b pc=0000606b SP=0010:00000000 CR2=0000606b
EAX=80000001 EBX=00000000 ECX=00000000 EDX=00000001
ESI=00000000 EDI=00000000 EBP=00000000 ESP=00000000
EIP=0000606b EFL=00000002 [-------] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0010 00000000 ffffffff 00cf9300 DPL=0 DS [-WA]
CS =0008 00000000 ffffffff 00cf9a00 DPL=0 CS32 [-R-]
SS =0010 00000000 ffffffff 00cf9300 DPL=0 DS [-WA]
DS =0010 00000000 ffffffff 00cf9300 DPL=0 DS [-WA]
FS =0010 00000000 ffffffff 00cf9300 DPL=0 DS [-WA]
GS =0010 00000000 ffffffff 00cf9300 DPL=0 DS [-WA]
LDT=0000 00000000 0000ffff 00008200 DPL=0 LDT
TR =0000 00000000 0000ffff 00008b00 DPL=0 TSS32-busy
GDT= 00006098 00000017
IDT= 00000000 0000ffff
CR0=80000011 CR2=0000606b CR3=f000ff53 CR4=00000000
DR0=00000000 DR1=00000000 DR2=00000000 DR3=00000000
DR6=ffff0ff0 DR7=00000400
CCS=00000000 CCD=00000001 CCO=LOGICL
EFER=0000000000000000
Ok, I've fixed garbage cr3, but now I have garbage in cr4 
classic
Ok, I officially have SMP on i686 builds
and it just trippel faults on real hardware 
Ok, I'm blaming Ultra
It tripple faults on physical hardware, even if I place infinite loop at kernel's entrypoint
Ok, I'm dumb
I forgot I nuked my repo and it was this #1277232930317537341 message
And it works on physical hardware...
Yeah
I've had i686 working for some time now, but without SMP
I think I'll implement ACPI sleep stuff on it tomorrow
(it's almost 3 am
)
I've made a generic function for parking CPUs, so bringing up APs after sleep will use the same code/mechanism as SMP init on first boot
(which is shared with x86_64)
I think I need multilib support...
userspace
I mean both
Idk, so I can compile 32 and 64 bit userspace binaries in one go
the kernel already supports compat mode
why do you want to run 32 bit apps though?
My 32 bit kernel doesn't boot in bochs
(because its bios is broken and I haven't figured out how to update it)
So that I can debug 32 bit aplications with 64 bit kernel...
(I think it's an X Y problem)
Also it's cool
Also for convenience
I have to recompile libc++ and friends every time I want to target a different architecture
(But maybe it's just a bad build system)
just have different build dirs for different targets
By that I mean that I need to figure out how to point lld to $SYSROOT/usr/lib/$ARCH instead of plain $SYSROOT/usr/lib
can't you just do that with env vars?
But I'm building everything in-source
I already use patched clang
I do that already
And also compile my libc and stuff 3 times for different architectures
can't you make a script that copies the bin into the target folder then?
this is not the issue
why?
like i already do that
then you should not need to recompile every time
the issue is with libraries
Ugh
Ok, time for 1: jmp 1b
I'm having a skill issue with this now...
ljmpl *%cs:(acpi_vec_jump_pmode - acpi_trampoline)
acpi_trampoline_jump_pmode:
Fun, ia32 builds are broken in bochs

I think framebuffer just isn't working
Nope, the whole userspace is broken
(but kernel didn't crash)
Timers are just broken
my pagefault handling is broken for some reason?
Ok, I have no clue why, but bochs just doesn't wake up
And QEMU triple faults
With nonsense
btw triple has one p
I need to get checked for dyslexia
I know why it's failing...

I crashed qemu
Nope
The whole WSL2
Ok, this looks like kernel address
I was missing .code16
Of course it's this
TSS init... FAIL
busy tss
Bruh
TSS init.. SUCCESS
But something pagefaulted, which kinda isn't nice I guess
Even SMP works...
Ok, i686 port is officially better that x86_64
What the fuck
normal
I'm semi-satisfied with S3 semi-working on x86_64 and i686 (the latter crashes on physical hardware for some reason during pthread creation?), so my plan is to write an ACPI (internal) bus thing in devicesd server, add a driver for RISC-V QEMU thing, and I'll probably merge it to main, before continuing with proper init server/driver management stuff
(at which point I'll add an interface for callbacks for sleep/resume)
And I'll probably implement IPC handles/permission system/whatever
I'm envisioning how the interface could look for Rust/C++ coroutines with IPC
(and C I guess)
What's "RISC-V qemu thing"?
The QEMU device for delivering ACPI events on hardware reduced platforms (ARM, RISC-V, loongarch)
The one that @ infy mentioned in uACPI thread a few days ago

could be an OOM since u use LTO
lol
what did u do
ntpoff is IA32 thing only apparently
On AMD64 tpoff is already negtive
Time to test new EC stuff...
I've changed its initialization to ACPI bus
Fun fact: I think my interrupts are broken on x86_64 in general, not just after waking up
i guess my pci driver is severely broken...
yep
vendor cece
Where
here lol
Yeah, PCI is reading garbage
your pci driver is cooked
well pci may be accessed during namespace load
(or I could fix ECAM)
I think they just hardcode it
Elixir Cross Referencer - source code of Linux v6.13.5: arch/x86/pci/early.c
Elixir Cross Referencer - source code of Linux v6.13.5: arch/x86/pci/acpi.c
_CRS is parsed later here, read the comment above ^
So just hardcode it?
tldr yes
does it not work correctly without ecam?
this means u returned UACPI_STATUS_NOT_FOUND
soo how does it fail
bruh
wtf
how did ecam even work?
This has to be something very dumb
Wait a second
So I have to have PCI before uacpi_namespace_load?
So before I init PCI, I have to basically provide it for bus 0 through 0xcf8?
What the fuck is this? https://elixir.bootlin.com/linux/v6.13.5/source/arch/x86/kernel/cpu/amd.c#L585
Yes
Lol
fin, my EC driver didn't survive
This assembly is funky...
(brainrot)
(I think my code quality did in fact decrease after disabling copilot)
Do MacBooks report lid opening degree/position or something?
Lol that's interesting
Yeah probably
Does it send a proper lid notify as well if you close it entirely?
My lenovo laptop seems to also mostly be working
BTW that AHCI controller info looks bogus
It is completely bogus because the drivers only support ECAM
And the kernel only uses legacy IO
Oh
Because I'm planning to make PCI accesses an IPC call
Since I don't have shared mutexes
(too many things to do)
It does
I think it has an accelerometer
Nice
Time for the QEMU device I guess...
You can probably read the angle via some method
Like if I just move the laptop it also spams those events
Idk why apple would have that
It's reasonable for tablets and 2 in 1s
BTW why does it fail to publish pci
Idk
No idea
Rust and C disagreements
Lol
(I basically have something akin to mbus written in Rust, and it's publishing to there)
Also, am I supposed to install devices before uacpi_finalize_gpe_initialization?
Nah
"EINVAL"
We talked about this error, its cosmetic
I remember that
No ec?
No, it seems to be fully working
Including AMD GPIO
Mostly because of that PCI error
Ah nice, you just didn't include it in the vid
I've basically copy-pasted code from osdev wiki
So the internal devices are also using ACPI bus thing now
(same with GPIO)
Time for the kernel to completely destroy me
(I think I'll do it tomorrow)
Nice
troll
fun
why i8
Kernel takes uint8_t *
as it should
Wait, no, it should be c_char
idk, I'm just dumb
it's i8 on x86 and u8 on risc-v
It's refusing to link for some reason...
Do I just do big time stubbing?
yeah
you can make rustc use u8 somehow
idk how
and to make the C abi match you can build with -funsigned-char
I've just set it to libc::c_char 
Kernel shouldn't care anyway
But why isn't it optimizing it out like on x86?
(I mean there was a flag to allow undefined symbols)

probably rng?
?
like it just didnt optimize out
because of luck
or yeah a compiler flag that made it ignore the errors
But I'm definitely not using opendir and stuff
Like it doesn't want it with C++
Ok, I need an ARM port to see if it's RISC-V skill issue or not being x86 skill issue
So RISC-V port is alive, and I've fixed ECAM
But there is a but
for some reason uACPI just quietly fails...
What the fuck
(I can smell UB and insane optimizations by clang)
@twilit talon
uACPI returns 7 (UACPI_STATUS_INVALID_ARGUMENT) in uacpi_finalize_gpe_initialization()
On RISC-V
Imma check x86 build just in case...
I think clang compiles libunwind as a shared library
And recompiling for x86, it fully works
It's not ECAM
I'm gonna look at it again tomorrow
There is no gpe on reduced hw
That said I should probably make it just return ok in this case
Do I ifndef UACPI_REDUCED_HARDWARE?
no
UACPI_REDUCED_HARDWARE is designed so that u dont have to ifndef anythign
u can just call finalize_gpe_initialization
I should just mark this as ALWAYS_OK
although what's interesting is ACPICA also does this
linux just doesnt check the return value
i'd still compile with UACPI_REDUCED_HARDWARE on risc-v
I was calling it before and it was not returning error
before what
yes
it cant possibly return OK on risc-v, never has
so tldr:
- on riscv, compile with
UACPI_REDUCED_HARDWAREto strip useless code - either don't call finalize_gpe_initialization on risc-v, or ignore its return value
because u cant finalize initialization of something that doesnt exist 
But it shouldn't be invalid argument then (?)
UACPI_STATUS_NOT_FOUND 
Ok, Rust also just worked on RISC-V
i have COMPILED_OUT
same as risc-v except u have 99999999999 instructions for manipulating caches
(inb4 I get destroyed by non 4K pages)
it has 4k pages
aarch64 is quite different from riscv
it's the hard mode risc-v
Loongarch seems to be similar
But also I have arm hardware
(Raspberry Pi 4 and 1)
And raspberry pi 4 is systemready certified
it's obviously different from risc-v, but a lot of risc-v code on linux is just adopted cp arm/x.c .
what parts exactly?
but all regs and stuff are different ofc
most memory related stuff i think
idk, ive looked at the port a while ago
there's a ton more btw
this is like 30% of the output
This sounds like a Linux devs skill issue
yeah if u can just straight up copy most stuff maybe it's not abstracted away very well
And weak ordering
(sounds fun)
It's not only weak ordering but caching in general
On aarch64 you can't just do unaligned accesses to devices or access mmio through page mappings with default cacheability etc
It's the same story on RISC-V
But I think that RISC-V's memory ordering is stronger
on risc-v the firmware is supposed to configure device memory using PMAs
we all know firmware can be trusted with that 
well, this is the same on x86, really
yes but on x86 at least it generally works
on risc-v on the other hand, see limine framebuffer on risc-v
nope
then you don't know if it's firmware misbehaving or not
we do because like
you can tell it's incorrect caching settings
some cache lines get flushed, others dont
also i remember someone mentioning u have to manually mess with PMA-related stuff on real boards
but maybe it's some other issue 
Maybe I was lied to 
also, if the limine framebuffer thing is caching related, it should be easy to fix, right?
just map as uncached
didn't somebody try that already?
No clue, I think Marvin never got around to it
I can probably take a look at this when i get access to a board with a non-broken uefi
I've decided that I'll finally write an init server, which would listen to pmbus and start the drivers...
(among other things)
what I'm thinking about is how to store/represent properties, and I think I'll use tree for it, and yaml for config

libc is almost compiling
what does that even mean
"ported to loongarch"
linux has had a loongarch port since forever
Don't they have their own kernel fork?
Yes but its called AltLinux
like its literally linux
with their own local patches for some stuff
Like for elbrus stupidity
maybe what they meant is that they now have an iso for loongarch
Closed source gcc patches is just insane
I guess, who knows
Russian CPU 
what was nice is they give anyone who wanted it an ssh server with that cpu
so u can try it out
via telegram or website application
But like how is one supposed to port operating systems to it
elbrus
which os i mean
anything that's not linux
why would they care like
its for the goverment
which uses linux
their own fork that has been verified via various crap
static analyzers etc
also it supports x86_64 emulation natively
how many osses are supported by loongarch 
Well, there will be pmOS and Menix 
(how to attract the attention of all 3 letter agencies)
LLVM only has Linux 
ported a distro

oh shit
i gotta do the loongarch mlibc port first
loongarch32 is a thing??
Yes
And RISC-V
I mean I was thinking about eventually supporting 32 bit risc-v userspace with 64 bit kernel
And I might do the same with loongarch because why not...
are you doing new world or old world?
if you do old world you might be able to get WPS Office running lmao
with some shims and syscall emulation
what are you referring to
loongarch abis
there's old world and new world
pretty much everything open source uses the new world so it's like the sys-v ABI for loongarch
what is the difference
I guess I'll also use it
no idea
but the proprietary OS(es?) made by loongson use the old world ABI
and the WPS Office joke is that there's a port of WPS Office to old world linux on loongarch
New world probably
Ok, the kernel already compiles (the arch-independent stuff that is)
I'm just missing paging, interrupts and timers
hmm I thought callconvs were different between OW/NW but apparently not
most of the differences are linux syscalls
the only differences that should really matter are ELF differences and firmware differences
What is the point of this?
theres probs an ifdef
If there isnt a define it uses a generic implementation
I give up and will probably add framebuffer output to kernel
For boot logs and panics
This is interesting...
So, in theory I should have all paging functions
Now I just gotta figure out the interrupt controllers + add flanterm to kernel
I guess it's time to resurrect this branch...
gcon :D
?
why put flanterm in the kernel
to be able to see kernel log messages before userspace is initialized
even Ironclad does that now lol
bold of you to suggest people use a project that was never ported to !Ironclad and you probably never used yourself
yeah we had issues with early initialization on certain machines that required that output for early debug
guh
we dont have a terminal that userland uses though, its just flanterm as a quick mirror of /dev/console
the quickest and roughest way to just get some text to screen before gcon hits
so if uacpi shits the bed, we can know instead of having a black screen on laptops
i initially wanted to do the same but you raise a good point
like things fail, if it was fool proof I wouldnt have it, but its just such a pain to do bug reports without that
ive had like 20 people tell me at random moments that Ironclad doesnt boot and they have a black screen
what do I do
what i meant to say is that there are very valid reasons to want to have text/terminal output from inside a kernel way before userland is initialised
loongarch doesn't seem to have a convenient serial controller
(maybe it does but docs are even more distributed than those of RISC-V)
Like there's no SBI debug output or 0xe9
you definitely have either pl011 or an 8250
yes you can
(maybe I can)
What's the address?
That also happened with pmOS
How do you handle kernel panics?
Like my solution is praying that it doesn't on physical HW, but it's not a good one
In terms of what, reporting to the user?
Yes
Like if kernel panics, you can't (easilly) ask userspace terminal driver to print it to the screen
for the kernel terminal? like what linux has
What you can though is take over the framebuffer again and print it yourself
yea but pmos is a microkernel, doesn't that make a difference?
I've been thinking about that, but what about GPU drivers and such
wellll
hydrogen by default writes the kernel log to one of the boot framebuffers, the init process gets a handle which allows it to 'detach' the kernel log which needs to be done before taking control of the fb
Like there needs to be an interface to notify kernel of their existence
its in the FDT
There's no way is the real answer, windows and Linux just die when the graphic driver dies and cannot be recovered
this is how it works on literally all platforms (except kinda not really riscv, and kinda x86)
I've been also thinking about having some sort of panic thread, which can be scheduled even if everything is on fire
Ironclad just assumes it can use it if it is not mapped by userland
If it's mapped by userland we don't use it
Simple and sweet
It's my first "serious" kernel, so a lot of the design decisions might not be the best I guess
As a microkernel you shouldn't panic much
i mean same
If at all
Yeah, somehow it's stable enough that it doesn't usually panic, but if it does, the system just freezes with no way to know what caused it if you don't have COM port
Note to myself and anyone doing loongarch: "If the exception processed is an error-related exception" means machine check exception
(so the interrupt handling is very similar to RISC-V)
Ok, so by the end of the day I'm missing
- Page walking
- Interrupt controllers
- Floating point?
- Exceptions
Limine is trolling me...