ppc64: Don't set Kp bit on SLB
[openbios.git] / forth / device / property.fs
blobd19546cc0384a0c15d2a6c42d33fc0b33daab487
1 \ tag: Property management
2 \
3 \ this code implements IEEE 1275-1994 ch. 5.3.5
4 \
5 \ Copyright (C) 2003 Stefan Reinauer
6 \
7 \ See the file "COPYING" for further information about
8 \ the copyright and warranty status of this work.
9 \
11 \ small helpers.. these should go elsewhere.
12 : bigendian?
13 10 here ! here c@ 10 <>
16 : l!-be ( val addr )
17 3 bounds swap do
18 dup ff and i c!
19 8 rshift
20 -1 +loop
21 drop
24 : l@-be ( addr )
25 0 swap 4 bounds do
26 i c@ swap 8 << or
27 loop
30 \ allocate n bytes for device tree information
31 \ until I know where to put this, I put it in the
32 \ dictionary.
34 : alloc-tree ( n -- addr )
35 dup >r \ save len
36 here swap allot
37 dup r> 0 fill \ clear memory
40 : align-tree ( -- )
41 null-align
44 : no-active true abort" no active package." ;
47 \ 5.3.5 Property management
50 \ Helper function
51 : find-property ( name len phandle -- &&prop|0 )
52 >dn.properties
53 begin
54 dup @
55 while
56 dup @ >prop.name @ ( name len prop propname )
57 2over comp0 ( name len prop equal? )
58 0= if nip nip exit then
59 >prop.next @
60 repeat
61 ( name len false )
62 3drop false
65 \ From package (5.3.4.1)
66 : next-property
67 ( previous-str previous-len phandle -- false | name-str name-len true )
69 2dup 0= swap 0= or if
70 2drop r> >dn.properties @
71 else
72 r> find-property dup if @ then
73 ?dup if >prop.next @ then
74 then
76 ?dup if
77 >prop.name @ dup cstrlen true
78 ( phandle name-str name-len true )
79 else
80 false
81 then
86 \ 5.3.5.4 Property value access
89 \ Return value for name string property in package phandle.
90 : get-package-property
91 ( name-str name-len phandle -- true | prop-addr prop-len false )
92 find-property ?dup if
93 @ dup >prop.addr @
94 swap >prop.len @
95 false
96 else
97 true
98 then
101 \ Return value for given property in the current instance or its parents.
102 : get-inherited-property
103 ( name-str name-len -- true | prop-addr prop-len false )
104 my-self
105 begin
106 ?dup
107 while
108 dup >in.device-node @ ( str len ihandle phandle )
109 2over rot find-property ?dup if
111 ( str len ihandle prop )
112 nip nip nip ( prop )
113 dup >prop.addr @ swap >prop.len @
114 false
115 exit
116 then
117 ( str len ihandle )
118 >in.my-parent @
119 repeat
120 2drop
121 true
124 \ Return value for given property in this package.
125 : get-my-property ( name-str name-len -- true | prop-addr prop-len false )
126 my-self >in.device-node @ ( -- phandle )
127 get-package-property
132 \ 5.3.5.2 Property array decoding
135 : decode-int ( prop-addr1 prop-len1 -- prop-addr2 prop-len2 n )
136 dup 0> if
137 dup 4 min >r ( addr1 len1 R:minlen )
138 over r@ + swap ( addr1 addr2 len1 R:minlen )
139 r> - ( addr1 addr2 len2 )
140 rot l@-be
141 else
143 then
146 \ HELPER: get #address-cell value (from parent)
147 \ Legal values are 1..4 (we may optionally support longer addresses)
148 : my-#acells ( -- #address-cells )
149 my-self ?dup if >in.device-node @ else active-package then
150 ?dup if >dn.parent @ then
151 ?dup if
152 " #address-cells" rot get-package-property if 2 exit then
153 \ we don't have to support more than 4 (and 0 is illegal)
154 decode-int nip nip 4 min 1 max
155 else
157 then
160 \ HELPER: get #size-cells value (from parent)
161 : my-#scells ( -- #size-cells )
162 my-self ?dup if >in.device-node @ else active-package then
163 ?dup if >dn.parent @ then
164 ?dup if
165 " #size-cells" rot get-package-property if 1 exit then
166 decode-int nip nip
167 else
169 then
172 : decode-string ( prop-addr1 prop-len1 -- prop-addr2 prop-len2 str len )
173 dup 0> if
174 2dup bounds \ check property for 0 bytes
175 0 -rot \ initial string len is 0
177 i c@ 0= if
178 leave
179 then
181 loop ( prop-addr1 prop-len1 len )
182 1+ rot >r ( prop-len1 len R: prop-addr1 )
183 over min 2dup - ( prop-len1 nlen prop-len2 R: prop-addr1 )
184 r@ 2 pick + ( prop-len1 nlen prop-len2 prop-addr2 )
185 >r >r >r ( R: prop-addr1 prop-addr2 prop-len2 nlen )
186 drop
187 r> r> r> ( nlen prop-len2 prop-addr2 )
188 -rot swap ( prop-addr2 prop-len2 nlen )
189 r> swap ( prop-addr2 prop-len2 str len )
190 else
192 then
195 : decode-bytes ( addr1 len1 #bytes -- addr len2 addr1 #bytes )
196 tuck - ( addr1 #bytes len2 )
197 r> 2dup + ( addr1 #bytes addr2 ) ( R: len2 )
198 r> 2swap
201 : decode-phys
202 ( prop-addr1 prop-len1 -- prop-addr2 prop-len2 phys.lo ... phys.hi )
203 my-#acells 0 ?do
204 decode-int r> r> rot >r >r >r
205 loop
206 my-#acells 0 ?do
207 r> r> r> -rot >r >r
208 loop
213 \ 5.3.5.1 Property array encoding
216 : encode-int ( n -- prop-addr prop-len )
217 /l alloc-tree tuck l!-be /l
220 : encode-string ( str len -- prop-addr prop-len )
221 \ we trust len here. should probably check string?
222 tuck char+ alloc-tree ( len str prop-addr )
223 tuck 3 pick move ( len prop-addr )
224 swap 1+
227 : encode-bytes ( data-addr data-len -- prop-addr prop-len )
228 tuck alloc-tree ( len str prop-addr )
229 tuck 3 pick move
230 swap
233 : encode+ ( prop-addr1 prop-len1 prop-addr2 prop-len2 -- prop-addr3 prop-len3 )
234 nip +
237 : encode-phys ( phys.lo ... phys.hi -- prop-addr prop-len )
238 encode-int my-#acells 1- 0 ?do
239 rot encode-int encode+
240 loop
243 defer sbus-intr>cpu ( sbus-intr# -- cpu-intr# )
244 : (sbus-intr>cpu) ." No SBUS present on this machine." cr ;
245 ['] (sbus-intr>cpu) to sbus-intr>cpu
249 \ 5.3.5.3 Property declaration
252 : (property) ( prop-addr prop-len name-str name-len dnode -- )
253 >r 2dup r@
254 align-tree
255 find-property ?dup if
256 \ If a property with that property name already exists in the
257 \ package in which the property would be created, replace its
258 \ value with the new value.
259 @ r> drop \ don't need the device node anymore.
260 -rot 2drop tuck \ drop property name
261 >prop.len ! \ overwrite old values
262 >prop.addr !
263 exit
264 then
266 ( prop-addr prop-len name-str name-len R: dn )
267 prop-node.size alloc-tree
268 dup >prop.next off
270 dup r> >dn.properties
271 begin dup @ while @ >prop.next repeat !
274 ( prop-addr prop-len name-str name-len R: prop )
276 \ create copy of property name
277 dup char+ alloc-tree
278 dup >r swap move r>
279 ( prop-addr prop-len new-name R: prop )
280 r@ >prop.name !
281 r@ >prop.len !
282 r> >prop.addr !
283 align-tree
286 : property ( prop-addr prop-len name-str name-len -- )
287 my-self ?dup if
288 >in.device-node @
289 else
290 active-package
291 then
292 dup if
293 (property)
294 else
295 no-active
296 then
299 : (delete-property) ( name len dnode -- )
300 find-property ?dup if
301 dup @ >prop.next @ swap !
302 \ maybe we should try to reclaim the space?
303 then
306 : delete-property ( name-str name-len -- )
307 active-package ?dup if
308 (delete-property)
309 else
310 2drop
311 then
314 \ Create the "name" property; value is indicated string.
315 : device-name ( str len -- )
316 encode-string " name" property
319 \ Create "device_type" property, value is indicated string.
320 : device-type ( str len -- )
321 encode-string " device_type" property
324 \ Create the "reg" property with the given values.
325 : reg ( phys.lo ... phys.hi size -- )
326 >r ( phys.lo ... phys.hi ) encode-phys ( addr len )
327 r> ( addr1 len1 size ) encode-int ( addr1 len1 addr2 len2 )
328 encode+ ( addr len )
329 " reg" property
332 \ Create the "model" property; value is indicated string.
333 : model ( str len -- )
334 encode-string " model" property