
: pci-gen-irq-map-one ( prop-addr prop-len slot pin -- prop-addr prop-len )
        2dup + 1- 3 and 1+          ( prop-addr prop-len slot pin parentpin )
        >r >r                       ( prop-addr prop-len slot R: swizzledpin pin )

        \ Child slot#
        B lshift encode-int+        ( prop-addr prop-len R: swizzledpin pin )
        \ Child 64bit BAR (not really used)
        0 encode-64+
        \ Chile pin#
        r> encode-int+              ( prop-addr prop-len R: swizzledpin )

        \ Parent phandle
        get-parent encode-int+

        \ Parent slot#
        get-node >space
        pci-addr2dev B lshift       ( prop-addr prop-len parent-slot R: swizzledpin )
        encode-int+
        \ Parent 64bit BAR (not really used)
        0 encode-64+
        \ Parent pin
        r> encode-int+              ( prop-addr prop-len R: )
;

: pci-gen-irq-entry ( prop-addr prop-len config-addr -- prop-addr prop-len )
        pci-addr2dev 4 mod          ( prop-addr prop-len slot )
        -rot                        ( slot prop-addr prop-len )
        5 1 DO
                2 pick i            ( slot prop-addr prop-len slot pin )
                pci-gen-irq-map-one
        LOOP
        rot drop
;

: pci-set-irq-line ( config-addr -- )
  drop
;


: pci-gen-irq-map-one ( prop-addr prop-len slot pin -- prop-addr prop-len )
        2dup + 1- 3 and 1+          ( prop-addr prop-len slot pin parentpin )
        >r >r                       ( prop-addr prop-len slot R: swizzledpin pin )

        \ Child slot#
        B lshift encode-int+        ( prop-addr prop-len R: swizzledpin pin )
        \ Child 64bit BAR (not really used)
        0 encode-64+
        \ Chile pin#
        r> encode-int+              ( prop-addr prop-len R: swizzledpin )

        \ Parent phandle
        get-parent encode-int+

        \ Parent slot#
        get-node >space
        pci-addr2dev B lshift       ( prop-addr prop-len parent-slot R: swizzledpin )
        encode-int+
        \ Parent 64bit BAR (not really used)
        0 encode-64+
        \ Parent pin
        r> encode-int+              ( prop-addr prop-len R: )
;

: pci-gen-irq-entry ( prop-addr prop-len config-addr -- prop-addr prop-len )
        pci-addr2dev                ( prop-addr prop-len slot )
        -rot                        ( slot prop-addr prop-len )
        5 1 DO
                2 pick i            ( slot prop-addr prop-len slot pin )
                pci-gen-irq-map-one
        LOOP
        rot drop
;

: pci-set-irq-line ( config-addr -- )
  drop
;

Allow PCI devices in PCI bridge slots greater than 4
Allow PCI devices in PCI bridge slots greater than 4

PCI bridges can have up to 31 slots. If we limit the value
from pci-addr2dev with "modulo 4", all devices in slots 4
and  higher won't work correctly since the interrupt-map
property then contains wrong values in this case. For
example, when QEMU is started with the following command
line, Linux is not able to use the balloon device:

 qemu-system-ppc64 ... \
    -device pci-bridge,bus=pci.0,id=bridge1,chassis_nr=1,addr=0x6 \
    -device virtio-balloon-pci,id=balloon0,bus=bridge1,addr=5

To fix this issue, simply remove the bogus "4 mod" calculation.

Buglink: https://bugzilla.redhat.com/show_bug.cgi?id=1366953
Signed-off-by: Thomas Huth <9e65be74847981e55b2564b6266c57d86d3bac05@redhat.com>
Signed-off-by: Alexey Kardashevskiy <ac1fc56530d7d037e1ea666f130daca22d72f964@ozlabs.ru>
