Subject: Item #402: Interrupt Mapping 0.9 Date: Tue, 7 Jan 97 11:11:07 -0800 From: P1275 Open Firmware Working Group Proposal -- Proposal #402 Ver 1 Title: map-interrupt procedure change Author: Ron Hochsprung Date: 1/7/97 Ed/Tech: Technical Synopsis: Updates the map-interrupt procedure to handle common special case of direct interrupt-parent. Doc & Version: Interrupt Mapping recommended practice 0.9 Problem: We have run in to a common case where a device can directly point to an interrupt controller (via the "interrupt-parent" property), where the interpretation of its "interrupts" property should be the resulting unit-interrupt-specifier, without having its unit-address used. Proposal: Change the map-interrupt procedure to include code at the front that checks if the device-node contains an "interrupt-parent" property. If so, use the parent's node to determine if the unit-address of the device-node should be considered part of the unit-interrupt-specifier. The following code shows the updated procedure: ***** BEGIN CODE ***** procedure map-interrupt( device-node, interrupt-specifier ) this-node = device-node unit-address = valueof( "reg"[0], this-node ) if present( "interrupt-parent", this-node ) parent-node = valueof( "interrupt-parent", this-node ) if present( "#address-cells", parent-node ) unit-interrupt-specifier = cat( unit-address, interrupt-specifier ) else unit-interrupt-specifier = interrupt-specifier this-node = parent-node begin \ loop up tree until we reach the root if present( "interrupt-controller", this-node ) if present( "interrupt-parent", this-node ) parent-node = valueof( "interrupt-parent", this-node ) if present( "#address-cells", parent-node ) unit-address = valueof( "reg"[0], this-node ) else unit-address = NULL then interrupt-specifier = valueof( "interrupts", this-node ) unit-interrupt-specifier = cat( unit-address, interrupt-specifier ) this-node = parent-node else \ this is the root node, we're done return( unit-interrupt-specifier ) then else \ not "interrupt-controller" if present( "interrupt-map", this-node ) \ we have a mapping to perform if present( "interrupt-map-mask", this-node ) mask = valueof( "interrupt-map-mask" ) unit-interrupt-specifier = unit-interrupt-specifier & mask then init-decode-cells( "interrupt-map", this-node ) found? = false begin child-specifier = decode-cells( sizeof( unit-interrupt-specifier ) ) parent-node = decode-cells( 1 ) if present( "#address-cells", parent-node ) #cells = valueof( "#address-cells", parent-node ) else #cells = 0 then #cells = #cells + valueof( "#interrupt-cells", parent-node ) if child-specifier == unit-interrupt-specifier found? = true else dummy = decode-cells( #cells ) then until found? interrupt-specifier = decode-cells( #cells ) if present( "#address-cells", parent-node) unit-address = valueof( "reg"[0], this-node ) else unit-address = NULL then unit-interrupt-specifier = cat( unit-address, interrupt-specifier ) this-node = parent-node else \ no "interrupt-map" table if present( "interrupt-parent", this-node ) this-node = valueof( "interrupt-parent", this-node ) else \ by default, use our device-tree parent this-node = device-tree-parent( this-node ) then again ***** END CODE ***** [ P1275 Item #402 -- Received: Tue Jan 7 11:10:51 PST 1997 ]