summaryrefslogtreecommitdiffstats
path: root/qemu/roms/SLOF/slof/fs/translate.fs
diff options
context:
space:
mode:
authorYang Zhang <yang.z.zhang@intel.com>2015-08-28 09:58:54 +0800
committerYang Zhang <yang.z.zhang@intel.com>2015-09-01 12:44:00 +0800
commite44e3482bdb4d0ebde2d8b41830ac2cdb07948fb (patch)
tree66b09f592c55df2878107a468a91d21506104d3f /qemu/roms/SLOF/slof/fs/translate.fs
parent9ca8dbcc65cfc63d6f5ef3312a33184e1d726e00 (diff)
Add qemu 2.4.0
Change-Id: Ic99cbad4b61f8b127b7dc74d04576c0bcbaaf4f5 Signed-off-by: Yang Zhang <yang.z.zhang@intel.com>
Diffstat (limited to 'qemu/roms/SLOF/slof/fs/translate.fs')
-rw-r--r--qemu/roms/SLOF/slof/fs/translate.fs150
1 files changed, 150 insertions, 0 deletions
diff --git a/qemu/roms/SLOF/slof/fs/translate.fs b/qemu/roms/SLOF/slof/fs/translate.fs
new file mode 100644
index 000000000..9654f242f
--- /dev/null
+++ b/qemu/roms/SLOF/slof/fs/translate.fs
@@ -0,0 +1,150 @@
+\ *****************************************************************************
+\ * Copyright (c) 2004, 2008 IBM Corporation
+\ * All rights reserved.
+\ * This program and the accompanying materials
+\ * are made available under the terms of the BSD License
+\ * which accompanies this distribution, and is available at
+\ * http://www.opensource.org/licenses/bsd-license.php
+\ *
+\ * Contributors:
+\ * IBM Corporation - initial implementation
+\ ****************************************************************************/
+
+\ this is a C-to-Forth translation from the translate
+\ address code in the client
+\ with extensions to handle different sizes of #size-cells
+
+\ this tries to figure out if it is a PCI device what kind of
+\ translation is wanted
+\ if prop_type is 0, "reg" property is used, otherwise "assigned-addresses"
+: pci-address-type ( node address prop_type -- type )
+ -rot 2 pick ( prop_type node address prop_type )
+ 0= IF
+ swap s" reg" rot get-property ( prop_type address data dlen false )
+ ELSE
+ swap s" assigned-addresses" rot get-property ( prop_type address data dlen false )
+ THEN
+ IF 2drop -1 EXIT THEN 4 / 5 /
+ \ advance (phys-addr(3) size(2)) steps
+ 0 DO
+ \ BARs and Expansion ROM must be in assigned-addresses...
+ \ so if prop_type is 0 ("reg") and a config space offset is set
+ \ we skip this entry...
+ dup l@ FF AND 0<> ( prop_type address data cfgspace_offset? )
+ 3 pick 0= ( prop_type address data cfgspace_offset? reg_prop? )
+ AND NOT IF
+ 2dup 4 + ( prop_type address data address data' )
+ 2dup @ 2 pick 8 + @ + <= -rot @ >= and IF
+ l@ 03000000 and 18 rshift nip
+ ( prop_type type )
+ swap drop ( type )
+ UNLOOP EXIT
+ THEN
+ THEN
+ \ advance in 4 byte steps and (phys-addr(3) size(2)) steps
+ 4 5 * +
+ LOOP
+ 3drop -1
+;
+
+: (range-read-cells) ( range-addr #cells -- range-value )
+ \ if number of cells != 1; do 64bit read; else a 32bit read
+ 1 = IF l@ ELSE @ THEN
+;
+
+\ this functions tries to find a mapping for the given address
+\ it assumes that if we have #address-cells == 3 that we are trying
+\ to do a PCI translation
+
+\ nac - #address-cells
+\ nsc - #size-cells
+\ pnac - parent #address-cells
+
+: (map-one-range) ( type range pnac nsc nac address -- address true | address false )
+ \ only check for the type if nac == 3 (PCI)
+ over 3 = 5 pick l@ 3000000 and 18 rshift 7 pick <> and IF
+ >r 2drop 3drop r> false EXIT
+ THEN
+ \ get size
+ 4 pick 4 pick 3 pick + 4 * +
+ \ get nsc
+ 3 pick
+ \ read size
+ ( type range pnac nsc nac address range nsc )
+ (range-read-cells)
+ ( type range pnac nsc nac address size )
+ \ skip type if PCI
+ 5 pick 3 pick 3 = IF
+ 4 +
+ THEN
+ \ get nac
+ 3 pick
+ ( type range pnac nsc nac address size range nac )
+ \ read child-mapping
+ (range-read-cells)
+ ( type range pnac nsc nac address size child-mapping )
+ dup >r dup 3 pick > >r + over <= r> or IF
+ \ address is not inside the mapping range
+ >r 2drop 3drop r> r> drop false EXIT
+ THEN
+ dup r> -
+ ( type range pnac nsc nac address offset )
+ \ add the offset on the parent mapping
+ 5 pick 5 pick 3 = IF
+ \ skip type if PCI
+ 4 +
+ THEN
+ 3 pick 4 * +
+ ( type range pnac nsc nac address offset parent-mapping-address )
+ \ get pnac
+ 5 pick
+ \ read parent mapping
+ (range-read-cells)
+ ( type range pnac nsc nac address offset parent-mapping )
+ + >r 3drop 3drop r> true
+;
+
+\ this word translates the given address starting from the node specified
+\ in node; the word will return to the node it was started from
+: translate-address ( node address -- address )
+ \ check for address type in "assigned-addresses"
+ 2dup 1 pci-address-type ( node address type )
+ dup -1 = IF
+ \ not found in "assigned-addresses", check in "reg"
+ drop 2dup 0 pci-address-type ( node address type )
+ THEN
+ rot parent BEGIN
+ \ check if it is the root node
+ dup parent 0= IF 2drop EXIT THEN
+ ( address type parent )
+ s" #address-cells" 2 pick get-property 2drop l@ >r \ nac
+ s" #size-cells" 2 pick get-property 2drop l@ >r \ nsc
+ s" #address-cells" 2 pick parent get-property 2drop l@ >r \ pnac
+ -rot ( node address type )
+ s" ranges" 4 pick get-property IF
+ 3drop
+ ABORT" no ranges property; not translatable"
+ THEN
+ r> r> r> 3 roll
+ ( node address type ranges pnac nsc nac length )
+ 4 / >r 3dup + + >r 5 roll r> r> swap / 0 ?DO
+ ( node type ranges pnac nsc nac address )
+ 6dup (map-one-range) IF
+ nip leave
+ THEN
+ nip
+ \ advance ranges
+ 4 roll
+ ( node type pnac nsc nac address ranges )
+ 4 pick 4 pick 4 pick + + 4 * + 4 -roll
+ LOOP
+ >r 2drop 2drop r> ( node type address )
+ swap rot parent ( address type node )
+ dup 0=
+ UNTIL
+;
+
+\ this words translates the given address starting from the current node
+: translate-my-address ( address -- address' )
+ get-node swap translate-address
+;