~ubuntu-branches/ubuntu/wily/slof/wily

« back to all changes in this revision

Viewing changes to slof/fs/translate.fs

  • Committer: Package Import Robot
  • Author(s): Aurelien Jarno
  • Date: 2012-09-16 23:05:23 UTC
  • Revision ID: package-import@ubuntu.com-20120916230523-r2ynulqmp2tyu2e5
Tags: upstream-20120217+dfsg
ImportĀ upstreamĀ versionĀ 20120217+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
\ this is a C-to-Forth translation from the translate
 
14
\ address code in the client
 
15
\ with extensions to handle different sizes of #size-cells
 
16
 
 
17
\ this tries to figure out if it is a PCI device what kind of
 
18
\ translation is wanted
 
19
\ if prop_type is 0, "reg" property is used, otherwise "assigned-addresses"
 
20
: pci-address-type  ( node address prop_type -- type )
 
21
   -rot 2 pick ( prop_type node address prop_type )
 
22
   0= IF
 
23
      swap s" reg" rot get-property  ( prop_type address data dlen false )
 
24
   ELSE
 
25
      swap s" assigned-addresses" rot get-property  ( prop_type address data dlen false )
 
26
   THEN
 
27
   IF  2drop -1  EXIT  THEN  4 / 5 /
 
28
   \ advance (phys-addr(3) size(2)) steps
 
29
   0 DO
 
30
      \ BARs and Expansion ROM must be in assigned-addresses...
 
31
      \ so if prop_type is 0 ("reg") and a config space offset is set
 
32
      \ we skip this entry...
 
33
      dup l@ FF AND 0<> ( prop_type address data cfgspace_offset? )
 
34
      3 pick 0= ( prop_type address data cfgspace_offset? reg_prop? )
 
35
      AND NOT IF 
 
36
         2dup 8 + ( prop_type address data address data' )
 
37
         2dup l@ 2 pick 8 + l@ + <= -rot l@  >= and  IF
 
38
            l@ 03000000 and 18 rshift nip
 
39
            \ no 64bit translations supported pretend it is 32bit
 
40
            dup 3 = IF  1-  THEN
 
41
            ( prop_type type )
 
42
            swap drop ( type )
 
43
            UNLOOP EXIT
 
44
         THEN
 
45
      THEN
 
46
      \ advance in 4 byte steps and (phys-addr(3) size(2)) steps
 
47
      4 5 * +
 
48
   LOOP
 
49
   3drop -1
 
50
;
 
51
 
 
52
: (range-read-cells)  ( range-addr #cells -- range-value )
 
53
   \ if number of cells != 1; do 64bit read; else a 32bit read
 
54
   1 =  IF  l@  ELSE  @  THEN
 
55
;
 
56
 
 
57
\ this functions tries to find a mapping for the given address
 
58
\ it assumes that if we have #address-cells == 3 that we are trying
 
59
\ to do a PCI translation
 
60
 
 
61
\ nac - #address-cells
 
62
\ nsc - #size-cells
 
63
\ pnac - parent #address-cells
 
64
 
 
65
: (map-one-range)  ( type range pnac nsc nac address -- address true | address false )
 
66
   \ only check for the type if nac == 3 (PCI)
 
67
   over 3 = 5 pick l@ 3000000 and 18 rshift 7 pick <> and  IF
 
68
      >r 2drop 3drop r> false EXIT
 
69
   THEN
 
70
   \ get size
 
71
   4 pick 4 pick 3 pick + 4 * +
 
72
   \ get nsc
 
73
   3 pick
 
74
   \ read size
 
75
   ( type range pnac nsc nac address range nsc )
 
76
   (range-read-cells)
 
77
   ( type range pnac nsc nac address size )
 
78
   \ skip type if PCI
 
79
   5 pick 3 pick 3 =  IF
 
80
      4 +
 
81
   THEN
 
82
   \ get nac
 
83
   3 pick
 
84
   ( type range pnac nsc nac address size range nac )
 
85
   \ read child-mapping
 
86
   (range-read-cells)
 
87
   ( type range pnac nsc nac address size child-mapping )
 
88
   dup >r dup 3 pick > >r + over <= r> or  IF
 
89
      \ address is not inside the mapping range
 
90
      >r 2drop 3drop r> r> drop false EXIT
 
91
   THEN
 
92
   dup r> -
 
93
   ( type range pnac nsc nac address offset )
 
94
   \ add the offset on the parent mapping
 
95
   5 pick 5 pick 3 =  IF
 
96
      \ skip type if PCI
 
97
      4 +
 
98
   THEN
 
99
   3 pick 4 * +
 
100
   ( type range pnac nsc nac address offset parent-mapping-address )
 
101
   \ get pnac
 
102
   5 pick
 
103
   \ read parent mapping
 
104
   (range-read-cells)
 
105
   ( type range pnac nsc nac address offset parent-mapping )
 
106
   + >r 3drop 3drop r> true
 
107
;
 
108
 
 
109
\ this word translates the given address starting from the node specified
 
110
\ in node; the word will return to the node it was started from
 
111
: translate-address  ( node address -- address )
 
112
   \ check for address type in "assigned-addresses"
 
113
   2dup 1 pci-address-type  ( node address type )
 
114
   dup -1 = IF
 
115
      \ not found in "assigned-addresses", check in "reg"
 
116
      drop 2dup 0 pci-address-type ( node address type )
 
117
   THEN
 
118
   rot parent BEGIN
 
119
      \ check if it is the root node
 
120
      dup parent 0=  IF  2drop EXIT  THEN
 
121
      ( address type parent )
 
122
      s" #address-cells" 2 pick get-property 2drop l@ >r        \ nac
 
123
      s" #size-cells" 2 pick get-property 2drop l@ >r           \ nsc
 
124
      s" #address-cells" 2 pick parent get-property 2drop l@ >r \ pnac
 
125
      -rot ( node address type )
 
126
      s" ranges" 4 pick get-property  IF
 
127
         3drop
 
128
         ABORT" no ranges property; not translatable"
 
129
      THEN
 
130
      r> r> r> 3 roll
 
131
      ( node address type ranges pnac nsc nac length )
 
132
      4 / >r 3dup + + >r 5 roll r> r> swap / 0 ?DO
 
133
         ( node type ranges pnac nsc nac address )
 
134
         6dup (map-one-range) IF
 
135
            nip leave
 
136
         THEN
 
137
         nip
 
138
         \ advance ranges
 
139
         4 roll
 
140
         ( node type pnac nsc nac address ranges )
 
141
         4 pick 4 pick 4 pick + + 4 * + 4 -roll
 
142
      LOOP
 
143
      >r 2drop 2drop r> ( node type address )
 
144
      swap rot parent ( address type node )
 
145
      dup 0=
 
146
   UNTIL
 
147
;
 
148
 
 
149
\ this words translates the given address starting from the current node
 
150
: translate-my-address  ( address -- address' )
 
151
   get-node swap translate-address
 
152
;