IRC channel logs
2024-03-05.log
back to list of logs
<solid_black>(does that mean you're about to afk, or the opposite?) <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>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>and can/should we avoid doing that on aarch64, and just always explicitly know which interrupt controller we're talking about <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 <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 <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>i invented the idea of irqdev i think, so that we could abstract all interrupt controllers into one flat list of irqs <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? <solid_black>and what happens if at runtime these are not present, can that happen? <damo22>i made the code accept one or two <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>yes, because PIC / APIC is a compile time flag due to mutually exclusive hw <solid_black>and, uh, how does that end up working in practice? do all modern systems just use one of them? (APIC?) <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>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>im guessing some ARM boards have ACPI <damo22>you can most likely reuse most of this code <solid_black>from what I've read, only high-end arm servers have acpi <damo22>how many there are, any irq overrides <damo22>and in DSDT you have pci routing <solid_black>yeah, we'd rather put as much as possible into userland <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>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 <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>dont try to copy what linux does <damo22>but you may want to write a simple parser for device trees that pulls out just what you need <solid_black>everything is device tree-powered, no hardcoded addresses <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>what does it have? a base address and a register? <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? <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>maybe you can just use the local one <damo22>it has all the features we need i think <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>i cant give you sound advice on it right now <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 <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>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 <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>whatever a peripheral is wired to, we need to handle <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>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>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 also restart the console service