|
|
1.1 ! root 1: /* ! 2: * Creation Date: <2004/08/28 18:38:22 greg> ! 3: * Time-stamp: <2004/08/28 18:38:22 greg> ! 4: * ! 5: * <methods.c> ! 6: * ! 7: * Misc device node methods ! 8: * ! 9: * Copyright (C) 2004 Greg Watson ! 10: * ! 11: * Based on MOL specific code which is ! 12: * ! 13: * Copyright (C) 2003, 2004 Samuel Rydh ([email protected]) ! 14: * ! 15: * This program is free software; you can redistribute it and/or ! 16: * modify it under the terms of the GNU General Public License ! 17: * version 2 ! 18: * ! 19: */ ! 20: ! 21: #include "config.h" ! 22: #include "libopenbios/bindings.h" ! 23: #include "libc/string.h" ! 24: #include "pearpc/pearpc.h" ! 25: #include "libopenbios/ofmem.h" ! 26: ! 27: /************************************************************************/ ! 28: /* RTAS (run-time abstraction services) */ ! 29: /************************************************************************/ ! 30: ! 31: #ifdef CONFIG_RTAS ! 32: DECLARE_NODE( rtas, INSTALL_OPEN, 0, "+/rtas" ); ! 33: ! 34: /* ( physbase -- rtas_callback ) */ ! 35: static void ! 36: rtas_instantiate( void ) ! 37: { ! 38: int physbase = POP(); ! 39: int s=0x1000, size = (int)of_rtas_end - (int)of_rtas_start; ! 40: unsigned long virt; ! 41: ! 42: while( s < size ) ! 43: s += 0x1000; ! 44: virt = ofmem_claim_virt( 0, s, 0x1000 ); ! 45: ofmem_map( physbase, virt, s, -1 ); ! 46: memcpy( (char*)virt, of_rtas_start, size ); ! 47: ! 48: printk("RTAS instantiated at %08x\n", physbase ); ! 49: flush_icache_range( (char*)virt, (char*)virt + size ); ! 50: ! 51: PUSH( physbase ); ! 52: } ! 53: ! 54: NODE_METHODS( rtas ) = { ! 55: { "instantiate", rtas_instantiate }, ! 56: { "instantiate-rtas", rtas_instantiate }, ! 57: }; ! 58: #endif ! 59: ! 60: ! 61: /************************************************************************/ ! 62: /* stdout */ ! 63: /************************************************************************/ ! 64: ! 65: DECLARE_NODE( video_stdout, INSTALL_OPEN, 0, "Tdisplay" ); ! 66: ! 67: /* ( addr len -- actual ) */ ! 68: static void ! 69: stdout_write( void ) ! 70: { ! 71: int len = POP(); ! 72: char *addr = (char*)POP(); ! 73: ! 74: printk( "%s", s ); ! 75: //vfd_draw_str( s ); ! 76: console_draw_fstr(addr, len); ! 77: ! 78: PUSH( len ); ! 79: } ! 80: ! 81: NODE_METHODS( video_stdout ) = { ! 82: { "write", stdout_write }, ! 83: }; ! 84: ! 85: ! 86: /************************************************************************/ ! 87: /* tty */ ! 88: /************************************************************************/ ! 89: ! 90: DECLARE_NODE( tty, INSTALL_OPEN, 0, "/packages/terminal-emulator" ); ! 91: ! 92: /* ( addr len -- actual ) */ ! 93: static void ! 94: tty_read( void ) ! 95: { ! 96: int ch, len = POP(); ! 97: char *p = (char*)POP(); ! 98: int ret=0; ! 99: ! 100: if( len > 0 ) { ! 101: ret = 1; ! 102: ch = getchar(); ! 103: if( ch >= 0 ) { ! 104: *p = ch; ! 105: } else { ! 106: ret = 0; ! 107: } ! 108: } ! 109: PUSH( ret ); ! 110: } ! 111: ! 112: /* ( addr len -- actual ) */ ! 113: static void ! 114: tty_write( void ) ! 115: { ! 116: int i, len = POP(); ! 117: char *p = (char*)POP(); ! 118: for( i=0; i<len; i++ ) ! 119: putchar( *p++ ); ! 120: RET( len ); ! 121: } ! 122: ! 123: NODE_METHODS( tty ) = { ! 124: { "read", tty_read }, ! 125: { "write", tty_write }, ! 126: }; ! 127: ! 128: /************************************************************************/ ! 129: /* client interface 'quiesce' */ ! 130: /************************************************************************/ ! 131: ! 132: DECLARE_NODE( ciface, 0, 0, "/packages/client-iface" ); ! 133: ! 134: /* ( -- ) */ ! 135: static void ! 136: ciface_quiesce( unsigned long args[], unsigned long ret[] ) ! 137: { ! 138: #if 0 ! 139: unsigned long msr; ! 140: /* This seems to be the correct thing to do - but I'm not sure */ ! 141: asm volatile("mfmsr %0" : "=r" (msr) : ); ! 142: msr &= ~(MSR_IR | MSR_DR); ! 143: asm volatile("mtmsr %0" :: "r" (msr) ); ! 144: #endif ! 145: printk("=============================================================\n\n"); ! 146: } ! 147: ! 148: /* ( -- ms ) */ ! 149: static void ! 150: ciface_milliseconds( unsigned long args[], unsigned long ret[] ) ! 151: { ! 152: extern unsigned long get_timer_freq(); ! 153: static unsigned long mticks=0, usecs=0; ! 154: unsigned long t; ! 155: ! 156: asm volatile("mftb %0" : "=r" (t) : ); ! 157: if( mticks ) ! 158: usecs += get_timer_freq() / 1000000 * ( t-mticks ); ! 159: mticks = t; ! 160: ! 161: PUSH( usecs/1000 ); ! 162: } ! 163: ! 164: ! 165: NODE_METHODS( ciface ) = { ! 166: { "quiesce", ciface_quiesce }, ! 167: { "milliseconds", ciface_milliseconds }, ! 168: }; ! 169: ! 170: ! 171: /************************************************************************/ ! 172: /* MMU/memory methods */ ! 173: /************************************************************************/ ! 174: ! 175: DECLARE_NODE( memory, INSTALL_OPEN, 0, "/memory" ); ! 176: DECLARE_NODE( mmu, INSTALL_OPEN, 0, "/cpu@0" ); ! 177: DECLARE_NODE( mmu_ciface, 0, 0, "/packages/client-iface" ); ! 178: ! 179: ! 180: /* ( phys size align --- base ) */ ! 181: static void ! 182: mem_claim( void ) ! 183: { ! 184: ucell align = POP(); ! 185: ucell size = POP(); ! 186: ucell phys = POP(); ! 187: ucell ret = ofmem_claim_phys( phys, size, align ); ! 188: ! 189: if( ret == (ucell)-1 ) { ! 190: printk("MEM: claim failure\n"); ! 191: throw( -13 ); ! 192: return; ! 193: } ! 194: PUSH( ret ); ! 195: } ! 196: ! 197: /* ( phys size --- ) */ ! 198: static void ! 199: mem_release( void ) ! 200: { ! 201: POP(); POP(); ! 202: } ! 203: ! 204: /* ( phys size align --- base ) */ ! 205: static void ! 206: mmu_claim( void ) ! 207: { ! 208: ucell align = POP(); ! 209: ucell size = POP(); ! 210: ucell phys = POP(); ! 211: ucell ret = ofmem_claim_virt( phys, size, align ); ! 212: ! 213: if( ret == -1 ) { ! 214: printk("MMU: CLAIM failure\n"); ! 215: throw( -13 ); ! 216: return; ! 217: } ! 218: PUSH( ret ); ! 219: } ! 220: ! 221: /* ( phys size --- ) */ ! 222: static void ! 223: mmu_release( void ) ! 224: { ! 225: POP(); POP(); ! 226: } ! 227: ! 228: /* ( phys virt size mode -- [ret???] ) */ ! 229: static void ! 230: mmu_map( void ) ! 231: { ! 232: ucell mode = POP(); ! 233: ucell size = POP(); ! 234: ucell virt = POP(); ! 235: ucell phys = POP(); ! 236: ucell ret; ! 237: ! 238: /* printk("mmu_map: %x %x %x %x\n", phys, virt, size, mode ); */ ! 239: ret = ofmem_map( phys, virt, size, mode ); ! 240: ! 241: if( ret ) { ! 242: printk("MMU: map failure\n"); ! 243: throw( -13 ); ! 244: return; ! 245: } ! 246: } ! 247: ! 248: /* ( virt size -- ) */ ! 249: static void ! 250: mmu_unmap( void ) ! 251: { ! 252: POP(); POP(); ! 253: } ! 254: ! 255: /* ( virt -- false | phys mode true ) */ ! 256: static void ! 257: mmu_translate( void ) ! 258: { ! 259: ucell mode; ! 260: ucell virt = POP(); ! 261: ucell phys = ofmem_translate( virt, &mode ); ! 262: ! 263: if( phys == -1 ) { ! 264: PUSH( 0 ); ! 265: } else { ! 266: PUSH( phys ); ! 267: PUSH( mode ); ! 268: PUSH( -1 ); ! 269: } ! 270: } ! 271: ! 272: /* ( virt size align -- baseaddr|-1 ) */ ! 273: static void ! 274: ciface_claim( void ) ! 275: { ! 276: ucell align = POP(); ! 277: ucell size = POP(); ! 278: ucell virt = POP(); ! 279: ucell ret = ofmem_claim( virt, size, align ); ! 280: ! 281: /* printk("ciface_claim: %08x %08x %x\n", virt, size, align ); */ ! 282: PUSH( ret ); ! 283: } ! 284: ! 285: /* ( virt size -- ) */ ! 286: static void ! 287: ciface_release( void ) ! 288: { ! 289: POP(); ! 290: POP(); ! 291: } ! 292: ! 293: ! 294: NODE_METHODS( memory ) = { ! 295: { "claim", mem_claim }, ! 296: { "release", mem_release }, ! 297: }; ! 298: ! 299: NODE_METHODS( mmu ) = { ! 300: { "claim", mmu_claim }, ! 301: { "release", mmu_release }, ! 302: { "map", mmu_map }, ! 303: { "unmap", mmu_unmap }, ! 304: { "translate", mmu_translate }, ! 305: }; ! 306: ! 307: NODE_METHODS( mmu_ciface ) = { ! 308: { "cif-claim", ciface_claim }, ! 309: { "cif-release", ciface_release }, ! 310: }; ! 311: ! 312: ! 313: /************************************************************************/ ! 314: /* init */ ! 315: /************************************************************************/ ! 316: ! 317: void ! 318: node_methods_init( void ) ! 319: { ! 320: #ifdef CONFIG_RTAS ! 321: REGISTER_NODE( rtas ); ! 322: #endif ! 323: REGISTER_NODE( video_stdout ); ! 324: REGISTER_NODE( ciface ); ! 325: REGISTER_NODE( memory ); ! 326: REGISTER_NODE( mmu ); ! 327: REGISTER_NODE( mmu_ciface ); ! 328: REGISTER_NODE( tty ); ! 329: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.