<dasabhi>
geist: porbably explains why MIT ported xv6 to riscv, i am just getting started with riscv
<geist>
yah it's almost certainly going to be the thing that lots of universities teach with now
<mrvn>
oh yeah, lets teach on some hardware none of the students have and most can't afford to buy.
<zid>
That was always the idea of riscv to begin with from what I understand
<zid>
replace MIPS as the teaching arch
X-Scale has quit [Ping timeout: 256 seconds]
<mrvn>
Anyone have and devs on a 64bit MIPS?
ripmalware_ has quit [Remote host closed the connection]
ripmalware_ has joined #osdev
Jari--- has joined #osdev
<Jari--->
Morning
<mrvn>
evening
<moon-child>
afternoon
<Jari--->
In Japan it is noon?
<zid>
we just had one
<mrvn>
noon? happens quite frequently.
<klange>
it's 9:35am
<klange>
lol
<mrvn>
I wagely remember there being a delete_iterator from my pre c++11 days. Was that ever a thing? What has replaced that?
netbsduser` has joined #osdev
X-Scale has joined #osdev
netbsduser has quit [Ping timeout: 246 seconds]
pretty_dumm_guy has quit [Quit: WeeChat 3.5]
<dasabhi>
you guys think we will get riscv machines soon enough in the cloud?
<dasabhi>
i had some virtualization ideas for riscv and xv6, but i doubt i should mess around with virtualization on qemu
<klange>
I see no real incentive for riscv-based cloud resources at this point in time. Hardware costs are the main factor at the moment, but ecosystem is also a key thing to keep in mind.
<geist>
probably not for a while. i think the H extension only just got ratified
<geist>
so need some hardware to actually exist to get real virtualization
<geist>
i did think i remember seeing something about KVM support for it going in? I'm kinda curious now, should sit down to try to grok the H extension
<geist>
i think qemu supports it now
<geist>
mrvn: somewhere i have a mips dev board somewhere, can run linux. i think it's 32bit though?
<dasabhi>
qemu can support the H extension even before the guys at berkley ratify it?
<dasabhi>
so in theory i can run a really shitty rsicv hypervisor with emulated ring -1 ? LOL
<geist>
qemu sure why not? most likely it's basically stable for a long time before it gets ratified so qemu is probably pretty safe implementing it. may actually be the main development platform for the extension itself
<dasabhi>
yeah that makes sense
<geist>
though i thought it recently got ratified. lemme see
Likorn has quit [Quit: WeeChat 3.4.1]
<klange>
I'm still in the "riscv seems neat, let me know when there's reasonable hardware for it" stage... purplexing to me that so many of the "budget" options are things with a dozen 'media engine' things bolted on.
<geist>
also FWIW I just saw that the hypervisor extension is at version 1.0 and in the latest priviledged spec 2.2
<geist>
so i guess it's ratified
<mrvn>
Does riscv beat out ARM on the MIPS-per-Watt?
<geist>
i dont think that's an arch specific question
<geist>
that has everything to do with implementation details
<geist>
also depends on what the sector is. is this a deeply embedded machine? something with page tables? etc
<mrvn>
geist: cloud service
<geist>
in the super deeply embedded space i'd assume that an 'e' spec riscv core could get pretty close to a cortex-m0 in terms of implementation, since it's about as complex
<geist>
oh who the hell knows. no such hardware exists
<heat>
ask western digital
<heat>
or nvidia
<heat>
they're big fans of RISCV ;)
<heat>
geist, issue with getting a real board rn is that all the CPUs are still crap
<geist>
sure
<heat>
paying 400 euro for a top notch SiFive board and getting half the performance of a rpi 4b is... underwhelming
<geist>
it all depends on what you want to do with it. i fiddle with vaxen and 68ks and by definition those cpus are 'crap' too
<heat>
yeah but those were designed a long time ago, not literally now
<geist>
i hear you loud and clear
<geist>
i assume some day hardware will catch up in which case i'll be ready to roll
<geist>
but if you wanna use real hardware and only happy if it's performant, that's totally a valid call
<heat>
right
<heat>
I don't need performance, just decent
<mrvn>
performant? That just means the kernel crashes sooner. :)
<geist>
heat: then you have to define decent
<zid>
It'll be interesting to see how quickly they can make a crap isa fast
<heat>
but for 400 euro, yeah I definitely ask for performance at that price point
<geist>
sure. what are your requirements? there are various boards out there i can point you at if you'd like
<geist>
that are less than 400
<heat>
geist, run linux/my OS decently, with like 2010 perf(?)
<geist>
can yo ube more specific?
<geist>
like 32 bit? 64bit? how much ram? does it require hard ethernet?
<geist>
what about storage
<geist>
2010 perf what? an equivalent x86 at the time?
<heat>
oh yeah 64-bit for sure, and like 512MB possibly (although I could probably get it lower)
<zid>
2010 perf puts you at ridiculous perf if you're willing to upclock the chips of the time..
<heat>
storage should be rpi-like, ethernet would be nice
<geist>
the 2010 perf thing is unreasonable, but aside from that i think i can find something
<geist>
i have one on order, actually wondering when that'll come in
<zid>
2500 is a good single core ranking at 5GHz *today*, fwiw
<geist>
thats an actual sifive superscalar dual core + something < $400
<geist>
it's still $200 of course
<heat>
right, that's too much for me, for basically a toy board
<geist>
hmm, unclear when it ships though, maybe that's why my preorder hasn't come through, but i think that;s the best bet for something kinda rpiish
<geist>
then okay, what are your pricing constraints?
<geist>
keep in mind it's hard to get ahold of ARM boards of similar horsepower at that price either
<geist>
except rpi, (when it's available)
<zid>
They're low volume and that's damn near a custom part
<heat>
around the price of a raspberry pi 4b/400
<zid>
so $200 is good tbh
<geist>
yeah, rpi has set the bar so low i dont think *anything* can get down there that's not a rpi
<geist>
also you get wha tyou pay for since the broadcomm chip on it is a piece of crap
<geist>
well some of the odroid stuff is fairly low too, but keep in mind most of those are shipping with 10 year old arm cores too
<kazinsal>
ha, yeah, you can find a lot of neat weird cards like that
<geist>
kazinsal: oh did you hear i got the server machine to fail with a 3900x in it? so it's not the cpu per se
<kazinsal>
oh interesting
<zid>
moar volts
<heat>
can the CPU keep up with all the ethernet?
<zid>
It's not about the perf it's about sending a message
<zid>
8 times
<geist>
i just did a bios update and am running it some more to see if that magically fixes it, otherwise i'll get a new mobo or maybe switch the power supply
<kazinsal>
wonder if you've got some bad vdroop on one of the power supply lines yeah
<geist>
zid: well to be fair i have recently discovered ethernet bonding and how relatively nice it is
<geist>
and linux does a pretty good job with it
<zid>
ISDN was basically bonded dialup
<zid>
an OC-48 is 48 T1 lines bonded together etc
<zid>
it's always been a really normal thing
<geist>
my synology nas for eample has a 4 way bonded setup, and the unifi switch loves it
<geist>
thoug of course it only really helps if you have a lot of clients and their connections tend to hash to separate nics
<kazinsal>
yeah
<zid>
Can you do it like RAID and set the mtu 4x as big and get 1/4 of a packet over each bitwise
<zid>
then recombine them
<geist>
no that's not how it works. bascally the switch and the OS agree to the hashing algorithm and it does a L2 level hash of the connection so that ports from a single client arrive in order
<zid>
I know it isn't how
<zid>
I'm asing if it's possible at all
<zid>
It'd be funnier
<geist>
oh i suppose
<kazinsal>
I mean in theory it's possible but it wouldn't be clean
<kazinsal>
and I've never seen any NICs that would allow you to do that
<geist>
yah the reassembly across the nics would be hard
<zid>
Yea reassembly would be hard unless you were like.. rtosing
<bslsk05>
wiki.osdev.org: Loading files under UEFI - OSDev Wiki
<heat>
i should do that too
<heat>
"you could write an OS... but if you usE ONYX THE BEST OPERATING SYSTEM EVER GITHUB.COM/HEATD/ONYX IT WOULD BE A LOT EASIER"
<bslsk05>
github.com: GitHub - heatd/Onyx: UNIX-like operating system written in C and C++
<klange>
bzt wrote the whole article, so it's no surprise really
<kazinsal>
naturally
<heat>
klange, bzt isn't around anymore right?
<heat>
i want to remove that and not cause a flamewar
<kazinsal>
I could have sworn he was unbanned at some point
<klange>
bzt had many poor interactions in violation of rules, was unbanned after some time, and then proceeded to do the same thing again
<kazinsal>
some people just can't post good
<heat>
"Sadly it is not so easy, considerably more complicated than reading sectors," <-- how is using a filesystem driver with Open(...), Read(), Write() harder than reading sectors?
<klange>
It really is a shame because he was a solid technical contributor, when he wasn't shilling his own shit and starting fights.
<klange>
heat: I think he means compared to the EFI interfaces for reading block devices directly, which aren't too bad
<klange>
the filesystem APIs are full of stupid
<heat>
no they're not what
<heat>
tell me what stupids they have
arch_angel has joined #osdev
<geist>
klange: yah always a bummer when you have someone that just sits there and ruins their whole thing they built
<mrvn>
The switch could just fragment the frame and have the NIC or OS reassemble the frames.
<geist>
by just being a complete asshat
<kazinsal>
you can't fragment layer 2 frames
<mrvn>
heat: read/write has to keep track of the position. Use pread/pwrite. :)
<geist>
kazinsal: yah you'd probably need to define a new ethertype that just contains fragmented normal ethernet frames or something
<mrvn>
kazinsal: but nobody is using that for large payloads
<geist>
heat: maybe a compromise is to move the add down to a new section
<geist>
like some sort of link to projects that might help
<mrvn>
IP fragments just fine
<geist>
vs it just being an ad on the second sentence
<kazinsal>
and IP doesn't care about NICs and bonding and all that
<heat>
mrvn, it's a simple open() -> read/write() -> close() API with GetPosition and SetPosition to do lseek
<mrvn>
geist: can you set the hash method to use the sequence number of IP packets?
<kazinsal>
also IP fragmentation makes things just really goddamn complicated and it should be illegal
<geist>
i think we had this discussion before but ipv6 *does* allow fragmentation or not?
<geist>
or was it simply that routers cant do it because that's not the routers problem in v6?
<mrvn>
kazinsal: modern NICs de-fragment unfragmenetd IP packets. Meaning with a MTU=1500 you get 10k frames and such.
<heat>
yes they allow fragmentation on v6
<heat>
but it needs to be explicit
<heat>
routers can't do it
<heat>
you actively need to know the path's MTU to send a larger IPv6 message (or fragment it into chunks)
<mrvn>
geist: imho if you get fragmentation you are doing something wrong. It's not like the MTU varries in unpredictable ways across the internet.
<geist>
well, yah
<mrvn>
MTU = path MTU should the the default.
<heat>
?
<geist>
and yeah that's right, nic based fragmentation and reassembly is probably the main reason it still exists
<geist>
since it's very convenient for the stack to blat out 64k packets and let the nic deal with it
<mrvn>
geist: I believe he NICs split the data into packets, not fragments.
<geist>
well, they have to do it in a way thats valid to the other side, because there's no assumption the other end can reassemble it
<mrvn>
exactly.
<heat>
they split it into fragments as well
<mrvn>
heat: your local NIC?
<heat>
tcp segmentation offloading makes packets, the others need to make fragments
<mrvn>
we are talking about the former
<heat>
no we're not
<kazinsal>
that is a completely different train of thought
<geist>
yah but it segments using ip fragments or does it just keep making new tcp packets?
<mrvn>
heat: at least I hope geist was when he mentioned dumping 64k blobs into the NIC.
<geist>
probalby the latter now that i think about it
<heat>
geist, packets (proper RFC793 segments)
<geist>
yah i guess that's more ideal: take a larger tcp packet and retransmit it (at the nic) as a series of smaller ones
<heat>
I think it says somewhere that you shouldn't fragment a TCP segment (hence the need for path MTU)
<kazinsal>
yeah, I think it's a SHOULD NOT
<kazinsal>
not a MUST NOT
<mrvn>
heat: you have to either handle the fragments correctly or send s ICMP_FRAGMENT. DSL router do neither.
<kazinsal>
aka "you're going to do it anyways but please for everyone's sanity consider not doing it"
<heat>
you'll get killed if you ignore a MUST
<klange>
heat: maybe just personal opinions, but BufferSize being in-out, file paths being UTF-16 (and no I will not accept "but everything is UTF-16 in EFI" as an excuse for this)...
<heat>
you'll just get shot if you ignore a SHOULD
<heat>
klange, that's just MSFT API design
<heat>
like literally the rest of UEFI is like this
<kazinsal>
april fools RFC idea: introduction of the PLEASE DON'T requirement level keyword
<zid>
Yea that's just winapi
<mrvn>
klange: can your UEFI boot <rocketship><female><medium skin tone><2 children family>.pe?
<heat>
no
<mrvn>
(female astronaut with 2 kids)
<heat>
it's not UTF-16 but UCS-2
<zid>
UCS-2 is what *W is in winapi yea
<heat>
and you clearly have an unhealthy obcession with unicode and emojis
<klange>
As someone who works in internationalization, it is hard to pick which is worse between the two.
<zid>
I work in internationalization in that I just use utf-8 and let god sort it out
<zid>
aka freetype
<zid>
It tells me how big of a texture to use or whatever and I say "yes daddy"
<klange>
UCS-2 is outdated, but at least a codepoint is a codepoint. UTF-16 gets you the whole range, but surrogate pairs were a bigger mistake than Han unification.
<mrvn>
UTF-16/UCS-2 are the worst of both worlds: Wastefull and insufficient to cover everything with constant size.
<heat>
ok but
<heat>
it's late 90s - early 2000s microsoft
<mrvn>
no, sorry, the but emoticon is on a different code page
<heat>
they literally had nt kernel people help out with UEFI
<heat>
you were bound to get microsoft design and code and you got it
<heat>
"Making the DLL thread-safe won't solve the issue, but it will help."
<mrvn>
zid: hey, no returning structs. That would be something a compiler from this millenium would support.
<heat>
you don't return structs in winapi/UEFI because the return type is reserved for EFI_STATUS
<heat>
or HRESULT
<mrvn>
god, let there be std::expected
<heat>
it's cleaner than the errno global variable
<heat>
that got pretty much #define'd into a TLS variable
<mrvn>
can't wait for c++23 support
<mrvn>
heat: modern languages can return multiple values.
<heat>
do you really want to fight that battle?
<mrvn>
even c++ has jumpted on the wagon: auto [quotient, remainder] = divide(14, 3);
<heat>
modern languages have decently integrated language features
<heat>
modern languages do things inside the compiler instead of building piles of language magic in header files and "oh no why is it slow to compile?"
<zid>
The HRESULT thing deals nicely with the whole "is 0 failure or success" thing too tbh, you just enum BLAH_OK and BLAH_ERRn to whatever matches
<heat>
i like 0 as a success, negative error values
<heat>
but that's UNIX-me talking :)
<zid>
yea but it's contra to the whole.. true false thing, unfortunately
<heat>
mrvn, by the way if you want a modern language we've got a GSoC student working rust support for EDK2 :)
<heat>
working on*
<klange>
don't worry, i already have a modern language in efi
<zid>
We've still not figured C out properly yet, geez
<zid>
You guys are rushing ahead
<mrvn>
zid: (-1)[&i[a]] = 666;
<mrvn>
Little things I want to fix in C: void free(void **)
<clever>
to null the ptr out automatically?
<mrvn>
exactly
<clever>
simplest option, make a safer_free with that api, and then make the real free harder to link to
<clever>
either by hiding the symbol or warning about uses not in a whitelist
<mrvn>
stop passing (uninitialized) buffers to functions, have them allocate and return buffers
<clever>
but constructors!
<clever>
and virtual contrustors!
<mrvn>
factory factories, jippey
<heat>
how would you fread() a buffer into MAP_SHARED memory if you can't pass buffers to functions
<mrvn>
simple: mmap() the data directly.
<mrvn>
memcpy
<mrvn>
splice
<heat>
it's a pipe and I don't have splice
<mrvn>
one more thing to fix :)
<mrvn>
read() should just map the pipebuf into the user address space and return the address
<mrvn>
There could also be a mread() for that special case
<heat>
mread() -> you mean read()?
<mrvn>
heat: no, read into an mmap()ed buffer that may copy data or remap pages.
<mrvn>
the plain read should return a fresh buffer.
<mrvn>
I kind of want write() to free the buffer but that's kind of problematic with EINTR.
<mrvn>
readv/writev are underused
<dasabhi>
geist: speaking of hardware, do you know if qemu emulates some shitty gpu?
<klange>
It emulates many shitty GPUs.
<klange>
Including some ATI cards!
<dasabhi>
i know it emulates a NIC, because xv6 makes you build a tcp/ip stack for a shitty nic with documentation for the shitty nic
<dasabhi>
interesting
<dasabhi>
so i could technically write a gpu driver
<dasabhi>
on xv6
<geist>
well, i mean depends on what you mean by shitty gpu
<klange>
QEMU emulates a wide range of hardware, some of which is _not_ shitty.
<mrvn>
dasabhi: do you want an accelerated graphics card or actually do GPU calculations?
<klange>
Like... several of the NICs.
<dasabhi>
mrvn: i have zero clue how graphics works and i am looking to fix that with xv6
<dasabhi>
so those are just words to me
<dasabhi>
i guess both
<mrvn>
dasabhi: then it totally emulates a ton of shitty and not so shitty stuff.
<dasabhi>
accelerated graphics so like video codec stuff?
<geist>
okay so maybe you mean video output?
<heat>
virtio-gpu is decent
<heat>
the rest... eh not so much
<geist>
to many folks 'gpu' means somethign quite specific
<heat>
mostly glorified framebuffers
<mrvn>
dasabhi: could be something as simple as scrolling the screen
<geist>
though it also tends to mean 'video device' or whatnot
<geist>
or 'everything to do with putting crap on monitors'
<clever>
in the case of the raspberry pi, the 2d subsystem (turning framebuffers into a video signal) is entirely seperate from the 3d subsystem (turning polygons into a 2d image)
<geist>
right, which is generally still kinda the case, even if it's implemented on the same physical device (ie a video card)
<dasabhi>
so i am really looking for something with some nice documentation, xv6 points us to a shitty NIC with nice documentation that helps you learn network drivers
<clever>
and the video encode/decode is also its own seperate block
<mrvn>
does qemu emulate the RPi 2D system now?
<dasabhi>
and qemu emulates said nic
<heat>
dasabhi, which nic?
<clever>
mrvn: it only emulates the mailbox framebuffer api, not the true 2d hardware
<dasabhi>
let me find out hold on
<geist>
yeah my question
<clever>
mrvn: so the emulation is of what the firmware wrapper around the hw exposes to linux
<geist>
waiting for them to point out e1000 or something
<mrvn>
clever: so only the bits that linux uses and nothing more :(
<dasabhi>
xv6 makes you right code for an E1000
<heat>
hahahaha
<clever>
mrvn: even less!, some of the new stuff about the number of framebuffers is missing, so the modern linux drivers bail out and dont even drive the display
<geist>
heat: ahahaha
<heat>
that's like the best documented NIC you'll ever find ever
<dasabhi>
i guess a look think to do would be to get xv6 to render a teacup
<geist>
yah it's kinda the gold standard of nics right now
<zid>
e1000e only has docs from like 2005 though, the newer chips are behind the intel insider thing still :(
<mrvn>
clever: ever thought of writing a different API for the VC and linux?
<clever>
mrvn: i have
<dasabhi>
oh damn i didnt know NIC docs were that hard to get
<klange>
Even the newest stuff has a degree of backwards compatibility, and the Linux drivers got split up mostly because support the whole range in one driver was becoming idiotic.
<clever>
mrvn: with the open firmware, the VC firmware is currently in complete control, so linux looses its 2d acceleration
<geist>
zid: not so sure, i gopt some fairly up to date docs, but indeed the 10gbe variants i think are harder to get docs for
<mrvn>
clever: yeah, bring that back please.
<geist>
right, e1000e seems to be the split where things started going multi-queue and heavily into MSI
<clever>
mrvn: if i fix linux's access to the 2d hw (it has some bugs), then the VC becomes locked out, so i need to come up with an api for sharing the hw
<heat>
dasabhi, good hw docs are hard to get because hardware people really don't bother
<geist>
that i think was a line in the sand making it hard to support
<heat>
the e1000/e1000e are like the best documented NICs you'll ever find
<zid>
Thankfully these days hardware people at least drop a linux driver
<heat>
and probably in the top 20 of general hardware documentation (barring CPUs)
<dasabhi>
any gpu version of an e1000?
<geist>
right, for opposite reasons than before: i think lots of hardware companies write a linux driver and then claim it's basically documentation
<geist>
whereas say 20 years ago they just would be secretive about everything
<zid>
Our cheap chinese clone card MUST be kept secret
<mrvn>
clever: that's what I mend above. :) I remember the accelerated framebuffer interface had just a few simple functions. Maybe just implement an interface for that. Mostly scrolling stuff
<heat>
geist, can they? what's the legality of using GPLv2 source code as docs?
<heat>
dasabhi, right. depends on what you mean by GPU
<clever>
geist: RPF has been doing pretty much that with every hw block they are allowing to have open drivers
<geist>
no, but theres no legality about docs
<geist>
it's more like they just say 'see linux driver' instead of bothering to release docs
<clever>
mrvn: i did recently implement scrolling in LK's graphics console
<dasabhi>
hmm i guess i could do rotating tea cup myself on a frame buffer
<geist>
which is strictly speaking better than no docs or driver at all
<heat>
the virtio-gpu is probably the gold standard of 3D acceleration in VMs
<dasabhi>
but then i am just dumping memory to a sector of memory and calling it a day
<heat>
BUT the 3D acceleration parts aren't particularly well defined AFAIK, you need to dig for those
<dasabhi>
virtio-gpu
<dasabhi>
got it
<geist>
heat: if what you mean is can you consider GPLv2 stuff to be docs for something that's not GPLv2
<heat>
the rest are basically glorified framebuffers
<geist>
that's a good question and i'd rather not push it
<heat>
yup exactly
<geist>
in general i avoid it because i dont know what my code will be used for downstream
<geist>
and i'd rather not be dragged in front of a bunch of lawyers about it later on
<heat>
geist, i've seen some FreeBSD code that looks like it was written looking at linux code
<mrvn>
clever: that makes me miss my C64
<mrvn>
faster-console-1.mp4
<mrvn>
loads much slower
<clever>
mrvn: the standard console, is a single dumb framebuffer, with memcpy() to scroll
<geist>
also keep in mind getting dragged in front of a lawyer is less so about whethe or not you broke the law or whatnot, it has everything to do with someone making money
<clever>
mrvn: while the faster console, just treats the bitmap as a circular buffer, and just wraps around to the top and never scrolls
<mrvn>
clever: hehe, the faster just flashes and it's all scrolled through.
<geist>
so if you have some situation where you think your little cog in the wheel ends up being part of some thing that is worth something, be careful
<heat>
dasabhi, for real hw you could look at the i915 but that's a whole different ballpark
<clever>
mrvn: but it then uses the 2d composition unit to slice the framebuffer in 2, and render it at the right offsets
<klange>
The closest thing in GPU land to an e1000 NIC as far documentation goes (and which exists as real hardware) is, appropriately enough, probably Intel's i965 series? But then nothing emulates one of those.
<zid>
82810 for life
<zid>
I have a physical one still somewhere
<heat>
klange, these days you can get one in a VM
<mrvn>
clever: yeah, you mentioned that before. Nice little trick to avoid copying anything.
<clever>
mrvn: and it dynamically moves the slice, as the circular buffer's seam moves
<geist>
oh i740 or gtfo
<clever>
mrvn: yep
<klange>
What emulates a 965? Or do you mean via passthrough while running a different card for the host?
<heat>
the VT-(insert weird intel letter here, it's g I think) emulates an intel GPU inside the kernel and passes is through using vfio
<clever>
mrvn: under linux, the /dev/fb0 api uses a virtual resolution and x/y offsets, but your going to hit the edge of the virtual screen eventually, and then what?
<zid>
isn't i*** the chipset
<zid>
the 82810 is the gpu on the i810
<heat>
klange, not exactly an i965 but all the intel GPUs have great docs
<mrvn>
clever: It's something I want to incorporate into my framebuffer interface. I already have slices so you can copy a a subset of a framebuffer. But having 2 or N blobs would be even better.
<heat>
(great for the boatload of shit they do)
<geist>
i740 was the predecessor to the i810 and was up until recently the only discrete gpu intel ever made
<geist>
pretty rare, kinda a collectors item
<clever>
mrvn: to implement the above, i had to add viewport support into my sprite framework, so now every visible image has a true w/h, a dest xy, a dest w/h (scaling), and a viewport xywh (cropping)
<mrvn>
clever: the usual way is to have a FB with double height and draw everything twice. Then when you hit the bottom you can reset to the top and it's the same data.
<mrvn>
wastefull and slow
<clever>
mrvn: yep, thats exactly how android does page-flipping on framebuffers
<clever>
thats also how i found a nasty bug in the original rpi firmware
<clever>
when you change the y-offset to flip, the firmware clears the buffer
<clever>
so android only ever displayed solid black
<klange>
heat: ah GVT-g
<heat>
aww jeez I was close
<clever>
mrvn: and the "fix" i found in the rpi-android fork of linux, was for the driver to double the virtual height, after the userland had already doubled it once
<heat>
the naming scheme is so clear and simple to understand
<clever>
mrvn: the quad height virtual size, was rejected by the rpi firmware, causing android to just disable pageflipping
<heat>
klange, anyway, the i915 series cards (but you should better pick a gen or two) are the best bet to get open source 3D acceleration going
<heat>
for real cards that is
<klange>
yeah, and like the e1000 there's some degree of backwards compatibility on them
<heat>
yes
<heat>
that's not necessarily good though
<klange>
which was the real sin of that powervr chipset they tried to push as an "intel" gpu
<heat>
the backwards compatibility make really hard to read drivers
<heat>
the e1000e and the i915 linux drivers are the hugest mess of spaghetti if's and "do this if you're one model, do that if you're another model, ..."
<clever>
heat: ive seen the same mess in dwc, and genet drivers
<heat>
but, ya know, over 20 years
<clever>
the rpi's 2d hvs drivers are slightly better, given that there are only 2 variants
<clever>
so far...
<klange>
It's a trade off, and of course Linux - and any maintained OS with the resources to put into it - will want to make the most of every new feature.
<heat>
yeah but it's not just new features
<klange>
But from our side of things, building hobby systems where we're lucky to get even the bare minimum working, it's nice to have hardware where that's still going to work as new things get added.
<geist>
yah exaclty. you pick and choose what hardware to support, hopefully trying to get something to unlock that part of the os
<heat>
klange, good chunks of the GPU get moved around between gens
<heat>
for instance, the sequence to drive the display of the i915 GPUs changes so significantly that most functions have _<gen> variants
<heat>
like i915_enable_display_hsw, i915_enable_display_skl, etc
<klange>
Which is an example of _not_ having good backwards compatibility, not an example of backwards compatibility being bad.
<heat>
it's just not backwards compatible, the design looks similar but you can't try to use your original i915 driver and expect it to work newer stuff
<dasabhi>
wait so how do you guys render shit to the screen
<dasabhi>
a lot of you have solid working OSes
<heat>
you plot to the framebuffer
<dasabhi>
ah so you just do the math and drop shit to the framebuffer,
<heat>
*(framebuffer + pixel_off) = 0xAA0000; <-- hey look it's red now
<dasabhi>
never touching and hardware to do the math faster is that right?
<heat>
it's slow
<dasabhi>
any hardware*
<heat>
hm?
<heat>
making hardware do the math and draw is way faster
<geist>
the key is to know what a 'framebuffer' is. in general it's a byte/word/etc per pixel
<geist>
so it looks like memory that you simply drop colors into at particular offsets
<klange>
There is roughly one "hobby OS" worth mentioning that has an actual accelerated graphics pipeline, and it notably implemented Linux APIs to assist with that and only has minimally functional drivers for actual hardware.
<geist>
and that makes a pixel light up
<dasabhi>
so i guess qemu doesnt have anything that emulates the make hardware do the math part
<heat>
klange, which one?
<klange>
managarm
<heat>
hmm
<heat>
dasabhi, some qemu GPUs take a stab at it but they're usually pretty bad at it
<heat>
virtio-gpu is the best stab you have
<heat>
klange, porting DRM is possible. making a vulkan-only driver is easier
papaya has joined #osdev
<heat>
mesa's Zink can do OpenGL on top of Vulkan, so you can still have OpenGL while only writing vulkan code, which is much easier
<klange>
managarm implemented the DRM APIs; and I was mistaken, I thought they had more than one actual hardware driver - could have sworn they were working on an AMD one, but I only see the Intel stuff.
<heat>
that's the BSD approach too
<heat>
it's not trivial to write a graphics stack :)
<dasabhi>
yeah not nearly as simple as networking
<dasabhi>
where its, packets go brrr
<dasabhi>
make a giant buffer with packet headers feed to NIC
<heat>
networking also isn't easy
<heat>
a good networking stack is _complex_
<dasabhi>
yeah i am just having a laugh
<dasabhi>
i just need something to learn off
<dasabhi>
thankfully the e1000 exists
<dasabhi>
so about this managram OS
<dasabhi>
they have the GLES gears rendering
<heat>
the rtl8138 is probably the most braindead nic you'll find
<dasabhi>
did they just do that by dumping to frame buffers at the end of the day?
<heat>
dasabhi, since they implemented the DRM apis I'm assuming they use mesa
<klange>
They implement Linux's DRM interfaces, alongside lots of other Linux APIs, and ported Wayland.
<heat>
which is the hard part that does the heavylifting in userspace
<heat>
shader compilation, vulkan/opengl implementation, it's all done here
<heat>
kernel drivers only drive the display, power management and submit commands
<dasabhi>
so at the end of the day, are they talking to a gpu?
<heat>
(and AFAIK commands usually are just buffers of opcodes the GPU executes)
<dasabhi>
i dont know much about mesa
<heat>
who's talking to a GPU?
<dasabhi>
managram
<heat>
managarm? probably, since they have a driver for it
<clever>
heat: in some cases, the kernel driver has to perform relocation type patching of those opcodes, to populate physical addresses
<dasabhi>
i cant believe all of that is just dumping to a framebuffer and doing math on your own
<heat>
quake uses OpenGL
<dasabhi>
game devs back then must have been math phds
<heat>
klange is using an older version of OpenGL which did software rendering without LLVM
<klange>
no
<heat>
s/OpenGL/Mesa/g
<heat>
no?
<klange>
quake has a software rasterizer, the OpenGL backend was optional
<heat>
oh TIL
<geist>
it was during that period of time when it wasn't implied that you had a 3d card
<geist>
and/or it was using things like GLide
<klange>
The OpenGL backend adds better dynamic lighting, among other things, but the software rasterizer is still excellent on its own and quite fast.
<dasabhi>
oh btw, what system calls do linux implement for graphics?
<dasabhi>
opengl is just a shared library in user space
<dasabhi>
what does it actually call to go to the kernel?
<dasabhi>
ioctl?
<heat>
ioctl with a bunch of IOCTLs
<geist>
yah in general
<heat>
and the IOCTLs are unique to each driver
<dasabhi>
and then ioctl figures out which driver to call yeah?
<heat>
there's no DRM_SUBMIT_COMMAND
<heat>
no
<heat>
the driver is already known because you opened the device
<heat>
that's just how UNIX works
<dasabhi>
right so opengl will call the nvidia /dev file?
<bslsk05>
github.com: lk-overlay/sdram.c at master · librerpi/lk-overlay · GitHub
<dasabhi>
ordinary linux kernel stress testing
<dasabhi>
wrote python scripts all day :(
<clever>
heat: although, i didnt write this driver, and i can barely tell what its doing
<clever>
heat: the pi4 and its ddr4 controller is more complex, and i have yet to RE the blob well enough to make a functional open source driver
<heat>
you probably won't be able to
<heat>
i've heard the modern memory training code is super complex
<clever>
luckily, RPF recently changed the blobs, and removed the bootloader from the ram-init blob
<clever>
so the blob is now only ram-init and nothing else
<clever>
so its more acceptable then before
<heat>
you might want to take the L for now and just use the blob
<clever>
yep
rustyy has quit [Read error: Connection reset by peer]
<clever>
originally, there was a single bootcode.bin blob, that did both ram-init, and loading of start4.elf from sd/usb/tftp/nvme
<clever>
and it uses some other memsys blobs for ram-init
<heat>
intel people said they literally have several megs of debug logs in memory training, they fuckin print histograms
<clever>
i have found such debug messages in the memsys files
<clever>
ELLI LAGDAOLOTS/E ERPECXNOIT:CP PE
xenos1984 has quit [Read error: Connection reset by peer]
<clever>
also, the byte order of the memsys files is backwards, every 4 byte chunk has to be byte-swapped
<clever>
my theory, is that there is a FIFO with a 32bit write port, for loading the memsys files into the ddr4 controller
<mxshift>
meh, I know someone who reverse engineered Intel's memory training process for a few ddr4 generations
<clever>
and with the host cpu being LE, the 4 bytes in that 32bit write port, must exist backwards in ram, for the copy loop to be simple
<mxshift>
err ddr3
<mxshift>
can't type today
<heat>
"In the PC ecosystem a single chipset family can power thousands of unique designs. So the DRAM memory needs to be external, support lots of different chipset packages(signal integrity...), support the lowest cost through the highest cost DRAM and thousands of different board layouts. So programing DRAM takes a masters degree in antenna design. I’ve seen MRC (Memory Reference Code) with over a MiB of DEBUG prints in it, and it literally is printin
<heat>
g histograms of what it is tuning. So all this code has to run before the system has any DRAM, thus it is running using the cache as RAM. I’ve not looked at the x86 architecture specs form the vendors in a while, but back in the day they did not support page tables in ROM or pinned cached. Now it might work, but if it breaks your CPU vendor blames you so you don’t code PEI in X64…."
<mxshift>
I've been looking at Zen3 ddr4 training logs to sus out margin in our server motherboard's design
rustyy has joined #osdev
<clever>
heat: the recent change in the rpi firmware, is a double-edged sword, they added the ability for the bootloader firmware (held in internal spi flash) to download the next stage over https, over the public internet
<heat>
mxshift, how do you get those?
<clever>
and i can see how thats a major red flag for the paranoid
marshmallow has quit [Ping timeout: 256 seconds]
<clever>
but the benefit there, is that https support was too big to fit within the cache-as-ram based binary
<clever>
so they had to seperate the bootloader from the ram-init
<heat>
how is the firmware in cache-as-ram?
<mxshift>
all zen parts do memory training via the PSP before the x86 cores are enabled. There are APCB tokens you can set to run MBIST which dumps out a bunch of timing/vref sweep data to show data eyes
<clever>
heat: the .bin file gets loaded into a 128kb L2 cache, and executed from there, then normal cache-as-ram rules follow
<clever>
dont cause a cache miss, dont cause a cache eviction
<heat>
that's cray-cray
<clever>
if you configure your linker script to stay within a 128kb block starting at 0, then your fine
<clever>
the bootrom pre-fills that region with nulls
<heat>
PC firmware just translates the firmware area up in the 32-bit space into SPI accesses
<clever>
so the cache will have a hit on anything in that range
<clever>
the rpi does have a boot rom mapped at 0x6000_0000
<clever>
which is directly in the soc itself
<heat>
also intel's cache-as-ram isn't as crazy as that
<clever>
the boot rom is responsible for priming the cache, by using wide stores
<heat>
you give it an address and it maps it as cache-as-ram for you
<clever>
so the cache doesnt try to back-fill the half of a line you didnt write
<clever>
the bootrom is also responsible for loading the .bin file into the cache, and passing off control
<clever>
yeah, i suspect this cache-as-ram is much more of a hack
<heat>
(also, something I found out about the other day: some server platforms use SRAM instead of cache-as-ram
<heat>
)
<clever>
it looks less like a proper mode, and more like just abusing the cache fill logic, so it never tries to contact dram
<clever>
the rpi does also have some sram at 0x6001_0000
<clever>
i'm not sure how big it is, and why the bootloader doesnt use it more
<clever>
the bootrom runs from that sram, before the cache has been primed
<clever>
and on some models, the bootrom leaves a copy of the boot signing keys in the sram!
<clever>
oops :P
<clever>
heat: the .bin stage also has a 0x200 byte hole at the start, the perfect size for a vector table, and the entry-point is always 0x8000_0200, with the whole .bin loaded at 0x8000_0000
<clever>
that design holds true for the entire rpi line, both vc4 and bcm2711 era
gog has quit [Ping timeout: 246 seconds]
<clever>
heat: and much like the PC platform, a flag can be set somewhere to make the rom/sram drop off the bus
<bslsk05>
github.com: rpi-open-firmware/rom.txt at master · librerpi/rpi-open-firmware · GitHub
<clever>
heat: for the entire VC4 line (pi0 to pi3), the bootrom supports booting from 8 sources, 3 of them are just SD (different controllers, 4bit vs 8bit mode), nand flash, spi flash, usb, i2c-slave, and something called mphi
<clever>
for the pi0/pi1/pi2, usb mode is in device only, like DFU on other boards
<clever>
pi3/pi02 adds usb-host abilities, where it can drive MSD sticks, or tftp the onboard USB NIC
<clever>
in all cases, it loads a bootcode.bin into the cache-as-ram, and executes it
<clever>
the pi4 scales that back, to just 3 sources, SD, SPI, and usb-device
<clever>
and the pi4 renamed it from bootcode.bin to recovery.bin
<heat>
yes its defo stockholm syndrome
<clever>
lol
<clever>
my claim is that its to free the other slaves :P
<heat>
you enjoy that cursed thing too much
<clever>
think of how many existing users there are, that i could set free!
<heat>
that might've been your original motivation but you definitely enjoy the thing now
<clever>
lol
<clever>
the original reason i picked this code up, was because the pi4 had onboard spi flash
<clever>
so i could have it boot from that, and do something like standard uefi, without any blobs on the SD card
<clever>
but its ddr4 got in the way, and i wound up fixing older models first
<clever>
the pi4 also had other boardblocks, the .bin file must have an hmac-sha1 signature appended to the end of the binary
<heat>
ok here's a cute fact
<clever>
and if its not signed correctly, the rom acts like it doesnt even exist
<heat>
the rpi UEFI builds have a non-osi package
<heat>
the freakin logo :)
<clever>
heh
<clever>
those builds also rely on the closed firmware to even start
<bslsk05>
github.com: edk2-platforms/Platform/RaspberryPi/RPi3 at master · tianocore/edk2-platforms · GitHub
<heat>
the RPi4 ones are for rpi4-likes, and the rpi3 ones are for rpi3-likes
<clever>
yep
<heat>
if you go to the .fdf files you can see what things they include
<clever>
pi3 is the only one of that pair, where i can boot to arm currently
<clever>
i dont have the pi4 booting to custom arm code yet
<heat>
how large is the SPI flash?
<clever>
512kb
<heat>
ok thats small
<clever>
and the bootrom enforces that its either 128kb or 512kb, and wont boot if its anything else
<heat>
no way you could fit EDK2 in there
<clever>
yeah, i would need a secondary spi flash
<clever>
let me double-check something
<heat>
the current RPi3 RPI_EFI.fd is 2MB long
<heat>
and that's with compression
<clever>
the official pi4's SPI firmware is also using compression
<clever>
ok, found the code, in the bootcode.bin, not the rom
<clever>
let me double-check against the rom
<clever>
ah right, the rom is uber-dumb
<clever>
heat: the SPI boot support in the rom is very dumb, it just writes a 3 (the spi read command), and then an infinite stream of 0's, and then checks (with many offsets) for the magic 32bit number
<clever>
that variable offset, deals with variable address size, for many spi flash chips
<clever>
and then the extra 0's, are just dummy ones, so spi can keep transfering
<clever>
once it finds the magic#, it expects a 32bit size, and then the raw bootcode.bin
<clever>
bootcode.bin itself, is what enforces the 128kb/512kb size restriction
<clever>
so i would need to patch it if i wanted to use a non-standard flash size like 2mb or 4mb
<clever>
heat: i did also come up with a multiboot inspired protocol to solve some things
<clever>
basically, when the arm comes out of reset, it begins executing whatever it found at 0 in ram
<clever>
how do you pass it arguments?
<heat>
tbf lots of intel FW engineers have been at the company for 20+ (intel is damn good at retaining talent I guess) so they don't have to work on stuff other than UEFI
<bslsk05>
www.systutorials.com: drm-gem: DRM Memory Management - Linux Man Pages (7)
<clever>
but its currently one set of paging tables for the entire 3d core, shared by all 3d clients
<clever>
so a stray pointer can let you peek at 3d state for another client
<clever>
the vc4 era v3d lacks an mmu, and the 3d core just has direct access to the entire physical memory, and possibly even mmio
<clever>
heat: do you know if most (say i915) drivers copy the drm buffers to gpu memory, or if the gpu is instructed to read directly from the buffer?
<dasabhi>
i am staying away from graphics for a long time
<dasabhi>
but hey why didnt the managram guys just....port i915 and talk to the gpu themselves?
<dasabhi>
i am guessing its probably a bigass driver
<heat>
clever, I don't think the i915 needs to copy buffers since it has no VRAM
<clever>
ahh
<heat>
as far as I remember you just map stuff to the GART (can't remember the proper name they give it)
<clever>
but directly sharing a buffer between userland and gpu can have risks
<clever>
in the case of the rpi, the control structures contain physical addresses for things
<clever>
so if the userland can still modify the buffer, then it can point the 3d core anywhere in ram
<clever>
and now permissions are effectively dead
<heat>
the i915 lacked per process protection for like 15 years :P
<dasabhi>
learned a lot asking dumbs questions here today, thank you for answering my stupid questions
<dasabhi>
i am gonna call it a night
<dasabhi>
goodnight every one
<clever>
heat: i think the bcm2711 v3d still lacks process level isolation, but at least prevents you from gaining root and escaping your user
<bslsk05>
github.com: linux/v3d_mmu.c at rpi-5.10.y · raspberrypi/linux · GitHub
<clever>
re-reading this again...
<clever>
> we load all BOs into the same 4GB address space.
<clever>
and from your links
<clever>
> BO: Buffer Object. GEM uses handles to identify the buffers used as graphics operands in order to avoid costly copies from userspace to kernel space. BO is the thing which is encapsulated by that handle.
<bslsk05>
'The Simpsons - No Homers Club' by kentuckyfriedpanda1 (00:00:45)
<bslsk05>
blog.ffwll.ch: Why no 2D Userspace API in DRM?
<heat>
probably interesting to you
<clever>
just like in this clip
<clever>
ah, i have been wondering that exact question!
<clever>
the general answer ive gotten before, is that most GPU's arent very capable in the 2d realm
<clever>
and linux itself then enforces a max of 16 planes in DRM
<clever>
and with some GPU's only supporting 3, the main framebuffer, an xvideo overlay, and the cursor
<clever>
so nobody bothers implementing code that uses more
<clever>
which makes the rpi weird, having support for ~292 planes on-screen at once
<clever>
thats enough that you could implement your entire compositing window manager in hardware, just tell DRM the dma_buf of every back-buffer, and the xy to display it at
<clever>
your done!
wxwisiasdf has joined #osdev
<wxwisiasdf>
my os now can load programs
<wxwisiasdf>
unfortunely it's all physical so i have to live with the caveats of not having paging
<clever>
no-mmu linux works around that by only having vfork()
<wxwisiasdf>
i could implement paging if i figure out the ibm docs from 1998
<clever>
in the really old days, fork() would actually copy the userland memory (and used mmu to not collide), and that was a major performance cost
<wxwisiasdf>
unfortunely "figuring out" means no gdb and only an emulator from 2003 to aid in the quest
<wxwisiasdf>
hmm yes, fork()
<clever>
vfork() was the hack to fix that, the parent would suspend until the child execve()'d, and the child would temporarily steal the parents ram
<clever>
but then fork() gained copy-on-write support, so it could share the parents ram cheaply, and vfork "died"
<wxwisiasdf>
my os of course has multitasking but it's all on a single 16MiB address space :(
<clever>
but without an mmu, vfork can return from the dead!
<wxwisiasdf>
hmm yes, let's go, vfork
<heat>
see, this pretty much shows that OS documentation is crap
<clever>
suspend the parent, whild the child runs
<clever>
when the child execve()'s, map it to an unused region of ram, and resume the parent
<heat>
i know a lot of stuff from random collections of links
<wxwisiasdf>
why don't archive.org it?
<heat>
idk
<wxwisiasdf>
:p
<heat>
just as an FYI
<heat>
you can't touch anything with vfork
<wxwisiasdf>
why
<heat>
undefined
<wxwisiasdf>
fair
<heat>
meaning shit will blow up in your face
<clever>
in the no-mmu case, the parent and child are literally using the exact same ram
<clever>
anything you modify in the child, will remain modified in the parents view
<heat>
and in the mmu case as well
<wxwisiasdf>
clever: literally everything in my OS is in the same RAM
<wxwisiasdf>
but the IBM mainframe has physical protection
<wxwisiasdf>
so it's beautifully like, "hey i am in the same ram as the kernel... but with less priv :("
<clever>
yeah, thats called an MPU in the cortex-m region
<clever>
and a sandbox in he VPU
<wxwisiasdf>
oh
<clever>
more common when you lack an mmu
<heat>
how do you use vfork() in a defined way inside C?
<clever>
rather then mapping memory, you just limit what addresses can be touched
<wxwisiasdf>
hmmm yes, time to spam skeys()
<wxwisiasdf>
(storage protection keys)
<clever>
heat: good question, any local vars in the stack frame could be trampled, kinda need to rely on barriers and the compiler not re-ordering things
<wxwisiasdf>
is vfork like setjmp?
<clever>
kinda
<clever>
the function has to return twice
<clever>
on a no-mmu kernel, the first time it returns is as the child
<clever>
and once the child does execve, it returns a second time, as the parent
<heat>
i guess you just use it and pray it doesn't do much stuff
<clever>
and the execve args are used to setup a new proc at a new addr
<heat>
like literally the only defined use of vfork is: "pid_t pid = vfork(); if (!pid) execve(...);
<clever>
and if everybody follows the rules (only touching what malloc gave it), they wont notice other procs sharing the addr space
<clever>
yeah, due to the parent suspending, there isnt much else you can do with vfork
<clever>
fork on the other hand, is a lot more flexible for abuse
<wxwisiasdf>
ok can i fork on nommu
<heat>
no
<wxwisiasdf>
like copy paste the whole thing
<clever>
factorio for example, can fork() out a clone of the entire game engine, and let the child serialize it to disk, while the parent continues to run
<heat>
if you swap everything, yes
<wxwisiasdf>
:/
netbsduser` has quit [Read error: Connection reset by peer]
<wxwisiasdf>
so basically i have to paging yes or yes
<geist>
indeed, the entire mechanism of fork is generally assuming there's at least some sort of way to set the current cpu context to some other memory
<geist>
paging or segmentation or whatnot
<wxwisiasdf>
oh sorry, paging, IBM calls it "Dynamic Address Translation" :/
<geist>
*or* you as heat says, literally swap everything. copy the process somewhere else, copy the new one in, run it, swap back
<wxwisiasdf>
that could be a solution yeah
<geist>
the minicomputers unix was designed to run on at least had some sort of address segment register to let you keep a few things in ram that thought they were 'at 0'
<geist>
even if it wasn't full paging (that came along a few years later)
<wxwisiasdf>
yeah IBM had like DAT
<geist>
i dont know precisely what pdp7 had, but pdp11 had reasonable segmentation scheme
<heat>
wxwisiasdf, that would be painfully slow
<geist>
even something like pdp8 which eventually grew the ability to run multiple tasks (though generally didnt) had an address extension register that extended 12 bits of address space out to 8 x 12 bits. (ie a 3 bit 'what page am i on' register)
<geist>
with that you could run basically 8 processes at once, each with 4K of ram
<wxwisiasdf>
so unfortunate the emulator doesn't print page tables
<geist>
what emulator and what arch?
<wxwisiasdf>
hercules - s390(x)
<geist>
ah
<wxwisiasdf>
qemu has s390x but it doesn't like css devices as much
<wxwisiasdf>
plus it's meant to run z/linux and not the "cool" things like mvs3.8
<heat>
on that end it has feature parity with qemu-system-riscv64 :)
<heat>
s/riscv/aarch/g
<wxwisiasdf>
i used to do riscv64 osdev :p
<wxwisiasdf>
it's amazing because you actually have documentation and stuff
<wxwisiasdf>
and of course i can hook gdb to it
<heat>
yes I meant aarch64
<wxwisiasdf>
ah
<clever>
> Gem-buffers cannot be created with a generic API. Each driver provides its own API to create gem-buffers.
<clever>
heat: ah, so while GEM is a common support framework in the kernel, the api to actually create a gem object isnt exposed to userland
<clever>
and every driver must create its own wrapper around it
<clever>
makes sense, since some share host ram, while others exist in gpu ram
<clever>
and different drivers will have different choices on syncing the object to gpu ram, when it exists
<clever>
and different rules about where in ram the buffer must live, its page size, and stride
<heat>
yes
<heat>
that's the rule of thumb in DRM
<heat>
no common API, but a common framework
<clever>
vc4 v3d lacks an mmu, so all textures/control-lists must be contiguous
<clever>
rpi hvs (display scanout) lacks an mmu, so all framebuffers must be contiguous, and in the lower 1gig of the physical space
<clever>
combine those 2, and how the bcm2711 v3d has to deal with more complications
<clever>
texture and control-list can exist anywhere in ram, thanks to the v3d mmu
<clever>
but the final 2d output frame, must both be contiguous, and in the local 1gig
<clever>
ive seen a use-case flag in some of the drm docs, that i think covers this
<clever>
intermediate textures, such as render to texture dont have to follow that rule, so it would be beneficial to allocate them from the larger pool
heat has quit [Ping timeout: 244 seconds]
<clever>
heat: another thing i notice, is that the dumb-buffer api, expects a width*height bitmap image, so how are things like compressed textures and control-lists handled?
wxwisiasdf has quit [Quit: leaving]
ThinkT510 has quit [Quit: WeeChat 3.5]
crm is now known as orthoplex64
ThinkT510 has joined #osdev
Mikaku has quit [Quit: server maintenance ...]
Mikaku has joined #osdev
<Griwes>
hmm. so I'm still trying to figure out how to square "I want the syscall code to not have to deal with interrupts" and "a syscall needs to issue tlb shootdowns and not deadlock", and just had what I am fairly certain is an insane idea - what if I made the memory unmapping syscall spin off the part that modifies the page tables into a temporary thread that steals the time of the thread invoking the syscall? this way I'd be able to have interrupts
<Griwes>
enabled while that is happening (to be able to handle external tlb shootdown requests) without having to rework everything about task switching that I have right now
<Griwes>
I'm absolutely certain there's very fundamental technical issues with this idea, but I guess we will see once I start mocking it up on
Likorn has joined #osdev
<geist>
hmm, so i'm not entirely sure what you're trying to work around here
<geist>
you want the syscall not to have to deal with interrupts. what precisely do you mean there?
<Griwes>
I'd like to not have to ever need to handle an interrupt while inside a syscall handler. I have this perfect imagined system where the mechanism for context switches is just iret/sysret, but having to do ipis to do tlb shootdowns is really hurting this goal
<geist>
so basically you want to leave interrupts disabled the entire time you're in a syscall?
<Griwes>
yes
<geist>
thus the kernel is non reentrant?
<geist>
well, non preemptiable that is
<Griwes>
the syscall handlers, yes
<geist>
okay. so given that, are you planning on supporting SMP?
<Griwes>
there's parts that'd run as their own threads in kernel space that would be preemptible
<Griwes>
yes
<geist>
so the issue is cross cpu tlb shootdown you have a deadlock to avoid?
<geist>
since two cpus cross tlb shooting down can wait forever for the other to complete?
<Griwes>
yes
<geist>
(really you can extend that to any cross cpu synchronous IPI, but TLB shootdowns are generally the big ones)
<geist>
so. here's what i'd suggest, and you really need it if you're preemptible or not: when a cpu is doing a cross cpu IPI, it also spins and looks for any incoming messages
<geist>
and handles them
arch_angel is now known as arch-angel
<geist>
if it's a synchronous IPI, then there's generally a per cpu mailbox of incoming events (or something thereabouts). so you put together a message for the other cpu(s), fire the IPI, and then spin waiting for either a complete on their message or an incoming message, which you then handle locally
<geist>
that avoids a cross cpu deadlock
<geist>
can be tricky business, but that lets you send IPIs from essentially any context, even with interrupts disabled. in your case interrupts are already disabled because you're in a syscall
<geist>
note synchronous ipis are different than async ones (like, 'cpu go reschedule yourself')
<geist>
synchronous ones you're sending a message to the other cpu (do a TLB sync, etc) and waiting for it to ack it
<Griwes>
hmm, doing this with per-cpu inboxes like that is an interesting idea that I need to ponder on
<geist>
doesn't necessarily have to be per cpu. you could have a global queue of pending IPIs that has a cpu bitmask on it or something, but the gist is the same
<Griwes>
I have a mechanism for doing concurrent execution on all the cores, but it has slots that are per request and not anything that's per cpu
<geist>
key is you have to wait for the IPI to complete inside a shared piece of code that generically handles ipi
<Griwes>
but that's too limited for a thing as dynamic as this
<geist>
mp_send_sync_request(tlb_sync); etc
<geist>
and inside that it spins and handles incoming ones
<Griwes>
yeah I think you gave me the right idea
<Griwes>
I'll need to rework my higher level ipi api
<Griwes>
because it clearly doesn't pass muster for anything non-trivial
<bslsk05>
fuchsia.googlesource.com: zircon/kernel/kernel/mp.cc - fuchsia - Git at Google
<geist>
(i need to back port that to LK now that i have mentioned it)
<Griwes>
(it's a bunch of slots that each has its own irq number, but that doesn't work for having a part of sending them do polling on incoming requests)
<kazinsal>
some days I wonder if I should just bolt all my shit onto LK instead of writing a new kernel core
<kazinsal>
but the allure of NIH keeps me from actually doing it, heh
<geist>
kazinsal: there are serious gaps on the x86 side of things that need to be addressed
<geist>
though most of them were addressed in zircon, so it's a matter of pulling some of those back and making sure they're appropriate for LK
<Griwes>
hmm, unsure if you're doing that in zircon (I'm going to try to figure it out without looking), but since most of the use cases I can see for this are going to be synchronous, I could do the trick of building an intrusive linked list out of state objects on the stack of the caller
<geist>
yep, that's precisely what zircon is doing
<Griwes>
it's such a great technique that only becomes obvious once you see it
<geist>
however, there's a caveat there: that means that you're effectively limiting the max number of cores you can send
<geist>
there's a TODO item there for zircon to move the local state *off* the stack, because of that
<geist>
ie, if you have 31 cores to send an IPI to, you have to make 31 copies of the message to put in 31 queues
<geist>
*or* you have some sort of notion of a broadcast queue that all cpus look at, etc. can get complicated
<geist>
the zircon code does the 31 copies thing
<Griwes>
okay, thanks for as usual pointing me into a sane direction
<geist>
cool! also you can use a sane arch like anything that's not x86 so you dont have to do this cross cpu shootdown
<geist>
or get a Zen 3+
<geist>
i hope intel picks that up eventually
<Griwes>
for async things I'll just carve out an irq number (can't really think of any async thing other than "do your preemption thing", and I think I can spare an irq number or two) and for sync things I'll try to figure this out
<geist>
yep, that's precisely what i do too
<Griwes>
I mean I'm sure tlb shootdown isn't the only thing that'll end up using this mechanism
<geist>
in my experience there's not a lot aside from some initial set up stuff (synchronizing MTRRs, etc) or shutdown (stop the other core RIGHT NOW)
<geist>
most IPIs are fire and forget
<geist>
which is good of course
<Griwes>
yeah I have some init steps that use the slots thing, there it works fine because the whole thing isn't particularly dynamic
<Griwes>
I also wish intel has done the sane thing from the start, but oh well
<geist>
ugh looking at this code now someone came along at some point and 'optimized' it and seriously nerfed it
<Griwes>
heh
<geist>
the structure that is allocated on the stack is a) no longer a POD and thus needs a constructor run and b) is now always constructed SMP_MAX_CPUS even if only one is needed
<geist>
that was a case where it was initially *not* a class or struct so that it would not require construction
<geist>
but someone moved thigns around and made it fancy because we have to have fancy things
<Griwes>
sounds like OOP brain worms
<geist>
general usual 'make things safer' mentality. which is generally not bad, but should be carefully watched sometimes
<geist>
that aside i think the compiler would garbage fill it anyway because we also have that feature on
<Griwes>
my SMP_MAX_CPUS is currently happily set to 1024, I don't think allocating that many on the stack will work so well :'D
<geist>
so need to deoptimize this a bit
<geist>
no, exactly. you'll need another scheme
<geist>
in zircon i think this is one of a handful of places where things are statically sized based on it. need to remove it some day, but its not a huge priority
<Griwes>
I'll ponder on it while it's raining around my camping spot for the whole day tomorrow
<geist>
yay fun
<Griwes>
(you may notice a pattern of me being more active here when I'm out in the wilds lol)
psykose has quit [Remote host closed the connection]
psykose has joined #osdev
psykose has quit [Remote host closed the connection]
psykose has joined #osdev
<Griwes>
Hmm, since a core can't only be doing a single outgoing request like this, maybe the solution is to just bite the N*N bullet and store a linked list entry table per core per target core within the cpu core object array, and store the actual state that those entries duplicate by pointing to it on the stack
kingoffrance has joined #osdev
the_lanetly_052_ has joined #osdev
diamondbond has joined #osdev
Likorn has quit [Quit: WeeChat 3.4.1]
floss-jas has quit [Remote host closed the connection]
zaquest has quit [Remote host closed the connection]
zaquest has joined #osdev
GeDaMo has joined #osdev
the_lanetly_052 has joined #osdev
the_lanetly_052_ has quit [Ping timeout: 246 seconds]
<geist>
Griwes: yeah that's probably a good idea
<geist>
was just thinking about having on the local cpu's struct, N entries, so that each cpu can have up to N other ones out there
<geist>
where N is the total number of cpus in the system
<geist>
since any given cpu can only be sending one round of IPIs at a time
Jari--- has quit [Ping timeout: 260 seconds]
the_lanetly_052_ has joined #osdev
the_lanetly_052 has quit [Ping timeout: 246 seconds]
pretty_dumm_guy has joined #osdev
floss-jas has joined #osdev
Jari--- has joined #osdev
Likorn has joined #osdev
mahmutov has joined #osdev
jafarlihi has joined #osdev
<jafarlihi>
I decided the only way I'm going to finish these compiler books if I read a chapter of each per day
lanodan has joined #osdev
diamondbond has quit [Ping timeout: 258 seconds]
jafarlihi has quit [Ping timeout: 240 seconds]
arch-angel has quit [Ping timeout: 272 seconds]
arch_angel has joined #osdev
Jari--- has quit [Remote host closed the connection]
Jari-- has joined #osdev
gog has joined #osdev
diamondbond has joined #osdev
<ckie>
afternoon, #osdev
gog has quit [Ping timeout: 258 seconds]
jafarlihi has joined #osdev
<mrvn>
jafarlihi: why are you reading compiler books when you are designing a kernel?
<ckie>
god the gdt packing is hurting my brain
<mrvn>
geist: If the message is too big to have 31 copies why can't you have a shared_ptr?
jafarlihi has quit [Quit: WeeChat 3.5]
the_lanetly_052_ has quit [Ping timeout: 246 seconds]
<mrvn>
ckie: that descriptor with struct { uint16_t pad; uint16_t high; uint32_t low; }?
<mrvn>
geist: If you have the message in the per cpu struct aren't you effectively sending abroadcast to other cores to look there?
<mrvn>
ckie: It's what happens when you extend a 16bit struct by 32bit.
<ckie>
mrvn: i'm dealing fine, just being annoyed at the structure
arch_angel has quit [Ping timeout: 258 seconds]
<ckie>
oh wait, you don't have to set base and limit on long mode!
<ckie>
i am freee~
<zid>
yea long mode is mostly like that
<zid>
"This is hardcoded as 0 or will #GP"
<zid>
Go look at the long mode TSS when you get a chance
<ckie>
zid: i am trying to bootstrap as little as possible so i can start porting tcc and then writing my compiler above it
<zid>
Well you'll need a TSS if you want IRQs
<j`ey>
ckie: you want to use tcc to build your OS or want to run tcc on your OS?
<mrvn>
I'm always a bit annoyed that in the docs they tell you all about this huge collection of bits and then at the end: In long mode a,b,c,d,e,f must be 0.
<ckie>
j`ey: yes
<mrvn>
Would be nice to have a switch "I'm in long mode" and all the cruft gets hidden.
<ckie>
(i am writing just enough with my host compiler to make tcc run and compile the rest of the OS when it starts)
<zid>
<source>:8:20: warning: overflow in conversion from 'int' to 'signed char:1' changes value from '12' to '0' [-Woverflow]
matrice64 has joined #osdev
<zid>
because 12 is even
<ckie>
oh that.. overflowed my screen
<ckie>
zid: so it is just a bit?
<zid>
that's what 1 bit often means yes, 1 bit
<zid>
also you don't need to pack chars
<zid>
and that's a union
<zid>
and you didn't compile with optimizations
<ckie>
zid: it wasn't initially, then i wanted to test More Things
<zid>
so literally none of this makes sense, grats :P
<ckie>
zid: )^:
<mrvn>
<source>:8:20: warning: overflow in conversion from 'int' to 'signed char:1' changes value from '12' to '0' [-Woverflow]
<heat>
the best part of a bool is how it literally just isn't a bit
<ckie>
mrvn: read above
<heat>
so you waste 7 other bools you could've stored there in the process
<zid>
heat: Bool should be 8 bits and have massively different bitpatterns and invariant checks for bitflips
<zid>
int isRoot :1; much less secure :p
<zid>
google had a machine hacked because of that, scale + bitflip rate is a bitch
<ckie>
the odds
<mrvn>
ckie: hopefully can only ever be 0 and -1
<mrvn>
or 0 and 1 on other archs
<mrvn>
Tip: never ever use char for anything but `const char *` C-style strings.
<ckie>
huh, the struct *does* get ceiled to byte
<zid>
ceiled?
<zid>
as in, ceil()? floating point round up to nearest integer?
<ckie>
yes, my brain works in weird ways
<mrvn>
ckie: it's a char. it's always going to be a char. Union members since C99 must share memory.
<ckie>
bit=0.125
<mrvn>
sizeof(union) == max(sizeof...(member))
<heat>
you mean rounded?
<ckie>
heat: yes, but always up, so ceil
<zid>
well there's no way to address a single bit
<zid>
it HAS to live in a byte
<heat>
but these are integers
<heat>
so rounded up
<mrvn>
zid: and doesn't that make you wonder how std:vector<bool> works? :)
<zid>
and the struct which contains the bitfield is 1 byte long, so making an array of those structs.. is an array of bytes
<zid>
not an array of bits
<ckie>
my actual situation is the segment descriptor type, i want a struct with four `u8 thing : 1;`s
<kingoffrance>
i found my action replay and ran your psx cd zid. i get a purple gradient background, the picture, and static-ish sound :/
<zid>
so why not look up how bitfields work
<mrvn>
ckie: question: shat size does A and B have: struct A { char x : 5; char y : 5; char z : 5; }; struct B { short x : 5; short y : 5; short z : 5; };?
<zid>
instead of guessing
<mrvn>
s/shat/what/
<zid>
but the answer is just that consecutive bitfields pack together naturally
<ckie>
zid: i mean, the reason i came here was because i didn't realize that that syntax also used the same term. i figured it'd have a fancy word like rust's ::<>
<ckie>
mrvn: -O?
<mrvn>
ckie: doesn't matter what -O you use.
<ckie>
okay then A, 3 chars, 3 bytes
<heat>
you're overengineering this
<ckie>
short 6
<mrvn>
ckie: no, B is 2
<heat>
it's a segment descriptor
<heat>
you can totally hardcode it
<ckie>
heat: i am a sucker for satisfying things like this
<heat>
that's the big stupid
<heat>
you'll get lost in the details
<psykose>
it's the big fun
<ckie>
yeah!
<heat>
also bitfields << shifts and masks
<heat>
you can't write them atomically without a union
<ckie>
heat: am i supposed to parse that message with << as shift
<heat>
no
<psykose>
bitfields << (shifts & masks)
<mrvn>
ckie: I would just define the bits in an enum and then you can declare the descriptor as NX | BIT64 | KERNEL or something.
<zid>
bitfields are an extension and are backwards wrt various compilers
<zid>
they're not very usable
<zid>
some compilers treat them as ABCD -> ABCDxxxx some as xxxxABCD some as xxxxDCBA etc
<heat>
right
<mrvn>
ckie: or do you plan to use lgdt?
<ckie>
mrvn: well, what else would i do?
<heat>
if you need to make sure they're in the correct order, don't use them
<zid>
[16:04] <zid> It isn't needed, you can always implement it with an array of char instead, it's just much nicer syntax wise
<ckie>
heat: but the syntax is so preeeettty
<mrvn>
ckie: wait, ldt? what's the acronym for the local gdt?
<zid>
That was 25 mins ago fwiw
<ckie>
ldt?
<ckie>
yeah
* ckie
goes to check
<heat>
ckie, the syntax is "pretty" but also horrific because YOU CANT SET TWO FIELDS AT ONCE
<mrvn>
ckie: the gdt you install once and never change. so making that fancy is wasted time. But some people use the local descriptor table dynamically.
<zid>
gotta rely on the compiler being clever to a large degree is always fun
<heat>
i'm also not sure what &s.bitfield returns and I'm scared to know
<ckie>
okay, you got me, i'll write it out by hand
<heat>
thanks
<mrvn>
heat: <source>:9:12: error: cannot take address of bit-field 'hopefully'
<ckie>
(but just for this though)
<heat>
don't use them for paging either
<mrvn>
ckie: I have it defined in my boot.S
<ckie>
once i get tcc working i can do whatever i want to it
<heat>
just a tip
<heat>
the "I can't set two fields at once" thing really hurts there
<ckie>
i can make it horribly not standard
<zid>
does tcc even support bitfields
<mrvn>
zid: it claims to be fully C99
<ckie>
zid: idk, but it will if i want it to
<heat>
mrvn, thankfully it errors out
<GeDaMo>
"TCC not only supports ANSI C, but also most of the new ISO C99 standard and many GNUC extensions including inline assembly." https://www.bellard.org/tcc/tcc-doc.html
<heat>
ckie, is this scope creep?
<ckie>
heat: no, the plan has always been to hit everything i don't like with hammers until it's how i want it to be
<ckie>
tcc is just a convenient starting point
<ckie>
for a while i was considering learning FPGA and starting from there but i recently rerealized that i hate hardware very much
<heat>
that sounds horrific good luck
<ckie>
(^:
<ckie>
heat: there's also a bit more of a plan than that FWIW
<ckie>
but the actual things i've thought a lot about are only *after* i get a working tcc
<ckie>
i've been mostly working on userspace C++/Rust things before this, and raw C is actually kind of nice
<bslsk05>
github.com: c4/c4.c at master · rswier/c4 · GitHub
<ckie>
except inline asm and weird register allocation bugs
<ckie>
GeDaMo: that's neat, but i need to be able to read it ideally
<ckie>
without a headache*
<GeDaMo>
It only implements a subset of C anyway :P
Mikaku has left #osdev [Leaving]
<ckie>
also, some more context, i won't be writing the runtime-compiled code in C, i want it to just be an IR since it's C and it's easy to read
* ckie
unless its a cursed bitfield
<j`ey>
i dont understand that sentence
<mrvn>
ckie: at least with older gcc bitfields aren't optimized well. Using your own bit masks gives better code.
<kingoffrance>
using C as intermediate representation
<ckie>
j`ey: i am writing barebones bootstrapping code rn so I can port tcc. then I will write a compiler that outputs C code which I'll feed to tcc, then jump to the asm
<j`ey>
oh ok
<mrvn>
ckie: and if your add volatile you really don't want bitfields as the compiler must not optimize those.
matrice64 has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
<j`ey>
i got confused by the 'i want it', i thought it refered to what you would write the code in
diamondbond has quit [Quit: Leaving]
<heat>
why C?
<heat>
llvm bitcode does what you want, but in a proper way
<j`ey>
harder to generate maybe?
<ckie>
heat: i don't wanna port llvm
<j`ey>
tcc is tiny
<ckie>
and i know c
<heat>
are you trying to port tcc to run on your os?
<ckie>
heat: later, yes
<heat>
what do you mean with "port tcc" then?
<ckie>
well, once i hit enough things to make the CPU happy, i'll go get the tcc code and hit it with enough hammers until it links
<ckie>
then i'll make it compile a hello world on startup and go from there
<ckie>
(and run)
<j`ey>
heat: ckie wants to compile their code at boot time
<j`ey>
with tcc
<heat>
hmm
<heat>
odd but ok
<ckie>
the end goal is not having to trust anything but the little bootstrap runtime
<ckie>
(by adding memory safety things to tcc so you can't just do whatever you want)
<ckie>
okay, and maybe some drivers
heat has quit [Remote host closed the connection]
heat has joined #osdev
* ckie
did something really dumb
<ckie>
god i should really write notes about where i left off
heat has quit [Ping timeout: 244 seconds]
alpha2023 has quit [Ping timeout: 240 seconds]
alpha2023 has joined #osdev
floss-jas has quit [Remote host closed the connection]
jimbzy has joined #osdev
dude12312414 has joined #osdev
nsmb has joined #osdev
puck has quit [Excess Flood]
puck has joined #osdev
pretty_dumm_guy has quit [Ping timeout: 246 seconds]
pretty_dumm_guy has joined #osdev
lanodan has quit [Ping timeout: 258 seconds]
lanodan has joined #osdev
kingoffrance has quit [Ping timeout: 265 seconds]
<geist>
good afternoon folks
<geist>
hows your weekend?
rustyy has quit [Quit: leaving]
rustyy has joined #osdev
<geist>
okay, after bios the server machine still crashed. so that's pretty much proof that it's the motherboard/ram/power supply. i guess i can swap the PS next before writing off the mobo
<zid>
I still call mobo
<zid>
ps is unlikely to be like, *slightly* flakey, it'll either die under load every time, or not work
<zid>
ram would cause ram errors that wouldn't MCE it'd just make things crash
<Griwes>
okay, I think I now have the new IPI handling code in place and it... appears to work, yay
<Griwes>
together with a thing that batches the invlpgs into batches of 32 to somewhat reduce the ipi pressure
<Griwes>
at some point I'll need to figure out how to do heuristics that decide to switch between that and just telling other cores using the modified page tables to just reload cr3 instead of doing invlpg, but that day is not today
<mrvn>
Griwes: If you collected 32 pages to invlpg isn't it faster to reload the page table?
<Griwes>
no idea
<Griwes>
I'll do some experiments at some point
<mrvn>
if you have to send an IPI every 32 pages then I would say that's your cutoff.
<j`ey>
Griwes: when you batch them.. that's just a loop right? I mean there's no hw support
<Griwes>
but right now I need this to be functional, not necessarily as optimized as possible
<Griwes>
j`ey, yeah I have an object that collects them and sends an IPI every 32 or on destruction
<mrvn>
collect pages and if the buffer overflows send a "reload CR3"
<Griwes>
more ideas stolen from geist :'D
<Griwes>
we'll see
<Griwes>
I'll tinker with it in the future and try to collect like actual data to make an informed design decision there
<j`ey>
Griwes: so the object is shared between all cores?
<Griwes>
no, it's local to a call to unmap()
Likorn has quit [Quit: WeeChat 3.4.1]
<geist>
yah something like 16 or 32 is probably about right
<geist>
i think we do 16 in zircon, but can probably test it
<j`ey>
Griwes: i mean once you send the IPI, how do the other cores know what to invplg
<geist>
the other optimization you'll want to do is store some sort of bitmap per address space of which cpus have it active
<geist>
and then only shoot TLB shootdowns to cpus that currently have that aspace active. unforunately the kernel aspace is always active
<geist>
which is why it's generally expensive to mess around with kernel mappings
<Griwes>
j`ey, the task inserted into the ipi work queue of any given core has a pointer back to the object
<geist>
j`ey: it's part of the message. you put together a list of things to flush, then send a *synchronous* (ie, wait for it to complete) message to all the affected cores
<mrvn>
microkernel, much fewer mapped pages. :)
<geist>
when they've all marked that they finished, you can move on
<j`ey>
Griwes: right, that's what I meant with 'so the object is shared between all cores?'
<geist>
note this is generally an x86ism. ARM has a much better solution
<geist>
riscv is curious: they basically make it a firmware call to do this
<Griwes>
geist, yeah, I know there's things to limit how many cores I notify; I'm planning to experiment with logical apic destinations to see where I can get
<geist>
but it does avoid the interrupts-disabled issue, because the firmware (at machine mode) is free to interrupt other cores when it wants to, even if they have interrupts disabled
<geist>
Griwes: frankly by the time you get to that many cores there are generally much bigger issues to fight
<geist>
but it's good to think about it
<Griwes>
hmm, so riscv effectively also has SMM?
<geist>
well, SMM *kinda*? it's much closer to EL3 in ARM
<geist>
but yeah the x86 analogy is SMM, except the higher modes are much more transparent on riscv and arm
<geist>
it's simply another priviledge level, and largely symmetric
<geist>
SMM is a bit more specialized and wonky
<Griwes>
I see
<geist>
but yes, functinoally it's similar to having a piece of SMM firmware that just does whatever magic is necessary to sync tlb
<bslsk05>
github.com: riscv-sbi-doc/riscv-sbi.adoc at master · riscv-non-isa/riscv-sbi-doc · GitHub
<geist>
i dunno if this is a good idea in the end, but riscv has generally hard tilted on putting complex stuff inn firmware. i think the idea being that if you're being virtualized it turns into largely a paravirtualization interface for you
<geist>
as a side note i read the riscv virtualization extensions yesterday. looks basically like ARM64 + VHE extension
<geist>
j`ey might be interested in that
<mrvn>
On the other hand in hardware it turns into every SOC doing it's own thing and you have to support them all.
dude12312414 has quit [Quit: THE RAM IS TOO DAMN HIGH]
<j`ey>
geist: im not looking at riscv at all!
<geist>
ie, it's not really another mode, but supervisor mode when the V extension is enabled (by writing an enable bit in misa) has a second set of control registers to deal with, that are largely banked
<Griwes>
huh, so it uses the exact same instruction as syscalls?
<Griwes>
that's very elegant tbh
<geist>
so you're kinda running in EL2 at that point. when you then eret to supervisor mode with the 'V' bit set in the main control registers, the banking happens and suddenly the guest code (in supervisor mode) is seeing the banked copies of stuff
<geist>
so effectively the 'V' bit in sstatus enables nested virt and switches core control regs to a shadow copy
<geist>
ie, sstatus is now the hypervisors status, and vsstatus is what the guest sees as sstatus, etc
<geist>
so it's pretty clean. the entire thing is basically a banked copy of about 6 control registers and the additional functionality of specifying a second level page table
<geist>
j`ey: well, i figured you might be interested only in that you probably know arm64 the most of folks here that are active right now
<geist>
anyway, think i'll fiddle with this a bit today. need to toy with riscv some more
<Griwes>
huh, IPIs are also an ECALL
<Griwes>
playing with this will be interesting
<j`ey>
im interested in virtualisation, working on a hypervisor type thing
<geist>
right. yeah, they basically say 'hey dont worry about how to do that, that's machine specific, we'll hide it behind firmware'
<geist>
Griwes: you'll also notice that timers themselves are implemented in machine mode. i think there's some effort underweigh to provide a supervisor level timer, since that may have been a bridge too far in 1.0 spec
<Griwes>
I like how they already have a "legacy extensions" section lol
<geist>
but, basically as it stands each cpu gets *1* timer, and its machine mode only, so you actually use SBI calls tos et a timer for you
<geist>
and that works by firing the timer irq in machine mode, and then that code reflects it down to supervisor mode.
<Griwes>
huh
<geist>
which at least arch wise is fairly easy to do, you could write a handful of assembly to look at the irq reason (in machine mode) and then decide, oh i'll just bounce this down to S mode by setting the corresponding timer irq bit in the status register and then eretting
<geist>
it'll then instantly fire in S mode
<geist>
basically s mode timers are virtual
<Griwes>
so effectively on riscv you're always virtualized
<Griwes>
neat
<geist>
yeah
<geist>
of course if yuo're some embedded cpu you probably just dot have supervisor mode, so you write your code to directly run in machine mode, so then you have to drive everything manually
<geist>
but that's fine, it's embedded
<Griwes>
yeah, and I don't have a particular desire to deal with truly embedded stuff myself
<geist>
it's kinda fun, but mostly because you put on a different hat and have to deal with differet set of constraints
<Griwes>
huh, armv9 is armv8 compatible? I guess this means that neither "arm64" not "aarch64" is going to become a horribly imprecise name any time soon
<j`ey>
yes armv9 isnt a break in compatability like that
<geist>
yah it's roughtly armv8.5 + SVE mandatory
<geist>
they didn't even spin it out into it's own manual. the armv9 manual is simply the current vrsion of the v8 manual
<geist>
i dunno how that's going to continue long term though. i've watched v8 in the last 10 years just grow exponentially more complex
<geist>
i'm still mostly dealing with v8.0 and v8.1 stuff, but once you getinto all the optional bits post v8.1 it gets really really really hard to follow
<geist>
need a cheat sheet of extensions
<Griwes>
is it still risc? *hides*
<geist>
very little fiddling with the ISA virtually all of these are kernel level things
<geist>
actually htat's probaby why they switched to v9: it's the first place where the user space ISA has changed fundamentally (with the addition of SVE)
<geist>
much to my chagrin what they didn't do in v9 was remove a lot of stuff, like arm32. it's still there, just only EL0
<j`ey>
still optional
<geist>
but, since the manual still covers v8 it means it still has this huge pile of chapters dealing with legacy mode arm32 supervisor mode
<geist>
which i think if they made a hard v9 manual you could at least delete a good 1000 pages out of it
<j`ey>
yeah a 64-bit only manual would be nice
<geist>
yah some sort of feature on a pdf viewer to just functionally knock out a range of pages would be nice
<geist>
like, just skip these thousand pages, dont let them show up in searches, etc
<geist>
i guess some sort of editor and re-save it with the 32bit chapters missing would work
<geist>
reminds me of a little mini battle i've been fighting with my coworkers the last few years: seems that lots of folks have the idea that when you add #defines/etc for registesr and whatnot out of the manual that you should give all the fields 'nice' names
<geist>
such that they're descriptive of what htey do. i get the idea
<geist>
but... it means it's really hard to cross reference them from the manual
<geist>
i have a generally hard rule that you *must* use the exact same name as the manual. and if it's not clear you add some comments at the place it's defined
<geist>
that way you can just do a pdf search for 'what does this bit mean?'
<geist>
but also accordingly it's really helpful of vendors use fairlyu unique monikers for registers and bits. ARM is good about it. SCTLR_EL1 only shows up as a single thing, etc
wand has quit [Remote host closed the connection]
<geist>
its worst when vendors use generic names like ENABLE
wand has joined #osdev
<geist>
some folks, for example, will define SCTLR_EL1 as something like SystemControlRegister with bits like EnablePaging
<geist>
nice. i get it, but that's really hard to figure out what it means in the ARM ARM
<Griwes>
I do rename some registers in code but I try to do that only when it's either very obvious where the docs are, or very obvious what the bits are
Bonstra has quit [Ping timeout: 260 seconds]
<geist>
yah you *could* make an argument that you rename it but then make sure at the place of definition you document what the manual calls it
<j`ey>
I'd rather have the defines as named by the spec, and just helper functions named better
<geist>
that's of course hard to do if the way you define thigns involves a bunch of templates and whatnot such that the editor can't 'find' the definition
<geist>
but thats another battle.
<mrvn>
geist: I want that with much more flexibility. Every optional thing should have an on/off switch in the reader.
<mrvn>
Give me an interactive manual.
<geist>
well we have this very complicated and flexible thing in fuchsia called hwreg which i'm not a fan of
<geist>
but it does do basically what you awnt
<geist>
you define a set of fields and it creates all these accessors and whatnot
<bslsk05>
fuchsia.googlesource.com: zircon/kernel/lib/arch/include/lib/arch/arm64/system.h - fuchsia - Git at Google
<geist>
that builds a whole class for that register with all the accessors and whatnot
<geist>
with some trait class thing that i guess stamps out 3 copies of it (for different ELs)
<mrvn>
geist: I was refering to the magic pdf reader :)
<geist>
ah yeah
GeDaMo has quit [Quit: There is as yet insufficient data for a meaningful answer.]
<mrvn>
I have a template mess too for describing registers for the RPi that deal with all the cases: bit, bits, mbz, ign, mbo, scattered bits, read-only, write-only.
<geist>
yeah. i guess i'll have to get used to it, but i'm still a bit grouchy about it
<geist>
the boilerplate to use it is pretty nasty
<geist>
but, it is efficient: this hwreg stuff does generate exactly what you'd want
<mrvn>
Not using it much because it's too much boilerplate as you say.
<mrvn>
enum class { NX = 1<<17 .... } is just so much simpler to write.
<mrvn>
What was the new way for volatile read/write again?
<geist>
right. the usage of it is something like `arch::ArmSctlEl1::Get().FromVal(0).SetFoo().ClearBar().SetBaz(54).WriteTo(system_register);` or something
<geist>
i forget how the writeTo part works, i think there's some factory to generate an accessor for real hardware register or something
vdamewood has joined #osdev
<Griwes>
OOP brain worms, smh
<geist>
i have always hated chaining things together like that, but that is very Rusty and i've seen that pattern make its way more heavily into work C++
<Griwes>
what's wrong with good old fashioned bitwise math
<geist>
well, as security folks will say it's very error prone, etc. which in my experience really isn't the case
<bslsk05>
fuchsia.googlesource.com: zircon/kernel/arch/arm64/arch.cc - fuchsia - Git at Google
<geist>
using a lambda even!
<mrvn>
geist: What's the semantic of that anyway? Does it do one after the other? Or does it optimize it into a single read-modify-write?
<geist>
that's right, there's a Modify() call you can make that gives you a place to run a lambda with the a variable already filled out that you then fiddle with and it'll write it back
* Griwes
barfs a little
<geist>
but. as i said the code actually compiles to precisely what you want, at least
<mrvn>
geist: My syntax is: reg_foo |= NX | MODE(3) | KERNEL_RW | USER_R;
<geist>
so strictly speaking it's 'better' because it efficiently implmenets a thing more safely and with some side debugging (there's a .dump() style routine you can call on it)
ripmalware_ has quit [Ping timeout: 240 seconds]
<geist>
but i'm being dragged kicking and screaming into this world
<Griwes>
it's like people looking at .unwrap().unwrap().unwrap() and saying that it's beautiful
xenos1984 has quit [Read error: Connection reset by peer]
<Griwes>
hang on, I'm not even 29 yet, I'm too young to be a grumpy old man
<geist>
Griwes: heh
<geist>
i mean yeah you kinda get used to it, i guess
<geist>
it's easier for me to accept when it's a new language that has that idiom
<geist>
since yuo have to sort of brain context switch
<mrvn>
geist: what happens when you forget the .WriteTo(system_register)?
<geist>
then it just hangs around
<mrvn>
geist: or write t0o the wrong one?
<geist>
that's how you read from it
ripmalware has joined #osdev
<geist>
you can do an `auto foo = blahblahbgetregister; something = foo.field();`
<geist>
doesn't require you write it bakc
<mrvn>
geist: modifications should be RAII
<geist>
that's probably why that `Modify()` helper routine exists, it does the read and writeback for you
<geist>
there's probably some feature for that. keep in mind myexample above was just off the top of my head
<geist>
the hwreg stuff has *lots* of helper routines and whatnt. wouldn't be surprised if there wasn't some RAII wrapper that does precisely what you want
<geist>
OTOH, I'd kinda rather not have writebacsk happen at arbitrary times
<geist>
generally the writeback is sort of important, so i'd rather it be explicit or and error if you forgot to (if you want to have safety rails)
<mrvn>
I'm still trying to get to something like this: WITH(reg_bla) { blub = 1; if (bla) baz = 2; ... };
<geist>
well, that's exactly what that Modify() thing above does
<mrvn>
The closing } writes back.
<geist>
takes a functor of some type. maybe thats your solution
<mrvn>
And the WITH opens up the namespace or scope or whatever so blub/bla/baz have meaning.
<geist>
that might e difficult
<mrvn>
yeah. that's the part I'm stuck with
<geist>
anyway my brain is running out of my nose now, thinking about c++ right now
<geist>
think i'm going to do something productive with my afternoon
<mrvn>
Can't do "using namespace REG_BLA { ... }"
<geist>
unrelated: i did my first surface mount chip solder yesterday. wasn't that hard
<geist>
but it was a SOP-14, so still fairly large
<geist>
going to try to solder some small ass resistors in a bit
Bonstra has joined #osdev
<mrvn>
ahh, nothing like the smell of hot led in the morning.
<mrvn>
lead
<mrvn>
geist: per hand or with an oven?
<geist>
by hand
<geist>
used a drag soldering method, though each pin would have also been doable
<zid>
for resistors my advice is give up now
<zid>
or use paste
<zid>
either works
<geist>
well, i think the only reason any of this works is i have a decent stereo binocular scope
<geist>
otherwise i wouldn't be able to see any of it
<geist>
and reasonably steady hands
<zid>
paste is gooey and then the positionig and the heating are diff steps
<zid>
you just pray it doesn't tombstone
<mrvn>
the quality of the board and pads is important too
<geist>
yah but you can pop that back off though if it tombstones (assuming my assumption is what it hin)
<zid>
yea if it does you just go again
<geist>
but you're right, i need to do some resistors next. i have a batch of 0805s which are pretty big
<zid>
What about a heat gnu?
<zid>
When a heat elk just won't cut it
<Griwes>
gnu/heat
<geist>
i have some rework station gun somewhere
<geist>
but yes i should get some skills there too
<geist>
like maybe use it to remove the chip i soldered down yesterday
<zid>
microsoldering is just not any good with an iron
<Griwes>
I think the time has come for me to start figuring out a DSL for userspace IPC, I'm expecting that to be quite the journey
<geist>
domain specific language?
<zid>
it's either that or dick sucking lips
<geist>
<gasp>
<zid>
I was about to ask though if that meant "A formal grammar" or just "a protocol"
<geist>
but you blew it right?
<geist>
now the conversation can never recover
<Griwes>
lol
<zid>
not for free
<Griwes>
Yes a domain specific language for protocol definitions, you filthy osdevvers
xenos1984 has joined #osdev
<geist>
btw i may have linked this the other day but this is a great description of drawing with atari 2600
<bslsk05>
'Racing the Beam Explained - Atari 2600 CPU vs. CRT Television' by Retro Game Mechanics Explained (00:38:25)
<mrvn>
I want segments for my IPC. I want to pass a blob of memory and any pointers should be relative to the message start and limited to the message size.
<zid>
I thought it was just "count cycles"
<geist>
this guy does pretty great deep dives into old stuff
<geist>
it's ver much count cycles, but he really has a great example and good visualizations of it
wootehfoot has joined #osdev
<mrvn>
I'm waiting for the TFT just being a device with RDMA for the framebuffer you write to directly.
<mrvn>
It's kind of stupid for the cpu to generate a video format for the output just so the monitor can parse it back into memory, scale to fit, and drive the display.
floss-jas has joined #osdev
<geist>
well that was no sweat. just soldered a couple of 0805s and that was ez
<zid>
how much cheating did you need
<geist>
zero. just went down fine
<geist>
put a solder blob, then tweezered it over and heated it up, stuck fine