<zid>
heat: if that's true, someone's short changed me out of 4 levels and a co-processor
<zid>
those bastards
<heat>
they're all there
<clever>
rpnx_: its just normal arm, so it should work the same on any arm device
<heat>
ring 0 - 3, ring -1, ring -2, intel ME
<zid>
nobody uses ring 1 or 2, ever, and the rest are abstractions and aren't real
<rpnx_>
I don't actually know the ARM instruction set that well outside of some userspace stuff, it's mostly that I wanted to use a raspberry pi since the SD card is easy to replace.
<heat>
nah the rest are really there
<clever>
rpnx_: the rpi is also able to network boot, which makes development far faster
<heat>
SMM is definitely a separate protection level, and so are hypervisors
<heat>
and *you* don't use ring 1 or 2 because *you* are poopy and smelly
gog has joined #osdev
<heat>
we'd all be living in 3022 if we unlocked the full power of ring 1 and 2
* CompanionCube
expects that even the VMS port doesn't use ring 1 and 2 and VMS actually has multiple kernel privilege levels doesn't it?
xenos1984 has joined #osdev
<\Test_User>
exactly, no one will bother to make use of them till 3022
<rpnx_>
There's a lot of code in littlekernel
<heat>
fax
<clever>
rpnx_: i have read it and am familiar with the mmu setup, do you want 32bit or 64bit arm?
<rpnx_>
64bit for sure, I'm trying to figure out how it works, for example, if there is some register that is set to provide a jump to a function that translates the virtual address to physical address or something like that
<clever>
rpnx_: its the same as on x86, you create a multi-level paging table, that maps virtual to physical, and put the physical addr of that table into a special register
<geist>
CompanionCube: that's a good question. x86-64 effectively doe't hae ring 1 and 2, so they havce to make it work with just 2 priviledge levels
<geist>
though ia64 i dont think did either, i thnk, so they probably already did it a while back
<rpnx_>
clever: so this register is just an array of pointers? One thing I am a little confused by is that I understand linux can add fields to the page table
<geist>
or alpha for that matter
<heat>
IA64 baby!
<rpnx_>
That's different from the hardware page table? Or the same?
<clever>
rpnx_: the register is a single pointer, to a big array in memory
<clever>
that array typically then has pointers to more arrays
<clever>
and some bits of those slots are instead flags instead of address
<rpnx_>
Ok, how would I set the size of this array?
<clever>
for aarch64, there is a register that sets how large the array is, i believe
<rpnx_>
Ok, so there is 1 register that sets the page table and 1 register that sets the size of it
<bslsk05>
wiki.osdev.org: ARM Paging - OSDev Wiki
<clever>
ah, but that page is 32bit only
<heat>
let's assume a 4-level page table layout (which is kind of the standard for 64-bit platforms with 4KB pages): You have L0 (u64 entries[PAGE_SIZE/8];), which point to L1 (u64 entries[PAGE_SIZE];), yadda yadda, until L3, which points to an actual page
<heat>
sorry, PAGE_SIZE/8 in L1 as well, etc. it's always a page full of pointers(therefore 8 bytes) plus some other encoded information
<clever>
and each tier is assumed to be aligned to something (i forget what), which means the lower N bits of that pointer are assumed to be 0
<heat>
they're page aligned
<clever>
which leaves those lower N bits in the entries array, free to be used for that other information
<heat>
yes
<clever>
for 4k pages, N=12 then
<heat>
so, to map something you would need to create a path from the L0 table to the L3 table, where you would create your 4KB mapping - this is your base case (and the most common one)
<clever>
on arm, that is where the cacheability is encoded, along with the r/w/x flags
<heat>
architectures then usually have a hardware register where you keep the L0 table, plus possibly some other bits
<heat>
ARM64 has <TO BE FILLED, CANT REMEMBER>, x86 has cr3
<clever>
on 32bit arm, each entry in the L0 table covers 1mb of the virtual space, and it does support 1mb pages
<bslsk05>
github.com: rpi-open-firmware/mmu.c at master · librerpi/rpi-open-firmware · GitHub
<clever>
heat: arm has TTBR0 and TTBR1, for the lower and higher halves
<heat>
TTBR? yes TTBR I think
<heat>
riscv has the satp
heat has quit [Remote host closed the connection]
<clever>
and there is a setting elsewhere for the size of each half
heat has joined #osdev
<heat>
clever, discussing every stupid little detail doesn't help!
<clever>
much older arm cores have just TTBR, for the whole space
<heat>
lets keep it simple
<heat>
rpnx_, following?
<rpnx_>
Oh, I was reading the wiki
<rpnx_>
Let me read this
sonny has joined #osdev
<heat>
a decently useful detail here (when bootstrapping) is large pages
<heat>
which is pretty much just a page table entry that instead of pointing to the next level, points to a large-sized, $size aligned very big page
<heat>
for instance your L2 entries each correspond to a 2MB range of address space - instead of mapping things 4KB by 4KB with a lot of granularity, you could map it all in a 2MB chunk with a large page
<heat>
this pretty much just saves you memory and hassle when bootstrapping; most bootstrapping code will use it
<rpnx_>
Ok, so when looking at the page table, does this lookup happen in an interrupt? Or is the page table inspected by the hardware without executing any kernel code
kof123 has quit [Read error: Connection reset by peer]
<clever>
yep, thats what i used in the mmu.c i linked above
<heat>
depends on the architecture
<heat>
most modern ones do page walks in hardware
<heat>
but I T A N I U M does it in software because it's the best architecture ever
<clever>
rpnx_: on arm/x86, the hardware reads the pagetable automatically, any time there is a TLB miss, the TLB acts as a cache, so it doesnt have to translate every single virtual address
<heat>
yeah, the TLB is like a cache that remembers the mapping virt -> physical and its permissions, caching, etc; it has a limited size
<heat>
but that's a problem for a later date
<heat>
(this is a architectural detail that isn't explicitly exposed to you apart from "invalidate tlb mapping" instructions)
<clever>
but i assume itanium instead only has a TLB and nothing else?, and software is then responsible for filling and evicting the TLB?
<rpnx_>
Ok, so if I want special properties like 'this page is mapped to a device' that would be put in a secondary structure?
<heat>
clever, oui
<heat>
rpnx_, no
<clever>
rpnx_: that would all go into the paging tables
<bslsk05>
github.com: rpi-open-firmware/mmu.c at master · librerpi/rpi-open-firmware · GitHub
<heat>
STOP LINKING SHIT
<heat>
let's get the basics straight
<heat>
so your platform/chipset/whatever the fuck configures devices to MMIO on a certain physical memory range
<heat>
(MMIO = memory mapped IO)
<heat>
the only thing you need to do wrt MMU and "device memory" is to make sure your caching is right (and coherent across all mappings of that page)
<heat>
$caching_is_right depends on the architecture of course
kof123 has joined #osdev
<heat>
and just so we're clear, this MMIO thing is how you talk with devices; you write some value to some location in MMIO range, and it goes to the device, and the device may do something and give the result back to you on another location
<heat>
a very easy example would be a framebuffer - you write some RGBA values to the framebuffer, it goes to your GPU which pushes it to your display
<heat>
rpnx_, still following?
<clever>
a framebuffer is also a case where you would enable write combining
<rpnx_>
I think I understand the concept but I'm looking for something like a document describing the fields in the page table structure
<heat>
write combining doesn't matter gith now
<rpnx_>
If I understand, it would be something like
<heat>
rpnx_, ok, I can tell you the chapter gimme a sec
<heat>
the arm arm is incredibly stupid and hard to go through
<heat>
and large, very lage
<rpnx_>
page_table[(pointer & (part of pointer)) >> offset][(pointer & (part of pointer2)) >> offset2][(pointer & (part of pointer3)) >> offset3]
<rpnx_>
Something like this?
<heat>
yes kinda
<clever>
rpnx_: yeah something like that, i did have a graphic at one point that showed the entire bit routing
<clever>
but i have lost it
<heat>
of course that won't work because the permission bits and all that
<rpnx_>
That's something I will need to understand for sure before implementing it
<heat>
but conceptually you're right
epony has joined #osdev
sonny has quit [Ping timeout: 252 seconds]
<clever>
heat: implementing it like that might actually explain spectre/meltdown, heh
<zid>
(It's just a binary prefix tree)
<clever>
check the permissions later, they dont matter!
freakazoid333 has quit [Ping timeout: 255 seconds]
<heat>
a tiny detail clever was mentioning back there is that ARM64 divides the address space into two halves, so you have two CPU register that point to two L0 tables; the first one points to the bottom half of the address space, the second points to the top half
<heat>
if you go through the math you'll notice that you have a hole in between the halves where nothing can be mapped - that's normal and pretty standard
<rpnx_>
One for userspace and one for kernel?
<clever>
yep
<zid>
oh that's neat
<heat>
since no one needs 2^64 bytes of memory, people only implement like 48 or 49 bits of the address space
<bslsk05>
developer.arm.com: Documentation – Arm Developer
<rpnx_>
Thanks
<heat>
rpnx_, if you look at D4.3 you'll find the descriptor formats pretty well layed out
<clever>
this shows some bits from TTBR0, and some bits from the virtual address, being combined, to form the address of a single entry in the L0 table
<heat>
note: DISREGARD ALL THE STUPID COMPLEXITY OF ARM64
<clever>
and then repeat down the tree
<zid>
I used lazy mmap to solve a code golf thingy challenge once that was fun, I needed a trie so I just used the mmu
<heat>
it has so many fucking options and realistically you just want to use 4KB pages, 48 bits (so 4 levels), two halves
<zid>
I thought 64kB pages were the hotness these days
<rpnx_>
Most linux distributions I know turn on overcommit by default
<zid>
epony: I also have no standards, which is why I use ARM
<zid>
*rimshot*
<heat>
epony, it does have standards!
<heat>
EBBR, SBBR, SBSA
<zid>
and those are just the ones that match his regex
<heat>
all of these require UEFI, SBBR requires ACPI and PCIe(right?) as well
<klys_>
****
<epony>
not quite, on paper maybe, on device.. surprises, and by the time you get something going, it's obsolete, expired, cancelled, eol and no more
<heat>
yes, on device
<epony>
so it's not a hobbyist platform, it's for big development teams and in vendor programming
<zid>
arm is very standard
<heat>
your server board needs to be SBBR compliant if you want to get ARM SystemReady(tm)(r) certification
<zid>
I counted at least 50
<heat>
the so called "x86 PC standards" are a lie btw
<heat>
mostly propagated by ACPI and UEFI protecting you from the platform, plus you consuming the same family of platforms from the same vendors for the last 30 years
<rpnx_>
Well, for now I am only targeting 1 device (raspberry pi 4) so those issues shouldn't matter too much for the time being
<heat>
oh, also, SMM! can't forget good old SMM making sure you think you still have a PS/2 controller
<heat>
the so called firmware bloat is also the thing make sure "hurr durr arm bad unstable, x86 good stable standardized" reminds kind of true
<heat>
which is why ARM wants it as well
<heat>
although I don't think ARM processors are growing SMM any time soon
* heat
knocks on wood
<klys_>
wouldn't nearly prognosticate a future arm system with no firmware payloads to chuck in
<epony>
arm* is just following up x86 with late delays and same mistakes done again, for short lived times and expired product lines
<epony>
in much much smaller quantities and general purpose adept produce
<epony>
"vendor managed" ;-) much more than x86
<heat>
anyway, bed time
<klys_>
good night heat.
<heat>
thanks
<heat>
love you klys_
<klys_>
yw
<rpnx_>
The arm documentation doesn't make too much sense to me, for example.
<rpnx_>
0x0 -> 1<<(32-N) that TTBR0 controls
<rpnx_>
What is this notation?
<rpnx_>
(0x0, 1 <<(32-n)) or [0x0, 1 <<(32-n)) or (0x0, 1 <<(32-n)] or something else?
sonny has joined #osdev
<clever>
i think `0x0 -> foo`, is an address range, from 0 to foo
<klys_>
the range from 0 to 1 shifted left 32-n times
<clever>
and 1<<(32-N) is the formula to convert N to an address
<clever>
yep, that
* clever
opens the 8000 page armv8 specs
<rpnx_>
Uh... ok... so they invented their own notation for a range instead of using something standard...
opal has quit [Ping timeout: 258 seconds]
<epony>
it is not called a reduced instruction set (of several such sets of no really reduced anything)
<epony>
and it changes between models and products
<epony>
and versions
heat has quit [Ping timeout: 260 seconds]
<rpnx_>
Hum, it looks like this is the 32-bit code?
<geist>
Yay I look away for a bit and fairly good conversations happen
opal has joined #osdev
<geist>
rpnx_: think of it this way
<geist>
The arm64 mmu is roughly equivalent in design to the x86 mmu and the riscv ones
<geist>
the page tables work basically the same way, basically. The details matter
<geist>
And arm64 has a bunch of extra knobs, but most folks configure it in the basic way (4 level paging, 4K pages)
<geist>
So what you may be seeing are some of the controls that you can set, like how ‘large’ and address space can be, but usually you configure it for a full 48 bits
<geist>
And that ‘N’ you’re seeing up there is i think one of the tunable knobs you usually leave in the default position
<klys_>
geist, how much firmware on an internal default fuchsia setup today, curious
<geist>
On x86 and riscv for example the configuring of the ‘size’ of the virtual address space is pretty coarse. You only really get to pick from 2 3 4 or 5 levels
<geist>
Arm64 lets you finelycontrol it down to the bit within a range they define
<geist>
klys_: hmm? I failed to parse that
<klys_>
geist, supposing there was such a device prototype at your company, I ask, how much firmware is loaded on the prototype
<epony>
these are SoC systems and have lots of firmware
<rpnx_>
Oh, I think I understand how this works... maybe. The value of N sets the split point between the OS and userspace I think?
<rpnx_>
But the limit here is 32
<geist>
Yeah, also depends a lot on what’s ou mean by firmware
<epony>
in the processor there are multiple blocks not just cores
<rpnx_>
So... not going to access 8GIB with this
<geist>
rpnx_: yep. Also to be clear precisely what are you reading and looking at?
<geist>
Is this armv8, 64bit mode paging?
<rpnx_>
6.12.1 First-level descriptor address
<klys_>
giest, blobs of data you know nothing about
<rpnx_>
I think this manual is for 32-bit arm
<geist>
Yeah but ti’s in the 64bit section in the arm … oh 32bit arm works differently
<geist>
64bit paging adds a bunch of features and looks similar but has different layouts in the page tables and whatnot
<bslsk05>
developer.arm.com: Documentation – Arm Developer
<geist>
It’s different enough that I consider arm32 and arm64 different architectures
<geist>
Basically 64bit is an ARM32 inspired 64bit architecture
<geist>
Annoyingly arm insists on documenting both in the same manual
<rpnx_>
Hum
<sonny>
they did more than just extend the registers?
<geist>
Much much more
<sonny>
ok time to refresh on arm
<geist>
The ISA is mostly different, and the system mode stuff, exception model, etc is basically completely different
<geist>
That’s why I consider it a different arch. in LK for example there’s arch/arm and arch/arm64
<geist>
You’ll find pretty much the same thing on BSD and Linux
<geist>
The main connection is arm64 cores can (optionally) also run arm32 in various run levels
<sonny>
so I never get the exception thing ... is that to support C++ or is it expected to be used by the OS programmer?
<rpnx_>
Arm exception is interrupt
eryjus has joined #osdev
eryjus has quit [Client Quit]
<rpnx_>
This will be very confusing when I add C++ support to the kernel :)
<geist>
Yah i dont mean programming exceptions, i mean the way the cpu accepts hardware exceptions and interrupts
<sonny>
doesn't arm have the stack winding thing?
<sonny>
oh
<moon-child>
rpnx_: better not do that, then
<geist>
ARM calls traps where the cpu stops for some program order reason an ‘exception’ and hardware initiated events as interrupts
<rpnx_>
moon-child, why not?
<geist>
Which i think is a nice clean model
<geist>
X86 mashes them all together
<sonny>
ok, I get that definition
<moon-child>
c++ is a foul beast which scorches the earth upon which it walks
<geist>
But in arm64 they completely changed the hardware exception model from arm32
<geist>
It’s much simpler and more straightforward. Arm32 exception model is frankly pretty wonky. Made sense back when everyone was hand writing assembly
<geist>
But wasn’t very extensible
<rpnx_>
moon-child, why did gcc switch to C++ and clang/llvm and MSVC all decide to use C++ then?
<moon-child>
programmers are known for their masochism
<rpnx_>
Your C compiler is written in C++ :)
<moon-child>
mine?
<klys_>
speaking of which
<rpnx_>
If you use gcc, yes
<rpnx_>
I don't know about icc
<rpnx_>
Since that's proprietary
<rpnx_>
No source code...
<geist>
rpnx_: heh you’ll get into a lot of trouble if you start assuming folks are using particular things
<geist>
You’ll find that lots of folks here are fairly fringe in terms of their choices of host OSes and toolchain and whatnot
<rpnx_>
Hum, I am using cmake and clang, can't get much more boring than that I suppose.
<moon-child>
you do not need the source code to an application in order to get information about it
<rpnx_>
oh
<rpnx_>
Seems icc also uses c++
<rpnx_>
So... hum.
<geist>
Anyway, re: c++ in the kernel. It can work. I work on one at work
<moon-child>
regardless: I got my stuff building under tcc (written in c). And wrote a decent chunk of my own c compiler (in c)
<geist>
You just have to be very careful. If you’re an experienced c++ dev and you know what’s a good idea and what’s bad idea in a resource-starved environment like a kernel, you’ll do fine
<moon-child>
(though I couldn't get tcc to link--had to use binutils stuff for that)
<rpnx_>
Oh, that's neat. I forgot about TCC.
<rpnx_>
geist: there is a nice YouTube video about some developers that got RTTI and C++ exceptions working in the Linux kernel
<geist>
Sure. That doesn’t meanit’s a particularly good idea
<bslsk05>
github.com: gcc/splay-tree.h at master · gcc-mirror/gcc · GitHub
<rpnx_>
I remember when I upgraded to I think it was 8GB ram, on a desktop
<geist>
But yes, for ‘big kernels’ i think size isn’t the biggest deal
<geist>
I remember when i added the last 16K to my desktop to expand it to a full 64KB
<rpnx_>
Now, even a $100 computer can have 8GiB
<geist>
Now i can load integer basic *and* AppleSoft basic! At the same time!
<geist>
(Apple 2 language card)
<rpnx_>
I think the oldest computer I had was a windows ME laptop
<rpnx_>
And that hard an expansion card with 256MB storage
<geist>
But anyway, like i said if you are thinking of doing C++ in your kernel, realize you are taking on a lot more work than you would if you stuck with something like C
<geist>
Only because you now have to consider all of the ramifications of the extended language and be very careful what to use where
<geist>
If you use it judiciously it’s very nice, in my experience
<rpnx_>
Hum, it's more work in some areas, such as needing the ELF loader and eh_frame management
<geist>
No i mean all these extra features in the language you should probably *not* use
<rpnx_>
What do you mean?
<rpnx_>
Like std::string?
<geist>
But then you have to avoid. Also things like if you like std:: template ibraries? Too bad. You probably can’t use most of those, so you’ll have to implement your own, etc
<rpnx_>
Geist: The developers in that video ported the STL to Linux and Windows kernelspace, lol
<geist>
And even knowing which parts of std:: are safe or not requires a fair amount of knowledge of how it all works
<geist>
rpnx_: yes but they also probably are very experienced devs. Are you?
<moon-child>
if I had to use a c++-alike for kernel, I would probably use d
<sonny>
rpnx_ would that be considered firmware now?
<moon-child>
not only because it's a more sensible language, but also there's been some serious effort done to get its runtime working in embedded contexts
<epony>
sonny, which one "that"?
<rpnx_>
I will probably reimplement the parts of the STL that I will use, and maybe copy some of their code because I think it is MIT licensed.
<geist>
My point is you can *do* it, but knowing what to do and what not to do is the hard part. And if you dont know what you dont know, you’ll get into a lot of trouble
<geist>
Which is itself a good learning thing, but keep in mind it’ll get in the way of progress if you’re just getting started
<sonny>
porting STL to kernel space, it seems to be about how much runtime you want to provide for yourself
SpikeHeron has quit [Quit: WeeChat 3.6]
<epony>
kernel space is programs that you load after boot, so it's not firmware
<geist>
It’s like saying ‘I’m going to build a car from scratch. I have some metal and some welding torches here (C) but i think I’ll make it in carbon fiber (C++)’
<geist>
Okay, sure, you can do the latter, but that’s a different class of learning curve you just added to the pile of things
<epony>
firmware is running on chip (processor, hardware device, controller or asic)
<rpnx_>
I will work on getting a kernel working before worrying about making it support C++
<geist>
But you said you wanted to write the kernel in c++
<rpnx_>
But eventually I want to have the main bits implemented in C++ so I can reuse the same libraries in kernel and userspace
<sonny>
epony: yeah but say you make an interpreter for real mode, what's that called?
<epony>
a program
<geist>
rpnx_: that is a thing I’d highly highly reomcmend not doing unless you have to
<geist>
Same reason: user and kernel space code has typically widely different requirements
<geist>
We have to thread that needle a lot in fuchsia and it definitely requires a lot of careful thought
<epony>
sonny, where you store and at which stage you run it makes it firmware or software
<geist>
And we only very judiciously do it (share library code with user and kernel space)
<epony>
it's software in general too, but one that is not user programmable
<sonny>
epony so whatever gets read from rom for initilisation?
<rpnx_>
Oh fushica, that's cool. I liked the way zircon looked
<epony>
more like, precisely, what is stored on chip and running their without the need for software and user programming
SpikeHeron has joined #osdev
<sonny>
oh
<geist>
soi forget, what was the firmware question a while back?
<geist>
I kinda got sidetracked
<klys_>
geist, about proprietary blobs
<geist>
Ah yes. For what kinda of devices are you asking?
<klys_>
how much blob is in the current prototype
<geist>
Current prototype of what? A consumer device? A server?
<klys_>
for all included devices, something for a future consumer
<geist>
Consumer devices tend to have not a tremendous amount of firmware blobs. Usually the first couple stages of the bootloader and then some code left behind to run in secure mode
<geist>
That’s usually from the vendor
<klys_>
what about the radios
<geist>
The bootloader probably too, though frequentlythat’s a just u-boot or a fork of LK or whatnot
frkzoid has joined #osdev
<geist>
If a device has a radio, yes usually it’s got some vendor provided firmware. Wi-Fi radios too
<epony>
the baseband modems are chip-computer ASIC and SoC too
<geist>
Maybe some blobs on the GPU
<klys_>
so, seeing as the iphone 11 for example had 5+ radios
<epony>
with firmware that is not open and not available to you as trade secret
<geist>
But outside of that usually there’s probably less blobs of ‘firmware’ than on a typical PC
<geist>
Well if you’re working on the product it’s probably available to you, even if you dont personally build it
<klys_>
do you have a few megabytes to look forward to?
<rpnx_>
Well, I can't even build C++ right now
<geist>
Usually you and the vendor have some sort of shared git repo and can send patches back and further
<rpnx_>
When I try to
<geist>
But then by the time it hits a product a lot of that code is just prebuilt
opal has quit [Ping timeout: 258 seconds]
<rpnx_>
Oh wait I'm dumb
<rpnx_>
I didn't even put C++ in enable_languages
<clever>
epony: in the case of the rpi, there are 3 blobs that occur before the arm core runs the user supplied kernel (typically linux, but anything that can run on arm fits)
<epony>
arm* are cores, but what you have as an IC is a lot more than that, it's an entire System on Chip (SoC) and even different models by the same vendor may differ too much adn required different set of firmware and binary payload
<clever>
epony: the maskrom, the .bin stage, and the .elf stage
<rpnx_>
CMake has the best error messages sometimes...
<epony>
there is firmware in the processor SoC too, which you don't bother to work with, but is there
<klys_>
opensbi, uboot, and...
<geist>
You can bet that apple has access to all of the source on their devices
<epony>
in about at least several locations, similar to the controllers on your generic PC and similar to the BIOS payloads
<geist>
But that’s cause they are total control freaks
<epony>
if they were, they'd have their own and not Arm* cores
<epony>
I think they are vendor / implementer like the others using Arm* cores
<rpnx_>
Now, the exception handling and ctor/dtor stuff is still missing
<geist>
Anyway like i said there’s a difference between the the device maker sees as a blob, and what the end user sees
<rpnx_>
So I'd have to reimplement librt and so on.
opal has joined #osdev
<klys_>
yes, there is. also, the kernel dev isn't likely the device maker either
<epony>
except in maybe Apple's case and a few other similar like Microsoft and Google specific products
<klys_>
so, epony, what's the current ios microkernel if you know
<epony>
where maker is the company that ordered the CPU / SoC batch, not making these themselves, but getting that done with fabless foundries and device integrator companies
<epony>
in that sense "Apple" does not "make" anything, but get it designed, ordered, programmed and sold / managed as services (same for the other similar software-device vendors)
<geist>
Uh, i think apple would extremely beg to differ
<geist>
If there’s a device maker that really designs their own shit its apple
rpnx_ has quit [Quit: This computer has gone to sleep]
<bslsk05>
developer.arm.com: Documentation – Arm Developer
<rpnx__>
For arm64
<geist>
Just saying go into it with eyes wide open. As a kernel developer that deals with c++ in the kernel, it’s quite powerful but also a lot of responsibility
<geist>
And i wouldn’t take it on at the same time as learning kernel stuff
<geist>
rpnx__:not by a long shot
<geist>
That’s the manual to a cpu from 2006
<geist>
What you want is the armv8 arm architecture manual
<geist>
We call it the ARM ARM
<rpnx__>
Ok, that would explain why I cannot find how to set up more than 32 bits on mmu :)
<geist>
And armv8 is the version of the arm architecture that added 64bit mode
<geist>
So what you’ll find, and this is different from x86, is there is a core architecture manual
<geist>
It explains and defines what the ARM architecture is. Basically the blueprints for how any given core implementation would implement the ARM architecture
<geist>
then there are multiple cores that each have their own manual
<geist>
Those manuals are much smaller because they’re basically describing how their cpu implements the ARM arch
<geist>
Arm1176 is from about 2006. It was a later mode implementation on armv6
<geist>
Armv7 came along shortly afterwards and then armv8 came along in the early 2010s
<bslsk05>
en.wikipedia.org: Comparison of instruction set architectures - Wikipedia
<klys_>
how about 6809, pretty reduced eh
<epony>
these designs are historic and go back 50 years
<klys_>
hmm I didn't realize the 6809 was big endian
<epony>
the popular ones are LE
<epony>
for CPU the endiannes optimisations lead to that, for NET the serialisation optimises for BE
<klys_>
well I have a bunch of dip sockets and some copper clad board, just need some hcl and an iron and I could use the press-n-peel to put together a 6809 board
rpnx_ has quit [Quit: This computer has gone to sleep]
<epony>
one of them you need
rpnx_ has joined #osdev
<rpnx_>
hum
<rpnx_>
I wish I didn't d/c every time my laptop went into sleep mode.
<clever>
rpnx_: run an irc client on another box, under screen, then ssh in and `screen -x`
<rpnx_>
If I wanted to learn a terminal IRC client...
\Test_User has quit [Ping timeout: 268 seconds]
\Test_User has joined #osdev
<rpnx_>
I wonder if I could make an OS with no terminal :)
<rpnx_>
GUI only
<rpnx_>
I think this mmu stuff will require me to just read the docs throughly, there doesn't seem to be many easily digestible summaries of how to set it up.
<bslsk05>
github.com: raspi3-tutorial/mmu.c at master · bztsrc/raspi3-tutorial · GitHub
Oshawott has quit [Ping timeout: 252 seconds]
<clever>
rpnx_: its far simpler when using pure identity paging, because you can just start in no-mmu C, generate the tables, turn the mmu on, and basically nothing changes
<clever>
the LK example i had linker earlier is more complex, because it wants to run from some high address, and the compiler/linker assumes the code is running from that address
<clever>
so if its not mapped correctly, C code just implodes
<clever>
which means having to generate the paging tables with asm instead
<rpnx_>
right
<rpnx_>
But identity paging will not allow me to set up the userspace
<clever>
you then have 2 options
<clever>
1: break the code up into 2 chunks, a loader written in C and linked for a low addr, that generates the paging tables to map the 2nd chunk mapped to a high addr, and jump to it
<clever>
2: write that 1st chunk in position independant asm, so it can be included in the same build and it wont care that its initially loaded to the wrong addr
<rpnx_>
So, if I understand correctly, it's using 512 pointers for the page table, and those are pointers to whereever.
<rpnx_>
Or possibly 1024
<clever>
512 for that L0 table i think, this code is complicated by putting L0, L1, L2, and L3 into the same array
<clever>
personally, i would have used multiple seperate arrays
<bslsk05>
github.com: rpi-open-firmware/mmu.c at master · librerpi/rpi-open-firmware · GitHub
<clever>
this is how i did it on 32bit arm
<clever>
for 32bit, the L0 entries each cover a 1mb chunk of the virtual space, and the hardware supports 1mb pages
<clever>
so i can just skip every other layer
\Test_User has quit [Quit: e]
<JerOfPanic>
morning
<rpnx_>
So it seems it eventually just points to the start of a page and has some extra bits for controlling things like execute and so on
<rpnx_>
So this isn't the same "page table" as I was thinking of
<rpnx_>
Fully hardware, I would need some other way to keep track of e.g. what processes are using what pages and such
<clever>
rpnx_: each entry in the L0 table, is pointing to the address of an L1 table, which must be page-aligned
<clever>
and then each entry in the L1 table, is pointing to a new L2 table
<clever>
so it forms a giant tree
<clever>
at some steps, you can set a special flag, to say that your pointing to a huge page of mapped data, rather then another table
<clever>
and that terminates the tree branch early
rpnx_ has quit [Quit: This computer has gone to sleep]
kof123 has quit [Ping timeout: 268 seconds]
<JerOfPanic>
I am working on FPU support for my multitasking, got any source code like this? Like e.g. storing FPU registers in variables? And returning an FPU state?
<JerOfPanic>
Intel documentation is highly versable.
<JerOfPanic>
I think I should do a FWAIT on FPU.
<JerOfPanic>
FSAVE, FLDENV
<JerOfPanic>
should I check for error conditions?
<JerOfPanic>
"The contents of the x87 FPU status register (referred to as the x87 FPU status word) can be stored in memory using the FSTSW/FNSTSW, FSTENV/FNSTENV, FSAVE/FNSAVE, and FXSAVE instructions. It can also be stored in the AX register of the integer unit, using the FSTSW/FNSTSW instructions."
<JerOfPanic>
this is very verbose
\Test_User has joined #osdev
xenos1984 has quit [Read error: Connection reset by peer]
<bslsk05>
www.felixcloutier.com: FXSAVE — Save x87 FPU, MMX Technology, and SSE State
<clever>
rpnx_: i think there are 2 seperate things, one for just making every page bigger, and then another for terminating the page-table walk early, and making even bigger "pages" from a collection of the 1st one
Clockfac1 has quit [Ping timeout: 268 seconds]
rpnx_ has quit [Quit: This computer has gone to sleep]
<JerOfPanic>
thinking
xenos1984 has joined #osdev
\Test_User has quit [Ping timeout: 252 seconds]
kof123 has joined #osdev
hbag has quit [Remote host closed the connection]
\Test_User has joined #osdev
bauen1 has quit [Ping timeout: 255 seconds]
epony has quit [Remote host closed the connection]
gildasio has quit [Read error: Connection reset by peer]
foudfou has quit [Remote host closed the connection]
foudfou has joined #osdev
gildasio has joined #osdev
gildasio has quit [Ping timeout: 258 seconds]
gildasio has joined #osdev
bauen1 has joined #osdev
ZipCPU_ has joined #osdev
ZipCPU has quit [Ping timeout: 255 seconds]
ZipCPU_ is now known as ZipCPU
zaquest has quit [Remote host closed the connection]
<bslsk05>
gnats.netbsd.org: NetBSD Problem Report #56979: fork(2) fails to be signal safe
xenos1984 has quit [Read error: Connection reset by peer]
eroux has quit [Ping timeout: 252 seconds]
xenos1984 has joined #osdev
eroux has joined #osdev
frkzoid has quit [Ping timeout: 244 seconds]
Ali_A has joined #osdev
netbsduser has joined #osdev
lkurusa has joined #osdev
<mrvn>
when I build spack it links against liba, libb, libc, libd. I wonder when they will get a libe.
gog` has joined #osdev
m5zs7k has joined #osdev
nyah has joined #osdev
TheSpecialist666 has joined #osdev
<TheSpecialist666>
I just want to warn everyone here to stay away from Discord OSDev. I worked hard to wrote a 64-bit OS which is already a challenge and I went there for help on a complicated problem with the GDT. Everytime they fixed a problem there was another one.
<TheSpecialist666>
I dont like debugging and I am new to it. THey still made me use GDB and other crap which is like using a hammer to fix a watch. When I had more problems later I asked again and all they did was bitch at me for not giving a diff for what I changed
<TheSpecialist666>
Which they said was why it broke. I don't even use patchutil and diffutil so of course I don't have a fucking diff.
<TheSpecialist666>
I almost had enough of 64 bit now but I would like to know why I get a triple fault https://github.com/TheSpecialist666/MiniOS on my OS. When you have figured it out made an issue on the repository.
<bslsk05>
TheSpecialist666/MiniOS - Hobby OS project (0 forks/2 stargazers)
TheSpecialist666 has quit [Quit: Thanks in Advance]
kof123 has quit [Ping timeout: 268 seconds]
<Mutabah>
... well, that's an attitude
<Mutabah>
While I've heard that the discord server can be a little brash... I assume they were asking for people to just fix the problem
<sham1>
More than likely
SGautam has quit [Quit: Connection closed for inactivity]
<netbsduser>
disappointed to read that
<netbsduser>
i spent over an hour last night assisting them to figure out a triple fault, and i went to some effort to outline why we used each tool in the toolbox to figure it out
<Mutabah>
yeah, that was my rough guess
gog has quit [Ping timeout: 252 seconds]
gog has joined #osdev
gog` has quit [Ping timeout: 252 seconds]
<netbsduser>
others assisted as well, including the author of the bootloader they used who noticed some other problems (the bootloader Limine provides a callback for printing to the framebuffer during early boot, but you've got to preserve the expected GDT layout + keep the framebuffer identity mapped)
<netbsduser>
oh well, i will just chalk it up to their frustration after a pretty rough introduction to the wonderful world of the bare metal
<Mutabah>
Yeah, that's probably it
isaacwoods has joined #osdev
<sbalmos>
Learning curves are steep, sniffle sniffle
<netbsduser>
there is no royal road to operating systems, and only those who do not dread the fatiguing climb of its steep paths have a chance of gaining its luminous summits
gog has quit [Ping timeout: 268 seconds]
<sbalmos>
if you consider a small campfire out in the wilderness luminous, fair enough
<heat>
>When you have figured it out made an issue on the repository.
<heat>
wow are you trying to nerdsnipe me?
rpnx has joined #osdev
<heat>
fork() in a signal handler is easily of the cursediest cursed thing ever
rpnx has quit [Ping timeout: 244 seconds]
isaacwoo1 has joined #osdev
matt__ has joined #osdev
isaacwoods has quit [Ping timeout: 244 seconds]
<heat>
klys_, btw, the amount of firmware on a typical machine is "a lot"
<heat>
the amount of proprietary blobs in that firmware is also "a lot"
<heat>
on a typical x86 system, you have the intel ME image (blob, not shared with vendors), the FSP (does a lot of the platform initialization, memory training, etc; afaik, not shared with vendors), a shit ton of proprietary modules that AMI and all the other crappy downstreams build on EDK2 (proprietary, shared with vendors), some proprietary Intel modules that are shared with vendors (like CSM), EDK2 (FOSS, although possibly modified)
<mrvn>
Give a man a bugfix and he will have fixed a bug. Teach a man to use GDB and he will fix bug for live. Excpet when the man is TheSpecialist666. Then he will just go on irc and command people there to fix his code.
<mrvn>
heat: I have code where everything (but the start) runs in signal handlers. Only way to change the stack.
<heat>
then each PCI device has a ROM, which is usually a EFI driver blob; Intel platforms' iGPU also has the VBT (video BIOS table) which is a non-free blob you have to copy (or build yourself, good luck have fun, most people just take it from the blob firmware)
<mrvn>
user space multithreading in C is fun.
<heat>
ACPI is, you guessed it, a bunch of blobs, although usually built dynamically in firmware
epony has quit [Remote host closed the connection]
epony has joined #osdev
pretty_dumm_guy has joined #osdev
gareppa has joined #osdev
gareppa has quit [Remote host closed the connection]
Mutabah has quit [Ping timeout: 268 seconds]
Mutabah has joined #osdev
carbonfiber has joined #osdev
terminalpusher has joined #osdev
gareppa has joined #osdev
Ali_A has quit [Quit: Connection closed]
gareppa has quit [Quit: Leaving]
Mutabah has quit [Ping timeout: 240 seconds]
Mutabah has joined #osdev
bauen1 has quit [Ping timeout: 260 seconds]
xenos1984 has quit [Ping timeout: 260 seconds]
xenos1984 has joined #osdev
gildasio has quit [Ping timeout: 258 seconds]
opal has quit [Ping timeout: 258 seconds]
lkurusa has quit [Quit: I probably fell asleep (or went out). Who will ever know.]
gildasio has joined #osdev
opal has joined #osdev
FreeFull has joined #osdev
nur has quit [Ping timeout: 268 seconds]
Matt|home has joined #osdev
bauen1 has joined #osdev
gog has quit [Ping timeout: 252 seconds]
matt__ is now known as freakazoid333
ghee has joined #osdev
ghee has quit [Client Quit]
gog has joined #osdev
terminalpusher has quit [Remote host closed the connection]
terminalpusher has joined #osdev
rpnx has joined #osdev
dude12312414 has joined #osdev
nur has joined #osdev
dude12312414 has quit [Client Quit]
nur has quit [Quit: Leaving]
nur has joined #osdev
freakazoid333 has quit [Ping timeout: 255 seconds]
lkurusa has joined #osdev
lkurusa has quit [Client Quit]
<mjg>
i just came up with a funny idea
<mjg>
consider a preemptible kernel and something which needs to disable preemption in the fast path
<mjg>
how do you avoid the branch on re-enabling it
<mjg>
ez
<mjg>
in the preemption ipi handler you check rip and if that's within the preempted func, you overwrite the return address with something which preempts (and stash the real return address somewhere in pcpu)
<mjg>
i think that's pretty decent, will implement probably next week
<geist>
problem there would likely be some sort of issue with the stack and whatnot. or at least the thing you replace the PC with would have to assume the stack is in a bad place, save all the regs, etc
<geist>
uestion is is it worth all the extra effort to avoid a branch, where modern machines branch predict the shit out of stuff like that
Ali_A has joined #osdev
<mjg>
geist: for something like malloc or unlock i do think it's 100% worth it
<geist>
okay
<mjg>
it can make fast path malloc juse have one branch: doy ou have enough in the per-cpu cache
gareppa has quit [Remote host closed the connection]
Ali_A has quit [Quit: Connection closed]
<moon-child>
mjg: yep, I came up with that trick a while ago
<mjg>
moon-child: fu man
<mjg>
moon-child: )
<moon-child>
been meaning to do a proper writeup to have something to refer to
<moon-child>
lol
<mjg>
on a serious note, one thing to watch out is tail call optimization
<mjg>
basically need to only patch up whitelisted sites
<zid>
-ftail-calls-are-banned-y
<zid>
o
<moon-child>
mjg: another application I came up with is preemptive ipc without ipi
<moon-child>
not _quite_ sure if it works, but I think it does
<mrvn>
mjg: if you disable IRQs then how would the ipi handler get called?
<moon-child>
that's the point; you don't disable irqs
<moon-child>
the isr itself is then responsible for ensuring that nothing untoward happens in the critical section
<mrvn>
why? then anything can preempt and you need a lot of branches to work around it
demindiro has joined #osdev
<moon-child>
why do you need a lot of branches?
<mrvn>
is sti/cli so expensive that you rather branch and meddl with return addresses?
<mrvn>
moon-child: to check if you are in any of the critical sections
<mrvn>
and you need that in every isr
<moon-child>
it's overhead that you only pay in the isr, when your performance is killed anyway
<moon-child>
and it's not too bad
<mrvn>
O(log(critical sections))
<demindiro>
If I'm following: you're trying to avoid a branch by overwriting the return address?
<mrvn>
you also loose all the tail calls as you mentioned.
<moon-child>
mrvn: not exactly
<moon-child>
it's O(log(# all critical sections that you might want to enter from a single isr call))
<moon-child>
if in one isr I want to access shared state X, and in another I want to access shared state Y, in each of those isrs I only have to check for one critical section
<moon-child>
even though there's a total of 2 critical sections in the kernel
<moon-child>
common case is just malloc (was why I came up with it too); then you're only checking one thing
<mrvn>
moon-child: hmm. so X fires and then Y fires. In Y you see that you are in the middle of X so you fiddle with the return address of X so that it calls do_Y instead and delay the isr?
demindiro has quit [Quit: Client closed]
<moon-child>
no; the point is that X and Y can run concurrently
<moon-child>
because they're touching different pieces of shared state
<moon-child>
think of it like a lock. You implicitly lock X by being in the region of code that modifies X. But locking X doesn't mean you have to lock Y too
<mrvn>
then what is the case where you fiddle with the return address?
<moon-child>
when you start modifying X in the main kernel, and then you get interrupted, and the isr wants to modify X too
<mrvn>
If I understand you right you are implementing a verry hackish wait-queue for a lock.
<moon-child>
yep!
<mrvn>
That will totally blow up with SMP by the way
<moon-child>
yes, that's why it's only for arbitrating core-specific stuff (such as, for example, malloc)
<mrvn>
Doesn't x86 also have a return address predictor that will mispredict when you fiddle with the return address?
<moon-child>
mjg: he doesn't like the stack trick :\
<moon-child>
mrvn: sure; the point is to avoid branches in the hot path
<mjg>
i'm busy for next 15-20 mins
<mjg>
will flame later
<mrvn>
moon-child: for the stack trick you need a function call. I think sti/cli will be cheaper than a function call.
<moon-child>
malloc is usually a function call anyway
<mrvn>
only if the whole function is one big critical section
<moon-child>
malloc is usually one big critical section
<moon-child>
but, well, ok, say the critical section is smaller than a whole function
<moon-child>
that just means that your 'scheduled' code runs a bit later than it otherwise would
<moon-child>
which is fine
<mrvn>
well, not here. it has process local data (the address space) and core local data (free pages for the core) and global data (reserve of free pages) that all need different locking.
<moon-child>
talking about kernel malloc here (presumably, if talking about isrs rather than signals), so you'd only hit the last two, and the third case is the slow one anyway
<moon-child>
again, this is about speeding up the hot path
<mrvn>
yeah, the third needs a full lock for SMP.
<mrvn>
The address space might need a full lock if you have threads for the process running on other cores
<mrvn>
kmalloc won't have that
<mjg>
so
<zid>
faputa-hime so cute :(
<mjg>
cli and sti are still quite slow, but i don't remember exact latency
<mjg>
the current code spends a branch to figure out whether it needs to go off cpu
<mrvn>
are they serializing?
biblio has joined #osdev
<mjg>
fair quesation, i don't remember
<mjg>
looks like no
<mjg>
anyhow
<mjg>
with the aforementioned hack the fast path does not have to check if preemption is needed
<mjg>
only the comparatively rare case of getting preempted there needs to do more work
<mjg>
which imo is a great tradeoff to make
<mjg>
i also have a wip hack to make sleepable mutexes be unlockable without atomics
<mjg>
which requires preemption to be disabled around it
<mjg>
not having to check for it in the routine would be A+
<mrvn>
what it the isr fires twice?
<mrvn>
you can only do the stack fiddling once
<mjg>
twice when
<mjg>
while within the preemption disabled area?
<mrvn>
yes, malloc can take some time
<mjg>
that's inconsequential, consider the current code
<mjg>
the preemption handler just keeps finding that preemption is disabled
<mjg>
and denotes it needs to be handled once enabled
<mjg>
i literally only need to do the stack fiddling once
<mrvn>
but it records the original return address in some variable and relaces it on the stack. so the 2nd call overwrites the safed return address.
<mjg>
and i can trivially check that i alreday did it -- return address is the special routine
<mjg>
which would not happen without preemption
<mrvn>
but then you need a counter for how often you tried to replace the address
<mjg>
i don't
<mjg>
you do realize that at the end of the day i only get preempted once, with or without the hack
<mrvn>
mjg: the example from moon-child wasn't about preemption but about accessing shared state.
<mjg>
i did not see his example
<mjg>
i'm saying the above should work for what i intend to use it for
<mjg>
which is protecting per-cpu state
<mrvn>
not without dropping interrupts
<mjg>
if interrupt handlers handlers are to legally mess with that state, sure
<mjg>
but that's not part of the state i'm concerned with here
<mjg>
for example in freebsd the internal allocator normally must NOT be called from irq handlers
<mjg>
so you are guaranteed to be safe with mere preemption disablement
<mjg>
my hack does not loosen anything here and removes the branch from the common case
<moon-child>
what's a sleepable mutex? The kind where you say 'wake me up if it's unlocked, or if x time passes without anything happening'?
<mjg>
moon-child: that's the "owner went off cpu, so i'm going off cpu too"
<mjg>
moon-child: "and i'm denoting that in the lock"
<mrvn>
mjg: so you only use a wait queue if the mutex is held by a non-running process?
<moon-child>
so you follow the owner to its new cpu?
<mjg>
mrvn: thread, yes
<mjg>
moon-child: so you go off cpu and propagate your priority to the sucker if applicable
<mjg>
the solaris way :>
<mrvn>
having a non-preemptible microkernel makes all this so much simpler.
<mjg>
mrvn: i agree, but i did not make it this way ;)
<mjg>
and i can't just make it not preemptible by default
<mrvn>
also not having threads
<moon-child>
well
<mrvn>
.oO(This process wants to malloc some memory, let fiddle with it's page table. I know no other core will access that)
<mjg>
who is doing that
<mrvn>
me
<mjg>
lul
<mjg>
that's some... interesting ideas you got there mate
<mrvn>
My kernel is based on message passing. There is no shared state between processes.
<moon-child>
so you have to copy everything all the time?
<moon-child>
.oO( the rust methodology, applied to os design )
<mjg>
speaking of
<mjg>
is there a perf comparison of rust stuff vs whatever else?
<mjg>
i don't mean "we implemented 2 totally different algos" which i managed to find osme time ago
<mjg>
:[
<moon-child>
I wouldn't expect any difference in microbenchmarks (vs c)
<klange>
absolute classic: beating C by writing a horrible implementation in C and a good implementation in the other language!
<moon-child>
I would expect there to be some impact on overall program design, but that is much harder to measure sensibly
<mrvn>
moon-child: I pass pages around.
<mjg>
klange: you bet
<moon-child>
can I write an audio server?
<moon-child>
can't really 'pass pages' there :P
<mrvn>
Does rust copy stuff around all the time? Isn't it about passing by reference and still knowing who owns the data at all time?
<mrvn>
moon-child: why not? You app fills a buffer, say 64k, with music and then passes that off to the sound card driver.
<moon-child>
for music, sure
<moon-child>
for low-latency stuff, less so
<mrvn>
4k sound data isn't verry long
<moon-child>
you wanna ring buffer which is continuously filled by the client and emptied by the server
<klange>
4k sound data is 23ms.
<moon-child>
re rust copying: yes, rust may require you to copy where another language would allow you to share
<klange>
Assuming stereo, 16-bit, 44.1kHz :) only 21 at 48!
<mrvn>
can't do that at the moment. Might be worth as optimization for streams but it's outside the design currently.
<zid>
I only use 192kHz audio from a cassette
<mjg>
moon-child: i'm moslty worried about branch predictor
<klange>
Only 5ms at 192kHz - that's less than a frame at even at 140Hz!
<zid>
don't forget 5.1
<moon-child>
depends on your framerate :P
<klange>
I literally said 140Hz.
<zid>
moon pay attention
<zid>
jesus
<moon-child>
oh I thought you were conflating with video frame
<zid>
moon-child more like moon-mmon amirite
<moon-child>
ok cool
<moon-child>
oh wait you were
<moon-child>
nvm
scoobydoo_ has joined #osdev
scoobydoo has quit [Ping timeout: 252 seconds]
scoobydoo_ is now known as scoobydoo
<moon-child>
is confusing because in audio context I interpret 'frame' to mean sample x channels
<klange>
I just call that a stereo sample, but I come from a different audio background.
<zid>
a frame is one round of a game of snooker
<zid>
why are you talking about audio
<mrvn>
But hey, my scheduler can handle really big process counts. I've tested it with 786432 processes, one per pixel for a 1024x768 framebuffer.
<moon-child>
mjg: why?
<klange>
A frame is what I never bother to put my photos in.
<zid>
I wonder where this jargon comes from
<zid>
a frame meaning a logical unit of something
<mrvn>
A frame is that thing around the picture holding it up.
<moon-child>
a frame is a context for something
<moon-child>
a wrapper
<moon-child>
in this case, the context is temporal--the frame is a snapshot of a bunch of states, which are connected in time
<klange>
A frame is the core structure of something (eg. the wooden frame of a house) or a wrapper (eg. a framed painting)
<moon-child>
mjg: I mean, with the current setup, you'd miss that branch anyway, right?
<mjg>
moon-child: i mean in rust progs vs c
<moon-child>
oh, why?
<mjg>
not worried in the preemption hack case
<mjg>
i presume it adds some branchin'
<moon-child>
like what? I mean, presumably boundschecks, but those should predict correctly
<mjg>
more branches in general == more conflict potential
<mrvn>
I assume the check_for_critical_section is written so the non mtching casde is the predicted path and the hit branches to some cold code and does the stack fiddling.
<moon-child>
mjg: sure
<moon-child>
(this is why I want branch hints)
<mrvn>
does x86 have any branch hints?
<moon-child>
used to, then they got rid of them
<moon-child>
mjg: oh, agner says that on some cpus, correctly-predicted never-taken branches won't take up a btb entry
<moon-child>
(but that doesn't help if a legitimate btb entry conflicts with a lolbranch)
<epony>
long jump
epony has quit [Remote host closed the connection]
terminalpusher has quit [Remote host closed the connection]
ckie has quit [Quit: *poof*]
ckie has joined #osdev
rpnx has quit [Ping timeout: 252 seconds]
rpnx has joined #osdev
epony has joined #osdev
qubasa has joined #osdev
smach has quit [Remote host closed the connection]
smach has joined #osdev
gildasio has quit [Ping timeout: 258 seconds]
MiningMarsh has joined #osdev
smach has quit [Remote host closed the connection]
smach has joined #osdev
sav_ has joined #osdev
sav_ has quit [Client Quit]
gildasio has joined #osdev
frkzoid has quit [Ping timeout: 255 seconds]
<mjg>
hey armz, do you happen to know how to silence this warn:
<mjg>
> warning: use of PC in the list is deprecated
<mjg>
stmia r3, {r4-r12, sp, lr, pc}
<mjg>
not an arm person myself, from what i hear the use of pc there is unavoidable
<zid>
march= it somehow?
<mjg>
i already march it, no dice
<mjg>
now that i asked
<mjg>
if (MI.getOperand(OI).getReg() == ARM::PC) {
<mjg>
Info = "use of PC in the list is deprecated";
<mjg>
thanks clang
smach has quit [Remote host closed the connection]
smach has joined #osdev
<zid>
lol
rpnx has quit [Read error: Connection reset by peer]
rpnx has joined #osdev
<moon-child>
#pragma gcc diagnostic ...?
Emil_ is now known as Emil
<mrvn>
mjg: why would you store the pc?
<mrvn>
and is that the address of the stmia or the opcode after?
<moon-child>
presumably because you wanna know what the pc was
<moon-child>
(eg could be for logging, to get a source location)
<heat>
and how tf do you deprecate an instruction
carbonfiber has quit [Quit: Connection closed for inactivity]
<geist>
mjg: which arm core are you compiling for?
<geist>
and/or which arm version? (ie, armv4, armv5, etc)
<geist>
but that being said, why are you storing PC there?
<geist>
that's usually pretty strange thing to do
<heat>
i think the real question is "why are they deprecating it"
<heat>
like, its a valid instruction, what's the issue?
<heat>
(and who's deprecating it? llvm? certainly not arm?)
<geist>
no, i think it's deprecated because it's pseudo undefined, in some cores
<geist>
but again, it's kinda an XY problem. there's very very little reason to do exactly that, so i kinda wonder why you are?
<geist>
store multiple of PC is generally not what you do. it's very common to `stmia ... { ..., lr }` and then later on `ldmia ... { ..., pc }`
<geist>
but the idiom of storing PC is pretty odd, since it's going to best case write the PC of the instruction 2 ahead, so the only reason you'd really want to do that is if you're going to branch in the next instruction, and then are writing something to return to the instruction after the branch
<geist>
which is feasible, but would be pretty specialized case
<heat>
why is storing pc undefined?
<geist>
my guess is since it's a very specialized case, and stmia is a multi cycle instruction, and by definition the last bit written is the last register, it's going to play havok with the pipelie
<geist>
so probably thinking there's some cpu somewhere where that's undefined
<geist>
ie 'we dont wanna deal with that specialized case'
netbsduser has quit [Remote host closed the connection]
<geist>
ah no i think it's for ARM/thumb reasons
<geist>
arm does straight up say PC is depreciated i the list, so clang is not full of shit
<geist>
(looking in the armv8 arm arm)
<heat>
deprecating a register is definitely new
<heat>
will the designs just stop decoding that instruction?
<geist>
here's why i think it's the case: ARM32 ISA has 16 bits in the stm/ldm instructions, so you can do it (though there are limitations butnot this)
<geist>
thumb1 only has 8 bits, so it can oly encode r0-r7
<geist>
thumb2 only has 14 bits, and one extra one for LR, but no bit for PC
sonny has joined #osdev
<geist>
so, i think what's going on here is ARM expects the 'unified' assembly syntax (some old thing they rolled out years ago) to work against pretty much all modern arm32 ISAs (thumb2 and arm32)
<geist>
so they basically deprecate using constructs that can't be emitted in both thumb2 and arm32
<geist>
and thus clang is trying to steer you away from it
<geist>
if you want to follow along i'm looking at DDI0487G_a_armv8_arm section F5.1.224 (the section describing STM instruction) page F5-2020
<geist>
so it's nothing to do with microarchitecture and mostly to do with ISA compatibility.
<geist>
if you're writing hard asm in a .S file and you're fixing it to .arm i think you're okay, if you're doing it in inline asm or whatnot clang is warning you not to do it because it would break depending on what instruction set the compiler is targetting (and it doesn't know what you want to do there)
<geist>
it's interesting a few pages before how much wiggle room ARM givesn themselves to invalid encodings of these instrutions
<geist>
it has all sorts of things like 'if you include no registers in the stm/ldm list here's a list of things that can happen'
<geist>
and undefined, nop, and more interestingly
<geist>
"The instruction operates as an STM with the same addressing mode but targeting an unspecified set of registers. These registers might include R15. If the instruction specifies writeback, the modification to the base address on writeback might differ from the number of registers stored."
<mrvn>
heat: as geist says the PC is incremented in parallel with the instruction and pipelining so you don't know what value you get when storing the PC. The encoding for the opcode has a bitfield of registers, same for stm and ldm. but only for ldm it's always defined what happens if you include PC.
<mrvn>
geist: so you might buffer overflow your storage, nice.
<geist>
my guess is they're giving themselves wiggle room for 'some schleppy thumb -> arm64 decoder and/or emulator can skip some logic for invalid encodings and just yolo it'
<geist>
shows how much they care about 32bit arm nowadays
<mrvn>
they should have left it undefined then they could reuse the opcode for something else if they need one.
<geist>
well, undefined implies there's logic to detect it
<geist>
vs this which is basically unpredicatable
<mrvn>
nah, not illegal opcode, just undefined
<geist>
ah but 'undefined' means something extremely specific in arm world. that means triggers an undefined opcode
<mrvn>
unspecified
<geist>
what they're doing here is saying 'it'll yolo you in any number of ways' which is effectiely what you're saying
qubasa has quit [Ping timeout: 252 seconds]
<mrvn>
yeah, bad word choide there with "undefined opcode"
qubasa has joined #osdev
<mrvn>
"illegal opcode" has a much harsher ring. .oO(I know what this is and I'm not doing THAT)