|
|
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.