diff options
author | Yang Zhang <yang.z.zhang@intel.com> | 2015-08-28 09:58:54 +0800 |
---|---|---|
committer | Yang Zhang <yang.z.zhang@intel.com> | 2015-09-01 12:44:00 +0800 |
commit | e44e3482bdb4d0ebde2d8b41830ac2cdb07948fb (patch) | |
tree | 66b09f592c55df2878107a468a91d21506104d3f /qemu/roms/SLOF/slof/fs/translate.fs | |
parent | 9ca8dbcc65cfc63d6f5ef3312a33184e1d726e00 (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.fs | 150 |
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 +; |