2 * Creation Date: <2003/11/24 12:30:18 samuel>
3 * Time-stamp: <2004/01/07 19:37:38 samuel>
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
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 /************************************************************************/
29 push_str( const char *str )
31 PUSH( pointer2cell(str) );
32 PUSH( str ? strlen(str) : 0 );
35 /* WARNING: sloooow - AVOID */
37 feval( const char *str )
40 return eword("evaluate", 2);
44 _eword( const char *word, xt_t *cache_xt, int nargs )
46 static xt_t catch_xt = 0;
50 catch_xt = findword("catch");
52 *cache_xt = findword( (char*)word );
56 enterforth( catch_xt );
63 /* note: only the built-in dictionary is searched */
65 _fword( const char *word, xt_t *cache_xt )
68 *cache_xt = findword( (char*)word );
71 enterforth( *cache_xt );
78 _selfword( const char *method, xt_t *cache_xt )
81 *cache_xt = find_ih_method( method, my_self() );
83 enterforth( *cache_xt );
90 _parword( const char *method, xt_t *cache_xt )
93 *cache_xt = find_ih_method( method, my_parent() );
95 enterforth( *cache_xt );
102 bind_func( const char *name, void (*func)(void) )
104 PUSH( pointer2cell(func) );
110 bind_xtfunc( const char *name, xt_t xt, ucell arg, void (*func)(void) )
114 PUSH( pointer2cell(func) );
116 fword("is-xt-cfunc");
120 bind_noname_func( void (*func)(void) )
122 PUSH( pointer2cell(func) );
123 fword("is-noname-cfunc");
135 /************************************************************************/
136 /* ihandle related */
137 /************************************************************************/
140 ih_to_phandle( ihandle_t ih )
143 fword("ihandle>phandle");
162 find_package_method( const char *method, phandle_t ph )
166 fword("find-method");
173 find_ih_method( const char *method, ihandle_t ih )
175 return find_package_method( method, ih_to_phandle(ih) );
180 find_parent_method( const char *method )
182 return find_ih_method( method, my_parent() );
186 call_package( xt_t xt, ihandle_t ihandle )
190 fword("call-package");
194 call_parent( xt_t xt )
197 fword("call-parent");
201 call_parent_method( const char *method )
204 fword("$call-parent");
208 /************************************************************************/
209 /* open/close package/dev */
210 /************************************************************************/
213 open_dev( const char *spec )
221 close_dev( ihandle_t ih )
228 open_package( const char *argstr, phandle_t ph )
232 fword("open-package");
237 close_package( ihandle_t ih )
240 fword("close-package");
244 /************************************************************************/
245 /* ihandle arguments */
246 /************************************************************************/
249 pop_fstr_copy( void )
252 char *str, *p = (char*)cell2pointer(POP());
255 str = malloc( len + 1 );
258 memcpy( str, p, len );
267 return pop_fstr_copy();
271 /************************************************************************/
273 /************************************************************************/
276 set_property( phandle_t ph, const char *name, const char *buf, int len )
279 printk("set_property: NULL phandle\n");
282 PUSH(pointer2cell(buf));
286 fword("set-property");
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) );
297 get_property( phandle_t ph, const char *name, int *retlen )
306 fword("get-package-property");
312 return (char*)cell2pointer(POP());
316 get_int_property( phandle_t ph, const char *name, int *retlen )
320 if( !(p=(u32 *)get_property(ph, name, retlen)) )
322 return __be32_to_cpu(*p);
326 /************************************************************************/
327 /* device selection / iteration */
328 /************************************************************************/
331 activate_dev( phandle_t ph )
334 fword("active-package!");
338 activate_device( const char *str )
340 phandle_t ph = find_dev( str );
354 fword("active-package");
359 find_dev( const char *path )
370 get_path_from_ph( phandle_t ph )
373 fword("get-package-path");
374 return pop_fstr_copy();
378 dt_iter_begin( void )
380 fword("iterate-tree-begin");
385 dt_iterate( phandle_t last_tree )
388 return dt_iter_begin();
390 PUSH_ph( last_tree );
391 fword("iterate-tree");
396 dt_iterate_type( phandle_t last_tree, const char *type )
399 last_tree = dt_iter_begin();
401 /* root node is never matched but we don't care about that */
402 while( (last_tree = dt_iterate(last_tree)) ) {
403 char *s = get_property( last_tree, "device_type", NULL );
404 if( s && !strcmp(type, s) )
411 /************************************************************************/
413 /************************************************************************/
416 make_openable( int only_parents )
418 phandle_t ph, save_ph = get_cur_dev();
430 activate_dev( save_ph );
436 void (*func)(cell v);
437 func = (void*)cell2pointer(POP());
444 add_methods( int flags, int size, const method_t *methods, int nmet )
449 /* nodes might be matched multiple times */
450 if( find_package_method(methods[0].name, get_cur_dev()) )
459 for( i=0; i<nmet; i++ ) {
460 /* null-name methods specify static initializers */
461 if( !methods[i].name ) {
462 typedef void (*initfunc)( void *p );
466 buf = (char*)cell2pointer(POP());
468 (*(initfunc)methods[i].func)( buf );
472 bind_func( methods[i].name, methods[i].func );
474 bind_xtfunc( methods[i].name, xt, pointer2cell(methods[i].func),
478 if( flags & INSTALL_OPEN )
483 bind_node( int flags, int size, const char * const *paths, int npaths,
484 const method_t *methods, int nmet )
486 phandle_t save_ph = get_cur_dev();
489 for( i=0; i<npaths; i++ ) {
490 const char *name = paths[i];
496 while( (ph=dt_iterate_type(ph, name)) ) {
498 add_methods( flags, size, methods, nmet );
504 if( activate_device(name) )
505 add_methods( flags, size, methods, nmet );
506 else if( *name == '+' ) {
507 /* create node (and missing parents) */
508 if( !activate_device(++name) ) {
510 fword("create-node");
512 add_methods( flags, size, methods, nmet );
515 activate_dev( save_ph );
519 bind_new_node( int flags, int size, const char *name,
520 const method_t *methods, int nmet )
522 phandle_t save_ph = get_cur_dev();
526 fword("create-node");
527 add_methods( flags, size, methods, nmet );
528 new_ph = get_cur_dev();
530 activate_dev( save_ph );