|
|
1.1 root 1: /*
2: * Creation Date: <2003/11/18 14:55:05 samuel>
3: * Time-stamp: <2004/03/27 02:03:55 samuel>
4: *
5: * <tree.c>
6: *
7: * device tree setup
8: *
9: * Copyright (C) 2003, 2004 Samuel Rydh ([email protected])
10: *
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
14: *
15: */
16:
17: #include "config.h"
18: #include "libopenbios/bindings.h"
19: #include "mol/mol.h"
20: #include "mol/prom.h"
21:
22:
23: /************************************************************************/
24: /* copy device tree */
25: /************************************************************************/
26:
27: static void
28: copy_node( mol_phandle_t molph )
29: {
30: char name[40], path[80];
31: int exists;
32: phandle_t ph;
33:
34: if( !molph )
35: return;
36:
37: prom_package_to_path( molph, path, sizeof(path) );
38:
39: /* don't copy /options node */
40: if( !strcmp("/options", path) ) {
41: copy_node( prom_peer(molph) );
42: return;
43: }
44:
45: exists = 1;
46: if( !(ph=find_dev(path)) ) {
47: exists = 0;
48: fword("new-device");
49: ph = get_cur_dev();
50: }
51: activate_dev( ph );
52:
53: name[0] = 0;
54: while( prom_next_prop(molph, name, name) > 0 ) {
55: int len = prom_get_prop_len( molph, name );
56: char *p;
57: #if 0
58: if( len > 0x1000 ) {
59: printk("prop to large (%d)\n", len );
60: continue;
61: }
62: #endif
63: /* don't copy /chosen/{stdin,stdout} (XXX: ugly hack...) */
64: if( !strcmp("/chosen", path) )
65: if( !strcmp("stdio", name) || !strcmp("stdout", name) )
66: continue;
67:
68: p = malloc( len );
69: prom_get_prop( molph, name, p, len );
70: set_property( ph, name, p, len );
71: free( p );
72: }
73:
74: set_int_property( ph, "MOL,phandle", molph );
75: copy_node( prom_child(molph) );
76:
77: if( !exists )
78: fword("finish-device");
79: else
80: activate_device("..");
81:
82: copy_node( prom_peer(molph) );
83: }
84:
85:
86:
87: /************************************************************************/
88: /* device tree cloning and tweaking */
89: /************************************************************************/
90:
91: static phandle_t
92: translate_molph( mol_phandle_t molph )
93: {
94: static mol_phandle_t cached_molph;
95: static phandle_t cached_ph;
96: phandle_t ph=0;
97:
98: if( cached_molph == molph )
99: return cached_ph;
100:
101: while( (ph=dt_iterate(ph)) )
102: if( get_int_property(ph, "MOL,phandle", NULL) == molph )
103: break;
104: cached_molph = molph;
105: cached_ph = ph;
106:
107: if( !ph )
108: printk("failed to translate molph\n");
109: return ph;
110: }
111:
112: static void
113: fix_phandles( void )
114: {
115: static char *pnames[] = { "interrupt-parent", "interrupt-controller", NULL } ;
116: int len, *map;
117: phandle_t ph=0;
118: char **pp;
119:
120: while( (ph=dt_iterate(ph)) ) {
121: for( pp=pnames; *pp; pp++ ) {
122: phandle_t *p = (phandle_t*)get_property( ph, *pp, &len );
123: if( len == 4 )
124: *p = translate_molph( *(int*)p );
125: }
126:
127: /* need to fix interrupt map properties too */
128: if( (map=(int*)get_property(ph, "interrupt-map", &len)) ) {
129: int i, acells = get_int_property(ph, "#address-cells", NULL);
130: int icells = get_int_property(ph, "#interrupt-cells", NULL);
131:
132: len /= sizeof(int);
133: for( i=0; i<len; i++ ) {
134: phandle_t ch_ph;
135: int ch_acells, ch_icells;
136:
137: i += acells + icells;
138: if( !(ch_ph=translate_molph(map[i])) )
139: break;
140: map[i] = (int)ch_ph;
141: ch_acells = get_int_property(ch_ph, "#address-cells", NULL);
142: ch_icells = get_int_property(ch_ph, "#interrupt-cells", NULL);
143: i += ch_acells + icells;
144: }
145: if( i != len )
146: printk("interrupt map fixing failure\n");
147: }
148: }
149: /* delete MOL,phandle properties */
150: for( ph=0; (ph=dt_iterate(ph)) ; ) {
151: push_str("MOL,phandle");
152: PUSH_ph(ph);
153: fword("(delete-property)");
154: }
155: fword("device-end");
156: }
157:
158: void
159: devtree_init( void )
160: {
161: activate_device("/");
162: copy_node( prom_peer(0) );
163: fix_phandles();
164: fword("tree-fixes");
165: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.