For random reasons I have been reading through the Open Firmware specifications. One in particular caught my attention the interrupt mapping specification. I really liked the basic structure, although I don't think the details themselves will map cleanly to LinuxBIOS.
The basic structure was:
Each device has it's interrupt. Each device has an interrupt parent. If not specified explicitly the interrupt parent is simply up the device tree but that was not required. An interrupt parent can have an interrupt mapping table that maps interrupts maps device#/interrupt pairs to ids consumed by devices up the interrupt tree. The interrupt mapping table can have a mask to reduce the size of the mapping table needed.
It is a very clean structure and it maps well to the LinuxBIOS device tree. There are few interesting complications that we need to handle like ACPI mode versus legacy PIC mode but those details should not be too difficult.
Once that infrastructure is implemented we should be able to auto generate pci-irq tables, mptables, acpi interrupt tables, and open firmware tables (Assuming we manage to export it all cleanly from the LinuxBIOS table).
Stefan how close is the open firmware code that we could test a port to generic LinuxBIOS. With the LinuxBIOS table providing this information?
Eric
ebiederman@lnxi.com (Eric W. Biederman) writes:
For random reasons I have been reading through the Open Firmware specifications. One in particular caught my attention the interrupt mapping specification. I really liked the basic structure, although I don't think the details themselves will map cleanly to LinuxBIOS.
The basic structure was:
Each device has it's interrupt. Each device has an interrupt parent. If not specified explicitly the interrupt parent is simply up the device tree but that was not required. An interrupt parent can have an interrupt mapping table that maps interrupts maps device#/interrupt pairs to ids consumed by devices up the interrupt tree. The interrupt mapping table can have a mask to reduce the size of the mapping table needed.
It is a very clean structure and it maps well to the LinuxBIOS device tree. There are few interesting complications that we need to handle like ACPI mode versus legacy PIC mode but those details should not be too difficult.
Thinking about this a little more open firmware defines one single root for it's interrupt tree, even if it must be purely virtual.
A simple extension of that idea is to have one root for each interrupt processing mode. And each node should be able to define multiple interrupt parents. That should be sufficient to handle the LinuxBIOS case.
That leaves a lot of details to handle but it should work.
Eric
* Eric W. Biederman ebiederman@lnxi.com [040202 01:28]:
Thinking about this a little more open firmware defines one single root for it's interrupt tree, even if it must be purely virtual.
A simple extension of that idea is to have one root for each interrupt processing mode. And each node should be able to define multiple interrupt parents. That should be sufficient to handle the LinuxBIOS case.
That leaves a lot of details to handle but it should work.
I'm not sure if I get you right... is this because the available interrupts can be spread over all the busses and IOAPICs?
Stefan
Stefan Reinauer wrote:
- Eric W. Biederman ebiederman@lnxi.com [040202 01:28]:
Thinking about this a little more open firmware defines one single root for it's interrupt tree, even if it must be purely virtual.
I seem to be dropping into this conversation late; What do you mean that there is a single root for the interrupt tree?
The interrupt-map stuff can point to interrupt owners anywhere in the tree; The common case I've run into is a system which has on-board devices with the interrupts routed to an interrupt controller on a PCI bridge. Since the on-board devices are frequently either children of a different PCI bus or occasionally not under a PCI bus at all, we need to use the interrupt-map property to say "use interrupt #17 under that chip over there".
I seem to be dropping into this conversation late; What do you mean that there is a single root for the interrupt tree?
Ah. Never mind, I found it:
Eric W. Biederman wrote: [...]
Each device has it's interrupt.
Plural. We have a number of devices which generate multiple interrupts. On PCI, that usually means being constrained to four interrupts, but for on-board devices we can deal with whole bunches of interrupt lines per device.
Each device has an interrupt parent. If not specified explicitly the interrupt parent is simply up the device tree but that was not required.
Device-tree parent is default, but not required.
An interrupt parent can have an interrupt mapping table that maps interrupts maps device#/interrupt pairs to ids consumed by devices up the interrupt tree.
It allows routing interrupts to anywhere else in the device tree. This construct was added explicitly because of hardware engineer's tendency to build boards which route interrupts differently than the datapaths, and we needed some way to deal with it. Since they weren't going to constrain themselves to a hierarchical structure for interrupts, we couldn't constrain the interrupt-map, either.
Tarl Neustaedter Tarl.Neustaedter@sun.com writes:
I seem to be dropping into this conversation late; What do you mean that there is a single root for the interrupt tree?
Ah. Never mind, I found it:
Eric W. Biederman wrote: [...]
Each device has it's interrupt.
Plural. We have a number of devices which generate multiple interrupts. On PCI, that usually means being constrained to four interrupts, but for on-board devices we can deal with whole bunches of interrupt lines per device.
That part I could not quite understand when reading the OF spec. How you can have multiple values per property. Base address registers seemed to have the same problem.
Each device has an interrupt parent. If not specified explicitly the interrupt parent is simply up the device tree but that was not required.
Device-tree parent is default, but not required.
What I was saying.
An interrupt parent can have an interrupt mapping table that maps interrupts maps device#/interrupt pairs to ids consumed by devices up the interrupt tree.
It allows routing interrupts to anywhere else in the device tree. This construct was added explicitly because of hardware engineer's tendency to build boards which route interrupts differently than the datapaths, and we needed some way to deal with it. Since they weren't going to constrain themselves to a hierarchical structure for interrupts, we couldn't constrain the interrupt-map, either.
Right, and the same applies to today boards until everyone transitions to pci express and hypertransport exclusively.
The only interesting thing I have is that in when using APICs interrupts are routed differently than when using the legacy x86 PIC. I think we can use two intertwined interrupt trees to model this.
Eric
Eric W. Biederman wrote:
Plural. We have a number of devices which generate multiple interrupts. On PCI, that usually means being constrained to four interrupts, but for on-board devices we can deal with whole bunches of interrupt lines per device.
That part I could not quite understand when reading the OF spec. How you can have multiple values per property. Base address registers seemed to have the same problem.
Ah. In the case of interrupts, where it's usually a single-cell value per interrupt, a trivial case is encoded as:
h# 17 encode-int " interrupts" property
In the case of a PCI slot where we (OpenFirmware) don't know what the device is, but have to allow for all four interrupts being used, we'll do something like:
h# 1 encode-int h# 2 encode-int encode+ \ encode+ concatenates two encoded properties h# 3 encode-int encode+ h# 4 encode-int encode+ " interrupts" property
When retrieving the property, you always get a address/length pair. It's up to the consumer to know what the base length of the item is, to know whether it's one or more items. In the above particular case:
{2} ok " interrupts" get-property {2} ok .s \ Show what stack has; address length false f00da140 10 0 {2} ok drop dump / 1 2 3 4 5 6 7 8 9 a b c d e f v123456789abcdef f00da140 00 00 00 01 00 00 00 02 00 00 00 03 00 00 00 04 ................
This shows four (4-byte) cells, containing 1,2,3 and 4.
The "reg" property is more of the same, but it's almost always got multiple entries. E.g., for a PCI device, we'll have a reg property with 5 cells for each entry (three address and two size), and at least two entries:
reg 00000800 00000000 00000000 00000000 00000000 02000810 00000000 00000000 00000000 00200000
The first line describes config space for a device, in this case for a device on pci address 1, function 0. The next four cells aren't relevant for config-space entries.
The second line describes a BAR; in this case, a memory addressable BAR at offset 10, which describes 200000 bytes of address space. Since this bar is relocateable, the 2nd and 3d cells are not filled in (are zeroes).
The only interesting thing I have is that in when using APICs interrupts are routed differently than when using the legacy x86 PIC.
Ah. That I missed. I'd never thought of interrupts being routed differently depending on something else. Assuming Linux is only going to use APICs, I wouldn't bother describing the legacy PIC, unless I'm missing something about interrupt configuration requiring that information anyway. Tarl
Tarl Neustaedter Tarl.Neustaedter@sun.com writes:
Eric W. Biederman wrote:
The only interesting thing I have is that in when using APICs interrupts are routed differently than when using the legacy x86 PIC.
Ah. That I missed. I'd never thought of interrupts being routed differently depending on something else. Assuming Linux is only going to use APICs, I wouldn't bother describing the legacy PIC, unless I'm missing something about interrupt configuration requiring that information anyway.
The APICs are not always present, and UP kernels tend not to use them. For the Opteron in 64bit mode you could probably not worry about it though.
It has come up too many times in the past that I need to support both that ignoring the legacy PIC in the design is just silly.
We currently can describe both the tables are just a hack and don't adjust when things like pci bus numbers change, or hypertransport unitids change.
Eric
* Eric W. Biederman ebiederman@lnxi.com [040202 00:59]:
Stefan how close is the open firmware code that we could test a port to generic LinuxBIOS. With the LinuxBIOS table providing this information?
I don't read the LinuxBIOS table yet, but support should be easy to implement. OpenBIOS has been running on LinuxBIOS and grub on x86 and amd64. It can also be used in MacOnLinux (MOL) to boot macos and Linux.
Find the latest tree on bitkeeper:
bk clone bk://openbios.bkbits.net/unstable
Stefan
Stefan Reinauer stepan@suse.de writes:
- Eric W. Biederman ebiederman@lnxi.com [040202 00:59]:
Stefan how close is the open firmware code that we could test a port to generic LinuxBIOS. With the LinuxBIOS table providing this information?
I don't read the LinuxBIOS table yet, but support should be easy to implement. OpenBIOS has been running on LinuxBIOS and grub on x86 and amd64. It can also be used in MacOnLinux (MOL) to boot macos and Linux.
Cool so you are getting close.
Find the latest tree on bitkeeper:
bk clone bk://openbios.bkbits.net/unstable
Is there any other way. I'm not allowed to use the free version of bk.
Eric
* Eric W. Biederman ebiederman@lnxi.com [040202 08:38]:
I don't read the LinuxBIOS table yet, but support should be easy to implement. OpenBIOS has been running on LinuxBIOS and grub on x86 and amd64. It can also be used in MacOnLinux (MOL) to boot macos and Linux.
Cool so you are getting close.
Indeed. Nonetheless some things are missing:
* there is no interrupt handling code doing the things you described * the ide driver is not fully working yet * boot support is incomplete on x86 and amd64 * there is no pci driver/device node yet * there is no linuxbios table parsing yet * lots of things with less priority
Find the latest tree on bitkeeper:
bk clone bk://openbios.bkbits.net/unstable
Is there any other way. I'm not allowed to use the free version of bk.
I've enabled a snapshot to be created every 4h at http://www.openbios.org/snapshots/ for now. There will probably be an arch repository for openbios soon.
Stefan