Author: wmb Date: Sat Jul 16 14:20:43 2011 New Revision: 2384 URL: http://tracker.coreboot.org/trac/openfirmware/changeset/2384
Log: PCI and PCI bridge drivers - better support for preassigned addresses.
Modified: dev/pci/pcibridg.fth dev/pcibus.fth
Modified: dev/pci/pcibridg.fth ============================================================================== --- dev/pci/pcibridg.fth Sat Jul 16 14:18:36 2011 (r2383) +++ dev/pci/pcibridg.fth Sat Jul 16 14:20:43 2011 (r2384) @@ -11,10 +11,6 @@ : my-l! ( l offset -- ) my-space + " config-l!" $call-parent ;
0 value my-bus# -0 value my-io-base -0 value my-io-limit -0 value my-mem-base -0 value my-mem-limit
defer parent-decode-unit
@@ -153,43 +149,58 @@ 2swap drop r> swap - encode-int encode+ ( adr' len' ) ;
-: make-ranges-property ( -- ) - 0 0 encode-bytes - my-io-base my-io-limit h# 8100.0000 +range-entry - my-mem-base my-mem-limit h# 8200.0000 +range-entry - " ranges" property -; - \ decode-unit and encode-unit must be static methods, so they can't use \ $call-parent at run-time
" decode-unit" parent-phandle find-method drop ( xt ) to parent-decode-unit " encode-unit" parent-phandle find-method drop ( xt ) to encode-unit
+: assign-addresses? ( -- flag ) +\ " addresses-preassigned" my-parent ihandle>phandle get-package-property if + " addresses-preassigned" get-inherited-property if + \ Property not present + true + else ( propval$ ) + \ Property present + 2drop false + then +; : prefetch-ranges-off ( -- ) \ Turn off prefetchable memory forwarding range h# 0000ffff h# 24 my-l! \ Prefetchable Limit,Base h# ffffffff h# 28 my-l! \ Prefetchable Base upper 32 bits h# 0 h# 2c my-l! \ Prefetchable Limit upper 32 bits ; -: set-bases ( mem-base io-base -- ) - 2dup to my-io-base to my-mem-base - - \ Set I/O forwarding base - lwsplit h# 30 my-w! wbsplit h# 1c my-b! drop ( mem-base ) - - \ Set non-prefetchable memory forwarding base - lwsplit h# 20 my-w! drop ( ) +: io-base@ ( -- base ) + 0 h# 1c my-b@ bwjoin h# 30 my-w@ wljoin ; -: set-limits ( mem-limit+1 io-limit+1 -- ) - 2dup to my-io-limit to my-mem-limit - - \ Set I/O forwarding limit - 1- lwsplit h# 32 my-w! wbsplit h# 1d my-b! drop ( mem-limit ) +: io-base! ( base -- ) + lwsplit h# 30 my-w! wbsplit h# 1c my-b! drop +; +: io-limit@ ( -- limit+1 ) + 0 h# 1d my-b@ bwjoin h# 32 my-w@ wljoin 1+ +; +: io-limit! ( limit+1 -- ) + 1- lwsplit h# 32 my-w! wbsplit h# 1d my-b! drop +; +: mem-base@ ( -- base ) 0 h# 20 my-w@ wljoin ; +: mem-base! ( base -- ) lwsplit h# 20 my-w! drop ; +: mem-limit@ ( -- limit+1 ) 0 h# 22 my-w@ wljoin 1+ ; +: mem-limit! ( limit+1 -- ) 1- lwsplit h# 22 my-w! drop ; +: pri-bus! ( bus# -- ) h# 18 my-b! ; +: pri-bus@ ( -- bus# ) h# 18 my-b@ ; +: sec-bus! ( bus# -- ) h# 19 my-b! ; +: sec-bus@ ( -- bus# ) h# 19 my-b@ ; +: bus-limit! ( bus# -- ) h# 1a my-b! ; +: bus-limit@ ( -- bus# ) h# 1a my-b@ ;
- \ Set non-prefetchable memory forwarding range - 1- lwsplit h# 22 my-w! drop ( ) +: make-ranges-property ( -- ) + 0 0 encode-bytes + io-base@ io-limit@ h# 8100.0000 +range-entry + mem-base@ mem-limit@ h# 8200.0000 +range-entry + " ranges" property ; + \ Paranoia, perhaps justified : disable-children ( -- ) my-bus# d# 16 lshift 4 + ( template ) @@ -198,19 +209,7 @@
7 value my-bridge-modes
-: setup-bridge ( -- ) - " pci" device-name - - " pci" encode-string " device_type" property - - 0 0 my-space encode-phys 0 encode-int encode+ 0 encode-int encode+ - " reg" property - - 2 encode-int " #size-cells" property - 3 encode-int " #address-cells" property - - start-interrupt-map - +: set-bridge-registers ( -- ) \ Turn off memory and I/O response and bus mastership while setting up 0 4 my-w!
@@ -218,19 +217,19 @@ h# 3e my-b@ dup h# 40 or h# 3e my-b! h# 40 invert and h# 3e my-b!
- my-space d# 16 rshift h# ff and h# 18 my-b! \ Primary bus# - 1 " allocate-bus#" $call-parent rot dup h# 19 my-b! \ Secondary bus# + my-space d# 16 rshift h# ff and pri-bus! \ Primary bus# + 1 " allocate-bus#" $call-parent rot dup sec-bus! \ Secondary bus# to my-bus# ( next-mem next-io )
\ Set the subordinate bus number to ff in order to pass through any \ type 1 cycle with a bus number higher then the secondary bus# - h# ff h# 1a my-b! ( next-mem next-io ) - disable-children - 2dup set-bases ( next-mem next-io ) + h# ff bus-limit! ( next-mem next-io ) + disable-children ( next-mem next-io ) + over mem-base! dup io-base! ( next-mem next-io )
\ Initially set the limits to encompassing the rest of the address space - 2drop mem-space-top io-space-top set-limits + 2drop mem-space-top mem-limit! io-space-top io-limit!
\ Clear status bits h# ffff h# 1e my-w! ( ) @@ -242,6 +241,33 @@ \ rebind the (global) value bridge-modes. " bridge-modes" $find if execute else 2drop my-bridge-modes then 4 my-w@ or 4 my-w! ( ) +; +: reduce-bridge-limits ( -- ) + \ Reduce the subordinate bus# to the maximum bus number of any of + \ our children, and the memory and IO forwarding limits to the + \ limits of the address space actually allocated. + 0 " allocate-bus#" $call-parent rot bus-limit! ( final-mem final-io ) + io-limit! mem-limit! +; +: setup-bridge ( -- ) + " pci" device-name + + " pci" encode-string " device_type" property + + 0 0 my-space encode-phys 0 encode-int encode+ 0 encode-int encode+ + " reg" property + + 2 encode-int " #size-cells" property + 3 encode-int " #address-cells" property + + start-interrupt-map + + assign-addresses? if + set-bridge-registers + else + sec-bus@ to my-bus# + 0 0 " addresses-preassigned" property + then
\ [ifdef] firepower \ \ The IBM bridge is somewhat funny @@ -254,20 +280,17 @@
" 0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f" prober-xt execute
- \ Reduce the subordinate bus# to the maximum bus number of any of - \ our children, and the memory and IO forwarding limits to the - \ limits of the address space actually allocated. - 0 " allocate-bus#" $call-parent rot h# 1a my-b! ( final-mem final-io ) - set-limits + assign-addresses? if reduce-bridge-limits then
make-ranges-property
finish-interrupt-map
- my-bus# encode-int h# 1a my-b@ encode-int encode+ + my-bus# encode-int bus-limit@ encode-int encode+ " bus-range" property ; setup-bridge + \ LICENSE_BEGIN \ Copyright (c) 2006 FirmWorks \
Modified: dev/pcibus.fth ============================================================================== --- dev/pcibus.fth Sat Jul 16 14:18:36 2011 (r2383) +++ dev/pcibus.fth Sat Jul 16 14:20:43 2011 (r2384) @@ -55,6 +55,18 @@ headers \ These headers are for debugging convenience 0 value current-bus#
+: have-property? ( propname$ -- flag ) + get-my-property if false else 2drop true then +; +: assign-addresses? ( -- flag ) " addresses-preassigned" have-property? 0= ; +: parent-assign-addresses? ( -- flag ) + " addresses-preassigned" get-inherited-property if ( ) + true + else ( propval$ ) + 2drop false + then +; + \ These cannot be package values because some words that use them are called \ directly from different contexts - both from the root of the PCI domain \ and also from child nodes and subordinate PCI-PCI bridge nodes. They need @@ -744,7 +756,7 @@ : find-fcode? ( -- false | adr len true )
next-mem to save-mem - temp-assign-addresses + parent-assign-addresses? if temp-assign-addresses then expansion-rom ( offset )
\ \ Map the expansion ROM at a high physical address that does not @@ -770,12 +782,14 @@ \ Turn on address decode enable in Expansion ROM Base Address Register r@ my-l@ 1 or r@ my-l! ( r: size virt offset ) ( virt )
- 2 4 my-w! \ Turn on memory enable ( virt ) + 4 my-w@ 2 or 4 my-w! \ Turn on memory enable ( virt )
- locate-fcode ( false | adr len true ) + locate-fcode ( r: size virt offset ) ( false | adr len true )
\ Turn off memory enable - 0 4 my-w! ( r: size virt offset ) ( false | adr len true ) + parent-assign-addresses? if ( r: size virt offset ) ( false | adr len true ) + 4 my-w@ 2 invert and 4 my-w! + then ( r: size virt offset ) ( false | adr len true )
\ Turn off address decode enable in Expansion ROM Base Address Register r@ my-l@ 1 invert and r> my-l! ( r: size virt ) ( false | adr len true ) @@ -944,7 +958,7 @@ make-child-properties ( ) card-bus? if make-common-properties exit then ( )
- clear-addresses ( ) + parent-assign-addresses? if clear-addresses then ( )
\ Interpret FCode if present; if not, invent "name" and "reg" properties find-fcode? if ( adr len ) @@ -954,9 +968,11 @@ then ( )
bridge? 0= if - clear-addresses ( ) - b my-b@ 6 <> if - 0 4 my-w! \ Disables all card response + parent-assign-addresses? if + clear-addresses ( ) + b my-b@ 6 <> if + 0 4 my-w! \ Disables all card response + then then then restore-fcodes @@ -1289,11 +1305,11 @@ update-pointers \ Re-init the temporary allocation pointers, \ thus erasing any probe-state mappings
- assign-all-addresses + assign-addresses? if assign-all-addresses then \ XXX TODO set-latency-timers set-fast-back-to-backs ; : master-probe ( adr len -- ) - true to probe-state? + assign-addresses? to probe-state? prober
\ Make permanent any address assignments that occurred during the
openfirmware@openfirmware.info