1\ ***************************************************************************** 2\ * Copyright (c) 2004, 2008 IBM Corporation 3\ * All rights reserved. 4\ * This program and the accompanying materials 5\ * are made available under the terms of the BSD License 6\ * which accompanies this distribution, and is available at 7\ * http://www.opensource.org/licenses/bsd-license.php 8\ * 9\ * Contributors: 10\ * IBM Corporation - initial implementation 11\ ****************************************************************************/ 12 13#include "pci-class-code-names.fs" 14 15\ read the various bar type sizes 16: pci-bar-size@ ( bar-addr -- bar-size ) -1 over rtas-config-l! rtas-config-l@ ; 17: pci-bar-size-mem@ ( bar-addr -- mem-size ) pci-bar-size@ -10 and invert 1+ FFFFFFFF and ; 18: pci-bar-size-io@ ( bar-addr -- io-size ) pci-bar-size@ -4 and invert 1+ FFFFFFFF and ; 19 20\ fetch raw bar size but keep original BAR value 21: pci-bar-size ( bar-addr -- bar-size-raw ) 22 dup rtas-config-l@ swap \ fetch original Value ( bval baddr ) 23 -1 over rtas-config-l! \ make BAR show size ( bval baddr ) 24 dup rtas-config-l@ \ and fetch the size ( bval baddr bsize ) 25 -rot rtas-config-l! \ restore Value 26; 27 28\ calc 32 bit MEM BAR size 29: pci-bar-size-mem32 ( bar-addr -- bar-size ) 30 pci-bar-size \ fetch raw size 31 -10 and invert 1+ \ calc size 32 FFFFFFFF and \ keep lower 32 bits 33; 34 35\ calc 32 bit ROM BAR size 36: pci-bar-size-rom ( bar-addr -- bar-size ) 37 pci-bar-size \ fetch raw size 38 FFFFF800 and invert 1+ \ calc size 39 FFFFFFFF and \ keep lower 32 bits 40; 41 42\ calc 64 bit MEM BAR size 43: pci-bar-size-mem64 ( bar-addr -- bar-size ) 44 dup pci-bar-size \ fetch raw size lower 32 bits 45 swap 4 + pci-bar-size \ fetch raw size upper 32 bits 46 20 lshift + \ and put them together 47 -10 and invert 1+ \ calc size 48; 49 50\ calc IO BAR size 51: pci-bar-size-io ( bar-addr -- bar-size ) 52 pci-bar-size \ fetch raw size 53 -4 and invert 1+ \ calc size 54 FFFFFFFF and \ keep lower 32 bits 55; 56 57 58\ decode the Bar Type 59\ +----------------------------------------------------------------------------------------+ 60\ | 3 2 1 0 | 61\ | +----------------------------+-+--+-+ | 62\ | MEM-BAR : | Base Address |P|TT|0| P - prefechtable ; TT - 00 : 32 Bit | 63\ | +----------------------------+-+--+-+ 10 : 64 Bit | 64\ | +-------------------------------+-+-+ | 65\ | IO-BAR : | Base Address |0|1| | 66\ | +-------------------------------+-+-+ | 67\ | That is: 0 - no encoded BarType | 68\ | 1 - IO - Bar | 69\ | 2 - Memory 32 Bit | 70\ | 3 - Memory 32 Bit prefetchable | 71\ | 4 - Memory 64 Bit | 72\ | 5 - Memory 64 Bit prefetchable | 73\ +----------------------------------------------------------------------------------------+ 74: pci-bar-code@ ( bar-addr -- 0|1..4|5 ) 75 rtas-config-l@ dup \ fetch the BaseAddressRegister 76 1 and IF \ IO BAR ? 77 2 and IF 0 ELSE 1 THEN \ only '01' is valid 78 ELSE \ Memory BAR ? 79 F and CASE 80 0 OF 2 ENDOF \ Memory 32 Bit Non-Prefetchable 81 8 OF 3 ENDOF \ Memory 32 Bit Prefetchable 82 4 OF 4 ENDOF \ Memory 64 Bit Non-Prefetchable 83 C OF 5 ENDOF \ Memory 64 Bit Prefechtable 84 dup OF 0 ENDOF \ Not a valid BarType 85 ENDCASE 86 THEN 87; 88 89\ *************************************************************************************** 90\ Assigning the new Value to the BARs 91\ *************************************************************************************** 92\ align the current mem and set var to next mem 93\ align with a size of 0 returns 0 !!! 94: assign-var-align ( size align var -- al-mem ) 95 dup >r @ \ ( size align cur-mem ) 96 swap #aligned \ ( size al-mem ) 97 tuck + \ ( al-mem new-mem ) 98 r> ! \ ( al-mem ) 99; 100 101: assign-var-min-align ( size min-align var -- al-mem ) 102 >r over umax \ ( size align ) 103 r> assign-var-align \ ( al-mem ) 104; 105 106\ set bar to current free mem ( in variable ) and set variable to next free mem 107: assign-bar-value32 ( bar size var -- 4 ) 108 over IF \ IF size > 0 109 >r \ | ( bar size ) 110 pci-mem-bar-min-align \ | ( bar size min-align ) 111 r> assign-var-min-align \ | ( bar al-mem ) set variable to next mem 112 swap rtas-config-l! \ | ( -- ) set the bar to al-mem 113 ELSE \ ELSE 114 2drop drop \ | clear stack 115 THEN \ FI 116 4 \ size of the base-address-register 117; 118 119\ set bar to current free mem ( in variable ) and set variable to next free mem 120: assign-io-bar-value32 ( bar size var -- 4 ) 121 over IF \ IF size > 0 122 >r \ | ( bar size ) 123 dup \ | ( bar size size-align ) 124 r> assign-var-align \ | ( bar al-mem ) set variable to next mem 125 swap rtas-config-l! \ | ( -- ) set the bar to al-mem 126 ELSE \ ELSE 127 2drop drop \ | clear stack 128 THEN \ FI 129 4 \ size of the base-address-register 130; 131 132\ set bar to current free mem ( in variable ) and set variable to next free mem 133: assign-bar-value64 ( bar size var -- 8 ) 134 over IF \ IF size > 0 135 >r \ | ( bar size ) 136 pci-mem-bar-min-align \ | ( bar size min-align ) 137 r> assign-var-min-align \ | ( bar al-mem ) set variable to next mem 138 swap \ | ( al-mem addr ) calc config-addr of this bar 139 2dup rtas-config-l! \ | ( al-mem addr ) set the Lower part of the bar to al-mem 140 4 + swap 20 rshift \ | ( al-mem>>32 addr ) prepare the upper part of the al-mem 141 swap rtas-config-l! \ | ( -- ) and set the upper part of the bar 142 ELSE \ ELSE 143 2drop drop \ | clear stack 144 THEN \ FI 145 8 \ size of the base-address-register 146; 147 148\ Setup a prefetchable 64bit BAR and return its size 149: assign-mem64-bar ( bar-addr -- 8 ) 150 dup pci-bar-size-mem64 \ fetch size 151 pci-next-mem64 @ 0 = IF \ Check if we have 64-bit memory range 152 pci-next-mem 153 ELSE 154 pci-next-mem64 155 THEN 156 assign-bar-value64 \ and set it all 157; 158 159\ Setup a prefetchable 32bit BAR and return its size 160: assign-mem32-bar ( bar-addr -- 4 ) 161 dup pci-bar-size-mem32 \ fetch size 162 \ Do we have a dedicated 32-bit prefetchable area? If not, use MMIO 163 pci-next-mem @ IF 164 pci-next-mem 165 ELSE 166 pci-next-mmio 167 THEN 168 assign-bar-value32 \ and set it all 169; 170 171\ Setup a non-prefetchable 64bit BAR and return its size 172: assign-mmio64-bar ( bar-addr -- 8 ) 173 dup pci-bar-size-mem64 \ fetch size 174 pci-next-mmio 175 assign-bar-value64 \ and set it all 176; 177 178\ Setup a non-prefetchable 32bit BAR and return its size 179: assign-mmio32-bar ( bar-addr -- 4 ) 180 dup pci-bar-size-mem32 \ fetch size 181 pci-next-mmio \ var to change 182 assign-bar-value32 \ and set it all 183; 184 185\ Setup an IO-Bar and return the size of the base-address-register 186: assign-io-bar ( bar-addr -- 4 ) 187 dup pci-bar-size-io \ fetch size 188 pci-next-io \ var to change 189 assign-io-bar-value32 \ and set it all 190; 191 192\ Setup an Expansion ROM bar 193: assign-rom-bar ( bar-addr -- ) 194 dup pci-bar-size-rom \ fetch size 195 dup IF \ IF size > 0 196 over >r \ | save bar addr for enable 197 pci-next-mmio \ | var to change 198 assign-bar-value32 \ | and set it 199 drop \ | forget the BAR length 200 r@ rtas-config-l@ \ | fetch BAR 201 1 or r> rtas-config-l! \ | and enable the ROM 202 ELSE \ ELSE 203 2drop \ | clear stack 204 THEN 205; 206 207\ Setup the BAR due to its type and return the size of the register (4 or 8 Bytes ) used as increment for the BAR-Loop 208: assign-bar ( bar-addr -- reg-size ) 209 dup pci-bar-code@ \ calc BAR type 210 dup IF \ IF >0 211 CASE \ | CASE Setup the right type 212 1 OF assign-io-bar ENDOF \ | - set up an IO-Bar 213 2 OF assign-mmio32-bar ENDOF \ | - set up an 32bit MMIO-Bar 214 3 OF assign-mem32-bar ENDOF \ | - set up an 32bit MEM-Bar (prefetchable) 215 4 OF assign-mmio64-bar ENDOF \ | - set up an 64bit MMIO-Bar 216 5 OF assign-mem64-bar ENDOF \ | - set up an 64bit MEM-Bar (prefetchable) 217 ENDCASE \ | ESAC 218 ELSE \ ELSE 219 ABORT \ | Throw an exception 220 THEN \ FI 221; 222 223\ Setup all the bars of a pci device 224: assign-all-device-bars ( configaddr -- ) 225 28 10 DO \ BARs start at 10 and end at 27 226 dup i + \ calc config-addr of the BAR 227 assign-bar \ and set it up 228 +LOOP \ add 4 or 8 to the index and loop 229 30 + assign-rom-bar \ set up the ROM if available 230; 231 232\ Setup all the bars of a pci device 233: assign-all-bridge-bars ( configaddr -- ) 234 18 10 DO \ BARs start at 10 and end at 17 235 dup i + \ calc config-addr of the BAR 236 assign-bar \ and set it up 237 +LOOP \ add 4 or 8 to the index and loop 238 38 + assign-rom-bar \ set up the ROM if available 239; 240 241\ +---------------------------------------------------------------------------------------+ 242\ | Numerical Representaton of a PCI address (PCI Bus Binding 2.2.1.1) | 243\ | | 244\ | 31 24 16 11 8 0 | 245\ | +--------+--------+-----+---+--------+ | 246\ | phys.hi: |npt000ss| bus | dev |fnc| reg | n - 0 relocatable | 247\ | +--------+--------+-----+---+--------+ p - 1 prefetchable | 248\ | t - 1 aliased or <1MB or <64KB | 249\ | ss - 00 Configuration Space | 250\ | 01 I/O Space | 251\ | 10 Memory Space 32bits | 252\ | 11 Memory Space 64bits | 253\ +---------------------------------------------------------------------------------------+ 254 255\ *************************************************************************************** 256\ Generating the assigned-addresses property 257\ *************************************************************************************** 258\ generate assigned-addresses property for non-prefetchable 64Bit MEM-BAR and 259\ return BAR-reg-size. Note: We use "32-bit" as space code here, since these 260\ BARs are allocated from the 32-bit MMIO window (see assign-mmio64-bar) 261: gen-mem64-bar-prop ( prop-addr prop-len bar-addr -- prop-addr prop-len 8 ) 262 dup pci-bar-size-mem64 \ fetch BAR Size ( paddr plen baddr bsize ) 263 dup IF \ IF Size > 0 264 >r dup rtas-config-l@ \ | save size and fetch lower 32 bits ( paddr plen baddr val.lo R: size) 265 over 4 + rtas-config-l@ \ | fetch upper 32 bits ( paddr plen baddr val.lo val.hi R: size) 266 20 lshift + -10 and >r \ | calc 64 bit value and save it ( paddr plen baddr R: size val ) 267 82000000 or encode-int+ \ | Encode config addr ( paddr plen R: size val ) 268 r> encode-64+ \ | Encode assigned addr ( paddr plen R: size ) 269 r> encode-64+ \ | Encode size ( paddr plen ) 270 ELSE \ ELSE 271 2drop \ | don't do anything 272 THEN \ FI 273 8 \ sizeof(BAR) = 8 Bytes 274; 275 276\ generate assigned-addresses property for prefetchable 64Bit MEM-BAR and return BAR-reg-size 277: gen-pmem64-bar-prop ( prop-addr prop-len bar-addr -- prop-addr prop-len 8 ) 278 dup pci-bar-size-mem64 \ fetch BAR Size ( paddr plen baddr bsize ) 279 dup IF \ IF Size > 0 280 >r dup rtas-config-l@ \ | save size and fetch lower 32 bits ( paddr plen baddr val.lo R: size) 281 over 4 + rtas-config-l@ \ | fetch upper 32 bits ( paddr plen baddr val.lo val.hi R: size) 282 20 lshift + -10 and >r \ | calc 64 bit value and save it ( paddr plen baddr R: size val ) 283 C3000000 or encode-int+ \ | Encode config addr ( paddr plen R: size val ) 284 r> encode-64+ \ | Encode assigned addr ( paddr plen R: size ) 285 r> encode-64+ \ | Encode size ( paddr plen ) 286 ELSE \ ELSE 287 2drop \ | don't do anything 288 THEN \ FI 289 8 \ sizeof(BAR) = 8 Bytes 290; 291 292\ generate assigned-addresses property for 32Bit MEM-BAR and return BAR-reg-size 293: gen-mem32-bar-prop ( prop-addr prop-len bar-addr -- prop-addr prop-len 4 ) 294 dup pci-bar-size-mem32 \ fetch BAR Size ( paddr plen baddr bsize ) 295 dup IF \ IF Size > 0 296 >r dup rtas-config-l@ \ | save size and fetch value ( paddr plen baddr val R: size) 297 -10 and >r \ | calc 32 bit value and save it ( paddr plen baddr R: size val ) 298 82000000 or encode-int+ \ | Encode config addr ( paddr plen R: size val ) 299 r> encode-64+ \ | Encode assigned addr ( paddr plen R: size ) 300 r> encode-64+ \ | Encode size ( paddr plen ) 301 ELSE \ ELSE 302 2drop \ | don't do anything 303 THEN \ FI 304 4 \ sizeof(BAR) = 4 Bytes 305; 306 307\ generate assigned-addresses property for prefetchable 32Bit MEM-BAR and return BAR-reg-size 308: gen-pmem32-bar-prop ( prop-addr prop-len bar-addr -- prop-addr prop-len 4 ) 309 dup pci-bar-size-mem32 \ fetch BAR Size ( paddr plen baddr bsize ) 310 dup IF \ IF Size > 0 311 >r dup rtas-config-l@ \ | save size and fetch value ( paddr plen baddr val R: size) 312 -10 and >r \ | calc 32 bit value and save it ( paddr plen baddr R: size val ) 313 C2000000 or encode-int+ \ | Encode config addr ( paddr plen R: size val ) 314 r> encode-64+ \ | Encode assigned addr ( paddr plen R: size ) 315 r> encode-64+ \ | Encode size ( paddr plen ) 316 ELSE \ ELSE 317 2drop \ | don't do anything 318 THEN \ FI 319 4 \ sizeof(BAR) = 4 Bytes 320; 321 322\ generate assigned-addresses property for IO-BAR and return BAR-reg-size 323: gen-io-bar-prop ( prop-addr prop-len bar-addr -- prop-addr prop-len 4 ) 324 dup pci-bar-size-io \ fetch BAR Size ( paddr plen baddr bsize ) 325 dup IF \ IF Size > 0 326 >r dup rtas-config-l@ \ | save size and fetch value ( paddr plen baddr val R: size) 327 -4 and >r \ | calc 32 bit value and save it ( paddr plen baddr R: size val ) 328 81000000 or encode-int+ \ | Encode config addr ( paddr plen R: size val ) 329 r> encode-64+ \ | Encode assigned addr ( paddr plen R: size ) 330 r> encode-64+ \ | Encode size ( paddr plen ) 331 ELSE \ ELSE 332 2drop \ | don't do anything 333 THEN \ FI 334 4 \ sizeof(BAR) = 4 Bytes 335; 336 337\ generate assigned-addresses property for ROM-BAR 338: gen-rom-bar-prop ( prop-addr prop-len bar-addr -- prop-addr prop-len ) 339 dup pci-bar-size-rom \ fetch BAR Size ( paddr plen baddr bsize ) 340 dup IF \ IF Size > 0 341 >r dup rtas-config-l@ \ | save size and fetch value ( paddr plen baddr val R: size) 342 FFFFF800 and >r \ | calc 32 bit value and save it ( paddr plen baddr R: size val ) 343 82000000 or encode-int+ \ | Encode config addr ( paddr plen R: size val ) 344 r> encode-64+ \ | Encode assigned addr ( paddr plen R: size ) 345 r> encode-64+ \ | Encode size ( paddr plen ) 346 ELSE \ ELSE 347 2drop \ | don't do anything 348 THEN \ FI 349; 350 351\ add another BAR to the assigned addresses property and return the size of the encoded register 352: pci-add-assigned-address ( prop-addr prop-len bar-addr -- prop-addr prop-len bsize ) 353 dup pci-bar-code@ \ calc BAR type ( paddr plen baddr btype) 354 CASE \ CASE for the BAR types ( paddr plen baddr ) 355 0 OF drop 4 ENDOF \ - not a valid type so do nothing 356 1 OF gen-io-bar-prop ENDOF \ - IO-BAR 357 2 OF gen-mem32-bar-prop ENDOF \ - MEM32 358 3 OF gen-pmem32-bar-prop ENDOF \ - MEM32 prefetchable 359 4 OF gen-mem64-bar-prop ENDOF \ - MEM64 360 5 OF gen-pmem64-bar-prop ENDOF \ - MEM64 prefetchable 361 ENDCASE \ ESAC ( paddr plen bsize ) 362; 363 364\ generate the assigned address property for a PCI device 365: pci-device-assigned-addresses-prop ( addr -- ) 366 encode-start \ provide mem for property ( addr paddr plen ) 367 2 pick 30 + gen-rom-bar-prop \ assign the rom bar 368 28 10 DO \ we have 6 possible BARs 369 2 pick i + \ calc BAR address ( addr paddr plen bar-addr ) 370 pci-add-assigned-address \ and generate the props for the BAR 371 +LOOP \ increase Index by returned len 372 s" assigned-addresses" property drop \ and write it into the device tree 373; 374 375\ generate the assigned address property for a PCI bridge 376: pci-bridge-assigned-addresses-prop ( addr -- ) 377 encode-start \ provide mem for property 378 2 pick 38 + gen-rom-bar-prop \ assign the rom bar 379 18 10 DO \ we have 2 possible BARs 380 2 pick i + \ ( addr paddr plen current-addr ) 381 pci-add-assigned-address \ and generate the props for the BAR 382 +LOOP \ increase Index by returned len 383 s" assigned-addresses" property drop \ and write it into the device tree 384; 385 386\ check if the range is valid and if so encode it into 387\ child.hi child.mid child.lo parent.hi parent.mid parent.lo size.hi size.lo 388\ This is needed to translate the childrens addresses 389\ We implement only 1:1 mapping for all PCI bridges 390: pci-bridge-gen-range ( paddr plen base limit type -- paddr plen ) 391 >r over - \ calc size ( paddr plen base size R:type ) 392 dup 0< IF \ IF Size < 0 ( paddr plen base size R:type ) 393 2drop r> drop \ | forget values ( paddr plen ) 394 ELSE \ ELSE 395 1+ swap 2swap \ | adjust stack ( size base paddr plen R:type ) 396 r@ encode-int+ \ | Child type ( size base paddr plen R:type ) 397 2 pick encode-64+ \ | Child address ( size base paddr plen R:type ) 398 r> encode-int+ \ | Parent type ( size base paddr plen ) 399 rot encode-64+ \ | Parent address ( size paddr plen ) 400 rot encode-64+ \ | Encode size ( paddr plen ) 401 THEN \ FI 402; 403 404 405\ generate an mmio space to the ranges property 406: pci-bridge-gen-mmio-range ( addr prop-addr prop-len -- addr prop-addr prop-len ) 407 2 pick 20 + rtas-config-l@ \ fetch Value ( addr paddr plen val ) 408 dup 0000FFF0 and 10 lshift \ calc base-address ( addr paddr plen val base ) 409 swap 000FFFFF or \ calc limit-address ( addr paddr plen base limit ) 410 02000000 pci-bridge-gen-range \ and generate it ( addr paddr plen ) 411; 412 413\ generate an mem space to the ranges property 414: pci-bridge-gen-mem-range ( addr prop-addr prop-len -- addr prop-addr prop-len ) 415 2 pick 24 + rtas-config-l@ \ fetch Value ( addr paddr plen val ) 416 dup 000FFFFF or \ calc limit Bits 31:0 ( addr paddr plen val limit.31:0 ) 417 swap 0000FFF0 and 10 lshift \ calc base Bits 31:0 ( addr paddr plen limit.31:0 base.31:0 ) 418 4 pick 28 + rtas-config-l@ \ fetch upper Basebits ( addr paddr plen limit.31:0 base.31:0 base.63:32 ) 419 20 lshift or swap \ and calc Base ( addr paddr plen base.63:0 limit.31:0 ) 420 4 pick 2C + rtas-config-l@ \ fetch upper Limitbits ( addr paddr plen base.63:0 limit.31:0 limit.63:32 ) 421 dup -rot 20 lshift or swap \ and calc Limit ( addr paddr plen base.63:0 limit.63:0 limit.63:32 ) 422 IF 43000000 ELSE 42000000 THEN \ 64-bit or 32-bit? ( addr paddr plen base.63:0 limit.63:0 type ) 423 pci-bridge-gen-range \ and generate it ( addr paddr plen ) 424; 425 426\ generate an io space to the ranges property 427: pci-bridge-gen-io-range ( addr prop-addr prop-len -- addr prop-addr prop-len ) 428 2 pick 1C + rtas-config-l@ \ fetch Value ( addr paddr plen val ) 429 dup 0000F000 and 00000FFF or \ calc Limit Bits 15:0 ( addr paddr plen val limit.15:0 ) 430 swap 000000F0 and 8 lshift \ calc Base Bits 15:0 ( addr paddr plen limit.15:0 base.15:0 ) 431 4 pick 30 + rtas-config-l@ \ fetch upper Bits ( addr paddr plen limit.15:0 base.15:0 val ) 432 dup FFFF and 10 lshift rot or \ calc Base ( addr paddr plen limit.15:0 val base.31:0 ) 433 -rot FFFF0000 and or \ calc Limit ( addr paddr plen base.31:0 limit.31:0 ) 434 01000000 pci-bridge-gen-range \ and generate it ( addr paddr plen ) 435; 436 437\ generate the ranges property for a PCI bridge 438: pci-bridge-range-props ( addr -- ) 439 encode-start \ provide mem for property 440 pci-bridge-gen-mmio-range \ generate the non prefetchable Memory Entry 441 pci-bridge-gen-mem-range \ generate the prefetchable Memory Entry 442 pci-bridge-gen-io-range \ generate the IO Entry 443 dup IF \ IF any space present (propsize>0) 444 s" ranges" property \ | write it into the device tree 445 ELSE \ ELSE 446 s" " s" ranges" property 447 2drop \ | forget the properties 448 THEN \ FI 449 drop \ forget the address 450; 451 452\ create the interrupt map for this bridge 453: pci-bridge-interrupt-map ( -- ) 454 encode-start \ create the property ( paddr plen ) 455 get-node child \ find the first child ( paddr plen handle ) 456 BEGIN dup WHILE \ Loop as long as the handle is non-zero ( paddr plen handle ) 457 dup >r >space \ Get the my-space ( paddr plen addr R: handle ) 458 pci-gen-irq-entry \ and Encode the interrupt settings ( paddr plen R: handle) 459 r> peer \ Get neighbour ( paddr plen handle ) 460 REPEAT \ process next childe node ( paddr plen handle ) 461 drop \ forget the null ( paddr plen ) 462 s" interrupt-map" property \ and set it ( -- ) 463 1 encode-int s" #interrupt-cells" property \ encode the cell# 464 f800 encode-int 0 encode-int+ 0 encode-int+ \ encode the bit mask for config addr (Dev only) 465 7 encode-int+ s" interrupt-map-mask" property \ encode IRQ#=7 and generate property 466; 467 468\ *************************************************************************************** 469\ Generating the reg property 470\ *************************************************************************************** 471\ reg = config-addr 0 0 0 0 [BAR-config-addr 0 0 size.high size.low] 472 473\ encode the reg prop for a nonprefetchable 32bit MEM-BAR 474: encode-mem32-bar ( prop-addr prop-len BAR-addr -- prop-addr prop-len 4 ) 475 dup pci-bar-size-mem32 \ calc BAR-size ( not changing the BAR ) 476 dup IF \ IF BAR-size > 0 ( paddr plen baddr bsize ) 477 >r 02000000 or encode-int+ \ | save size and encode BAR addr 478 0 encode-64+ \ | make mid and lo zero 479 r> encode-64+ \ | encode size 480 ELSE \ ELSE 481 2drop \ | don't do anything 482 THEN \ FI 483 4 \ BAR-Len = 4 (32Bit) 484; 485 486\ encode the reg prop for a prefetchable 32bit MEM-BAR 487: encode-pmem32-bar ( prop-addr prop-len BAR-addr -- prop-addr prop-len 4 ) 488 dup pci-bar-size-mem32 \ calc BAR-size ( not changing the BAR ) 489 dup IF \ IF BAR-size > 0 ( paddr plen baddr bsize ) 490 >r 42000000 or encode-int+ \ | save size and encode BAR addr 491 0 encode-64+ \ | make mid and lo zero 492 r> encode-64+ \ | encode size 493 ELSE \ ELSE 494 2drop \ | don't do anything 495 THEN \ FI 496 4 \ BAR-Len = 4 (32Bit) 497; 498 499\ encode the reg prop for a nonprefetchable 64bit MEM-BAR 500: encode-mem64-bar ( prop-addr prop-len BAR-addr -- prop-addr prop-len 8 ) 501 dup pci-bar-size-mem64 \ calc BAR-size ( not changing the BAR ) 502 dup IF \ IF BAR-size > 0 ( paddr plen baddr bsize ) 503 >r 03000000 or encode-int+ \ | save size and encode BAR addr 504 0 encode-64+ \ | make mid and lo zero 505 r> encode-64+ \ | encode size 506 ELSE \ ELSE 507 2drop \ | don't do anything 508 THEN \ FI 509 8 \ BAR-Len = 8 (64Bit) 510; 511 512\ encode the reg prop for a prefetchable 64bit MEM-BAR 513: encode-pmem64-bar ( prop-addr prop-len BAR-addr -- prop-addr prop-len 8 ) 514 dup pci-bar-size-mem64 \ calc BAR-size ( not changing the BAR ) 515 dup IF \ IF BAR-size > 0 ( paddr plen baddr bsize ) 516 >r 43000000 or encode-int+ \ | save size and encode BAR addr 517 0 encode-64+ \ | make mid and lo zero 518 r> encode-64+ \ | encode size 519 ELSE \ ELSE 520 2drop \ | don't do anything 521 THEN \ FI 522 8 \ BAR-Len = 8 (64Bit) 523; 524 525\ encode the reg prop for a ROM-BAR 526: encode-rom-bar ( prop-addr prop-len configaddr -- prop-addr prop-len ) 527 dup pci-bar-size-rom \ fetch raw BAR-size 528 dup IF \ IF BAR is used 529 >r 02000000 or encode-int+ \ | save size and encode BAR addr 530 0 encode-64+ \ | make mid and lo zero 531 r> encode-64+ \ | calc and encode the size 532 ELSE \ ELSE 533 2drop \ | don't do anything 534 THEN \ FI 535; 536 537\ encode the reg prop for an IO-BAR 538: encode-io-bar ( prop-addr prop-len BAR-addr BAR-value -- prop-addr prop-len 4 ) 539 dup pci-bar-size-io \ calc BAR-size ( not changing the BAR ) 540 dup IF \ IF BAR-size > 0 ( paddr plen baddr bsize ) 541 >r 01000000 or encode-int+ \ | save size and encode BAR addr 542 0 encode-64+ \ | make mid and lo zero 543 r> encode-64+ \ | encode size 544 ELSE \ ELSE 545 2drop \ | don't do anything 546 THEN \ FI 547 4 \ BAR-Len = 4 (32Bit) 548; 549 550\ write the representation of this BAR into the reg property 551: encode-bar ( prop-addr prop-len bar-addr -- prop-addr prop-len bar-len ) 552 dup pci-bar-code@ \ calc BAR type 553 CASE \ CASE for the BAR types ( paddr plen baddr val ) 554 0 OF drop 4 ENDOF \ - not a valid type so do nothing 555 1 OF encode-io-bar ENDOF \ - IO-BAR 556 2 OF encode-mem32-bar ENDOF \ - MEM32 557 3 OF encode-pmem32-bar ENDOF \ - MEM32 prefetchable 558 4 OF encode-mem64-bar ENDOF \ - MEM64 559 5 OF encode-pmem64-bar ENDOF \ - MEM64 prefetchable 560 ENDCASE \ ESAC ( paddr plen blen ) 561; 562 563\ Setup reg property 564\ first encode the configuration space address 565: pci-reg-props ( configaddr -- ) 566 dup encode-int \ configuration space ( caddr paddr plen ) 567 0 encode-64+ \ make the rest 0 568 0 encode-64+ \ encode the size as 0 569 2 pick pci-htype@ \ fetch Header Type ( caddr paddr plen type ) 570 1 and IF \ IF Bridge ( caddr paddr plen ) 571 18 10 DO \ | loop over all BARs 572 2 pick i + \ | calc bar-addr ( caddr paddr plen baddr ) 573 encode-bar \ | encode this BAR ( caddr paddr plen blen ) 574 +LOOP \ | increase LoopIndex by the BARlen 575 2 pick 38 + \ | calc ROM-BAR for a bridge ( caddr paddr plen baddr ) 576 encode-rom-bar \ | encode the ROM-BAR ( caddr paddr plen ) 577 ELSE \ ELSE ordinary device ( caddr paddr plen ) 578 28 10 DO \ | loop over all BARs 579 2 pick i + \ | calc bar-addr ( caddr paddr plen baddr ) 580 encode-bar \ | encode this BAR ( caddr paddr plen blen ) 581 +LOOP \ | increase LoopIndex by the BARlen 582 2 pick 30 + \ | calc ROM-BAR for a device ( caddr paddr plen baddr ) 583 encode-rom-bar \ | encode the ROM-BAR ( caddr paddr plen ) 584 THEN \ FI ( caddr paddr plen ) 585 s" reg" property \ and store it into the property 586 drop 587; 588 589\ *************************************************************************************** 590\ Generating common properties 591\ *************************************************************************************** 592\ set up common properties for devices and bridges 593: pci-common-props ( addr -- ) 594 dup pci-class-name device-name 595 dup pci-vendor@ encode-int s" vendor-id" property 596 dup pci-device@ encode-int s" device-id" property 597 dup pci-revision@ encode-int s" revision-id" property 598 dup pci-class@ encode-int s" class-code" property 599 3 encode-int s" #address-cells" property 600 2 encode-int s" #size-cells" property 601 602 dup pci-config-ext? IF 1 encode-int s" ibm,pci-config-space-type" property THEN 603 604 dup pci-status@ 605 dup 9 rshift 3 and encode-int s" devsel-speed" property 606 dup 7 rshift 1 and IF 0 0 s" fast-back-to-back" property THEN 607 dup 6 rshift 1 and IF 0 0 s" 66mhz-capable" property THEN 608 5 rshift 1 and IF 0 0 s" udf-supported" property THEN 609 dup pci-cache@ ?dup IF encode-int s" cache-line-size" property THEN 610 pci-interrupt@ ?dup IF encode-int s" interrupts" property THEN 611; 612 613\ set up device only properties 614: pci-device-props ( addr -- ) 615 \ FIXME no s" compatible" prop 616 \ FIXME no s" alternate-reg" prop 617 \ FIXME no s" fcode-rom-offset" prop 618 \ FIXME no s" power-consumption" prop 619 dup pci-common-props 620 dup pci-min-grant@ encode-int s" min-grant" property 621 dup pci-max-lat@ encode-int s" max-latency" property 622 dup pci-sub-device@ ?dup IF encode-int s" subsystem-id" property THEN 623 dup pci-sub-vendor@ ?dup IF encode-int s" subsystem-vendor-id" property THEN 624 dup pci-device-assigned-addresses-prop 625 pci-reg-props 626 pci-hotplug-enabled IF 627 \ QEMU uses static assignments for my-drc-index: 628 \ 40000000h + $bus << 8 + $slot << 3 629 dup dup pci-addr2bus 8 lshift 630 swap pci-addr2dev 3 lshift or 631 40000000 + encode-int s" ibm,my-drc-index" property 632 \ QEMU uses "Slot $bus*32$slotno" for loc-code 633 dup dup pci-addr2bus 20 * 634 swap pci-addr2dev + 635 a base ! 636 s" Slot " rot $cathex 637 hex 638 encode-string s" ibm,loc-code" property 639 THEN 640; 641 642\ set up bridge only properties 643: pci-bridge-props ( addr -- ) 644 \ FIXME no s" slot-names" prop 645 \ FIXME no s" bus-master-capable" prop 646 \ FIXME no s" clock-frequency" prop 647 dup pci-bus@ 648 encode-int s" primary-bus" property 649 encode-int s" secondary-bus" property 650 encode-int s" subordinate-bus" property 651 dup pci-bus@ drop encode-int rot encode-int+ s" bus-range" property 652 pci-device-slots encode-int s" slot-names" property 653 dup pci-bridge-range-props 654 dup pci-bridge-assigned-addresses-prop 655 \ Only create interrupt-map when it doesn't already exist 656 \ (it can be provided by qemu) 657 s" interrupt-map" get-node get-property IF 658 pci-bridge-interrupt-map 659 ELSE 2drop THEN 660 pci-reg-props 661; 662 663 664\ used to set up all unknown Bridges. 665\ If a Bridge has no special handling for setup 666\ the device file (pci-bridge_VENDOR_DEVICE.fs) can call 667\ this word to setup busses and scan beyond. 668: pci-bridge-generic-setup ( addr -- ) 669 pci-device-slots >r \ save the slot array on return stack 670 dup pci-common-props \ set the common properties before scanning the bus 671 s" pci" device-type \ the type is allways "pci" 672 dup func-pci-bridge-probe \ find all device connected to it 673 dup assign-all-bridge-bars \ set up all memory access BARs 674 dup pci-set-irq-line \ set the interrupt pin 675 dup pci-set-capabilities \ set up the capabilities 676 pci-bridge-props \ and generate all properties 677 r> TO pci-device-slots \ and reset the slot array 678; 679 680DEFER func-pci-device-props 681 682\ used for an gerneric device set up 683\ if a device has no special handling for setup 684\ the device file (pci-device_VENDOR_DEVICE.fs) can call 685\ this word to setup the device 686: pci-device-generic-setup ( config-addr -- ) 687 dup assign-all-device-bars \ calc all BARs 688 dup pci-set-irq-line \ set the interrupt pin 689 dup pci-set-capabilities \ set up the capabilities 690 dup func-pci-device-props \ and generate all properties 691 drop \ forget the config-addr 692; 693 694' pci-device-props TO func-pci-device-props 695