ppc64: Don't set Kp bit on SLB
[openbios.git] / libopenbios / bindings.c
blob5323421f51073a32a93fd8b2a39e3cf7f6bc59a2
1 /*
2 * Creation Date: <2003/11/24 12:30:18 samuel>
3 * Time-stamp: <2004/01/07 19:37:38 samuel>
5 * <bindings.c>
7 * Forth bindings
9 * Copyright (C) 2003, 2004 Samuel Rydh (samuel@ibrium.se)
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * version 2
17 #include "config.h"
18 #include "libopenbios/bindings.h"
19 #include "libc/string.h"
20 #include "libc/stdlib.h"
21 #include "libc/byteorder.h"
24 /************************************************************************/
25 /* forth interface glue */
26 /************************************************************************/
28 void
29 push_str( const char *str )
31 PUSH( pointer2cell(str) );
32 PUSH( str ? strlen(str) : 0 );
35 /* WARNING: sloooow - AVOID */
36 cell
37 feval( const char *str )
39 push_str( str );
40 return eword("evaluate", 2);
43 cell
44 _eword( const char *word, xt_t *cache_xt, int nargs )
46 static xt_t catch_xt = 0;
47 cell ret = -1;
49 if( !catch_xt )
50 catch_xt = findword("catch");
51 if( !*cache_xt )
52 *cache_xt = findword( (char*)word );
54 if( *cache_xt ) {
55 PUSH_xt( *cache_xt );
56 enterforth( catch_xt );
57 if( (ret=POP()) )
58 dstackcnt -= nargs;
60 return ret;
63 /* note: only the built-in dictionary is searched */
64 int
65 _fword( const char *word, xt_t *cache_xt )
67 if( !*cache_xt )
68 *cache_xt = findword( (char*)word );
70 if( *cache_xt ) {
71 enterforth( *cache_xt );
72 return 0;
74 return -1;
77 int
78 _selfword( const char *method, xt_t *cache_xt )
80 if( !*cache_xt )
81 *cache_xt = find_ih_method( method, my_self() );
82 if( *cache_xt ) {
83 enterforth( *cache_xt );
84 return 0;
86 return -1;
89 int
90 _parword( const char *method, xt_t *cache_xt )
92 if( !*cache_xt )
93 *cache_xt = find_ih_method( method, my_parent() );
94 if( *cache_xt ) {
95 enterforth( *cache_xt );
96 return 0;
98 return -1;
101 void
102 bind_func( const char *name, void (*func)(void) )
104 PUSH( pointer2cell(func) );
105 push_str( name );
106 fword("is-cfunc");
109 void
110 bind_xtfunc( const char *name, xt_t xt, ucell arg, void (*func)(void) )
112 PUSH_xt( xt );
113 PUSH( arg );
114 PUSH( pointer2cell(func) );
115 push_str( name );
116 fword("is-xt-cfunc");
119 xt_t
120 bind_noname_func( void (*func)(void) )
122 PUSH( pointer2cell(func) );
123 fword("is-noname-cfunc");
124 return POP_xt();
127 void
128 throw( int error )
130 PUSH( error );
131 fword("throw");
135 /************************************************************************/
136 /* ihandle related */
137 /************************************************************************/
139 phandle_t
140 ih_to_phandle( ihandle_t ih )
142 PUSH_ih( ih );
143 fword("ihandle>phandle");
144 return POP_ph();
147 ihandle_t
148 my_parent( void )
150 fword("my-parent");
151 return POP_ih();
154 ihandle_t
155 my_self( void )
157 fword("my-self");
158 return POP_ih();
161 xt_t
162 find_package_method( const char *method, phandle_t ph )
164 push_str( method );
165 PUSH_ph( ph );
166 fword("find-method");
167 if( POP() )
168 return POP_xt();
169 return 0;
172 xt_t
173 find_ih_method( const char *method, ihandle_t ih )
175 return find_package_method( method, ih_to_phandle(ih) );
179 xt_t
180 find_parent_method( const char *method )
182 return find_ih_method( method, my_parent() );
185 void
186 call_package( xt_t xt, ihandle_t ihandle )
188 PUSH_xt( xt );
189 PUSH_ih( ihandle );
190 fword("call-package");
193 void
194 call_parent( xt_t xt )
196 PUSH_xt( xt );
197 fword("call-parent");
200 void
201 call_parent_method( const char *method )
203 push_str( method );
204 fword("$call-parent");
208 /************************************************************************/
209 /* open/close package/dev */
210 /************************************************************************/
212 ihandle_t
213 open_dev( const char *spec )
215 push_str( spec );
216 fword("open-dev");
217 return POP_ih();
220 void
221 close_dev( ihandle_t ih )
223 PUSH_ih( ih );
224 fword("close-dev");
227 ihandle_t
228 open_package( const char *argstr, phandle_t ph )
230 push_str( argstr );
231 PUSH_ph( ph );
232 fword("open-package");
233 return POP_ih();
236 void
237 close_package( ihandle_t ih )
239 PUSH_ih( ih );
240 fword("close-package");
244 /************************************************************************/
245 /* ihandle arguments */
246 /************************************************************************/
248 char *
249 pop_fstr_copy( void )
251 int len = POP();
252 char *str, *p = (char*)cell2pointer(POP());
253 if( !len )
254 return NULL;
255 str = malloc( len + 1 );
256 if( !str )
257 return NULL;
258 memcpy( str, p, len );
259 str[len] = 0;
260 return str;
263 char *
264 my_args_copy( void )
266 fword("my-args");
267 return pop_fstr_copy();
271 /************************************************************************/
272 /* properties */
273 /************************************************************************/
275 void
276 set_property( phandle_t ph, const char *name, const char *buf, int len )
278 if( !ph ) {
279 printk("set_property: NULL phandle\n");
280 return;
282 PUSH(pointer2cell(buf));
283 PUSH(len);
284 push_str( name );
285 PUSH_ph(ph);
286 fword("set-property");
289 void
290 set_int_property( phandle_t ph, const char *name, u32 val )
292 u32 swapped=__cpu_to_be32(val);
293 set_property( ph, name, (char*)&swapped, sizeof(swapped) );
296 char *
297 get_property( phandle_t ph, const char *name, int *retlen )
299 int len;
301 if( retlen )
302 *retlen = -1;
304 push_str( name );
305 PUSH_ph( ph );
306 fword("get-package-property");
307 if( POP() )
308 return NULL;
309 len = POP();
310 if( retlen )
311 *retlen = len;
312 return (char*)cell2pointer(POP());
316 get_int_property( phandle_t ph, const char *name, int *retlen )
318 u32 *p;
320 if( !(p=(u32 *)get_property(ph, name, retlen)) )
321 return 0;
322 return __be32_to_cpu(*p);
326 /************************************************************************/
327 /* device selection / iteration */
328 /************************************************************************/
330 void
331 activate_dev( phandle_t ph )
333 PUSH_ph( ph );
334 fword("active-package!");
337 phandle_t
338 activate_device( const char *str )
340 phandle_t ph = find_dev( str );
341 activate_dev( ph );
342 return ph;
345 void
346 device_end( void )
348 fword("device-end");
351 phandle_t
352 get_cur_dev( void )
354 fword("active-package");
355 return POP_ph();
358 phandle_t
359 find_dev( const char *path )
361 phandle_t ret = 0;
362 push_str( path );
363 fword("(find-dev)");
364 if( POP() )
365 return POP_ph();
366 return ret;
369 phandle_t
370 dt_iter_begin( void )
372 fword("iterate-tree-begin");
373 return POP_ph();
376 phandle_t
377 dt_iterate( phandle_t last_tree )
379 if( !last_tree )
380 return dt_iter_begin();
382 PUSH_ph( last_tree );
383 fword("iterate-tree");
384 return POP_ph();
387 phandle_t
388 dt_iterate_type( phandle_t last_tree, const char *type )
390 if( !last_tree )
391 last_tree = dt_iter_begin();
393 /* root node is never matched but we don't care about that */
394 while( (last_tree = dt_iterate(last_tree)) ) {
395 char *s = get_property( last_tree, "device_type", NULL );
396 if( s && !strcmp(type, s) )
397 break;
399 return last_tree;
403 /************************************************************************/
404 /* node methods */
405 /************************************************************************/
407 void
408 make_openable( int only_parents )
410 phandle_t ph, save_ph = get_cur_dev();
411 PUSH_ph( save_ph );
413 for( ;; ) {
414 if( only_parents++ )
415 fword("parent");
416 if( !(ph=POP_ph()) )
417 break;
418 activate_dev( ph );
419 PUSH_ph( ph );
420 fword("is-open");
422 activate_dev( save_ph );
425 static void
426 call1_func( void )
428 void (*func)(cell v);
429 func = (void*)cell2pointer(POP());
431 (*func)( POP() );
435 static void
436 add_methods( int flags, int size, const method_t *methods, int nmet )
438 xt_t xt=0;
439 int i;
441 /* nodes might be matched multiple times */
442 if( find_package_method(methods[0].name, get_cur_dev()) )
443 return;
445 if( size ) {
446 PUSH( size );
447 fword("is-ibuf");
448 xt = POP_xt();
451 for( i=0; i<nmet; i++ ) {
452 /* null-name methods specify static initializers */
453 if( !methods[i].name ) {
454 typedef void (*initfunc)( void *p );
455 char *buf = NULL;
456 if( xt ) {
457 enterforth( xt );
458 buf = (char*)cell2pointer(POP());
460 (*(initfunc)methods[i].func)( buf );
461 continue;
463 if( !size )
464 bind_func( methods[i].name, methods[i].func );
465 else
466 bind_xtfunc( methods[i].name, xt, pointer2cell(methods[i].func),
467 &call1_func );
470 if( flags & INSTALL_OPEN )
471 make_openable(0);
474 void
475 bind_node( int flags, int size, const char * const *paths, int npaths,
476 const method_t *methods, int nmet )
478 phandle_t save_ph = get_cur_dev();
479 int i;
481 for( i=0; i<npaths; i++ ) {
482 const char *name = paths[i];
484 /* type matching? */
485 if( *name == 'T' ) {
486 phandle_t ph = 0;
487 name++;
488 while( (ph=dt_iterate_type(ph, name)) ) {
489 activate_dev( ph );
490 add_methods( flags, size, methods, nmet );
492 continue;
495 /* path patching */
496 if( activate_device(name) )
497 add_methods( flags, size, methods, nmet );
498 else if( *name == '+' ) {
499 /* create node (and missing parents) */
500 if( !activate_device(++name) ) {
501 push_str( name );
502 fword("create-node");
504 add_methods( flags, size, methods, nmet );
507 activate_dev( save_ph );
510 phandle_t
511 bind_new_node( int flags, int size, const char *name,
512 const method_t *methods, int nmet )
514 phandle_t save_ph = get_cur_dev();
515 phandle_t new_ph;
516 /* create node */
517 push_str( name );
518 fword("create-node");
519 add_methods( flags, size, methods, nmet );
520 new_ph = get_cur_dev();
522 activate_dev( save_ph );
523 return new_ph;