IRC channel logs

2024-03-05.log

back to list of logs

<damo22>youpi: https://lists.gnu.org/archive/html/bug-hurd/2024-03/msg00009.html i need to address this review but it seems you merged everything already?
<solid_black>hi all
<damo22>hi im nearly done at work
<solid_black>(does that mean you're about to afk, or the opposite?)
<damo22>almost nonafk
<damo22>ok
<solid_black>do I understand it right that there can be multiple interrupt controllers connected to the same system? can they be not nested/chained/cascaded, and just connected independently? if they are cascaded, that means that an irq on a "more nested" controller would not affect the CPU directly, but would request an interrupt on its interrupt-parent, right? does the CPU need to acknowledge / clear the interrupt on both controllers in that case, or only on the
<solid_black> root one? can there be multiple levels of nesting?
<solid_black>do I understand it right that each interrupt controller has its local namespace for irq numbers, and Linux (and most kernels?) maps those controller-local irq numbers to a single global namespace that doesn't directly correspond to anything in hardware? does gnumach do the same on i386?
<damo22>first q: yes, there is nesting of PIC, it is constructed out of master and slave controllers
<damo22>and yes, there is a special way to ack the eoi
<damo22>second q: i think so... we also map these to natural numbers counting from 0
<solid_black>where is the logic for that?
<solid_black>and can/should we avoid doing that on aarch64, and just always explicitly know which interrupt controller we're talking about
<damo22>i386/i386/irq.c
<damo22>irqtab
<solid_black>does 'struct irqdev' represent a single interrupt controller?
<damo22>i think it represents all the interrupts in the system
<damo22>which makes me realise i forgot to update that when i added 2 IOAPICs
<damo22>the first list should be 0-63
<solid_black>is there any mechanism in the hardware / whatever irq protocol to avoid races between CPU ack'ing and irq and the new irq being raised? like some irq serial numbers perhaps, so you'd specify which specific irq notification you're acknowledging?
<solid_black>looks like irqtab (an instance of struct irqdev) is the global list of all (top-level?) interrupts indeed, but there must be a reason for irqdev_ack() accepting self-pointer, there is clearly meant to be more than one
<solid_black>is EOI the same thing as acking?
<damo22>eoi means end of interrupt, it is what you do when you acknowledge the interrupt
<damo22>i wrote the irq code, i should know more
<damo22>s/wrote/rewrote
<damo22>i invented the idea of irqdev i think, so that we could abstract all interrupt controllers into one flat list of irqs
<damo22>regardless of arch
<solid_black>ok, but why do we want that?
<damo22>i think it should make porting a new arch with different irq controller easier
<solid_black>porting to a new arch with different irq controllers is exactly what I'm doing :)
<solid_black>so you are saying that I should try and map all irqs from all irq controllers to a single linear list?
<damo22>i think you just need to implement arch/arch/irq.c
<damo22>and a way to mask/unmask and eoi
<solid_black>yeah, but I don't understand how that would work, given that there may be multiple interrupt controllers, each with its own API for masking/unmasking/whatever irq numbers that make sense to it, and they can be chained to each other, and we need to keep track of this and multiplex it somehow -- that's why I'm asking al lthese questions
<damo22>the way i did it was ensure the list is mapped linearly from all the controllers
<damo22>so IOAPIC0 goes from [0,n] and IOAPIC1 goes from [n+1, m] where n < 32 and m < 64
<solid_black>but can they be stacked/chained/cascaded/nested on one another?
<damo22>not these no
<damo22>they are separate ones
<solid_black>and what happens if at runtime these are not present, can that happen?
<damo22>at least one is always present
<damo22>i made the code accept one or two
<damo22>i think that covers many x86
<solid_black>I see i386/i386/apic.h uses #ifdef APIC to define mask_irq/unmask_irq one way, and otherwise i386/i386/pic.c defines them in a different way
<damo22>if not all of them
<solid_black>but that's a compile-time flag?
<damo22>yes, because PIC / APIC is a compile time flag due to mutually exclusive hw
<solid_black>ah, they are mutually exclusive?
<damo22>yes
<damo22>you cant run both
<solid_black>and, uh, how does that end up working in practice? do all modern systems just use one of them? (APIC?)
<damo22>we want to move to APIC 100%
<damo22>yes
<damo22>PIC is legacy
<damo22>possibly not even supported on some new boards
<solid_black>so you basically (if so configured at build time) always assume there's a specific interrupt controller model (APIC), and access it directly when you want to mask/unmask an irq?
<damo22>yes, but i detect it via the ACPI tables
<solid_black>where's the code for that?
<damo22>see acpi_parse_apic.c
<solid_black>does Mach even deal with ACPI? I thought that was /hurd/acpi in userland
<damo22>it has basic support for the MADT table and HPET
<damo22>just so it can detect ioapics and lapics
<damo22>and the hpet
<damo22>im guessing some ARM boards have ACPI
<damo22>you can most likely reuse most of this code
<solid_black>what info about APIC do you get from ACPI?
<solid_black>from what I've read, only high-end arm servers have acpi
<damo22>how many there are, any irq overrides
<solid_black>but eventually we could reuse that yeah
<damo22>and in DSDT you have pci routing
<damo22>but that is for userland to do
<solid_black>yeah, we'd rather put as much as possible into userland
<damo22>its done already
<damo22> but some stuff is required in mach so we can bring up irqs
<solid_black>but interrupts and timers have to be handled in Mach
<damo22>it was a design decision yes
<damo22>i mean, you could put them in userspace, but it would be very tricky to do
<damo22>lets just assume irqs and timers are in mach
<damo22>because they are already working
<solid_black>so again, the situation, as I understand it, is that there are several interrupt controller models in the arm/aarch64 world, and they're not exclusive in hardware, they can be multiple at the same time (I've only encountered two, one nested to another, so far, but who knows), and you don't statically know which ones you're going to get, you have to read all of this from the device tree
<damo22>i see
<damo22>that makes it tricky
<solid_black>please take a look at this https://s-matyukevich.github.io/raspberry-pi-os/docs/lesson03/linux/interrupt_controllers.html
<solid_black>right now, I have an extremely simple dirver for ARM GIC v2 (the model that qemu's "virt" machine has), and whenever I need to enable/disable/acknowledge an irq I call into that directly (i.e. gic_v2_enable_irq(int irq)), and that works for booting on "virt", since it has a single gic v2
<solid_black>but really I should make that into a struct with state (base mmio address), to be able to support multiple of them, and add drivers for other models, and multiplex between them somehow, and support chaining
<damo22>yeah
<damo22>dont try to copy what linux does
<damo22>its too complicated
<damo22>but you may want to write a simple parser for device trees that pulls out just what you need
<solid_black>yeah, that part is done already
<solid_black>everything is device tree-powered, no hardcoded addresses
<damo22>nice
<solid_black>(except for early serial console that'd used early, before we parse the device tree -- gotta do something about that)
<solid_black>but once I discover interrupt controllers via the device tree, how do I manage this all multiplexing and chaining between them? -- that's my question
<damo22>yeah its a good q
<damo22>what does it have? a base address and a register?
<damo22>and some kind of pin mapping?
<solid_black>a few base addresses (for GIC v2, distributor base/size + cpu base/size, though I don't exactly understand what those are), at least, and model/driver-specific ways of interacting with them
<solid_black>maybe there's more state, I haven't looked at controllers other than GICv2 closely yet
<solid_black>'cause I need the infrastructure in place to have many before I can implement them
<solid_black>does Linux's 'struct irq_chip' abstraction make sense?
<damo22>nah
<solid_black>(goes without saying, it would be so much better if someone with actual experience & understanding of hardware/arm was hacking on this, not me! but at least I'm learning a lot this way)
<damo22>i dont understand why there are two interrupt controllers
<damo22>and are nested
<solid_black>that makes two of us :)
<solid_black>but apparently that's how things are on rpi
<damo22>maybe you can just use the local one
<damo22>it has all the features we need i think
<solid_black>well that is just one specific case
<solid_black>another board is going to have a different setup
<damo22>we only need an interrupt controller that can configure all interrupts going to cpu0, sending equivalent of ipis and handling timer interrupts
<solid_black>but various pieces of hardware may be wired to different interrupt controllers
<damo22>we dont really need to support every possible arm device in the first iteration do we?
<solid_black>gpio (whatever that is) seems to be an interrupt controller of its own for example
<solid_black>definetely not every single arm device in the first iteration, but we need the framework for flexible intrrupt controller handling to be there from the start
<solid_black>as opposed to hardcoding a single instance of a single model, as I have things now
<damo22>right
<damo22>i dont know enough about arm
<damo22>i cant give you sound advice on it right now
<solid_black>I see, thanks anyway
<damo22>maybe ask another guy called "clever", he reverse engineered a fair bit of the raspberry pi firmware
<solid_black>it's less about raspberry pi and more about what abstractions we want to have for this in Mach
<damo22>yeah but he probably knows a lot of the device tree stuff and has seen a few
<damo22>or ask on a channel where they discuss arm hardware
<solid_black>maybe I should do that yeah
<damo22>see the indirection: device/intr.c: __enable_irq (irqtab.irq[e->id]);
<solid_black>and on i386, irqtab.irq is always a 1-to-1 mapping? (judging by irqtab definition in i386/i386/irq.c)
<damo22>yeah
<damo22>if it makes it easier for your case, you can make it non 1-1
<solid_black>but then again, that's not enough context; enable irq on which controller? there has to be a better multiplexing mechanism for this
<damo22>2*N+M
<damo22>or 1*N+M
<solid_black>we could do that, yeah
<damo22>controller_id * max_irqs + GSI
<damo22>again, it maps to a flat liast
<damo22>list*
<solid_black>one of the reasons I wanted to avoid that though is because the max number of irqs per controller is controller model dependent, and large
<solid_black>i.e. not 16, more like 1024
<damo22>really?
<damo22>we dont need more than 256 irqs
<solid_black>we?
<solid_black>I mean, we don't have a choice, do we?
<solid_black>whatever a peripheral is wired to, we need to handle
<damo22>or ignore the device
<solid_black>that'd be sad
<youpi>damo22: I merged everything because it could be indeed, the comment I had was to go even further than what you patches already do
<solid_black>sneek: later tell damo22, https://gitlab.gnome.org/GNOME/glib/-/merge_requests/3950
<sneek>Got it.
<solid_black>what does INTEL_PTE_WIRED do? (wire the page table entry, but in what sense?)
<biblio>solid_black: #define INTEL_PTE_WIRED 0x00000200 |= INTEL_PTE_WIRED & INTEL_PTE_WIRED - it is offsetting something.
<Pellescours>by running the latest gnumach (compiled myself) I get a divide by 0 error when playing with /dev folder (listing folder content, ...)
<Pellescours>I have in the console [ 41.xxxxx] cd0: dos partition I/O error
<Pellescours>kernel: Divide error (0), code=0
<Pellescours>I’m running with rump and I compiled with disable-linux-groups
<youpi>that's most probably the bug that flavio fixed
<youpi>in rumpdisk itself, not librump
<Pellescours>Ah ok, I probably don’t have the latest rumpdisk version
<Pellescours>how can I test a console client I built locally with motifications? I know I can replace the one in /bin/console and reboot but it’s not convenient
<youpi>you can start it by hand
<youpi>you can also restart the console service